@micha.bigler/ui-core-micha 3.14.4 → 4.0.1

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 (341) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +7 -0
  3. package/dist/chat/kitSxRegistry.js +9 -0
  4. package/dist/components/charts/kitSxRegistry.js +6 -0
  5. package/dist/entries/charts.js +6 -0
  6. package/dist/entries/chat.js +8 -0
  7. package/dist/entries/markdown.js +1 -0
  8. package/dist/index.js +0 -14
  9. package/dist/pages/AccountPage.js +1 -2
  10. package/dist/pages/LoginPage.js +1 -2
  11. package/dist/pages/PasswordChangePage.js +1 -2
  12. package/dist/pages/PasswordInvitePage.js +1 -2
  13. package/dist/pages/PasswordResetRequestPage.js +1 -2
  14. package/dist/pages/SignUpPage.js +1 -2
  15. package/dist/pages/SignupConfirmPage.js +1 -2
  16. package/dist/theme/kitSxEntry.js +11 -0
  17. package/dist/theme/kitSxRegistry.js +2 -15
  18. package/package.json +31 -7
  19. package/.github/workflows/ci.yml +0 -35
  20. package/.github/workflows/publish.yml +0 -126
  21. package/DESIGN.md +0 -60
  22. package/WORK_ORDERS.md +0 -150
  23. package/dev/entries.jsx +0 -721
  24. package/dev/fixtures.js +0 -26
  25. package/dev/main.jsx +0 -75
  26. package/dev/mockTransport.jsx +0 -128
  27. package/docs/CHART-LAYOUT.md +0 -157
  28. package/docs/DARK-TOKENS.md +0 -140
  29. package/docs/TYPE-SCALE.md +0 -111
  30. package/docs/messaging-deviations.md +0 -118
  31. package/index.html +0 -12
  32. package/renovate.json +0 -10
  33. package/scripts/chart-api-census.mjs +0 -415
  34. package/src/auth/AuthContext.jsx +0 -158
  35. package/src/auth/ReauthModal.jsx +0 -82
  36. package/src/auth/UserMenu.jsx +0 -121
  37. package/src/auth/apiClient.jsx +0 -232
  38. package/src/auth/authApi.jsx +0 -539
  39. package/src/auth/authConfig.jsx +0 -34
  40. package/src/auth/reauth.js +0 -47
  41. package/src/chat/ChatComposer.jsx +0 -36
  42. package/src/chat/ChatList.jsx +0 -87
  43. package/src/chat/ChatThread.jsx +0 -128
  44. package/src/chat/ChatWorkspace.jsx +0 -244
  45. package/src/chat/MarkdownReply.jsx +0 -22
  46. package/src/chat/ModelPicker.jsx +0 -85
  47. package/src/chat/api.js +0 -18
  48. package/src/chat/useChatSocket.js +0 -32
  49. package/src/chat/wire.js +0 -7
  50. package/src/components/AccessCodeManager.jsx +0 -288
  51. package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
  52. package/src/components/AllowedEmailDomainsManager.jsx +0 -92
  53. package/src/components/AuthFactorRequirementCard.jsx +0 -95
  54. package/src/components/BulkInviteCsvTab.jsx +0 -198
  55. package/src/components/EmptyState.jsx +0 -38
  56. package/src/components/LoginForm.jsx +0 -159
  57. package/src/components/MFAComponent.jsx +0 -350
  58. package/src/components/MfaLoginComponent.jsx +0 -252
  59. package/src/components/MobileBottomNav.jsx +0 -82
  60. package/src/components/PasskeysComponent.jsx +0 -252
  61. package/src/components/PasswordChangeForm.jsx +0 -87
  62. package/src/components/PasswordResetRequestForm.jsx +0 -43
  63. package/src/components/PasswordSetForm.jsx +0 -97
  64. package/src/components/ProfileComponent.jsx +0 -348
  65. package/src/components/QrSignupManager.jsx +0 -404
  66. package/src/components/QrSignupValidityManager.jsx +0 -106
  67. package/src/components/RegistrationMethodsManager.jsx +0 -150
  68. package/src/components/SecurityComponent.jsx +0 -141
  69. package/src/components/SocialLoginButtons.jsx +0 -83
  70. package/src/components/SoftChip.jsx +0 -93
  71. package/src/components/StatTile.jsx +0 -39
  72. package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
  73. package/src/components/TurnstileWidget.jsx +0 -99
  74. package/src/components/UserInviteComponent.jsx +0 -76
  75. package/src/components/UserListComponent.jsx +0 -618
  76. package/src/components/charts/BarChart.jsx +0 -102
  77. package/src/components/charts/ChartFrame.jsx +0 -214
  78. package/src/components/charts/LineChart.jsx +0 -126
  79. package/src/components/charts/ScatterChart.jsx +0 -299
  80. package/src/components/charts/TimeSeriesChart.jsx +0 -300
  81. package/src/components/charts/chartDefaults.js +0 -644
  82. package/src/components/charts/chartLabels.js +0 -36
  83. package/src/components/charts/exportChart.js +0 -258
  84. package/src/components/charts/formatters.js +0 -39
  85. package/src/components/charts/palette.js +0 -33
  86. package/src/components/charts/yearTickInterval.js +0 -7
  87. package/src/i18n/authTranslations.ts +0 -2651
  88. package/src/i18n/chartsTranslations.ts +0 -91
  89. package/src/i18n/chatTranslations.ts +0 -55
  90. package/src/i18n/messagingTranslations.ts +0 -120
  91. package/src/i18n/notificationsTranslations.ts +0 -32
  92. package/src/i18n/onboardingTranslations.ts +0 -29
  93. package/src/i18n/sectionNavTranslations.ts +0 -20
  94. package/src/i18n/uiCoreTranslations.js +0 -29
  95. package/src/i18n/userMenuTranslations.ts +0 -5
  96. package/src/index.js +0 -158
  97. package/src/layout/PageLayout.jsx +0 -36
  98. package/src/layout/SectionNav.jsx +0 -320
  99. package/src/messaging/AttachmentList.jsx +0 -145
  100. package/src/messaging/Composer.jsx +0 -197
  101. package/src/messaging/ConversationLaunchers.jsx +0 -51
  102. package/src/messaging/ConversationList.jsx +0 -109
  103. package/src/messaging/DirectMessageLauncher.jsx +0 -112
  104. package/src/messaging/MessageBubble.jsx +0 -183
  105. package/src/messaging/MessagingProvider.jsx +0 -0
  106. package/src/messaging/MessagingScopeConfig.jsx +0 -24
  107. package/src/messaging/PollCard.jsx +0 -163
  108. package/src/messaging/ReactionBar.jsx +0 -43
  109. package/src/messaging/ReadTicks.jsx +0 -82
  110. package/src/messaging/Thread.jsx +0 -195
  111. package/src/messaging/api.js +0 -48
  112. package/src/messaging/composerImageCompression.js +0 -35
  113. package/src/messaging/linkifyText.jsx +0 -37
  114. package/src/notifications/NotificationBell.jsx +0 -84
  115. package/src/notifications/NotificationSettings.jsx +0 -330
  116. package/src/notifications/NotificationsProvider.jsx +0 -224
  117. package/src/notifications/PopupSurface.jsx +0 -105
  118. package/src/notifications/api.js +0 -55
  119. package/src/notifications/feedApi.js +0 -18
  120. package/src/notifications/realtime.jsx +0 -138
  121. package/src/notifications/serviceWorker/sw.js +0 -50
  122. package/src/onboarding/OnboardingProvider.jsx +0 -326
  123. package/src/onboarding/OnboardingWizard.jsx +0 -61
  124. package/src/onboarding/WizardDialogShell.jsx +0 -51
  125. package/src/onboarding/api.js +0 -13
  126. package/src/onboarding/stepSelection.js +0 -16
  127. package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
  128. package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
  129. package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
  130. package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
  131. package/src/pages/AccountPage.jsx +0 -394
  132. package/src/pages/LoginPage.jsx +0 -343
  133. package/src/pages/PasswordChangePage.jsx +0 -62
  134. package/src/pages/PasswordInvitePage.jsx +0 -177
  135. package/src/pages/PasswordResetRequestPage.jsx +0 -68
  136. package/src/pages/SignUpPage.jsx +0 -268
  137. package/src/pages/SignupConfirmPage.jsx +0 -155
  138. package/src/testing/checkKitIntegration.js +0 -233
  139. package/src/theme/createAppTheme.js +0 -423
  140. package/src/theme/fonts.js +0 -3
  141. package/src/theme/index.js +0 -21
  142. package/src/theme/kitSxRegistry.js +0 -285
  143. package/src/theme/themeCompleteness.js +0 -1045
  144. package/src/theme/tokens.js +0 -478
  145. package/src/utils/auth-errors.js +0 -76
  146. package/src/utils/authService.js +0 -223
  147. package/src/utils/resolveErrorText.js +0 -28
  148. package/src/utils/webauthn.js +0 -51
  149. package/tests/AccountPage.profileStatements.test.jsx +0 -162
  150. package/tests/AccountPage.test.jsx +0 -200
  151. package/tests/AuthContext.test.jsx +0 -129
  152. package/tests/BarChart.test.jsx +0 -112
  153. package/tests/BrowserPushStep.test.jsx +0 -110
  154. package/tests/ChartFrame.test.jsx +0 -336
  155. package/tests/ConversationList.test.jsx +0 -144
  156. package/tests/CookieConsentStep.test.jsx +0 -69
  157. package/tests/EmptyState.test.jsx +0 -62
  158. package/tests/LineChart.test.jsx +0 -80
  159. package/tests/MessagingProvider.test.jsx +0 -50
  160. package/tests/MobileBottomNav.test.jsx +0 -319
  161. package/tests/NotificationBell.test.jsx +0 -60
  162. package/tests/NotificationSettings.test.jsx +0 -276
  163. package/tests/NotificationsProvider.test.jsx +0 -240
  164. package/tests/OnboardingProvider.test.jsx +0 -294
  165. package/tests/OnboardingWizard.test.jsx +0 -143
  166. package/tests/PasswordChangeForm.test.jsx +0 -70
  167. package/tests/PasswordInvitePage.test.jsx +0 -142
  168. package/tests/PasswordSetForm.test.jsx +0 -70
  169. package/tests/PopupSurface.test.jsx +0 -142
  170. package/tests/ProfileComponent.refresh.test.jsx +0 -194
  171. package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
  172. package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
  173. package/tests/ScatterChart.test.jsx +0 -270
  174. package/tests/SectionNav.test.jsx +0 -363
  175. package/tests/SignUpPage.test.jsx +0 -208
  176. package/tests/SoftChip.test.jsx +0 -105
  177. package/tests/StatTile.test.jsx +0 -57
  178. package/tests/Thread.test.jsx +0 -151
  179. package/tests/TimeSeriesChart.test.jsx +0 -367
  180. package/tests/UserListComponent.test.jsx +0 -192
  181. package/tests/UserMenu.test.jsx +0 -171
  182. package/tests/apiClientLanguage.test.js +0 -33
  183. package/tests/apiClientPublicPaths.test.js +0 -178
  184. package/tests/authApiLogin.test.js +0 -42
  185. package/tests/authApiRegistration.test.js +0 -31
  186. package/tests/authErrorCodeRendering.test.jsx +0 -77
  187. package/tests/authErrors.test.js +0 -74
  188. package/tests/authTranslations.test.js +0 -74
  189. package/tests/chart-api-census.test.js +0 -366
  190. package/tests/chartAxisTickBand.test.jsx +0 -95
  191. package/tests/chartDefaults.test.js +0 -902
  192. package/tests/chartLabels.test.js +0 -50
  193. package/tests/chartsPalette.test.js +0 -99
  194. package/tests/chatApi.test.js +0 -48
  195. package/tests/chatDriverNames.test.jsx +0 -71
  196. package/tests/chatExports.test.js +0 -3
  197. package/tests/chatList.test.jsx +0 -84
  198. package/tests/chatPicker.test.jsx +0 -82
  199. package/tests/chatSocket.test.jsx +0 -26
  200. package/tests/chatThread.test.jsx +0 -116
  201. package/tests/chatTranslations.test.js +0 -47
  202. package/tests/chatWorkspace.test.jsx +0 -234
  203. package/tests/checkKitIntegration.test.jsx +0 -219
  204. package/tests/createAppTheme.test.js +0 -132
  205. package/tests/createAppThemeDark.test.js +0 -127
  206. package/tests/createAppThemeLightGuard.test.js +0 -40
  207. package/tests/createAppThemePageContrast.test.js +0 -108
  208. package/tests/createAppThemeTypography.test.js +0 -53
  209. package/tests/errorCallSiteGuard.test.js +0 -32
  210. package/tests/exportChart.test.js +0 -313
  211. package/tests/feedApi.test.js +0 -46
  212. package/tests/fixtures/light-theme-baseline.json +0 -2234
  213. package/tests/i18nAggregate.test.js +0 -120
  214. package/tests/i18nGermanVariant.test.js +0 -65
  215. package/tests/loginPageErrorResolution.test.jsx +0 -102
  216. package/tests/messagingApi.test.js +0 -32
  217. package/tests/messagingChunk6.test.jsx +0 -116
  218. package/tests/messagingCompactBubble.test.jsx +0 -64
  219. package/tests/messagingComposer.test.jsx +0 -136
  220. package/tests/messagingComposerChunk5.test.jsx +0 -113
  221. package/tests/messagingContractConformance.test.js +0 -69
  222. package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
  223. package/tests/messagingExports.test.js +0 -21
  224. package/tests/messagingInteractions.test.jsx +0 -136
  225. package/tests/messagingLastMessagePreview.test.jsx +0 -93
  226. package/tests/messagingLinkify.test.jsx +0 -51
  227. package/tests/messagingMessageActions.test.jsx +0 -163
  228. package/tests/messagingMsg6.test.jsx +0 -105
  229. package/tests/messagingMsg6f.test.jsx +0 -155
  230. package/tests/messagingMsg6g.test.jsx +0 -166
  231. package/tests/messagingMsg6h.test.jsx +0 -136
  232. package/tests/messagingMsg6i.test.jsx +0 -129
  233. package/tests/messagingPollRendering.test.jsx +0 -142
  234. package/tests/messagingReactionMerge.test.jsx +0 -77
  235. package/tests/messagingReadTicksTooltip.test.jsx +0 -36
  236. package/tests/messagingThreadReceipts.test.jsx +0 -178
  237. package/tests/messagingThreadingQuoting.test.jsx +0 -87
  238. package/tests/messagingUnreadLifecycle.test.jsx +0 -78
  239. package/tests/notificationsApi.test.js +0 -41
  240. package/tests/notificationsExports.test.js +0 -34
  241. package/tests/onboardingDescriptors.test.js +0 -132
  242. package/tests/packageTreeShaking.test.js +0 -126
  243. package/tests/realtime.test.jsx +0 -219
  244. package/tests/resolveErrorText.test.js +0 -72
  245. package/tests/stepSelection.test.js +0 -53
  246. package/tests/themeCompleteness.test.js +0 -626
  247. package/tests/timeSeriesLegend.test.js +0 -99
  248. package/tests/userScreenTranslations.test.jsx +0 -218
  249. package/tsconfig.build.json +0 -18
  250. package/vite.config.mjs +0 -6
  251. package/work-orders/AUTH-1.md +0 -74
  252. package/work-orders/AUTH-2.md +0 -74
  253. package/work-orders/AUTH-4.md +0 -183
  254. package/work-orders/AUTH-5.md +0 -154
  255. package/work-orders/AUTH-7.md +0 -181
  256. package/work-orders/AUTH-8.md +0 -184
  257. package/work-orders/CHART-1.md +0 -285
  258. package/work-orders/CHART-2.md +0 -222
  259. package/work-orders/CHART-3.md +0 -163
  260. package/work-orders/CHART-4.md +0 -203
  261. package/work-orders/CHART-5.md +0 -226
  262. package/work-orders/CHART-6.md +0 -428
  263. package/work-orders/CHART-7.md +0 -175
  264. package/work-orders/DX-1.md +0 -169
  265. package/work-orders/DX-2.md +0 -188
  266. package/work-orders/DX-3.md +0 -195
  267. package/work-orders/I18N-1.md +0 -254
  268. package/work-orders/I18N-3.md +0 -207
  269. package/work-orders/MSG-3.md +0 -375
  270. package/work-orders/MSG-3b.md +0 -1002
  271. package/work-orders/MSG-3c.md +0 -378
  272. package/work-orders/MSG-3d.md +0 -268
  273. package/work-orders/MSG-3e.md +0 -164
  274. package/work-orders/MSG-3f.md +0 -391
  275. package/work-orders/MSG-6e.md +0 -308
  276. package/work-orders/MSG-6f.md +0 -214
  277. package/work-orders/MSG-6g.md +0 -244
  278. package/work-orders/MSG-6h.md +0 -238
  279. package/work-orders/MSG-6i.md +0 -271
  280. package/work-orders/MSG-6j.md +0 -117
  281. package/work-orders/NOTIF-12.md +0 -214
  282. package/work-orders/NOTIF-13.md +0 -142
  283. package/work-orders/NOTIF-14.md +0 -151
  284. package/work-orders/PRIM-1.md +0 -177
  285. package/work-orders/SHELL-1.md +0 -255
  286. package/work-orders/SHELL-2.md +0 -197
  287. package/work-orders/SHELL-3.md +0 -359
  288. package/work-orders/SHELL-4.md +0 -351
  289. package/work-orders/SHELL-5.md +0 -345
  290. package/work-orders/SHELL-6.md +0 -210
  291. package/work-orders/THEME-1.md +0 -587
  292. package/work-orders/THEME-10.md +0 -303
  293. package/work-orders/THEME-11.md +0 -208
  294. package/work-orders/THEME-2.md +0 -339
  295. package/work-orders/THEME-3.md +0 -210
  296. package/work-orders/THEME-4.md +0 -271
  297. package/work-orders/THEME-5.md +0 -341
  298. package/work-orders/THEME-6.md +0 -247
  299. package/work-orders/THEME-7.md +0 -82
  300. package/work-orders/THEME-8.md +0 -211
  301. package/work-orders/THEME-9.md +0 -194
  302. package/work-orders/UCM-AUTH-10.md +0 -490
  303. package/work-orders/UCM-AUTH-11.md +0 -185
  304. package/work-orders/UCM-AUTH-12.md +0 -98
  305. package/work-orders/UCM-AUTH-13.md +0 -47
  306. package/work-orders/UCM-AUTH-9.md +0 -207
  307. package/work-orders/UCM-CHART-10.md +0 -150
  308. package/work-orders/UCM-CHART-11.md +0 -132
  309. package/work-orders/UCM-CHART-12.md +0 -348
  310. package/work-orders/UCM-CHART-13.md +0 -122
  311. package/work-orders/UCM-CHART-14.md +0 -198
  312. package/work-orders/UCM-CHART-15.md +0 -187
  313. package/work-orders/UCM-CHART-16.md +0 -169
  314. package/work-orders/UCM-CHART-17.md +0 -195
  315. package/work-orders/UCM-CHART-18.md +0 -200
  316. package/work-orders/UCM-CHART-8.md +0 -147
  317. package/work-orders/UCM-CHART-9.md +0 -265
  318. package/work-orders/UCM-CHAT-1.md +0 -190
  319. package/work-orders/UCM-CHAT-2.md +0 -75
  320. package/work-orders/UCM-CI-1.md +0 -65
  321. package/work-orders/UCM-DEP-1.md +0 -63
  322. package/work-orders/UCM-I18N-4.md +0 -226
  323. package/work-orders/UCM-I18N-5.md +0 -211
  324. package/work-orders/UCM-MSG-20.md +0 -192
  325. package/work-orders/UCM-PRIM-2.md +0 -114
  326. package/work-orders/UCM-SHELL-7.md +0 -134
  327. package/work-orders/UCM-SHELL-8.md +0 -125
  328. package/work-orders/UCM-TEST-1.md +0 -304
  329. package/work-orders/UCM-THEME-13.md +0 -69
  330. package/work-orders/UCM-THEME-14.md +0 -312
  331. package/work-orders/UCM-THEME-15.md +0 -356
  332. package/work-orders/UCM-THEME-16.md +0 -80
  333. package/work-orders/UCM-THEME-17.md +0 -111
  334. package/work-orders/UCM-THEME-18.md +0 -184
  335. package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
  336. package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
  337. package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
  338. package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
  339. package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
  340. package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
  341. package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
@@ -1,1352 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>DS2 — MUI Theme Baseline Reference Sheet</title>
7
- <style>
8
- /* DM Sans, weights 400/500/600, embedded below as base64 woff2.
9
- Copyright 2014 The DM Sans Project Authors (https://github.com/googlefonts/dm-fonts).
10
- Licensed under the SIL Open Font License, Version 1.1 -- http://scripts.sil.org/OFL
11
- OFL requires the copyright notice and licence to accompany the font files, which is why
12
- this notice sits here: embedding the binary is redistribution. Source: the
13
- @fontsource/dm-sans@5.2.8 package already vendored in this estate ("license": "OFL-1.1").
14
- Not modified, so the Reserved Font Name clause does not apply. */
15
- @font-face { font-family:'DM Sans'; font-style:normal; font-weight:400; font-display:swap;
16
- src:url(data:font/woff2;base64,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) format('woff2'); }
17
- @font-face { font-family:'DM Sans'; font-style:normal; font-weight:500; font-display:swap;
18
- src:url(data:font/woff2;base64,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) format('woff2'); }
19
- @font-face { font-family:'DM Sans'; font-style:normal; font-weight:600; font-display:swap;
20
- src:url(data:font/woff2;base64,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) format('woff2'); }
21
-
22
-
23
- /* ============================================================
24
- /* ============================================================
25
- BASELINE TOKENS — DECIDED (v4). No A/B/C variants remain:
26
- bg-page is #FAFAFA (operator, 2026-08-09); the four-value
27
- candidate strip further down is provenance, not a live choice.
28
- Every value here also appears in the "Canonical baseline
29
- tokens" table at the END of the document, which is the value
30
- source a work order should reference instead of retyping numbers.
31
- ============================================================ */
32
- :root{
33
- --ink-1:#212529; --ink-2:#5B6670; --ink-3:#6A7178;
34
- --border-c: rgba(33,37,41,0.10);
35
- --control-border: rgba(33,37,41,0.50);
36
- --control-border-hover: rgba(33,37,41,0.65);
37
- --control-border-focus: #3D5A99;
38
- --focus-ring: #3D5A99; --focus-ring-width: 2px;
39
- --control-border-error: #BF3227;
40
- --bg-page:#FAFAFA; --bg-surface:#FFFFFF;
41
-
42
- --success:#35794A; --success-bg:#E5F4E9;
43
- --success-fill:#1B8038; --success-fill-text:#FFFFFF;
44
-
45
- --warning:#976100; --warning-bg:#FBF0DC;
46
- --warning-fill:#C08A2C; --warning-fill-text:#212529;
47
-
48
- --stale:#5B6B7D; --stale-bg:#EAEDF1;
49
- --stale-fill:#5B6B7D; --stale-fill-text:#FFFFFF;
50
-
51
- --critical:#BF3227; --critical-bg:#FBEAE8;
52
- --critical-fill:#BF3227; --critical-fill-text:#FFFFFF;
53
-
54
- --shadow-rest: none;
55
- --shadow-overlay: 0 8px 24px rgba(20,26,31,0.16), 0 2px 8px rgba(20,26,31,0.08);
56
-
57
- --radius-control: 3px; --radius-card: 8px;
58
-
59
- --font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
60
- --font-note: 'DM Sans (embedded)';
61
-
62
- /* Typography — decided scale, no A/B/C left */
63
- --fs-h1:32px; --fw-h1:600; --lh-h1:1.2;
64
- --fs-h2:28px; --fw-h2:600; --lh-h2:1.22;
65
- --fs-h3:24px; --fw-h3:600; --lh-h3:1.25;
66
- --fs-h4:20px; --fw-h4:600; --lh-h4:1.3;
67
- --fs-h5:18px; --fw-h5:600; --lh-h5:1.3;
68
- --fs-h6:16px; --fw-h6:600; --lh-h6:1.35;
69
- --fs-sub1:15px; --fw-sub1:600; --lh-sub1:1.4;
70
- --fs-sub2:13px; --fw-sub2:500; --lh-sub2:1.4;
71
- --fs-body1:14px; --fw-body1:400; --lh-body1:1.55;
72
- --fs-body2:13px; --fw-body2:400; --lh-body2:1.55;
73
- --fs-btn:14px; --fw-btn:500; --tt-btn:none; --ls-btn:0;
74
- --fs-cap:12px; --fw-cap:400; --lh-cap:1.4;
75
- --fs-ov:11px; --fw-ov:600; --tt-ov:uppercase; --ls-ov:0.4px;
76
-
77
- /* Density — single decided step, 40px control */
78
- --control-h: 40px;
79
- --table-pad: 10px 16px;
80
- --chip-h: 32px; --chip-radius: 16px; --chip-fs: 13px;
81
-
82
- --btn-radius: var(--radius-control);
83
- --btn-shadow-contained: none;
84
- --input-border: rgba(33,37,41,0.23);
85
- --input-border-hover: rgba(33,37,41,0.45);
86
- }
87
-
88
- /* 40px is the desktop/mouse control height; bump to the 44px touch
89
- guideline under a coarse pointer. any-pointer, not pointer, so hybrid devices with
90
- both a mouse and a touchscreen are covered. NOTE: 44px is WCAG 2.5.5 (AAA) and an
91
- INTERNAL principle here -- the AA floor is 24x24 (2.5.8). Visual size may stay
92
- smaller than 44; the HIT AREA must reach it. */
93
- @media (any-pointer: coarse) {
94
- :root{ --control-h: 44px; }
95
- }
96
-
97
- /* ============================================================
98
- MUI RAW DEFAULT — Material Design 2014 theme, undisturbed.
99
- Values transcribed from MUI v7's documented theme defaults
100
- (typography scale, shape.borderRadius=4, shadows[1]/[2]/[24],
101
- palette.text.primary/secondary/disabled, Alert color mixes).
102
- Font: MUI's actual default is Roboto; since embedding a second
103
- full font family purely for a column label isn't warranted,
104
- this column renders in a plain system-sans stand-in — labelled
105
- below so no one mistakes it for a font judgment.
106
- ============================================================ */
107
- .th-mui{
108
- --ink-1: rgba(0,0,0,0.87); --ink-2: rgba(0,0,0,0.6); --ink-3: rgba(0,0,0,0.38);
109
- --border-c: rgba(0,0,0,0.12);
110
- --bg-page:#FFFFFF; --bg-surface:#FFFFFF;
111
-
112
- --success:#2E7D32; --success-bg:#EDF7ED;
113
- --warning:#663C00; --warning-bg:#FFF4E5;
114
- --stale:#014361; --stale-bg:#E5F6FD; /* MUI has no "stale" — nearest built-in is info (blue) */
115
- --critical:#5F2120; --critical-bg:#FDEDED;
116
-
117
- --shadow-rest: 0px 2px 1px -1px rgba(0,0,0,0.2), 0px 1px 1px 0px rgba(0,0,0,0.14), 0px 1px 3px 0px rgba(0,0,0,0.12);
118
- --shadow-overlay: 0px 11px 15px -7px rgba(0,0,0,0.2), 0px 24px 38px 3px rgba(0,0,0,0.14), 0px 9px 46px 8px rgba(0,0,0,0.12);
119
-
120
- --radius-control: 4px; --radius-card: 4px;
121
-
122
- --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
123
- --font-note: 'system sans — Roboto stand-in, undisclosed swap would be dishonest so it is named here';
124
-
125
- --fs-h1:96px; --fw-h1:300; --lh-h1:1.1;
126
- --fs-h2:60px; --fw-h2:300; --lh-h2:1.15;
127
- --fs-h3:48px; --fw-h3:400; --lh-h3:1.15;
128
- --fs-h4:34px; --fw-h4:400; --lh-h4:1.2;
129
- --fs-h5:24px; --fw-h5:400; --lh-h5:1.25;
130
- --fs-h6:20px; --fw-h6:500; --lh-h6:1.3;
131
- --fs-sub1:16px; --fw-sub1:400; --lh-sub1:1.5;
132
- --fs-sub2:14px; --fw-sub2:500; --lh-sub2:1.5;
133
- --fs-body1:16px; --fw-body1:400; --lh-body1:1.5;
134
- --fs-body2:14px; --fw-body2:400; --lh-body2:1.5;
135
- --fs-btn:14px; --fw-btn:500; --tt-btn:uppercase; --ls-btn:0.02857em;
136
- --fs-cap:12px; --fw-cap:400; --lh-cap:1.4;
137
- --fs-ov:12px; --fw-ov:500; --tt-ov:uppercase; --ls-ov:1px;
138
-
139
- --control-h: 56px;
140
- --table-pad: 16px;
141
- --chip-h: 32px; --chip-radius: 16px; --chip-fs: 13px;
142
-
143
- --btn-radius: 4px;
144
- --btn-shadow-contained: 0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12);
145
- --input-border: rgba(0,0,0,0.23);
146
- --input-border-hover: rgba(0,0,0,0.87);
147
- }
148
-
149
- /* ============================================================
150
- BASE / LAYOUT
151
- ============================================================ */
152
- *{ box-sizing:border-box; }
153
- html,body{ margin:0; padding:0; background:#EEF1F3; color:#1a1e22; color-scheme: light only;
154
- font-family:'DM Sans','Segoe UI',sans-serif; font-variant-numeric:tabular-nums; }
155
- body{ padding:32px 28px 80px; }
156
- .doc-wrap{ max-width:1400px; margin:0 auto; }
157
-
158
- h1.doc-title{ font-family:'DM Sans',sans-serif; font-size:26px; font-weight:600; margin:0 0 4px; color:#14181c; }
159
- p.doc-sub{ font-size:13.5px; color:#5B6670; margin:0 0 28px; max-width:920px; line-height:1.55; }
160
-
161
- section.doc-section{ background:#fff; border:1px solid #E1E5E9; border-radius:12px; padding:22px 26px; margin-bottom:20px; }
162
- section.doc-section > h2{ font-size:16px; font-weight:600; margin:0 0 6px; color:#14181c; }
163
- section.doc-section > h3{ font-size:13.5px; font-weight:600; margin:20px 0 10px; color:#14181c; text-transform:uppercase; letter-spacing:0.3px; }
164
- section.doc-section > p.section-note{ font-size:13px; line-height:1.6; color:#5B6670; margin:0 0 16px; max-width:980px; }
165
- section.doc-section code{ font-family:ui-monospace,Consolas,monospace; font-size:12px; background:#F0F2F4; padding:1px 5px; border-radius:4px; }
166
-
167
- .axis-badge{ display:inline-flex; align-items:center; gap:6px; background:#EEF1F5; border:1px solid #D7DEE4; color:#3A4552;
168
- font-size:11px; font-weight:600; padding:3px 10px; border-radius:20px; margin-bottom:14px; }
169
-
170
- /* ---- column grid ---- */
171
- .cols{ display:flex; gap:18px; align-items:flex-start; flex-wrap:wrap; }
172
- .col{ background:var(--bg-page); border:1px solid #E1E5E9; border-radius:10px; padding:16px; flex:1 1 260px; min-width:230px; }
173
- .col-label{ font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:#6A7178;
174
- display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
175
- .col-label .tag{ font-size:9.5px; font-weight:700; padding:1px 6px; border-radius:8px; text-transform:none; letter-spacing:0.2px; }
176
- .col-label .tag.mui{ background:#FCE9E7; color:#8B2E23; }
177
- .col-label .tag.cand{ background:#E5F4E9; color:#1E6B32; }
178
- .col-sub{ font-size:11.5px; color:#6A7178; margin:-8px 0 12px; font-weight:400; text-transform:none; letter-spacing:0; }
179
-
180
- .stack{ display:flex; flex-direction:column; gap:10px; }
181
- .row{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
182
-
183
- /* ---- computed contrast badges (see inline script at end of body) ---- */
184
- .ratio-badge{ display:inline-flex; align-items:center; gap:4px; font-size:11.5px; font-weight:700;
185
- padding:2px 8px; border-radius:20px; font-family:ui-monospace,Consolas,monospace; margin-left:6px;
186
- white-space:nowrap; vertical-align:middle; }
187
- .ratio-badge.pass{ background:#E5F4E9; color:#1E6B32; }
188
- .ratio-badge.fail{ background:#FBEAE8; color:#8B2E23; }
189
- .ratio-row{ display:flex; align-items:center; flex-wrap:wrap; gap:4px; margin-top:4px; }
190
- .ratio-row .ratio-label{ font-size:11.5px; color:#6A7178; }
191
-
192
- /* ============================================================
193
- TYPOGRAPHY SPECIMENS
194
- ============================================================ */
195
- .type-line{ font-family:var(--font-family); color:var(--ink-1); margin:0 0 10px; }
196
- .type-line .tag{ font-size:9.5px; font-weight:600; color:#6A7178; margin-left:8px; vertical-align:middle; }
197
- .t-h1{ font-size:var(--fs-h1); font-weight:var(--fw-h1); line-height:var(--lh-h1); }
198
- .t-h2{ font-size:var(--fs-h2); font-weight:var(--fw-h2); line-height:var(--lh-h2); }
199
- .t-h3{ font-size:var(--fs-h3); font-weight:var(--fw-h3); line-height:var(--lh-h3); }
200
- .t-h4{ font-size:var(--fs-h4); font-weight:var(--fw-h4); line-height:var(--lh-h4); }
201
- .t-h5{ font-size:var(--fs-h5); font-weight:var(--fw-h5); line-height:var(--lh-h5); }
202
- .t-h6{ font-size:var(--fs-h6); font-weight:var(--fw-h6); line-height:var(--lh-h6); }
203
- .t-sub1{ font-size:var(--fs-sub1); font-weight:var(--fw-sub1); line-height:var(--lh-sub1); }
204
- .t-sub2{ font-size:var(--fs-sub2); font-weight:var(--fw-sub2); line-height:var(--lh-sub2); color:var(--ink-2); }
205
- .t-body1{ font-size:var(--fs-body1); font-weight:var(--fw-body1); line-height:var(--lh-body1); }
206
- .t-body2{ font-size:var(--fs-body2); font-weight:var(--fw-body2); line-height:var(--lh-body2); color:var(--ink-2); }
207
- .t-btn{ font-size:var(--fs-btn); font-weight:var(--fw-btn); text-transform:var(--tt-btn); letter-spacing:var(--ls-btn); }
208
- .t-cap{ font-size:var(--fs-cap); font-weight:var(--fw-cap); line-height:var(--lh-cap); color:var(--ink-3); }
209
- .t-ov{ font-size:var(--fs-ov); font-weight:var(--fw-ov); text-transform:var(--tt-ov); letter-spacing:var(--ls-ov); color:var(--ink-3); }
210
-
211
- /* ============================================================
212
- COMPONENTS
213
- ============================================================ */
214
-
215
- /* Buttons */
216
- .sf-btn{ font-family:var(--font-family); font-size:var(--fs-btn); font-weight:var(--fw-btn);
217
- text-transform:var(--tt-btn); letter-spacing:var(--ls-btn); border-radius:var(--btn-radius);
218
- height:var(--control-h); padding:0 18px; display:inline-flex; align-items:center; justify-content:center;
219
- border:1px solid transparent; cursor:default; white-space:nowrap; }
220
- .sf-btn--sm{ height:calc(var(--control-h) - 12px); padding:0 12px; font-size:calc(var(--fs-btn) - 1px); }
221
- .sf-btn--lg{ height:calc(var(--control-h) + 8px); padding:0 24px; }
222
- .sf-btn--contained{ background:#3D5A99; color:#fff; box-shadow:var(--btn-shadow-contained); }
223
- .sf-btn--outlined{ background:transparent; color:#3D5A99; border-color:var(--control-border); }
224
- .sf-btn--text{ background:transparent; color:#3D5A99; }
225
-
226
- /* Table */
227
- .sf-table{ width:100%; border-collapse:collapse; font-family:var(--font-family); background:var(--bg-surface);
228
- border:1px solid var(--border-c); border-radius:var(--radius-card); overflow:hidden; }
229
- .sf-table th{ text-align:left; font-size:var(--fs-body2); font-weight:600; color:var(--ink-1);
230
- padding:var(--table-pad); border-bottom:1px solid var(--border-c); background:var(--bg-page); }
231
- .sf-table td{ font-size:var(--fs-body2); color:var(--ink-2); padding:var(--table-pad); border-bottom:1px solid var(--border-c); }
232
- .sf-table tr:last-child td{ border-bottom:none; }
233
-
234
- /* Icon button */
235
- .sf-icon-btn{ width:var(--control-h); height:var(--control-h); max-width:40px; max-height:40px;
236
- border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:var(--ink-2); background:transparent; }
237
- .sf-icon-btn svg{ width:19px; height:19px; }
238
-
239
- /* Divider */
240
- .sf-divider{ height:1px; background:var(--border-c); border:none; margin:14px 0; }
241
-
242
- /* Tooltip — transient surface, keeps a real shadow */
243
- .sf-tooltip-wrap{ position:relative; display:inline-block; }
244
- .sf-tooltip{ position:absolute; bottom:calc(100% + 8px); left:50%; transform:translateX(-50%);
245
- background:var(--ink-1); color:#fff; font-size:11px; font-weight:500; padding:5px 9px; border-radius:6px;
246
- white-space:nowrap; box-shadow:var(--shadow-overlay); }
247
- .th-mui .sf-tooltip{ background:rgba(97,97,97,0.92); border-radius:4px; font-size:10px; padding:4px 8px; }
248
- .sf-tooltip:after{ content:''; position:absolute; top:100%; left:50%; transform:translateX(-50%);
249
- border:5px solid transparent; border-top-color:var(--ink-1); }
250
- .th-mui .sf-tooltip:after{ border-top-color:rgba(97,97,97,0.92); }
251
-
252
- /* Select / TextField — rest/hover/focus/error boundary uses --control-border*,
253
- the interactive-control tier of the border split (>=3:1 vs. surface). The
254
- old --input-border/--input-border-hover tokens are kept below only as the
255
- "before" comparison value (they measured under 3:1 and are superseded). */
256
- .sf-field{ display:flex; flex-direction:column; gap:4px; }
257
- .sf-field-label{ font-size:11px; font-weight:600; color:var(--ink-2); }
258
- .sf-ph{ color:var(--ink-3); }
259
- .sf-caret{ margin-left:auto; color:var(--ink-2); flex:none; }
260
- .sf-select, .sf-input{ display:flex; align-items:center; gap:8px; font-family:var(--font-family); font-size:14px; color:var(--ink-1); height:var(--control-h);
261
- border:1px solid var(--control-border); border-radius:var(--radius-control); padding:0 12px; background:var(--bg-surface);
262
- min-width:170px; }
263
- .sf-select.state-hover, .sf-input.state-hover{ border-color:var(--control-border-hover); }
264
- .sf-select.state-focus, .sf-input.state-focus{ border-color:var(--control-border-focus); box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring); outline:none; }
265
- .sf-select.state-error, .sf-input.state-error{ border-color:var(--control-border-error); }
266
- .th-mui .sf-select, .th-mui .sf-input{ border-color:rgba(0,0,0,0.23); }
267
- .th-mui .sf-select.state-hover, .th-mui .sf-input.state-hover{ border-color:rgba(0,0,0,0.87); }
268
- .th-mui .sf-select.state-focus, .th-mui .sf-input.state-focus{ border-color:#1976d2; box-shadow:0 0 0 1px #1976d2; }
269
- .th-mui .sf-select.state-error, .th-mui .sf-input.state-error{ border-color:#d32f2f; }
270
- .sf-outlined-wrap{ position:relative; display:inline-block; }
271
- .sf-outlined-wrap .float-label{ position:absolute; top:-7px; left:10px; background:var(--bg-surface); padding:0 5px;
272
- font-size:11px; font-weight:600; color:var(--ink-2); }
273
-
274
- /* Checkbox / FormControlLabel — box boundary is a control border too */
275
- .sf-checkbox{ width:18px; height:18px; border-radius:3px; border:2px solid var(--control-border); display:inline-flex;
276
- align-items:center; justify-content:center; flex-shrink:0; }
277
- .sf-checkbox.checked{ background:#3D5A99; border-color:#3D5A99; }
278
- .sf-checkbox.checked:after{ content:''; width:5px; height:9px; border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg) translate(-1px,-1px); }
279
- .sf-fcl{ display:flex; align-items:center; gap:8px; font-family:var(--font-family); font-size:var(--fs-body1); color:var(--ink-1); }
280
-
281
- /* Container */
282
- .sf-container-demo{ background:repeating-linear-gradient(90deg, rgba(61,90,153,0.07) 0 1px, transparent 1px 8px); border:1px dashed #B9C2CB; border-radius:6px; }
283
- .sf-container-inner{ background:var(--bg-surface); border-left:2px dashed #3D5A99; border-right:2px dashed #3D5A99; height:54px;
284
- display:flex; align-items:center; padding:0 16px; font-size:11px; color:#3D5A99; font-weight:600; }
285
-
286
- /* Paper / Card — rest state is border-only for the candidate, no exceptions.
287
- Real shadow is reserved for transient surfaces (Dialog, Drawer, Menu, Tooltip). */
288
- .sf-paper{ background:var(--bg-surface); border-radius:var(--radius-card); padding:16px; font-family:var(--font-family); }
289
- .sf-paper--outlined{ border:1px solid var(--border-c); box-shadow:none; }
290
- .sf-paper--elevation{ border:1px solid var(--border-c); box-shadow:var(--shadow-rest); }
291
- .th-mui .sf-paper--elevation{ border:1px solid transparent; box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.14),0px 2px 1px -1px rgba(0,0,0,0.12),0px 1px 3px 0px rgba(0,0,0,0.2); }
292
- .sf-card-title{ font-size:var(--fs-h6); font-weight:var(--fw-h6); color:var(--ink-1); margin-bottom:4px; }
293
- .sf-card-body{ font-size:var(--fs-body2); color:var(--ink-2); }
294
-
295
- /* Chip */
296
- .sf-chip{ display:inline-flex; align-items:center; height:var(--chip-h); padding:0 12px; border-radius:var(--chip-radius);
297
- font-size:var(--chip-fs); font-weight:500; font-family:var(--font-family); background:#E9EEF5; color:#2F4E86; gap:6px; }
298
- .sf-chip.outlined{ background:transparent; border:1px solid var(--control-border); color:var(--ink-2); }
299
-
300
- /* Status fill chip — the new "fill + contrastText" role, distinct from the
301
- text/icon role and from the pale Alert background tint below. */
302
- .status-fill{ display:inline-flex; align-items:center; height:var(--chip-h); padding:0 14px; border-radius:var(--chip-radius);
303
- font-family:var(--font-family); font-size:var(--chip-fs); font-weight:600; }
304
- .status-fill.success{ background:var(--success-fill); color:var(--success-fill-text); }
305
- .status-fill.warning{ background:var(--warning-fill); color:var(--warning-fill-text); }
306
- .status-fill.stale{ background:var(--stale-fill); color:var(--stale-fill-text); }
307
- .status-fill.critical{ background:var(--critical-fill); color:var(--critical-fill-text); }
308
-
309
- /* Dialog header — transient surface, keeps a real shadow */
310
- .sf-dialog{ background:var(--bg-surface); border-radius:var(--radius-card); box-shadow:var(--shadow-overlay); overflow:hidden; max-width:360px; }
311
- .sf-dialog-title{ font-size:var(--fs-h6); font-weight:var(--fw-h6); color:var(--ink-1); padding:16px 24px; }
312
- .sf-dialog-body{ padding:0 24px 20px; font-size:var(--fs-body2); color:var(--ink-2); }
313
-
314
- /* Alert */
315
- .sf-alert{ display:flex; align-items:flex-start; gap:10px; padding:8px 14px; border-radius:var(--radius-control);
316
- font-family:var(--font-family); font-size:var(--fs-body2); }
317
- .sf-alert .dot{ width:8px; height:8px; border-radius:50%; margin-top:5px; flex-shrink:0; }
318
- .sf-alert.success{ background:var(--success-bg); color:var(--success); }
319
- .sf-alert.warning{ background:var(--warning-bg); color:var(--warning); }
320
- .sf-alert.stale{ background:var(--stale-bg); color:var(--stale); }
321
- .sf-alert.critical{ background:var(--critical-bg); color:var(--critical); }
322
- .sf-alert .dot.success{ background:var(--success); }
323
- .sf-alert .dot.warning{ background:var(--warning); }
324
- .sf-alert .dot.stale{ background:var(--stale); }
325
- .sf-alert .dot.critical{ background:var(--critical); }
326
-
327
- /* Swatches */
328
- .swatch-row{ display:flex; flex-wrap:wrap; gap:14px; }
329
- .swatch{ width:158px; }
330
- .swatch-chip{ height:52px; border-radius:8px; border:1px solid rgba(0,0,0,0.06); margin-bottom:6px; position:relative; }
331
- .swatch-name{ font-size:12px; font-weight:600; color:#14181c; }
332
- .swatch-val{ font-size:11px; color:#6A7178; font-family:ui-monospace,monospace; }
333
-
334
- /* Greyscale (data-series) check */
335
- .gray-swatch{ height:52px; border-radius:8px; border:1px solid rgba(0,0,0,0.06); margin-bottom:6px; background:#ccc; position:relative; }
336
- .gray-value{ font-size:11px; color:#6A7178; font-family:ui-monospace,monospace; }
337
- /* second-channel glyph overlaid on a ramp/greyscale chip — the same marker
338
- shape used for that series in the line chart below, so identity survives
339
- desaturation instead of relying on hue alone */
340
- .chip-marker{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; }
341
-
342
- /* Data-series charts — second channel (dasharray+marker for lines,
343
- SVG <pattern> fills for bars) alongside the plain colour version */
344
- .chart-pair{ display:flex; gap:20px; flex-wrap:wrap; align-items:flex-start; margin-top:12px; }
345
- .chart-box{ flex:1 1 320px; min-width:300px; }
346
- .chart-box.desat svg{ filter:grayscale(1); }
347
- .chart-box-label{ font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:#6A7178; margin-bottom:8px; }
348
- .chart-box svg{ width:100%; height:auto; display:block; background:#fff; border:1px solid var(--border-c); border-radius:8px; }
349
- .legend-row{ display:flex; flex-wrap:wrap; gap:14px 20px; margin-top:12px; }
350
- .legend-item{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--ink-2); font-family:var(--font-family); }
351
- .legend-line-sample{ width:34px; height:14px; flex-shrink:0; }
352
- .legend-swatch{ width:22px; height:22px; border-radius:4px; flex-shrink:0; border:1px solid rgba(0,0,0,0.1); }
353
-
354
- /* Page-background candidate strip */
355
- .bg-strip{ display:flex; gap:16px; flex-wrap:wrap; }
356
- .bg-card{ flex:1 1 220px; min-width:210px; border-radius:10px; border:1px solid #E1E5E9; padding:14px; }
357
- .bg-card-label{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.4px; color:#3A4552; margin-bottom:2px; }
358
- .bg-card-val{ font-size:11.5px; color:#6A7178; font-family:ui-monospace,monospace; margin-bottom:10px; }
359
- .bg-card-surface{ background:#fff; border:1px solid rgba(0,0,0,0.08); border-radius:8px; padding:10px; margin-bottom:10px; box-shadow:0 1px 2px rgba(20,26,31,0.05); }
360
- .bg-card-surface .t-cap{ margin:0; }
361
- .bg-card-text{ font-size:12.5px; color:#212529; margin:0 0 4px; }
362
- .bg-card-caption{ font-size:11px; color:#6A7178; margin:0; }
363
- .bg-delta{ font-size:11px; color:#3A4552; margin-top:10px; line-height:1.5; }
364
- .bg-delta code{ font-family:ui-monospace,Consolas,monospace; background:#F0F2F4; padding:1px 4px; border-radius:3px; }
365
- .bg-card.chosen{ border-color:#3D5A99; box-shadow:0 0 0 2px rgba(61,90,153,0.18); }
366
-
367
- /* Mobile frame */
368
- .phone{ width:375px; border:8px solid #1c2126; border-radius:32px; background:var(--bg-page); padding:14px 10px; box-shadow:0 10px 30px rgba(0,0,0,0.18); }
369
- .phone-notch{ width:90px; height:16px; background:#1c2126; border-radius:0 0 12px 12px; margin:-14px auto 10px; }
370
- .phone-inner{ background:var(--bg-page); }
371
-
372
- /* canonical token table + assertion list */
373
- .token-table{ width:100%; border-collapse:collapse; font-family:var(--font-family); background:var(--bg-surface);
374
- border:1px solid var(--border-c); border-radius:10px; overflow:hidden; font-size:12.5px; }
375
- .token-table th{ text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:0.3px; font-weight:700; color:#6A7178;
376
- padding:8px 12px; border-bottom:1px solid var(--border-c); background:var(--bg-page); }
377
- .token-table td{ padding:7px 12px; border-bottom:1px solid var(--border-c); color:var(--ink-1); vertical-align:top; }
378
- .token-table tr:last-child td{ border-bottom:none; }
379
- .token-table tr.group-row td{ background:#F0F2F4; font-weight:700; font-size:11px; text-transform:uppercase; letter-spacing:0.4px; color:#3A4552; padding:6px 12px; }
380
- .token-table code{ font-family:ui-monospace,Consolas,monospace; font-size:11.5px; background:#F0F2F4; padding:1px 5px; border-radius:4px; }
381
- .token-table .note{ color:#6A7178; font-size:11.5px; }
382
- .token-swatch{ display:inline-block; width:14px; height:14px; border-radius:3px; border:1px solid rgba(0,0,0,0.12); vertical-align:-2px; margin-right:6px; }
383
-
384
- .decision-item{ display:flex; gap:12px; padding:12px 0; border-bottom:1px solid #EEF1F3; }
385
- .decision-item:last-child{ border-bottom:none; }
386
- .doc-summary{ border:1px solid var(--border-c); border-radius:8px; padding:14px 16px; margin:14px 0 22px;
387
- background:var(--bg-surface); }
388
- .doc-summary-title{ font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.4px;
389
- color:var(--ink-3); margin-bottom:8px; }
390
- .doc-summary ul{ margin:0; padding-left:18px; }
391
- .doc-summary li{ font-size:13px; line-height:1.55; color:var(--ink-2); margin-bottom:5px; }
392
- .doc-summary li strong{ color:var(--ink-1); }
393
- .doc-nav{ margin-top:10px; padding-top:10px; border-top:1px solid var(--border-c); font-size:12px; line-height:1.9; color:var(--ink-3); }
394
- .doc-nav a{ color:var(--focus-ring); text-decoration:none; }
395
- .doc-nav a:hover{ text-decoration:underline; }
396
- .appendix-h{ font-size:13px; text-transform:uppercase; letter-spacing:0.5px; color:var(--ink-3);
397
- border-top:1px solid var(--border-c); padding-top:16px; margin:28px 0 0; }
398
- .decision-num{ flex:none; align-self:flex-start; padding:2px 8px; border-radius:999px;
399
- background:var(--primary-tint,#EDF1F8); color:#2C4470; font-size:11.5px; font-weight:700;
400
- letter-spacing:0.2px; white-space:nowrap; text-transform:uppercase; }
401
- .decision-txt strong{ color:#14181c; }
402
- .decision-txt{ font-size:13px; color:#3A4552; line-height:1.55; }
403
-
404
- .two-col{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }
405
- @media (max-width:900px){ .two-col{ grid-template-columns:1fr; } }
406
- </style>
407
- </head>
408
- <body>
409
- <div class="doc-wrap">
410
-
411
- <h1 class="doc-title">DS2 — shared MUI theme baseline, acceptance &amp; verification sheet (Musterbogen)</h1>
412
- <p class="doc-sub">The candidate baseline from round 1 is now decided. This sheet is no longer a chooser between variants — it is the <strong>acceptance record for the locked <code>createAppTheme(overrides)</code> baseline</strong>, and the object later theme changes get re-checked against. The MUI 7.3.11 raw-default comparison stays throughout so the delta is still visible. Every contrast ratio shown is computed by an inline script at render time, not hand-typed. Static HTML/CSS, light mode only, no app code.</p>
413
-
414
- <div class="doc-summary">
415
- <div class="doc-summary-title">In one screen</div>
416
- <ul>
417
- <li><strong>Status: release candidate.</strong> Reviewed 2026-08-09 by a second reader; the corrections are folded in.</li>
418
- <li><strong>Values are settled</strong> over four rounds: DM Sans 14px body, <code>#FAFAFA</code> page, three opaque ink tiers, status split into text and fill roles, 40px controls (44px hit area on touch), 3/8px radii, no resting shadow.</li>
419
- <li><strong>Every contrast figure is computed at render time</strong> &mdash; text tones against their real surface, not against white.</li>
420
- <li><strong>Two known limitations:</strong> a six-series chart separated by hue alone does not satisfy WCAG 1.4.1 (the shape overlay is opt-in, DS-13), and <code>stale</code> has no precedent in the estate and is unvalidated in a running screen.</li>
421
- <li><strong>The token table at the end is the value source.</strong> A work order references it by token name instead of retyping numbers.</li>
422
- </ul>
423
- <div class="doc-nav"><a href="#declared-coverage">Declared coverage</a> &middot; <a href="#font-disclosure">Font disclosure</a> &middot; <a href="#page-background-candidate-strip">Page background — candidate strip</a> &middot; <a href="#ink-border-surface">Ink, border, surface</a> &middot; <a href="#status-split-by-role-and-the-freshness-s">Status, split by role, and the freshness semantic</a> &middot; <a href="#data-series-ramp-categorical-owned-by-th">Data-series ramp (categorical, owned by the baseline)</a> &middot; <a href="#shadow-rest-vs-transient-now-a-binary-ru">Shadow: rest vs. transient — now a binary rule</a> &middot; <a href="#typography-settled-scale">Typography — settled scale</a> &middot; <a href="#control-height-touch-target-radius-settl">Control height, touch target &amp; radius — settled</a> &middot; <a href="#component-gallery">Component gallery</a> &middot; <a href="#mobile-frame-375px">Mobile frame — 375px</a> &middot; <a href="#what-this-sheet-asserts-and-what-remains">What this sheet asserts, and what remains unverified</a> &middot; <a href="#canonical-baseline-tokens">Canonical baseline tokens</a></div>
424
- </div>
425
-
426
- <!-- =========================================================
427
- CANONICAL TOKEN TABLE — the value source
428
- ========================================================= -->
429
-
430
-
431
- <section class="doc-section" id="declared-coverage">
432
- <h2>Declared coverage</h2>
433
- <p class="section-note" style="margin-bottom:10px"><strong>Covers:</strong> the token table; ink/border/surface with the page-background strip; the <code>divider</code>/<code>controlBorder</code> split; status split into text and fill roles; the settled type scale, control height, radius and shadow rule; the data-series ramp and its greyscale check; a render-time contrast script; and the 14 agreed component specimens, each beside its MUI default.</p>
434
- <p class="section-note" style="margin-bottom:10px"><strong>Does not cover:</strong> dark mode (out of scope for v1); components outside the agreed list; the <code>createAppTheme()</code> implementation and its override API; an audit of the 14 apps against this baseline; and the series-4/5 hue proximity itself, which is unchanged.</p>
435
- <p class="section-note" style="margin:0"><strong>Explicit:</strong> the MUI column is a CSS transcription of MUI v7's documented defaults, not a live mount, and it renders in a system-sans stand-in rather than Roboto. Judge size, weight, radius, colour and shadow from it &mdash; not glyph shapes.</p>
436
- </section>
437
-
438
- <section class="doc-section" id="font-disclosure">
439
- <h2>Font disclosure</h2>
440
- <p class="section-note" style="margin:0">Baseline columns use DM Sans 400/500/600, base64-embedded from <code>@fontsource/dm-sans@5.2.8</code> in this estate's <code>node_modules</code> &mdash; no network fetch. MUI columns use a system-sans stand-in, not Roboto.</p>
441
- </section>
442
-
443
- <!-- =========================================================
444
- PAGE BACKGROUND — CANDIDATE STRIP (round 3)
445
- ========================================================= -->
446
-
447
-
448
- <!-- =========================================================
449
- COLOR / INK / STATUS TOKENS
450
- ========================================================= -->
451
- <section class="doc-section" id="ink-border-surface">
452
- <h2>Ink, border, surface</h2>
453
- <p class="section-note">MUI's default text is translucent (<code>rgba(0,0,0,0.87)</code>) and shifts with whatever sits behind it. The candidate uses three fixed opaque tiers. Muted was darkened twice: <code>#6A7178</code> &rarr; <code>#6A7178</code> &rarr; <code>#6A7178</code>.</p>
454
- <div class="cols">
455
- <div class="col th-mui">
456
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
457
- <div class="swatch-row">
458
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-1)"></div><div class="swatch-name">text.primary</div><div class="swatch-val">rgba(0,0,0,.87)</div>
459
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(0,0,0,0.87)" data-bg="#FFFFFF" data-min="4.5"></span></div></div>
460
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-2)"></div><div class="swatch-name">text.secondary</div><div class="swatch-val">rgba(0,0,0,.6)</div>
461
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(0,0,0,0.6)" data-bg="#FFFFFF" data-min="4.5"></span></div></div>
462
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-3)"></div><div class="swatch-name">text.disabled</div><div class="swatch-val">rgba(0,0,0,.38)</div>
463
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(0,0,0,0.38)" data-bg="#FFFFFF" data-min="4.5"></span><span class="ratio-label">disabled UI is WCAG-exempt from AA text contrast — shown for reference only</span></div></div>
464
- <div class="swatch"><div class="swatch-chip" style="background:var(--bg-page); border:1px solid var(--border-c)"></div><div class="swatch-name">background.default</div><div class="swatch-val">#FAFAFA</div></div>
465
- <div class="swatch"><div class="swatch-chip" style="background:var(--border-c)"></div><div class="swatch-name">divider</div><div class="swatch-val">rgba(0,0,0,.12)</div></div>
466
- </div>
467
- </div>
468
- <div class="col th-candidate">
469
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
470
- <div class="swatch-row">
471
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-1)"></div><div class="swatch-name">ink.primary</div><div class="swatch-val">#212529</div>
472
- <div class="ratio-row"><span class="ratio-badge" data-fg="#212529" data-bg="#FFFFFF" data-min="4.5"></span></div></div>
473
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-2)"></div><div class="swatch-name">ink.secondary</div><div class="swatch-val">#5B6670</div>
474
- <div class="ratio-row"><span class="ratio-badge" data-fg="#5B6670" data-bg="#FFFFFF" data-min="4.5"></span></div></div>
475
- <div class="swatch"><div class="swatch-chip" style="background:var(--ink-3)"></div><div class="swatch-name">ink.muted</div><div class="swatch-val">#6A7178 <span style="text-decoration:line-through;opacity:.6">#6A7178</span></div>
476
- <div class="ratio-row"><span class="ratio-badge" data-fg="#6A7178" data-bg="#FFFFFF" data-min="4.6"></span><span class="ratio-label">on page bg (B):</span><span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAFA" data-min="4.6"></span><span class="ratio-label">on palest candidate (C):</span><span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAFA" data-min="4.6"></span></div></div>
477
- <div class="swatch"><div class="swatch-chip" style="background:var(--bg-page); border:1px solid var(--border-c)"></div><div class="swatch-name">bg.page</div><div class="swatch-val">#FAF9F7 <span style="text-decoration:line-through;opacity:.6">#F7F6F3</span></div></div>
478
- <div class="swatch"><div class="swatch-chip" style="background:var(--border-c)"></div><div class="swatch-name">divider</div><div class="swatch-val">rgba(33,37,41,.10)</div>
479
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(33,37,41,0.10)" data-bg="#FFFFFF" data-min="3"></span><span class="ratio-label">decorative — 1.4.11-exempt, see below</span></div></div>
480
- </div>
481
- </div>
482
- </div>
483
-
484
- <h3>Border, split in two: <code>divider</code> vs. <code>controlBorder</code></h3>
485
- <p class="section-note">WCAG treats the two differently, so one token cannot serve both. <code>divider</code> is decorative and exempt from 1.4.11; it stays pale. <code>controlBorder</code> is a control's boundary and needs <strong>&ge;3:1</strong> against its surface &mdash; the inherited <code>input.border</code> never cleared it. Derived from the same ink hue at higher opacity.</p>
486
- <div class="swatch-row">
487
- <div class="swatch"><div class="swatch-chip" style="border:2px solid var(--control-border); background:#fff"></div><div class="swatch-name">controlBorder (rest)</div><div class="swatch-val">rgba(33,37,41,.50)</div>
488
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FFFFFF" data-min="3"></span></div>
489
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FAFAFA" data-min="3"></span><span class="ratio-label">on C</span></div></div>
490
- <div class="swatch"><div class="swatch-chip" style="border:2px solid var(--control-border-hover); background:#fff"></div><div class="swatch-name">controlBorder (hover)</div><div class="swatch-val">rgba(33,37,41,.65)</div>
491
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FFFFFF" data-min="3"></span></div>
492
- <div class="ratio-row"><span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FAFAFA" data-min="3"></span><span class="ratio-label">on C</span></div></div>
493
- <div class="swatch"><div class="swatch-chip" style="border:2px solid var(--control-border-focus); background:#fff"></div><div class="swatch-name">controlBorder (focus)</div><div class="swatch-val">#3D5A99 (primary)</div>
494
- <div class="ratio-row"><span class="ratio-badge" data-fg="#3D5A99" data-bg="#FFFFFF" data-min="3"></span></div>
495
- <div class="ratio-row"><span class="ratio-badge" data-fg="#3D5A99" data-bg="#FAFAFA" data-min="3"></span><span class="ratio-label">on C</span></div></div>
496
- <div class="swatch"><div class="swatch-chip" style="border:2px solid var(--control-border-error); background:#fff"></div><div class="swatch-name">controlBorder (error)</div><div class="swatch-val">#BF3227 (critical)</div>
497
- <div class="ratio-row"><span class="ratio-badge" data-fg="#BF3227" data-bg="#FFFFFF" data-min="3"></span></div>
498
- <div class="ratio-row"><span class="ratio-badge" data-fg="#BF3227" data-bg="#FAFAFA" data-min="3"></span><span class="ratio-label">on C</span></div></div>
499
- </div>
500
-
501
- <h3>TextField / Select — rest, hover, focus, error</h3>
502
- <p class="section-note">Same four states, MUI default beside the candidate, every boundary computed live. MUI's <strong>rest</strong> default also fails 3:1; its hover/focus/error states clear it. A rest-state gap in the library, not a deviation from it.</p>
503
- <div class="cols">
504
- <div class="col th-mui">
505
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
506
- <div class="stack">
507
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Rest</span><div class="sf-input" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="rgba(0,0,0,0.23)" data-bg="#FFFFFF" data-min="3"></span></div>
508
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Hover</span><div class="sf-input state-hover" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="rgba(0,0,0,0.87)" data-bg="#FFFFFF" data-min="3"></span></div>
509
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Focus</span><div class="sf-input state-focus" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="#1976d2" data-bg="#FFFFFF" data-min="3"></span></div>
510
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Error</span><div class="sf-input state-error" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="#d32f2f" data-bg="#FFFFFF" data-min="3"></span></div>
511
- <div class="row" style="margin-top:6px"><div class="sf-select" aria-hidden="true"><span>Select — rest</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="rgba(0,0,0,0.23)" data-bg="#FFFFFF" data-min="3"></span></div>
512
- <div class="row"><div class="sf-select state-hover" aria-hidden="true"><span>Select — hover</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="rgba(0,0,0,0.87)" data-bg="#FFFFFF" data-min="3"></span></div>
513
- <div class="row"><div class="sf-select state-focus" aria-hidden="true"><span>Select — focus</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="#1976d2" data-bg="#FFFFFF" data-min="3"></span></div>
514
- <div class="row"><div class="sf-select state-error" aria-hidden="true"><span>Select — error</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="#d32f2f" data-bg="#FFFFFF" data-min="3"></span></div>
515
- </div>
516
- </div>
517
- <div class="col th-candidate">
518
- <div class="col-label">Baseline candidate — controlBorder <span class="tag cand">DS2</span></div>
519
- <div class="stack">
520
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Rest</span><div class="sf-input" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FFFFFF" data-min="3"></span></div>
521
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Hover</span><div class="sf-input state-hover" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FFFFFF" data-min="3"></span></div>
522
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Focus</span><div class="sf-input state-focus" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="#3D5A99" data-bg="#FFFFFF" data-min="3"></span></div>
523
- <div class="row"><div class="sf-outlined-wrap"><span class="float-label">Error</span><div class="sf-input state-error" aria-hidden="true"><span class="sf-ph">hram…</span></div></div><span class="ratio-badge" data-fg="#BF3227" data-bg="#FFFFFF" data-min="3"></span></div>
524
- <div class="row" style="margin-top:6px"><div class="sf-select" aria-hidden="true"><span>Select — rest</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FFFFFF" data-min="3"></span></div>
525
- <div class="row"><div class="sf-select state-hover" aria-hidden="true"><span>Select — hover</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FFFFFF" data-min="3"></span></div>
526
- <div class="row"><div class="sf-select state-focus" aria-hidden="true"><span>Select — focus</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="#3D5A99" data-bg="#FFFFFF" data-min="3"></span></div>
527
- <div class="row"><div class="sf-select state-error" aria-hidden="true"><span>Select — error</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div><span class="ratio-badge" data-fg="#BF3227" data-bg="#FFFFFF" data-min="3"></span></div>
528
- </div>
529
- </div>
530
- </div>
531
- <p class="section-note" style="margin:12px 0 0">Checkbox boxes and outlined Button/Chip edges use <code>controlBorder</code> too &mdash; the same rest-state fix wherever the sub-3:1 <code>input.border</code> was the outline.</p>
532
- </section>
533
-
534
- <section class="doc-section" id="status-split-by-role-and-the-freshness-s">
535
- <h2>Status, split by role, and the freshness semantic</h2>
536
- <p class="section-note">One hex cannot be both text and fill: <code>#1E8E3E</code> measures 4.20:1 as text on white and &mdash; the formula being symmetric &mdash; the same 4.20:1 as a fill under white text. Each status now carries a text tone and a fill tone with its own <code>contrastText</code>. <strong>The text tones are checked against their own Alert tint, not against white</strong> — a tint <em>lowers</em> contrast, and checking the wrong surface hid a real failure: warning measured 4.10:1 on <code>#FBF0DC</code>, now <code>#976100</code> at 4.62:1.</p>
537
- <div class="cols">
538
- <div class="col th-mui">
539
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
540
- <div class="stack">
541
- <div class="sf-alert success"><span class="dot success"></span><div>success.main — deploy healthy</div></div>
542
- <div class="sf-alert warning"><span class="dot warning"></span><div>warning.main — CI flaky</div></div>
543
- <div class="sf-alert stale"><span class="dot stale"></span><div>info.main — no "stale" concept; nearest is info (blue), semantically wrong for freshness</div></div>
544
- <div class="sf-alert critical"><span class="dot critical"></span><div>error.main — server unreachable</div></div>
545
- </div>
546
- <p class="col-sub" style="margin-top:10px">MUI's own <code>palette.contrastThreshold</code> defaults to 3, not WCAG's 4.5 — its auto-computed <code>contrastText</code> can legally ship combinations that fail AA normal text. No fill+contrastText row is rendered for this column: the point being made is the token design, not a second MUI demo.</p>
547
- </div>
548
- <div class="col th-candidate">
549
- <div class="col-label">Baseline candidate — text/icon role <span class="tag cand">DS2</span></div>
550
- <div class="stack">
551
- <div class="sf-alert success"><span class="dot success"></span><div>success — deploy healthy <span class="ratio-badge" data-fg="#35794A" data-bg="#E5F4E9" data-min="4.5"></span></div></div>
552
- <div class="sf-alert warning"><span class="dot warning"></span><div>warning — CI flaky <span class="ratio-badge" data-fg="#976100" data-bg="#FBF0DC" data-min="4.5"></span></div></div>
553
- <div class="sf-alert stale"><span class="dot stale"></span><div>stale — last refreshed 6h ago <span class="ratio-badge" data-fg="#5B6B7D" data-bg="#EAEDF1" data-min="4.5"></span></div></div>
554
- <div class="sf-alert critical"><span class="dot critical"></span><div>critical — server unreachable <span class="ratio-badge" data-fg="#BF3227" data-bg="#FBEAE8" data-min="4.5"></span></div></div>
555
- </div>
556
- </div>
557
- </div>
558
- <h3>Fill role — solid chip/badge, contrastText pair</h3>
559
- <div class="row">
560
- <div class="status-fill success">Success<span class="ratio-badge" data-fg="#FFFFFF" data-bg="#1B8038" data-min="4.5"></span></div>
561
- <div class="status-fill warning">Warning<span class="ratio-badge" data-fg="#212529" data-bg="#C08A2C" data-min="4.5"></span></div>
562
- <div class="status-fill stale">Stale<span class="ratio-badge" data-fg="#FFFFFF" data-bg="#5B6B7D" data-min="4.5"></span></div>
563
- <div class="status-fill critical">Critical<span class="ratio-badge" data-fg="#FFFFFF" data-bg="#BF3227" data-min="4.5"></span></div>
564
- </div>
565
- <p class="section-note" style="margin:14px 0 0"><strong>No estate precedent.</strong> Three prototypes invented a stale concept, all in amber: cockpit <code>#9a7b33</code>, fitness-monitor reused <code>--status-warn</code>. <code>#5B6B7D</code> is new &mdash; included on the operator's decision, because reusing amber would collide with <code>warning</code>, which is the reason the token exists. Unvalidated in a running screen; the first consuming app validates it.</p>
566
- </section>
567
-
568
- <!-- =========================================================
569
- DATA SERIES RAMP
570
- ========================================================= -->
571
- <section class="doc-section" id="data-series-ramp-categorical-owned-by-th">
572
- <h2>Data-series ramp (categorical, owned by the baseline)</h2>
573
- <p class="section-note">Six colours chosen to avoid every status hue (no green, amber, red or blue-grey), so a series is never mistaken for a status. Muted and cool-to-neutral, unchanged on the operator's verdict. <strong>No second channel:</strong> dash patterns, marker shapes and pattern fills were all removed on review &mdash; how a chart separates series is DS-4's question.</p>
574
- <div class="swatch-row" style="margin-bottom:10px">
575
- <div class="swatch"><div class="swatch-chip" style="background:#3D5A99"></div><div class="swatch-name">series 1</div><div class="swatch-val">#3D5A99 — circle</div>
576
- <div class="ratio-row"><span class="ratio-badge" data-fg="#3D5A99" data-bg="#FFFFFF" data-min="3"></span></div></div>
577
- <div class="swatch"><div class="swatch-chip" style="background:#3E80B8"></div><div class="swatch-name">series 2</div><div class="swatch-val">#3E80B8 — square</div>
578
- <div class="ratio-row"><span class="ratio-badge" data-fg="#3E80B8" data-bg="#FFFFFF" data-min="3"></span></div></div>
579
- <div class="swatch"><div class="swatch-chip" style="background:#2E8F8A"></div><div class="swatch-name">series 3</div><div class="swatch-val">#2E8F8A — triangle</div>
580
- <div class="ratio-row"><span class="ratio-badge" data-fg="#2E8F8A" data-bg="#FFFFFF" data-min="3"></span></div></div>
581
- <div class="swatch"><div class="swatch-chip" style="background:#7A5FA8"></div><div class="swatch-name">series 4</div><div class="swatch-val">#7A5FA8 — diamond</div>
582
- <div class="ratio-row"><span class="ratio-badge" data-fg="#7A5FA8" data-bg="#FFFFFF" data-min="3"></span></div></div>
583
- <div class="swatch"><div class="swatch-chip" style="background:#9C4F86"></div><div class="swatch-name">series 5</div><div class="swatch-val">#9C4F86 — cross</div>
584
- <div class="ratio-row"><span class="ratio-badge" data-fg="#9C4F86" data-bg="#FFFFFF" data-min="3"></span></div></div>
585
- <div class="swatch"><div class="swatch-chip" style="background:#8A7355"></div><div class="swatch-name">series 6</div><div class="swatch-val">#8A7355 — plus</div>
586
- <div class="ratio-row"><span class="ratio-badge" data-fg="#8A7355" data-bg="#FFFFFF" data-min="3"></span></div></div>
587
- </div>
588
-
589
- <h3>Greyscale check — same swatches, desaturated to luminance only</h3>
590
- <p class="section-note">Colour removed. Series 4 and 5 remain near-identical greys (109 vs 106), and <strong>nothing else distinguishes them</strong> since the marker glyphs were dropped.</p>
591
- <div class="swatch-row">
592
- <div class="swatch"><div class="gray-swatch" data-gray-source="#3D5A99"></div><div class="swatch-name">series 1</div><div class="gray-value"></div></div>
593
- <div class="swatch"><div class="gray-swatch" data-gray-source="#3E80B8"></div><div class="swatch-name">series 2</div><div class="gray-value"></div></div>
594
- <div class="swatch"><div class="gray-swatch" data-gray-source="#2E8F8A"></div><div class="swatch-name">series 3</div><div class="gray-value"></div></div>
595
- <div class="swatch"><div class="gray-swatch" data-gray-source="#7A5FA8"></div><div class="swatch-name">series 4</div><div class="gray-value"></div></div>
596
- <div class="swatch"><div class="gray-swatch" data-gray-source="#9C4F86"></div><div class="swatch-name">series 5</div><div class="gray-value"></div></div>
597
- <div class="swatch"><div class="gray-swatch" data-gray-source="#8A7355"></div><div class="swatch-name">series 6</div><div class="gray-value"></div></div>
598
- </div>
599
- <p class="section-note" style="margin:14px 0 0">Desaturated greys (live, sRGB 0&ndash;255): 92 &middot; 123 &middot; 129 &middot; 109 &middot; 106 &middot; 119. Series 4 and 5 differ by ~3/255, below reliable perception; 2/3/6 sit inside 10 points. With nothing but hue carrying identity, a six-series chart does not satisfy WCAG 1.4.1.</p>
600
-
601
- <h3>Second channel in practice — multi-series line chart</h3>
602
- <p class="section-note">Same six series, solid strokes, no per-series pattern or marker &mdash; removed on operator review (2026-08-09). Series 4 and 5 cross around March/May, which is where the close-luminance pair matters most; in the desaturated pane they are not reliably separable.</p>
603
- <div class="chart-pair">
604
- <div class="chart-box">
605
- <div class="chart-box-label">Colour</div>
606
- <svg viewBox="0 0 640 250" xmlns="http://www.w3.org/2000/svg">
607
- <line x1="40" y1="220" x2="600" y2="220" stroke="#D7DEE4" stroke-width="1"/>
608
- <text x="60" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Jan</text>
609
- <text x="160" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Feb</text>
610
- <text x="260" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Mar</text>
611
- <text x="360" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Apr</text>
612
- <text x="460" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">May</text>
613
- <text x="560" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Jun</text>
614
- <polyline points="60,140.0 160,110.0 260,120.0 360,80.0 460,90.0 560,60.0" fill="none" stroke="#3D5A99" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
615
- <polyline points="60,80.0 160,100.0 260,70.0 360,110.0 460,84.0 560,104.0" fill="none" stroke="#3E80B8" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
616
- <polyline points="60,160.0 160,130.0 260,140.0 360,100.0 460,120.0 560,90.0" fill="none" stroke="#2E8F8A" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
617
- <polyline points="60,110.0 160,120.0 260,104.0 360,124.0 460,100.0 560,116.0" fill="none" stroke="#7A5FA8" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
618
- <polyline points="60,120.0 160,110.0 260,116.0 360,104.0 460,120.0 560,100.0" fill="none" stroke="#9C4F86" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
619
- <polyline points="60,180.0 160,160.0 260,170.0 360,140.0 460,150.0 560,130.0" fill="none" stroke="#8A7355" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
620
- </svg>
621
- </div>
622
- <div class="chart-box desat">
623
- <div class="chart-box-label">Desaturated — colour removed, shape kept</div>
624
- <svg viewBox="0 0 640 250" xmlns="http://www.w3.org/2000/svg">
625
- <line x1="40" y1="220" x2="600" y2="220" stroke="#D7DEE4" stroke-width="1"/>
626
- <text x="60" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Jan</text>
627
- <text x="160" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Feb</text>
628
- <text x="260" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Mar</text>
629
- <text x="360" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Apr</text>
630
- <text x="460" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">May</text>
631
- <text x="560" y="238" font-size="10.5" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">Jun</text>
632
- <polyline points="60,140.0 160,110.0 260,120.0 360,80.0 460,90.0 560,60.0" fill="none" stroke="#3D5A99" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
633
- <polyline points="60,80.0 160,100.0 260,70.0 360,110.0 460,84.0 560,104.0" fill="none" stroke="#3E80B8" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
634
- <polyline points="60,160.0 160,130.0 260,140.0 360,100.0 460,120.0 560,90.0" fill="none" stroke="#2E8F8A" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
635
- <polyline points="60,110.0 160,120.0 260,104.0 360,124.0 460,100.0 560,116.0" fill="none" stroke="#7A5FA8" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
636
- <polyline points="60,120.0 160,110.0 260,116.0 360,104.0 460,120.0 560,100.0" fill="none" stroke="#9C4F86" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
637
- <polyline points="60,180.0 160,160.0 260,170.0 360,140.0 460,150.0 560,130.0" fill="none" stroke="#8A7355" stroke-width="2.25" stroke-linejoin="round" stroke-linecap="round"/>
638
- </svg>
639
- </div>
640
- </div>
641
- <div class="legend-row">
642
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#3D5A99" stroke-width="2.2" stroke-linecap="round"/><circle cx="17" cy="7" r="3.2" fill="#3D5A99"/></svg><span>Series 1 / circle</span></div>
643
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#3E80B8" stroke-width="2.2" stroke-linecap="round"/><rect x="14.2" y="4.2" width="5.6" height="5.6" fill="#3E80B8"/></svg><span>Series 2 — dashed / square</span></div>
644
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#2E8F8A" stroke-width="2.2" stroke-linecap="round"/><polygon points="17,3 13,10.2 21,10.2" fill="#2E8F8A"/></svg><span>Series 3 — dotted / triangle</span></div>
645
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#7A5FA8" stroke-width="2.2" stroke-linecap="round"/><polygon points="17,2.8 21.2,7 17,11.2 12.8,7" fill="#7A5FA8"/></svg><span>Series 4 — dash-dot / diamond</span></div>
646
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#9C4F86" stroke-width="2.2" stroke-linecap="round"/><path d="M14,4 L20,10 M14,10 L20,4" stroke="#9C4F86" stroke-width="1.6" stroke-linecap="round"/></svg><span>Series 5 — long dash / cross</span></div>
647
- <div class="legend-item"><svg class="legend-line-sample" viewBox="0 0 34 14" xmlns="http://www.w3.org/2000/svg"><line x1="2" y1="7" x2="32" y2="7" stroke="#8A7355" stroke-width="2.2" stroke-linecap="round"/><path d="M17,3 L17,11 M13,7 L21,7" stroke="#8A7355" stroke-width="1.6" stroke-linecap="round"/></svg><span>Series 6 — dash-dot-dot / plus</span></div>
648
- </div>
649
-
650
- <h3>Second channel in practice — grouped bar chart</h3>
651
- <p class="section-note">The same six series as bar fills &mdash; flat colour, no pattern. In the desaturated pane the close pairs are not separable.</p>
652
- <div class="chart-pair">
653
- <div class="chart-box">
654
- <div class="chart-box-label">Colour</div>
655
- <svg viewBox="0 0 680 250" xmlns="http://www.w3.org/2000/svg">
656
- <defs>
657
- <pattern id="bar-p1" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#3D5A99"/></pattern>
658
- <pattern id="bar-p2" width="7" height="7" patternUnits="userSpaceOnUse"><rect width="7" height="7" fill="#3E80B8"/></pattern>
659
- <pattern id="bar-p3" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#2E8F8A"/></pattern>
660
- <pattern id="bar-p4" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#7A5FA8"/></pattern>
661
- <pattern id="bar-p5" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#9C4F86"/></pattern>
662
- <pattern id="bar-p6" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#8A7355"/></pattern>
663
- </defs>
664
- <line x1="20" y1="220" x2="660" y2="220" stroke="#D7DEE4" stroke-width="1"/>
665
- <rect x="30" y="106.0" width="22" height="114.0" fill="url(#bar-p1)" rx="1.5"/>
666
- <rect x="56" y="134.5" width="22" height="85.5" fill="url(#bar-p2)" rx="1.5"/>
667
- <rect x="82" y="87.0" width="22" height="133.0" fill="url(#bar-p3)" rx="1.5"/>
668
- <rect x="108" y="125.0" width="22" height="95.0" fill="url(#bar-p4)" rx="1.5"/>
669
- <rect x="134" y="128.8" width="22" height="91.2" fill="url(#bar-p5)" rx="1.5"/>
670
- <rect x="160" y="163.0" width="22" height="57.0" fill="url(#bar-p6)" rx="1.5"/>
671
- <text x="106.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">hram</text>
672
- <rect x="238" y="144.0" width="22" height="76.0" fill="url(#bar-p1)" rx="1.5"/>
673
- <rect x="264" y="96.5" width="22" height="123.5" fill="url(#bar-p2)" rx="1.5"/>
674
- <rect x="290" y="153.5" width="22" height="66.5" fill="url(#bar-p3)" rx="1.5"/>
675
- <rect x="316" y="115.5" width="22" height="104.5" fill="url(#bar-p4)" rx="1.5"/>
676
- <rect x="342" y="109.8" width="22" height="110.2" fill="url(#bar-p5)" rx="1.5"/>
677
- <rect x="368" y="140.2" width="22" height="79.8" fill="url(#bar-p6)" rx="1.5"/>
678
- <text x="314.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">jg-ferien</text>
679
- <rect x="446" y="77.5" width="22" height="142.5" fill="url(#bar-p1)" rx="1.5"/>
680
- <rect x="472" y="163.0" width="22" height="57.0" fill="url(#bar-p2)" rx="1.5"/>
681
- <rect x="498" y="125.0" width="22" height="95.0" fill="url(#bar-p3)" rx="1.5"/>
682
- <rect x="524" y="102.2" width="22" height="117.8" fill="url(#bar-p4)" rx="1.5"/>
683
- <rect x="550" y="134.5" width="22" height="85.5" fill="url(#bar-p5)" rx="1.5"/>
684
- <rect x="576" y="90.8" width="22" height="129.2" fill="url(#bar-p6)" rx="1.5"/>
685
- <text x="522.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">spesix</text>
686
- </svg>
687
- </div>
688
- <div class="chart-box desat">
689
- <div class="chart-box-label">Desaturated — colour removed, pattern kept</div>
690
- <svg viewBox="0 0 680 250" xmlns="http://www.w3.org/2000/svg">
691
- <defs>
692
- <pattern id="bar-p1-d" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#3D5A99"/></pattern>
693
- <pattern id="bar-p2-d" width="7" height="7" patternUnits="userSpaceOnUse"><rect width="7" height="7" fill="#3E80B8"/></pattern>
694
- <pattern id="bar-p3-d" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#2E8F8A"/></pattern>
695
- <pattern id="bar-p4-d" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#7A5FA8"/></pattern>
696
- <pattern id="bar-p5-d" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#9C4F86"/></pattern>
697
- <pattern id="bar-p6-d" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#8A7355"/></pattern>
698
- </defs>
699
- <line x1="20" y1="220" x2="660" y2="220" stroke="#D7DEE4" stroke-width="1"/>
700
- <rect x="30" y="106.0" width="22" height="114.0" fill="url(#bar-p1-d)" rx="1.5"/>
701
- <rect x="56" y="134.5" width="22" height="85.5" fill="url(#bar-p2-d)" rx="1.5"/>
702
- <rect x="82" y="87.0" width="22" height="133.0" fill="url(#bar-p3-d)" rx="1.5"/>
703
- <rect x="108" y="125.0" width="22" height="95.0" fill="url(#bar-p4-d)" rx="1.5"/>
704
- <rect x="134" y="128.8" width="22" height="91.2" fill="url(#bar-p5-d)" rx="1.5"/>
705
- <rect x="160" y="163.0" width="22" height="57.0" fill="url(#bar-p6-d)" rx="1.5"/>
706
- <text x="106.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">hram</text>
707
- <rect x="238" y="144.0" width="22" height="76.0" fill="url(#bar-p1-d)" rx="1.5"/>
708
- <rect x="264" y="96.5" width="22" height="123.5" fill="url(#bar-p2-d)" rx="1.5"/>
709
- <rect x="290" y="153.5" width="22" height="66.5" fill="url(#bar-p3-d)" rx="1.5"/>
710
- <rect x="316" y="115.5" width="22" height="104.5" fill="url(#bar-p4-d)" rx="1.5"/>
711
- <rect x="342" y="109.8" width="22" height="110.2" fill="url(#bar-p5-d)" rx="1.5"/>
712
- <rect x="368" y="140.2" width="22" height="79.8" fill="url(#bar-p6-d)" rx="1.5"/>
713
- <text x="314.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">jg-ferien</text>
714
- <rect x="446" y="77.5" width="22" height="142.5" fill="url(#bar-p1-d)" rx="1.5"/>
715
- <rect x="472" y="163.0" width="22" height="57.0" fill="url(#bar-p2-d)" rx="1.5"/>
716
- <rect x="498" y="125.0" width="22" height="95.0" fill="url(#bar-p3-d)" rx="1.5"/>
717
- <rect x="524" y="102.2" width="22" height="117.8" fill="url(#bar-p4-d)" rx="1.5"/>
718
- <rect x="550" y="134.5" width="22" height="85.5" fill="url(#bar-p5-d)" rx="1.5"/>
719
- <rect x="576" y="90.8" width="22" height="129.2" fill="url(#bar-p6-d)" rx="1.5"/>
720
- <text x="522.0" y="238" font-size="11" fill="#6A7178" text-anchor="middle" font-family="DM Sans, sans-serif">spesix</text>
721
- </svg>
722
- </div>
723
- </div>
724
- <div class="legend-row">
725
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p1" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#3D5A99"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p1)"/></svg><span>Series 1</span></div>
726
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p2" width="7" height="7" patternUnits="userSpaceOnUse"><rect width="7" height="7" fill="#3E80B8"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p2)"/></svg><span>Series 2</span></div>
727
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p3" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#2E8F8A"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p3)"/></svg><span>Series 3</span></div>
728
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p4" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#7A5FA8"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p4)"/></svg><span>Series 4</span></div>
729
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p5" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#9C4F86"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p5)"/></svg><span>Series 5</span></div>
730
- <div class="legend-item"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><defs><pattern id="legend-p6" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="8" height="8" fill="#8A7355"/></pattern></defs><rect width="22" height="22" rx="4" fill="url(#legend-p6)"/></svg><span>Series 6</span></div>
731
- </div>
732
- <p class="section-note" style="margin:14px 0 0">With the second channel gone, the desaturated panes are <strong>not</strong> reliably readable &mdash; series 4 and 5 in particular. Surface contrast is unaffected (desaturation preserves relative luminance); this section is about series-to-series distinguishability under 1.4.1, not text contrast.</p>
733
- </section>
734
-
735
- <!-- =========================================================
736
- SHADOWS
737
- ========================================================= -->
738
- <section class="doc-section" id="shadow-rest-vs-transient-now-a-binary-ru">
739
- <h2>Shadow: rest vs. transient — now a binary rule</h2>
740
- <p class="section-note">MUI's <code>shadows[1]</code> is a visible three-layer drop shadow &mdash; right for 2014 Material, wrong for a flat dashboard. Round 1's near-invisible shadow only moved the judgment to <em>how invisible is enough</em>. The rule: Paper and Card at rest have <strong>zero</strong> shadow (<code>elevation: 0</code>, <code>variant: 'outlined'</code>); weight exists only on transient surfaces &mdash; Dialog, Drawer, Menu, Tooltip. Binary and checkable in review.</p>
741
- <div class="cols">
742
- <div class="col th-mui">
743
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
744
- <div class="row">
745
- <div style="width:130px;height:80px;background:#fff;border-radius:4px;box-shadow:var(--shadow-rest);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px;box-sizing:border-box;line-height:1.3;font-size:11px;color:var(--ink-2);text-align:center">shadows[1]<br>rest (Paper/Card)</div>
746
- <div style="width:130px;height:80px;background:#fff;border-radius:4px;box-shadow:var(--shadow-overlay);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px;box-sizing:border-box;line-height:1.3;font-size:11px;color:var(--ink-2);text-align:center">shadows[24]<br>overlay</div>
747
- </div>
748
- </div>
749
- <div class="col th-candidate">
750
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
751
- <div class="row">
752
- <div style="width:130px;height:80px;background:#fff;border:1px solid var(--border-c);border-radius:8px;box-shadow:var(--shadow-rest);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px;box-sizing:border-box;line-height:1.3;font-size:11px;color:var(--ink-2);text-align:center">rest (Paper/Card)<br><strong>no shadow, ever</strong></div>
753
- <div style="width:130px;height:80px;background:#fff;border-radius:8px;box-shadow:var(--shadow-overlay);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:6px;box-sizing:border-box;line-height:1.3;font-size:11px;color:var(--ink-2);text-align:center">overlay<br>Dialog/Drawer/Menu/Tooltip</div>
754
- </div>
755
- </div>
756
- </div>
757
- <div class="row" style="margin-top:16px; gap:8px">
758
- <span class="axis-badge">Paper — no shadow</span>
759
- <span class="axis-badge">Card — no shadow</span>
760
- <span class="axis-badge">Button (contained) — no shadow</span>
761
- <span class="axis-badge" style="background:#E5F4E9;border-color:#C7E4CE;color:#1E6B32">Dialog — shadow</span>
762
- <span class="axis-badge" style="background:#E5F4E9;border-color:#C7E4CE;color:#1E6B32">Drawer — shadow</span>
763
- <span class="axis-badge" style="background:#E5F4E9;border-color:#C7E4CE;color:#1E6B32">Menu — shadow</span>
764
- <span class="axis-badge" style="background:#E5F4E9;border-color:#C7E4CE;color:#1E6B32">Tooltip — shadow</span>
765
- </div>
766
- </section>
767
-
768
- <!-- =========================================================
769
- TYPOGRAPHY — settled, no variants
770
- ========================================================= -->
771
- <section class="doc-section" id="typography-settled-scale">
772
- <h2>Typography — settled scale</h2>
773
- <p class="section-note">MUI's h6 is 20px/500; the corpus runs 15&ndash;16px card titles and 13px tile titles. In the decided scale <strong>h4 (20px) is the screen title</strong> — a <em>visual</em> variant only. Semantically it stays <code>&lt;h1&gt;</code>: in MUI, <code>component="h1" variant="h4"</code>. Treating the variant as the element produces a broken heading hierarchy and h6 (16px) the card title; h1&ndash;h3 stay usable rather than decorative.</p>
774
- <div class="cols">
775
- <div class="col th-mui" style="flex-basis:100%">
776
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
777
- <div class="type-line t-h1">H1 heading<span class="tag">96/300</span></div>
778
- <div class="type-line t-h2">H2 heading<span class="tag">60/300</span></div>
779
- <div class="type-line t-h3">H3 heading<span class="tag">48/400</span></div>
780
- <div class="type-line t-h4">H4 heading<span class="tag">34/400</span></div>
781
- <div class="type-line t-h5">H5 heading<span class="tag">24/400</span></div>
782
- <div class="type-line t-h6">H6 heading<span class="tag">20/500</span></div>
783
- <div class="type-line t-sub1">Subtitle 1<span class="tag">16/400</span></div>
784
- <div class="type-line t-sub2">Subtitle 2<span class="tag">14/500</span></div>
785
- <div class="type-line t-body1">Body 1 — the quick brown fox jumps over the lazy dog<span class="tag">16/400</span></div>
786
- <div class="type-line t-body2">Body 2 — the quick brown fox jumps over the lazy dog<span class="tag">14/400</span></div>
787
- <div class="type-line t-btn">BUTTON LABEL<span class="tag">14/500 uppercase</span></div>
788
- <div class="type-line t-cap">Caption text<span class="tag">12/400</span></div>
789
- <div class="type-line t-ov">OVERLINE TEXT<span class="tag">12/500</span></div>
790
- </div>
791
- </div>
792
- <div style="height:10px"></div>
793
- <div class="cols">
794
- <div class="col th-candidate" style="flex-basis:100%">
795
- <div class="col-label">Baseline candidate — decided scale <span class="tag cand">DS2</span></div>
796
- <div class="type-line t-h1">H1 heading<span class="tag">32/600</span></div>
797
- <div class="type-line t-h2">H2 heading<span class="tag">28/600</span></div>
798
- <div class="type-line t-h3">H3 heading<span class="tag">24/600</span></div>
799
- <div class="type-line t-h4">H4 heading — screen title<span class="tag">20/600</span></div>
800
- <div class="type-line t-h5">H5 heading<span class="tag">18/600</span></div>
801
- <div class="type-line t-h6">H6 heading — card title<span class="tag">16/600</span></div>
802
- <div class="type-line t-sub1">Subtitle 1<span class="tag">15/600</span></div>
803
- <div class="type-line t-sub2">Subtitle 2<span class="tag">13/500</span></div>
804
- <div class="type-line t-body1">Body 1 — the quick brown fox jumps over the lazy dog<span class="tag">14/400</span></div>
805
- <div class="type-line t-body2">Body 2 — the quick brown fox jumps over the lazy dog<span class="tag">13/400</span></div>
806
- <div class="type-line t-btn">Button label<span class="tag">14/500, no uppercase</span></div>
807
- <div class="type-line t-cap">Caption text<span class="tag">12/400</span></div>
808
- <div class="type-line t-ov">OVERLINE TEXT<span class="tag">11/600</span></div>
809
- </div>
810
- </div>
811
- </section>
812
-
813
- <!-- =========================================================
814
- CONTROL HEIGHT, TOUCH TARGET, RADIUS — settled, no variants
815
- ========================================================= -->
816
- <section class="doc-section" id="control-height-touch-target-radius-settl">
817
- <h2>Control height, touch target &amp; radius — settled</h2>
818
- <p class="section-note">MUI: medium <code>OutlinedInput</code> ~56px, <code>small</code> ~40px. Decided: <strong>40px</strong> (36px in round 1), consistently across Button/Select/TextField/Chip. 34&ndash;36px is a recorded defect against the 44px touch guideline in an approved envelope; 40px sits on MUI's <code>small</code>, and <code>@media (pointer: coarse)</code> bumps to 44px &mdash; simulated here. Radius settled at 3px control / 8px card.</p>
819
- <div class="cols">
820
- <div class="col th-mui">
821
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
822
- <div class="col-sub">control 56px · cell pad 16px · radius 4/4</div>
823
- <div class="stack">
824
- <button class="sf-btn sf-btn--contained">Save</button>
825
- <div class="sf-select" aria-hidden="true"><span>Select…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
826
- <div class="sf-chip">Chip</div>
827
- <div class="sf-paper sf-paper--outlined" style="width:140px"><div class="sf-card-title">Card</div><div class="sf-card-body">radius 4</div></div>
828
- </div>
829
- </div>
830
- <div class="col th-candidate">
831
- <div class="col-label">Baseline candidate — desktop <span class="tag cand">DS2</span></div>
832
- <div class="col-sub">control 40px · cell pad 10/16 · radius 3/8</div>
833
- <div class="stack">
834
- <button class="sf-btn sf-btn--contained">Save</button>
835
- <div class="sf-select" aria-hidden="true"><span>Select…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
836
- <div class="sf-chip">Chip</div>
837
- <div class="sf-paper sf-paper--outlined" style="width:140px"><div class="sf-card-title">Card</div><div class="sf-card-body">radius 8</div></div>
838
- </div>
839
- </div>
840
- <div class="col th-candidate" style="--control-h:44px">
841
- <div class="col-label">Baseline candidate — touch (simulated) <span class="tag cand">DS2</span></div>
842
- <div class="col-sub">44px hit area via @media (any-pointer: coarse)</div>
843
- <div class="stack">
844
- <button class="sf-btn sf-btn--contained">Save</button>
845
- <div class="sf-select" aria-hidden="true"><span>Select…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
846
- <div class="sf-chip">Chip</div>
847
- <div class="sf-paper sf-paper--outlined" style="width:140px"><div class="sf-card-title">Card</div><div class="sf-card-body">radius 8</div></div>
848
- </div>
849
- </div>
850
- </div>
851
- </section>
852
-
853
- <!-- =========================================================
854
- COMPONENT GALLERY
855
- ========================================================= -->
856
- <section class="doc-section" id="component-gallery">
857
- <h2>Component gallery</h2>
858
- <p class="section-note">Decided baseline throughout, no variants left to pick. Buttons: <code>textTransform: none</code>, no elevation on contained &mdash; all 7 sampled app themes override MUI's uppercase independently, so this replaces 7 repeated overrides.</p>
859
-
860
- <h3>Button — all variants × sizes</h3>
861
- <div class="cols">
862
- <div class="col th-mui">
863
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
864
- <div class="stack">
865
- <div class="row"><button class="sf-btn sf-btn--contained sf-btn--sm">Contained</button><button class="sf-btn sf-btn--contained">Contained</button><button class="sf-btn sf-btn--contained sf-btn--lg">Contained</button></div>
866
- <div class="row"><button class="sf-btn sf-btn--outlined sf-btn--sm">Outlined</button><button class="sf-btn sf-btn--outlined">Outlined</button><button class="sf-btn sf-btn--outlined sf-btn--lg">Outlined</button></div>
867
- <div class="row"><button class="sf-btn sf-btn--text sf-btn--sm">Text</button><button class="sf-btn sf-btn--text">Text</button><button class="sf-btn sf-btn--text sf-btn--lg">Text</button></div>
868
- </div>
869
- </div>
870
- <div class="col th-candidate">
871
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
872
- <div class="stack">
873
- <div class="row"><button class="sf-btn sf-btn--contained sf-btn--sm">Contained</button><button class="sf-btn sf-btn--contained">Contained</button><button class="sf-btn sf-btn--contained sf-btn--lg">Contained</button></div>
874
- <div class="row"><button class="sf-btn sf-btn--outlined sf-btn--sm">Outlined</button><button class="sf-btn sf-btn--outlined">Outlined</button><button class="sf-btn sf-btn--outlined sf-btn--lg">Outlined</button></div>
875
- <div class="row"><button class="sf-btn sf-btn--text sf-btn--sm">Text</button><button class="sf-btn sf-btn--text">Text</button><button class="sf-btn sf-btn--text sf-btn--lg">Text</button></div>
876
- </div>
877
- </div>
878
- </div>
879
-
880
- <h3>Table — head + body, default + dense</h3>
881
- <div class="cols">
882
- <div class="col th-mui" style="flex-basis:47%">
883
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
884
- <table class="sf-table"><thead><tr><th>App</th><th>Staging</th><th>CI</th></tr></thead>
885
- <tbody><tr><td>hram</td><td>Success · 4h</td><td>2 failing</td></tr><tr><td>jg-ferien</td><td>Success · 5d</td><td>OK</td></tr></tbody></table>
886
- </div>
887
- <div class="col th-candidate" style="flex-basis:47%">
888
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
889
- <table class="sf-table"><thead><tr><th>App</th><th>Staging</th><th>CI</th></tr></thead>
890
- <tbody><tr><td>hram</td><td>Success · 4h</td><td>2 failing</td></tr><tr><td>jg-ferien</td><td>Success · 5d</td><td>OK</td></tr></tbody></table>
891
- </div>
892
- </div>
893
- <div style="height:12px"></div>
894
- <div class="cols">
895
- <div class="col th-mui" style="flex-basis:47%">
896
- <div class="col-label">MUI dense <span class="tag mui">MUI</span></div>
897
- <table class="sf-table" style="--table-pad:6px 16px"><thead><tr><th>App</th><th>Staging</th><th>CI</th></tr></thead>
898
- <tbody><tr><td>hram</td><td>Success · 4h</td><td>2 failing</td></tr><tr><td>jg-ferien</td><td>Success · 5d</td><td>OK</td></tr></tbody></table>
899
- </div>
900
- <div class="col th-candidate" style="flex-basis:47%">
901
- <div class="col-label">Baseline — table-pad 10/16 <span class="tag cand">DS2</span></div>
902
- <table class="sf-table"><thead><tr><th>App</th><th>Staging</th><th>CI</th></tr></thead>
903
- <tbody><tr><td>hram</td><td>Success · 4h</td><td>2 failing</td></tr><tr><td>jg-ferien</td><td>Success · 5d</td><td>OK</td></tr></tbody></table>
904
- </div>
905
- </div>
906
-
907
- <h3>IconButton, Divider, Tooltip</h3>
908
- <div class="cols">
909
- <div class="col th-mui">
910
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
911
- <div class="row">
912
- <button class="sf-icon-btn" style="background:rgba(0,0,0,0.04)"><svg viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
913
- <div class="sf-tooltip-wrap"><button class="sf-icon-btn" style="background:rgba(0,0,0,0.04)"><svg viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button><div class="sf-tooltip">Tooltip text</div></div>
914
- </div>
915
- <hr class="sf-divider" />
916
- <div class="t-body2">Content below divider</div>
917
- </div>
918
- <div class="col th-candidate">
919
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
920
- <div class="row">
921
- <button class="sf-icon-btn" style="background:var(--bg-page)"><svg viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
922
- <div class="sf-tooltip-wrap"><button class="sf-icon-btn" style="background:var(--bg-page)"><svg viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button><div class="sf-tooltip">Tooltip text</div></div>
923
- </div>
924
- <hr class="sf-divider" />
925
- <div class="t-body2">Content below divider</div>
926
- </div>
927
- </div>
928
-
929
- <h3>Select, Checkbox, FormControlLabel</h3>
930
- <div class="cols">
931
- <div class="col th-mui">
932
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
933
- <div class="stack">
934
- <div class="sf-select" aria-hidden="true"><span>Select an app…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
935
- <label class="sf-fcl"><span class="sf-checkbox checked"></span> Notify on failure</label>
936
- <label class="sf-fcl"><span class="sf-checkbox"></span> Include archived</label>
937
- </div>
938
- </div>
939
- <div class="col th-candidate">
940
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
941
- <div class="stack">
942
- <div class="sf-select" aria-hidden="true"><span>Select an app…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
943
- <label class="sf-fcl"><span class="sf-checkbox checked"></span> Notify on failure</label>
944
- <label class="sf-fcl"><span class="sf-checkbox"></span> Include archived</label>
945
- </div>
946
- </div>
947
- </div>
948
-
949
- <h3>TextField / OutlinedInput</h3>
950
- <div class="cols">
951
- <div class="col th-mui">
952
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
953
- <div class="sf-outlined-wrap"><span class="float-label">Search apps</span><div class="sf-input" aria-hidden="true"><span class="sf-ph">hram…</span></div></div>
954
- </div>
955
- <div class="col th-candidate">
956
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
957
- <div class="sf-outlined-wrap"><span class="float-label">Search apps</span><div class="sf-input" aria-hidden="true"><span class="sf-ph">hram…</span></div></div>
958
- </div>
959
- </div>
960
-
961
- <h3>Paper / Card — outlined vs. elevation</h3>
962
- <div class="cols">
963
- <div class="col th-mui">
964
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
965
- <div class="row">
966
- <div class="sf-paper sf-paper--outlined" style="width:150px"><div class="sf-card-title">Outlined</div><div class="sf-card-body">border only</div></div>
967
- <div class="sf-paper sf-paper--elevation" style="width:150px"><div class="sf-card-title">Elevation</div><div class="sf-card-body">shadows[1]</div></div>
968
- </div>
969
- </div>
970
- <div class="col th-candidate">
971
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
972
- <div class="row">
973
- <div class="sf-paper sf-paper--outlined" style="width:150px"><div class="sf-card-title">Outlined (default)</div><div class="sf-card-body">border only</div></div>
974
- <div class="sf-paper sf-paper--elevation" style="width:150px"><div class="sf-card-title">"Elevation"</div><div class="sf-card-body">identical — no rest shadow exists</div></div>
975
- </div>
976
- </div>
977
- </div>
978
-
979
- <h3>Chip</h3>
980
- <div class="cols">
981
- <div class="col th-mui">
982
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
983
- <div class="row"><div class="sf-chip">Filled</div><div class="sf-chip outlined">Outlined</div></div>
984
- </div>
985
- <div class="col th-candidate">
986
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
987
- <div class="row"><div class="sf-chip">Filled</div><div class="sf-chip outlined">Outlined</div></div>
988
- </div>
989
- </div>
990
-
991
- <h3>Dialog header</h3>
992
- <div class="cols">
993
- <div class="col th-mui">
994
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
995
- <div class="sf-dialog"><div class="sf-dialog-title">Confirm deploy</div><div class="sf-dialog-body">This will push develop to staging.</div></div>
996
- </div>
997
- <div class="col th-candidate">
998
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
999
- <div class="sf-dialog"><div class="sf-dialog-title">Confirm deploy</div><div class="sf-dialog-body">This will push develop to staging.</div></div>
1000
- </div>
1001
- </div>
1002
-
1003
- <h3>Alert (standard variant)</h3>
1004
- <div class="cols">
1005
- <div class="col th-mui">
1006
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
1007
- <div class="stack"><div class="sf-alert success"><span class="dot success"></span>Deploy succeeded</div><div class="sf-alert critical"><span class="dot critical"></span>CI failing on develop</div></div>
1008
- </div>
1009
- <div class="col th-candidate">
1010
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
1011
- <div class="stack"><div class="sf-alert success"><span class="dot success"></span>Deploy succeeded</div><div class="sf-alert critical"><span class="dot critical"></span>CI failing on develop</div></div>
1012
- </div>
1013
- </div>
1014
-
1015
- <h3>Container — page-gutter difference</h3>
1016
- <div class="cols">
1017
- <div class="col th-mui" style="flex-basis:47%">
1018
- <div class="col-label">MUI raw default <span class="tag mui">MUI</span></div>
1019
- <div class="col-sub">px: xs 16px / sm+ 24px</div>
1020
- <div class="sf-container-demo"><div class="sf-container-inner" style="margin:0 16px">content area, 16px gutter</div></div>
1021
- </div>
1022
- <div class="col th-candidate" style="flex-basis:47%">
1023
- <div class="col-label">Baseline candidate <span class="tag cand">DS2</span></div>
1024
- <div class="col-sub">consistent 24px gutter, 32px ≥1200px</div>
1025
- <div class="sf-container-demo"><div class="sf-container-inner" style="margin:0 24px">content area, 24px gutter</div></div>
1026
- </div>
1027
- </div>
1028
- </section>
1029
-
1030
- <!-- =========================================================
1031
- MOBILE FRAME
1032
- ========================================================= -->
1033
- <section class="doc-section" id="mobile-frame-375px">
1034
- <h2>Mobile frame — 375px</h2>
1035
- <p class="section-note">A literal phone frame, not a resized window &mdash; at the decided control height, with the table&rarr;card behaviour below the usual breakpoint.</p>
1036
- <div class="two-col">
1037
- <div>
1038
- <h3 style="margin-top:0">Controls at 375px (40px control height)</h3>
1039
- <div class="phone"><div class="phone-notch"></div>
1040
- <div class="phone-inner th-candidate" style="padding:14px">
1041
- <div class="stack">
1042
- <button class="sf-btn sf-btn--contained" style="width:100%">Deploy to staging</button>
1043
- <div class="sf-select" style="width:100%" aria-hidden="true"><span class="sf-ph">Filter by app…</span><svg class="sf-caret" viewBox="0 0 10 6" width="10" height="6"><polyline points="1,1 5,5 9,1" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></div>
1044
- <div class="row"><div class="sf-chip">hram</div><div class="sf-chip">jg-ferien</div><div class="sf-chip outlined">+3</div></div>
1045
- </div>
1046
- </div>
1047
- </div>
1048
- </div>
1049
- <div>
1050
- <h3 style="margin-top:0">Table → card collapse</h3>
1051
- <div class="phone"><div class="phone-notch"></div>
1052
- <div class="phone-inner th-candidate" style="padding:14px">
1053
- <div class="stack">
1054
- <div class="sf-paper sf-paper--outlined">
1055
- <div class="sf-card-title">hram</div>
1056
- <div class="row" style="margin-top:6px"><span class="t-cap">Staging</span><span class="t-body2">Success · 4h</span></div>
1057
- <div class="row"><span class="t-cap">CI</span><span class="t-body2" style="color:var(--critical)">2 failing</span></div>
1058
- </div>
1059
- <div class="sf-paper sf-paper--outlined">
1060
- <div class="sf-card-title">jg-ferien</div>
1061
- <div class="row" style="margin-top:6px"><span class="t-cap">Staging</span><span class="t-body2">Success · 5d</span></div>
1062
- <div class="row"><span class="t-cap">CI</span><span class="t-body2" style="color:var(--success)">OK</span></div>
1063
- </div>
1064
- </div>
1065
- <p class="t-cap" style="margin-top:10px">Below the corpus breakpoint, each row becomes a card — same fields, stacked instead of columned. Cards are border-only at rest, per the shadow rule above.</p>
1066
- </div>
1067
- </div>
1068
- </div>
1069
- </div>
1070
- </section>
1071
-
1072
- <!-- =========================================================
1073
- CLOSING — what this sheet asserts / what remains open
1074
- ========================================================= -->
1075
- <section class="doc-section" id="what-this-sheet-asserts-and-what-remains">
1076
- <h2>What this sheet asserts, and what remains unverified</h2>
1077
- <p class="section-note"><strong>Release candidate, not yet a locked baseline.</strong> The motion tokens are declared but <strong>not demonstrated</strong> — a static specimen cannot show timing, and this document renders without JS in the environments it has been opened in so far. Reviewed 2026-08-09 by a second reader; the warning/tint contrast failure, the chart-token contradiction, the touch and focus rules and this document's own legibility were corrected in response. This document is what a later theme change gets re-checked against. Below: what is verified here at render time, and what still has to be confirmed elsewhere.</p>
1078
- <div class="decision-item">
1079
- <div class="decision-num">Verified</div>
1080
- <div class="decision-txt">Every ink tone clears 4.5:1 on white and every status text tone clears 4.6:1 on its own Alert tint, computed live. Muted ink was darkened twice &mdash; now to a 4.6:1 target that also holds on a near-white page.</div>
1081
- </div>
1082
- <div class="decision-item">
1083
- <div class="decision-num">Verified</div>
1084
- <div class="decision-txt">Every status fill&harr;<code>contrastText</code> pair clears 4.5:1. Success and warning needed a fill hue distinct from their text tone; critical and stale reuse one hex, which clears in both directions.</div>
1085
- </div>
1086
- <div class="decision-item">
1087
- <div class="decision-num">Verified</div>
1088
- <div class="decision-txt">Muted ink is verified against the page background, not only a white surface &mdash; the round-2 gap is closed.</div>
1089
- </div>
1090
- <div class="decision-item">
1091
- <div class="decision-num">Verified</div>
1092
- <div class="decision-txt">Control-boundary contrast is fixed. The old <code>input.border</code> (1.59 rest / 2.72 hover) never cleared 3:1. Split into <code>divider</code> (exempt) and <code>controlBorder</code> (all states &ge;3:1), applied to TextField, Select, Checkbox and outlined Button/Chip.</div>
1093
- </div>
1094
- <div class="decision-item">
1095
- <div class="decision-num">Decided</div>
1096
- <div class="decision-txt">The second non-colour channel was removed on operator review (2026-08-09) &mdash; hatch fills, dash patterns and marker shapes all read as noise. Series identity now rests on colour alone, so the series-4/5 greyscale proximity is a <strong>live limitation</strong> and a six-series chart does not satisfy WCAG 1.4.1. Resolving it belongs to DS-4, not to the theme.</div>
1097
- </div>
1098
- <div class="decision-item">
1099
- <div class="decision-num">Decided</div>
1100
- <div class="decision-txt"><code>#FAFAFA</code> is decided (operator, 2026-08-09) after three warm candidates were rejected. The four-value strip is kept as provenance.</div>
1101
- </div>
1102
- <div class="decision-item">
1103
- <div class="decision-num">Known limitation</div>
1104
- <div class="decision-txt"><code>stale</code> has no estate precedent and has not been seen in a running screen &mdash; a decision, not a validation. The first consuming app tests it.</div>
1105
- </div>
1106
- <div class="decision-item">
1107
- <div class="decision-num">Open</div>
1108
- <div class="decision-txt">Out of scope here: dark mode, components outside the agreed list, the <code>createAppTheme()</code> implementation, and per-app conformance.</div>
1109
- </div>
1110
- </section>
1111
-
1112
- <h2 class="appendix-h">Appendix — provenance</h2>
1113
- <section class="doc-section" id="page-background-candidate-strip">
1114
- <h2>Page background — candidate strip</h2>
1115
- <p class="section-note">Four values side by side: pure white, the chosen neutral, the original cool value, and the smallest perceptible warm shift. Each carries a real white card, so the question is whether the card still reads as a card. Path: <code>#F5F7F8</code> &rarr; <code>#F7F6F3</code> &rarr; <code>#FCFBF9</code> &rarr; <code>#FAFAFA</code>.</p>
1116
- <div class="bg-strip">
1117
- <div class="bg-card">
1118
- <div class="bg-card-label">#FFFFFF</div>
1119
- <div class="bg-card-val">pure white — the reference</div>
1120
- <div style="background:#FFFFFF; border-radius:8px; padding:12px">
1121
- <div class="bg-card-surface"><p class="bg-card-text">Card on #FFFFFF</p><p class="bg-card-caption">body text inside a white surface</p></div>
1122
- <p class="bg-card-text" style="margin-top:2px">Body text directly on the page</p>
1123
- <p class="bg-card-caption" style="margin:4px 0 0">Muted caption directly on the page <span class="ratio-badge" data-fg="#6A7178" data-bg="#FFFFFF" data-min="4.5"></span></p>
1124
- </div>
1125
- <div class="bg-delta">&Delta; from white (R,G,B): <code>0, 0, 0</code> &middot; cast (R&minus;B): <code>0</code></div>
1126
- <div class="bg-delta" style="opacity:.8">reference: hram, fitness-monitor and innoservice ship this today</div>
1127
- </div>
1128
- <div class="bg-card chosen">
1129
- <div class="bg-card-label">#FAFAFA</div>
1130
- <div class="bg-card-val">neutral, one step off white</div>
1131
- <div style="background:#FAFAFA; border-radius:8px; padding:12px">
1132
- <div class="bg-card-surface"><p class="bg-card-text">Card on #FAFAFA</p><p class="bg-card-caption">body text inside a white surface</p></div>
1133
- <p class="bg-card-text" style="margin-top:2px">Body text directly on the page</p>
1134
- <p class="bg-card-caption" style="margin:4px 0 0">Muted caption directly on the page <span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAFA" data-min="4.5"></span></p>
1135
- </div>
1136
- <div class="bg-delta">&Delta; from white (R,G,B): <code>5, 5, 5</code> &middot; cast (R&minus;B): <code>0</code></div>
1137
- <div class="bg-delta" style="opacity:.8">CHOSEN 2026-08-09 — MUI grey[50], no colour cast</div>
1138
- </div>
1139
- <div class="bg-card">
1140
- <div class="bg-card-label">#F5F7F8</div>
1141
- <div class="bg-card-val">slightly cool — round 1</div>
1142
- <div style="background:#F5F7F8; border-radius:8px; padding:12px">
1143
- <div class="bg-card-surface"><p class="bg-card-text">Card on #F5F7F8</p><p class="bg-card-caption">body text inside a white surface</p></div>
1144
- <p class="bg-card-text" style="margin-top:2px">Body text directly on the page</p>
1145
- <p class="bg-card-caption" style="margin:4px 0 0">Muted caption directly on the page <span class="ratio-badge" data-fg="#6A7178" data-bg="#F5F7F8" data-min="4.5"></span></p>
1146
- </div>
1147
- <div class="bg-delta">&Delta; from white (R,G,B): <code>10, 8, 7</code> &middot; cast (R&minus;B): <code>&minus;3</code></div>
1148
- <div class="bg-delta" style="opacity:.8">the original blue-cast value; note it is also ~5 points darker, so its difference is not only the cast</div>
1149
- </div>
1150
- <div class="bg-card">
1151
- <div class="bg-card-label">#FAFAF7</div>
1152
- <div class="bg-card-val">one nuance toward yellow</div>
1153
- <div style="background:#FAFAF7; border-radius:8px; padding:12px">
1154
- <div class="bg-card-surface"><p class="bg-card-text">Card on #FAFAF7</p><p class="bg-card-caption">body text inside a white surface</p></div>
1155
- <p class="bg-card-text" style="margin-top:2px">Body text directly on the page</p>
1156
- <p class="bg-card-caption" style="margin:4px 0 0">Muted caption directly on the page <span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAF7" data-min="4.5"></span></p>
1157
- </div>
1158
- <div class="bg-delta">&Delta; from white (R,G,B): <code>5, 5, 8</code> &middot; cast (R&minus;B): <code>+3</code></div>
1159
- <div class="bg-delta" style="opacity:.8">same lightness as the chosen value, blue lowered by 3 — the minimum perceptible warm shift</div>
1160
- </div>
1161
- </div>
1162
- <p class="section-note" style="margin:14px 0 0"><strong><code>#FAFAFA</code> is the chosen <code>bg.page</code></strong> (operator, 2026-08-09). All three warm candidates read as too warm: against a blue-cast value, <em>warmer</em> meant <strong>neutral</strong>, and the need was a lightness step off white, not a hue. <code>#FAFAFA</code> is MUI's <code>grey[50]</code>. hram, fitness-monitor and innoservice ship pure white today and change visibly on adoption; jg-ferien and spesix override for identity.</p>
1163
- <p class="section-note" style="margin:10px 0 0"><code>#6A7178</code> cleared 4.5:1 only on pure white (4.549) and failed all three page candidates (4.399 / 4.324 / 4.247). Darkened along the same hue to <strong><code>#6A7178</code></strong>: 4.946 on white, 4.616 on the darkest candidate &mdash; against a 4.6 target, not a nudge over 4.5. Used everywhere <code>ink.muted</code> appears.</p>
1164
- </section>
1165
-
1166
- <section class="doc-section" id="canonical-baseline-tokens">
1167
- <h2>Canonical baseline tokens</h2>
1168
- <p class="section-note">Every decided value, once. A work order references this table by token name rather than retyping values; if a number here and a number in a WO disagree, this table is the one to fix. Contrast badges are computed live.</p>
1169
- <div style="overflow-x:auto">
1170
- <table class="token-table">
1171
- <thead><tr><th>Token</th><th>Value</th><th>Role</th><th>Computed contrast</th><th>Note</th></tr></thead>
1172
- <tbody>
1173
- <tr class="group-row"><td colspan="5">Ink &amp; surface</td></tr>
1174
- <tr><td><code>ink.primary</code></td><td><span class="token-swatch" style="background:#212529"></span><code>#212529</code></td><td>body text, headings</td>
1175
- <td><span class="ratio-badge" data-fg="#212529" data-bg="#FFFFFF" data-min="4.5"></span></td><td class="note">unchanged</td></tr>
1176
- <tr><td><code>ink.secondary</code></td><td><span class="token-swatch" style="background:#5B6670"></span><code>#5B6670</code></td><td>subtitle2, secondary text</td>
1177
- <td><span class="ratio-badge" data-fg="#5B6670" data-bg="#FFFFFF" data-min="4.5"></span></td><td class="note">unchanged</td></tr>
1178
- <tr><td><code>ink.muted</code></td><td><span class="token-swatch" style="background:#6A7178"></span><code>#6A7178</code></td><td>captions, meta text</td>
1179
- <td><span class="ratio-badge" data-fg="#6A7178" data-bg="#FFFFFF" data-min="4.6"></span> <span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAFA" data-min="4.6"></span> <span class="ratio-badge" data-fg="#6A7178" data-bg="#FAFAFA" data-min="4.6"></span></td>
1180
- <td class="note">was <code>#6A7178</code> (4.549 on white, 4.247 on the darkest page candidate). Darkened to clear 4.6:1 on all of them.</td></tr>
1181
- <tr><td><code>divider</code></td><td><span class="token-swatch" style="background:#e9e9ea"></span><code>rgba(33,37,41,.10)</code></td><td>decorative separators, card outline</td>
1182
- <td><span class="ratio-badge" data-fg="rgba(33,37,41,0.10)" data-bg="#FFFFFF" data-min="3"></span></td><td class="note">decorative &mdash; exempt from WCAG 1.4.11. Split off from the single border token this round.</td></tr>
1183
- <tr><td><code>controlBorder</code> (rest)</td><td><span class="token-swatch" style="background:#909294"></span><code>rgba(33,37,41,.50)</code></td><td>TextField/Select rest, Checkbox box, outlined Button/Chip</td>
1184
- <td><span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FFFFFF" data-min="3"></span> <span class="ratio-badge" data-fg="rgba(33,37,41,0.50)" data-bg="#FAFAFA" data-min="3"></span></td>
1185
- <td class="note">new &mdash; supersedes <code>input.border</code> (0.23 alpha), which never cleared 3:1. Same ink hue, higher opacity.</td></tr>
1186
- <tr><td><code>controlBorder-hover</code></td><td><span class="token-swatch" style="background:#7a7c7f"></span><code>rgba(33,37,41,.65)</code></td><td>control outline on hover</td>
1187
- <td><span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FFFFFF" data-min="3"></span> <span class="ratio-badge" data-fg="rgba(33,37,41,0.65)" data-bg="#FAFAFA" data-min="3"></span></td>
1188
- <td class="note">supersedes <code>input.border-hover</code> (<code>rgba(33,37,41,.45)</code>, 2.72:1, also sub-3:1)</td></tr>
1189
- <tr><td><code>control.autofill</code></td><td>surface inset shadow + <code>-webkit-text-fill-color</code> = <code>ink.primary</code></td><td>autofilled input/select background and text</td>
1190
- <td class="note">not a contrast pair — a suppression</td><td class="note"><strong>MUI has no autofill styling, and the browsers disagree:</strong> the same field rendered yellow in Chromium, dark grey in Opera, dark blue in Firefox (operator, 2026-08-09). <code>:-webkit-autofill</code> alone misses Firefox &mdash; the standard <code>:autofill</code> is needed too. Not demonstrated here: this sheet's form controls are inert, so no native chrome pollutes the comparisons. The gap is real for the apps.</td></tr>
1191
- <tr><td><code>controlBorder-focus</code></td><td><em>derived from the app's <code>primary</code></em>, auto-darkened until it clears 3:1 against the surface (MUI <code>getContrastRatio</code>/<code>darken</code>). No fixed hex — the baseline defines no <code>primary</code>. Ratios for the four real estate accents &rarr;</td><td>control outline on focus</td>
1192
- <td style="line-height:1.9">hram <code>#468AB2</code> <span class="ratio-badge" data-fg="#468AB2" data-bg="#FCFBF9" data-min="3"></span><br>spesix <code>#1B8FD8</code> <span class="ratio-badge" data-fg="#1B8FD8" data-bg="#FCFBF9" data-min="3"></span><br>fm <code>#0F62FE</code> <span class="ratio-badge" data-fg="#0F62FE" data-bg="#FCFBF9" data-min="3"></span><br>survey <code>#432CA1</code> <span class="ratio-badge" data-fg="#432CA1" data-bg="#FCFBF9" data-min="3"></span></td>
1193
- <td class="note">new — reuses the existing primary hue rather than introducing another colour</td></tr>
1194
- <tr><td><code>controlBorder-error</code></td><td><span class="token-swatch" style="background:#BF3227"></span><code>#BF3227</code></td><td>control outline in error state</td>
1195
- <td><span class="ratio-badge" data-fg="#BF3227" data-bg="#FFFFFF" data-min="3"></span> <span class="ratio-badge" data-fg="#BF3227" data-bg="#FAFAFA" data-min="3"></span></td>
1196
- <td class="note">new — reuses the existing critical hue</td></tr>
1197
- <tr><td><code>bg.page</code></td><td><span class="token-swatch" style="background:#FAFAFA"></span><code>#FAFAFA</code></td><td>app canvas / page background</td><td>—</td>
1198
- <td class="note">neutral, no cast &mdash; MUI <code>grey[50]</code>. Fourth in the chain <code>#F5F7F8</code> &rarr; <code>#F7F6F3</code> &rarr; <code>#FCFBF9</code> &rarr; <code>#FAFAFA</code>.</td></tr>
1199
- <tr><td><code>bg.surface</code></td><td><span class="token-swatch" style="background:#FFFFFF"></span><code>#FFFFFF</code></td><td>Paper/Card/Table/Dialog</td><td>—</td><td class="note">unchanged</td></tr>
1200
-
1201
- <tr class="group-row"><td colspan="5">Status — success</td></tr>
1202
- <tr><td><code>success.text</code></td><td><span class="token-swatch" style="background:#35794A"></span><code>#35794A</code></td><td>Alert text/icon, table cell text</td>
1203
- <td><span class="ratio-badge" data-fg="#35794A" data-bg="#E5F4E9" data-min="4.5"></span></td><td class="note">was #1E8E3E (4.20:1, FAIL). Replaced with jg-ferien's validated tone.</td></tr>
1204
- <tr><td><code>success.fill</code> / <code>.fillText</code></td><td><span class="token-swatch" style="background:#1B8038"></span><code>#1B8038</code> / <code>#FFFFFF</code></td><td>solid chip/badge fill</td>
1205
- <td><span class="ratio-badge" data-fg="#FFFFFF" data-bg="#1B8038" data-min="4.5"></span></td><td class="note">new &mdash; <code>#1E8E3E</code> fails as a fill too (4.20:1 either direction, by symmetry). Darkened until fill+white clears 4.5:1.</td></tr>
1206
- <tr><td><code>success.bg</code></td><td><span class="token-swatch" style="background:#E5F4E9"></span><code>#E5F4E9</code></td><td>Alert background tint</td><td>—</td><td class="note">unchanged; pairs with success.text, contrast only improves vs. pure white</td></tr>
1207
-
1208
- <tr class="group-row"><td colspan="5">Status — warning</td></tr>
1209
- <tr><td><code>warning.text</code></td><td><span class="token-swatch" style="background:#976100"></span><code>#976100</code></td><td>Alert text/icon, table cell text</td>
1210
- <td><span class="ratio-badge" data-fg="#976100" data-bg="#FBF0DC" data-min="4.5"></span></td><td class="note">was #A66A00 (4.484:1, short by 0.016). Darkened minimally along the same muted brown-amber hue — never yellow.</td></tr>
1211
- <tr><td><code>warning.fill</code> / <code>.fillText</code></td><td><span class="token-swatch" style="background:#C08A2C"></span><code>#C08A2C</code> / <code>#212529</code></td><td>solid chip/badge fill</td>
1212
- <td><span class="ratio-badge" data-fg="#212529" data-bg="#C08A2C" data-min="4.5"></span></td><td class="note">jg-ferien's validated precedent, dark ink as <code>contrastText</code> &mdash; a mid-tone amber fails under white text.</td></tr>
1213
- <tr><td><code>warning.bg</code></td><td><span class="token-swatch" style="background:#FBF0DC"></span><code>#FBF0DC</code></td><td>Alert background tint</td><td>—</td><td class="note">unchanged</td></tr>
1214
-
1215
- <tr class="group-row"><td colspan="5">Status — critical</td></tr>
1216
- <tr><td><code>critical.text</code></td><td><span class="token-swatch" style="background:#BF3227"></span><code>#BF3227</code></td><td>Alert text/icon, table cell text</td>
1217
- <td><span class="ratio-badge" data-fg="#BF3227" data-bg="#FBEAE8" data-min="4.5"></span></td><td class="note">kept — already passes</td></tr>
1218
- <tr><td><code>critical.fill</code> / <code>.fillText</code></td><td><span class="token-swatch" style="background:#BF3227"></span><code>#BF3227</code> / <code>#FFFFFF</code></td><td>solid chip/badge fill</td>
1219
- <td><span class="ratio-badge" data-fg="#FFFFFF" data-bg="#BF3227" data-min="4.5"></span></td><td class="note">one hex, both roles: it clears 4.5:1 on white, so by symmetry white-on-it clears too. No second hue needed.</td></tr>
1220
- <tr><td><code>critical.bg</code></td><td><span class="token-swatch" style="background:#FBEAE8"></span><code>#FBEAE8</code></td><td>Alert background tint</td><td>—</td><td class="note">unchanged</td></tr>
1221
-
1222
- <tr class="group-row"><td colspan="5">Status — stale</td></tr>
1223
- <tr><td><code>stale.text</code></td><td><span class="token-swatch" style="background:#5B6B7D"></span><code>#5B6B7D</code></td><td>Alert text/icon, table cell text</td>
1224
- <td><span class="ratio-badge" data-fg="#5B6B7D" data-bg="#EAEDF1" data-min="4.5"></span></td><td class="note">kept — already passes</td></tr>
1225
- <tr><td><code>stale.fill</code> / <code>.fillText</code></td><td><span class="token-swatch" style="background:#5B6B7D"></span><code>#5B6B7D</code> / <code>#FFFFFF</code></td><td>solid chip/badge fill</td>
1226
- <td><span class="ratio-badge" data-fg="#FFFFFF" data-bg="#5B6B7D" data-min="4.5"></span></td><td class="note">same hex, same symmetry argument as critical</td></tr>
1227
- <tr><td><code>stale.bg</code></td><td><span class="token-swatch" style="background:#EAEDF1"></span><code>#EAEDF1</code></td><td>Alert background tint</td><td>—</td><td class="note">unchanged. No precedent elsewhere in the estate — see the provenance note below.</td></tr>
1228
-
1229
- <tr class="group-row"><td colspan="5">Typography</td></tr>
1230
- <tr><td><code>h1</code></td><td>32px / 600</td><td>rare, top-level marketing-adjacent heading</td><td>—</td><td class="note">was 38px</td></tr>
1231
- <tr><td><code>h2</code></td><td>28px / 600</td><td>section heading</td><td>—</td><td class="note">was 30px</td></tr>
1232
- <tr><td><code>h3</code></td><td>24px / 600</td><td>subsection heading</td><td>—</td><td class="note">was 25px</td></tr>
1233
- <tr><td><code>h4</code></td><td>20px / 600</td><td><strong>screen title</strong> (visual variant; the element stays <code>&lt;h1&gt;</code>) — matches the estate's real 19-22px screen titles</td><td>—</td><td class="note">was 21px</td></tr>
1234
- <tr><td><code>h5</code></td><td>18px / 600</td><td>panel / dialog heading</td><td>—</td><td class="note">unchanged</td></tr>
1235
- <tr><td><code>h6</code></td><td>16px / 600</td><td><strong>card title</strong></td><td>—</td><td class="note">unchanged</td></tr>
1236
- <tr><td><code>subtitle1</code></td><td>15px / 600</td><td>emphasised secondary line</td><td>—</td><td class="note">was 14px</td></tr>
1237
- <tr><td><code>subtitle2</code></td><td>13px / 500</td><td>secondary tile title</td><td>—</td><td class="note">unchanged</td></tr>
1238
- <tr><td><code>body1</code></td><td>14px / 400</td><td>primary body copy</td><td>—</td><td class="note">unchanged</td></tr>
1239
- <tr><td><code>body2</code></td><td>13px / 400</td><td>secondary body copy, table cells</td><td>—</td><td class="note">unchanged</td></tr>
1240
- <tr><td><code>button</code></td><td>14px / 500, no uppercase</td><td>Button label</td><td>—</td><td class="note">unchanged</td></tr>
1241
- <tr><td><code>caption</code></td><td>12px / 400</td><td>captions</td><td>—</td><td class="note">unchanged</td></tr>
1242
- <tr><td><code>overline</code></td><td>11px / 600, uppercase</td><td>overline labels</td><td>—</td><td class="note">unchanged</td></tr>
1243
-
1244
- <tr class="group-row"><td colspan="5">Density &amp; control height</td></tr>
1245
- <tr><td><code>control.height</code></td><td>40px<br>44px <span class="note">@ (pointer: coarse)</span></td><td>Button/Select/TextField height</td><td>—</td>
1246
- <td class="note">was 36px. 34&ndash;36px is a recorded defect against the 44px touch guideline; 40px sits on MUI's <code>small</code>, 44px activates under a coarse pointer.</td></tr>
1247
- <tr><td><code>table.cellPadding</code></td><td>10px 16px</td><td>TableCell</td><td>—</td><td class="note">was 8px 12px, scaled proportionally with control height</td></tr>
1248
- <tr><td><code>chip.height</code> / <code>.radius</code> / <code>.fontSize</code></td><td>32px / 16px / 13px</td><td>Chip</td><td>—</td><td class="note">was 28px / 14px / 12.5px, same proportional scaling</td></tr>
1249
-
1250
- <tr class="group-row"><td colspan="5">Radius</td></tr>
1251
- <tr><td><code>radius.control</code></td><td>3px</td><td>Button/Select/TextField/Chip corner</td><td>—</td><td class="note">settled — no A/B variant left</td></tr>
1252
- <tr><td><code>radius.card</code></td><td>8px</td><td>Paper/Card/Dialog corner</td><td>—</td><td class="note">settled — no A/B variant left</td></tr>
1253
-
1254
- <tr class="group-row"><td colspan="5">Shadow</td></tr>
1255
- <tr><td><code>shadow.rest</code></td><td><code>none</code></td><td>Paper/Card at rest — <code>elevation:0</code>, <code>variant:'outlined'</code> is the default</td><td>—</td><td class="note">binary rule now: rest state never has a shadow, full stop</td></tr>
1256
- <tr><td><code>shadow.overlay</code></td><td><code>0 8px 24px rgba(20,26,31,.16), 0 2px 8px rgba(20,26,31,.08)</code></td><td>Dialog, Drawer, Menu, Tooltip only</td><td>—</td><td class="note">unchanged value; scope narrowed to transient surfaces only</td></tr>
1257
-
1258
- <tr class="group-row"><td colspan="5">Data-series ramp (categorical)</td></tr>
1259
- <tr><td><code>series.1</code>…<code>series.6</code></td><td>#3D5A99 · #3E80B8 · #2E8F8A · #7A5FA8 · #9C4F86 · #8A7355</td><td>charts, categorical fills</td><td>see the ramp section below</td>
1260
- <td class="note">hues unchanged per the operator's verdict. The series-4/5 greyscale collision is <strong>not</strong> fixed &mdash; the second channel that covered it was removed; see DS-4.</td></tr>
1261
- <tr><td><code>series.marker</code></td><td>circle · square · triangle · diamond · cross · plus</td><td>line chart point markers, series 1→6 in order</td><td>—</td><td class="note"><strong>opt-in, off by default</strong> — DS-13. Not applied in the charts above; a multi-series chart satisfies WCAG 1.4.1 only with the overlay switched on.</td></tr>
1262
- <tr><td><code>series.dasharray</code></td><td>none · 8,4 · 2,3 · 10,3,2,3 · 14,4 · 8,3,2,3,2,3</td><td>line stroke pattern, series 1→6 in order</td><td>—</td><td class="note"><strong>opt-in, off by default</strong> — DS-13. Not applied in the charts above; a multi-series chart satisfies WCAG 1.4.1 only with the overlay switched on.</td></tr>
1263
- <tr><td><code>series.pattern</code></td><td>solid · diagonal hatch · dots · cross-hatch · h-lines · v-lines</td><td>bar/area fill pattern, series 1→6 in order</td><td>—</td><td class="note"><strong>opt-in, off by default</strong> — DS-13. Not applied in the charts above; a multi-series chart satisfies WCAG 1.4.1 only with the overlay switched on.</td></tr>
1264
- <tr><td><code>motion.fast</code></td><td>120ms</td><td>hover, focus, border and colour state on controls</td>
1265
- <td class="note">not a contrast pair</td><td class="note">below ~100ms no transition is perceived; above ~150ms a control feels sluggish</td></tr>
1266
- <tr><td><code>motion.base</code></td><td>180ms</td><td>expand/collapse, reveal, list-item enter</td>
1267
- <td class="note">—</td><td class="note">—</td></tr>
1268
- <tr><td><code>motion.overlay</code></td><td>220ms in / 180ms out</td><td>Dialog, Drawer, Menu, Tooltip</td>
1269
- <td class="note">—</td><td class="note">asymmetric on purpose, following MUI's own 225/195: an entrance may be followed, an exit should get out of the way</td></tr>
1270
- <tr><td><code>motion.chart</code></td><td>300ms</td><td>chart entry only</td>
1271
- <td class="note">—</td><td class="note">MUI's <code>standard: 300</code> is kept for exactly this case, where a line needs time to draw. <strong>Charts that poll or re-render on a timer get <code>skipAnimation</code></strong> (cockpit's status board, hram's <code>CampaignMonitorPanel</code>) — X-Charts 8.28.2 offers no separate enter/update control, so those two lose entry animation too. A library limit, not a design choice.</td></tr>
1272
- <tr><td><code>motion.easing</code></td><td>enter <code>easeOut</code> · exit <code>easeIn</code> · state <code>easeInOut</code></td><td>which of MUI's curves applies where</td>
1273
- <td class="note">—</td><td class="note">curves are MUI's own, unchanged — only the assignment is decided here</td></tr>
1274
- <tr><td><code>motion.reduced</code></td><td>all durations → <code>0.01ms</code></td><td><code>prefers-reduced-motion: reduce</code></td>
1275
- <td class="note">—</td><td class="note"><strong>0.01ms, not 0</strong> — at exactly 0 some browsers never fire <code>transitionend</code>, and MUI's <code>Grow</code>/<code>Fade</code> wait for it, so the component hangs. Kept as courtesy, not compliance: reduced-motion is not itself a WCAG criterion (2.2.2 is A for auto-playing motion over 5s, 2.3.3 is AAA).</td></tr>
1276
-
1277
- <tr class="group-row"><td colspan="5">Spacing, gutters, buttons (already settled, unchanged)</td></tr>
1278
- <tr><td><code>spacing.unit</code></td><td>8px</td><td>layout rhythm multiplier</td><td>—</td><td class="note">unchanged</td></tr>
1279
- <tr><td><code>container.gutter</code></td><td>24px (32px ≥1200px)</td><td>Container</td><td>—</td><td class="note">unchanged</td></tr>
1280
- <tr><td><code>button.textTransform</code></td><td><code>none</code></td><td>Button label casing</td><td>—</td><td class="note">unchanged</td></tr>
1281
- <tr><td><code>button.elevation</code></td><td><code>none</code> (contained)</td><td>Button contained variant</td><td>—</td><td class="note">unchanged, and now consistent with the shadow.rest rule above</td></tr>
1282
- </tbody>
1283
- </table>
1284
- </div>
1285
- </section>
1286
-
1287
- </div>
1288
-
1289
- <script>
1290
- (function(){
1291
- function parseColor(str){
1292
- if (!str) return [255,255,255,1];
1293
- str = str.trim();
1294
- if (str.startsWith('#')) {
1295
- var hex = str.slice(1);
1296
- if (hex.length === 3) hex = hex.split('').map(function(c){ return c+c; }).join('');
1297
- var num = parseInt(hex,16);
1298
- return [ (num>>16)&255, (num>>8)&255, num&255, 1 ];
1299
- }
1300
- var m = str.match(/rgba?\(([^)]+)\)/);
1301
- if (m) {
1302
- var parts = m[1].split(',').map(function(s){ return parseFloat(s.trim()); });
1303
- return [ parts[0], parts[1], parts[2], parts.length > 3 ? parts[3] : 1 ];
1304
- }
1305
- return [255,255,255,1];
1306
- }
1307
- function blend(fg, bg){
1308
- var r = fg[0], g = fg[1], b = fg[2], a = fg[3];
1309
- if (a >= 1) return [r,g,b];
1310
- return [ r*a + bg[0]*(1-a), g*a + bg[1]*(1-a), b*a + bg[2]*(1-a) ];
1311
- }
1312
- function channel(c){ c = c/255; return c <= 0.03928 ? c/12.92 : Math.pow((c+0.055)/1.055, 2.4); }
1313
- function relLum(rgb){ return 0.2126*channel(rgb[0]) + 0.7152*channel(rgb[1]) + 0.0722*channel(rgb[2]); }
1314
- function contrastRatio(fgStr, bgStr){
1315
- var bgRgba = parseColor(bgStr);
1316
- var bgRgb = [bgRgba[0], bgRgba[1], bgRgba[2]];
1317
- var fgRgb = blend(parseColor(fgStr), bgRgb);
1318
- var L1 = relLum(fgRgb), L2 = relLum(bgRgb);
1319
- var lighter = Math.max(L1,L2), darker = Math.min(L1,L2);
1320
- return (lighter+0.05)/(darker+0.05);
1321
- }
1322
- function grayFromColor(str){
1323
- var rgb = parseColor(str);
1324
- var blended = blend(rgb, [255,255,255]);
1325
- var L = relLum(blended);
1326
- var inv = function(Lc){ return Lc <= 0.0031308 ? Lc*12.92 : 1.055*Math.pow(Lc, 1/2.4) - 0.055; };
1327
- var g = Math.max(0, Math.min(255, Math.round(inv(L)*255)));
1328
- return { g: g, hex: '#'+[g,g,g].map(function(c){ return c.toString(16).padStart(2,'0'); }).join('') };
1329
- }
1330
-
1331
- document.querySelectorAll('.ratio-badge[data-fg][data-bg]').forEach(function(el){
1332
- var fg = el.getAttribute('data-fg');
1333
- var bg = el.getAttribute('data-bg');
1334
- var min = parseFloat(el.getAttribute('data-min') || '4.5');
1335
- var r = contrastRatio(fg, bg);
1336
- var pass = r >= min;
1337
- el.textContent = r.toFixed(2) + ':1 ' + (pass ? 'PASS' : 'FAIL');
1338
- el.classList.add(pass ? 'pass' : 'fail');
1339
- el.title = 'computed at render time · threshold ' + min.toFixed(1) + ':1';
1340
- });
1341
-
1342
- document.querySelectorAll('[data-gray-source]').forEach(function(el){
1343
- var src = el.getAttribute('data-gray-source');
1344
- var res = grayFromColor(src);
1345
- el.style.background = res.hex;
1346
- var sib = el.parentElement.querySelector('.gray-value');
1347
- if (sib) sib.textContent = 'gray ' + res.g + '/255 (' + res.hex + ')';
1348
- });
1349
- })();
1350
- </script>
1351
- </body>
1352
- </html>