@felloinnovations/brand-kit 0.4.0 → 0.5.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 (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +221 -0
  3. package/README.md +38 -9
  4. package/design-system/01-how-claude-decides.md +26 -17
  5. package/design-system/02-principles.md +11 -6
  6. package/design-system/03-colour.md +135 -47
  7. package/design-system/04-type.md +45 -23
  8. package/design-system/05-space-and-layout.md +175 -52
  9. package/design-system/06-sizing-profiles.md +4 -4
  10. package/design-system/07-scrolling.md +66 -20
  11. package/design-system/08-choosing-components.md +50 -22
  12. package/design-system/09-charts.md +71 -28
  13. package/design-system/10-patterns.md +33 -10
  14. package/design-system/11-page-recipes.md +110 -23
  15. package/design-system/12-content.md +2 -1
  16. package/design-system/13-motion.md +330 -47
  17. package/design-system/14-accessibility.md +47 -24
  18. package/design-system/15-ai-experiences.md +11 -6
  19. package/design-system/16-creativity.md +1 -1
  20. package/design-system/17-decisions.md +367 -1
  21. package/design-system/18-checklist.md +79 -16
  22. package/design-system/19-public-pages.md +6 -4
  23. package/design-system/20-palettes.md +275 -0
  24. package/design-system/README.md +30 -17
  25. package/design-system/components/ActionList/README.md +96 -10
  26. package/design-system/components/ActionList/preview.html +52 -7
  27. package/design-system/components/ActionList/style.css +64 -0
  28. package/design-system/components/ActivityGrid/README.md +38 -2
  29. package/design-system/components/ActivityGrid/preview.html +1 -1
  30. package/design-system/components/ActivityGrid/style.css +35 -0
  31. package/design-system/components/AppShell/README.md +205 -75
  32. package/design-system/components/AppShell/preview.html +339 -58
  33. package/design-system/components/AppShell/style.css +154 -0
  34. package/design-system/components/Avatar/README.md +37 -10
  35. package/design-system/components/Avatar/preview.html +13 -4
  36. package/design-system/components/Avatar/style.css +14 -0
  37. package/design-system/components/Badge/README.md +41 -19
  38. package/design-system/components/Badge/preview.html +13 -10
  39. package/design-system/components/Badge/style.css +23 -0
  40. package/design-system/components/Banner/README.md +30 -9
  41. package/design-system/components/Banner/preview.html +1 -1
  42. package/design-system/components/Banner/style.css +19 -0
  43. package/design-system/components/Breadcrumb/README.md +58 -46
  44. package/design-system/components/Breadcrumb/preview.html +16 -16
  45. package/design-system/components/Breadcrumb/style.css +17 -0
  46. package/design-system/components/Button/README.md +113 -55
  47. package/design-system/components/Button/preview.html +98 -25
  48. package/design-system/components/Button/style.css +86 -0
  49. package/design-system/components/Card/README.md +158 -49
  50. package/design-system/components/Card/preview.html +141 -19
  51. package/design-system/components/Card/style.css +115 -0
  52. package/design-system/components/CardBoard/README.md +58 -37
  53. package/design-system/components/CardBoard/preview.html +26 -29
  54. package/design-system/components/ChatCard/README.md +115 -29
  55. package/design-system/components/ChatCard/preview.html +149 -32
  56. package/design-system/components/ChatCard/style.css +49 -0
  57. package/design-system/components/ChatShell/README.md +116 -0
  58. package/design-system/components/ChatShell/preview.html +201 -0
  59. package/design-system/components/ChatShell/style.css +86 -0
  60. package/design-system/components/ChatTurn/README.md +78 -35
  61. package/design-system/components/ChatTurn/preview.html +60 -28
  62. package/design-system/components/ChatTurn/style.css +50 -0
  63. package/design-system/components/CheckRow/README.md +141 -0
  64. package/design-system/components/CheckRow/preview.html +140 -0
  65. package/design-system/components/CheckRow/style.css +88 -0
  66. package/design-system/components/Checkbox/README.md +58 -22
  67. package/design-system/components/Checkbox/preview.html +112 -50
  68. package/design-system/components/Checkbox/style.css +45 -0
  69. package/design-system/components/Chip/README.md +78 -47
  70. package/design-system/components/Chip/preview.html +29 -4
  71. package/design-system/components/Chip/style.css +17 -0
  72. package/design-system/components/Combobox/README.md +44 -11
  73. package/design-system/components/Combobox/preview.html +35 -12
  74. package/design-system/components/Combobox/style.css +54 -0
  75. package/design-system/components/Composer/README.md +137 -35
  76. package/design-system/components/Composer/preview.html +115 -40
  77. package/design-system/components/Composer/style.css +81 -0
  78. package/design-system/components/ConfirmDialog/README.md +73 -52
  79. package/design-system/components/ConfirmDialog/preview.html +70 -26
  80. package/design-system/components/ConfirmDialog/style.css +5 -0
  81. package/design-system/components/Cover/preview.html +3 -3
  82. package/design-system/components/Cover/style.css +19 -0
  83. package/design-system/components/DateInput/README.md +77 -12
  84. package/design-system/components/DateInput/preview.html +27 -12
  85. package/design-system/components/DateInput/style.css +38 -0
  86. package/design-system/components/Dialog/README.md +112 -44
  87. package/design-system/components/Dialog/preview.html +141 -18
  88. package/design-system/components/Dialog/style.css +74 -0
  89. package/design-system/components/EmptyState/README.md +42 -12
  90. package/design-system/components/EmptyState/preview.html +11 -11
  91. package/design-system/components/EmptyState/style.css +9 -0
  92. package/design-system/components/EntryShell/README.md +73 -48
  93. package/design-system/components/EntryShell/preview.html +60 -27
  94. package/design-system/components/EntryShell/style.css +19 -0
  95. package/design-system/components/FeatureGrid/README.md +61 -39
  96. package/design-system/components/FeatureGrid/preview.html +2 -2
  97. package/design-system/components/FeatureGrid/style.css +20 -0
  98. package/design-system/components/FileUpload/README.md +33 -3
  99. package/design-system/components/FileUpload/preview.html +18 -4
  100. package/design-system/components/FileUpload/style.css +23 -0
  101. package/design-system/components/FilterBar/README.md +114 -0
  102. package/design-system/components/FilterBar/preview.html +82 -0
  103. package/design-system/components/FilterBar/style.css +22 -0
  104. package/design-system/components/Fold/README.md +84 -26
  105. package/design-system/components/Fold/preview.html +77 -34
  106. package/design-system/components/Fold/style.css +48 -0
  107. package/design-system/components/Footer/README.md +62 -39
  108. package/design-system/components/Footer/preview.html +5 -5
  109. package/design-system/components/Footer/style.css +30 -0
  110. package/design-system/components/FunnelBars/README.md +24 -3
  111. package/design-system/components/FunnelBars/preview.html +5 -5
  112. package/design-system/components/FunnelBars/style.css +13 -0
  113. package/design-system/components/GoalBars/README.md +54 -10
  114. package/design-system/components/GoalBars/preview.html +69 -28
  115. package/design-system/components/GoalBars/style.css +51 -0
  116. package/design-system/components/GoalTicks/README.md +74 -58
  117. package/design-system/components/GoalTicks/preview.html +41 -118
  118. package/design-system/components/GoalTicks/style.css +37 -0
  119. package/design-system/components/GoalTubes/README.md +29 -3
  120. package/design-system/components/GoalTubes/preview.html +6 -6
  121. package/design-system/components/GoalTubes/style.css +23 -0
  122. package/design-system/components/Heatmap/README.md +133 -0
  123. package/design-system/components/Heatmap/preview.html +168 -0
  124. package/design-system/components/Heatmap/style.css +119 -0
  125. package/design-system/components/Hero/README.md +58 -40
  126. package/design-system/components/Hero/preview.html +1 -1
  127. package/design-system/components/Hero/style.css +19 -0
  128. package/design-system/components/HoverCard/README.md +114 -0
  129. package/design-system/components/HoverCard/preview.html +107 -0
  130. package/design-system/components/HoverCard/style.css +59 -0
  131. package/design-system/components/IconButton/README.md +69 -38
  132. package/design-system/components/IconButton/preview.html +77 -43
  133. package/design-system/components/IconButton/style.css +45 -0
  134. package/design-system/components/Input/README.md +36 -11
  135. package/design-system/components/Input/preview.html +1 -1
  136. package/design-system/components/Input/style.css +23 -0
  137. package/design-system/components/KanbanBoard/README.md +93 -45
  138. package/design-system/components/KanbanBoard/preview.html +159 -43
  139. package/design-system/components/KanbanBoard/style.css +53 -0
  140. package/design-system/components/Kbd/README.md +25 -9
  141. package/design-system/components/Kbd/preview.html +6 -2
  142. package/design-system/components/Kbd/style.css +9 -0
  143. package/design-system/components/KitButton/README.md +81 -47
  144. package/design-system/components/KitButton/preview.html +35 -13
  145. package/design-system/components/KitButton/style.css +46 -0
  146. package/design-system/components/KitCard/README.md +75 -44
  147. package/design-system/components/KitCard/preview.html +18 -10
  148. package/design-system/components/KitCard/style.css +15 -0
  149. package/design-system/components/KitInput/README.md +54 -39
  150. package/design-system/components/KitInput/preview.html +7 -7
  151. package/design-system/components/KitInput/style.css +23 -0
  152. package/design-system/components/Leaderboard/README.md +76 -49
  153. package/design-system/components/Leaderboard/preview.html +61 -26
  154. package/design-system/components/Leaderboard/style.css +44 -0
  155. package/design-system/components/ListDetail/README.md +222 -0
  156. package/design-system/components/ListDetail/preview.html +213 -0
  157. package/design-system/components/ListDetail/style.css +148 -0
  158. package/design-system/components/LoadBar/README.md +79 -0
  159. package/design-system/components/LoadBar/preview.html +40 -0
  160. package/design-system/components/LoadBar/style.css +17 -0
  161. package/design-system/components/MarketingNav/README.md +76 -42
  162. package/design-system/components/MarketingNav/preview.html +37 -8
  163. package/design-system/components/MarketingNav/style.css +45 -0
  164. package/design-system/components/Matrix/README.md +129 -0
  165. package/design-system/components/Matrix/preview.html +99 -0
  166. package/design-system/components/Matrix/style.css +84 -0
  167. package/design-system/components/Menu/README.md +117 -41
  168. package/design-system/components/Menu/preview.html +85 -23
  169. package/design-system/components/Menu/style.css +61 -0
  170. package/design-system/components/Meter/README.md +39 -4
  171. package/design-system/components/Meter/preview.html +18 -1
  172. package/design-system/components/Meter/style.css +23 -0
  173. package/design-system/components/MetricTile/README.md +237 -0
  174. package/design-system/components/MetricTile/preview.html +241 -0
  175. package/design-system/components/MetricTile/style.css +129 -0
  176. package/design-system/components/Morph/README.md +106 -0
  177. package/design-system/components/Morph/preview.html +103 -0
  178. package/design-system/components/Morph/style.css +31 -0
  179. package/design-system/components/Motion/README.md +164 -0
  180. package/design-system/components/Motion/preview.html +2537 -0
  181. package/design-system/components/NumberInput/README.md +27 -8
  182. package/design-system/components/NumberInput/preview.html +21 -5
  183. package/design-system/components/NumberInput/style.css +34 -0
  184. package/design-system/components/PaceBar/README.md +75 -0
  185. package/design-system/components/PaceBar/preview.html +67 -0
  186. package/design-system/components/PaceBar/style.css +25 -0
  187. package/design-system/components/Page/README.md +57 -18
  188. package/design-system/components/Page/preview.html +15 -17
  189. package/design-system/components/Page/style.css +7 -0
  190. package/design-system/components/PageBar/README.md +90 -34
  191. package/design-system/components/PageBar/preview.html +60 -19
  192. package/design-system/components/PageBar/style.css +35 -0
  193. package/design-system/components/PageHero/README.md +87 -51
  194. package/design-system/components/PageHero/preview.html +35 -6
  195. package/design-system/components/PageHero/style.css +31 -0
  196. package/design-system/components/Pagination/README.md +70 -49
  197. package/design-system/components/Pagination/preview.html +24 -15
  198. package/design-system/components/Pagination/style.css +12 -0
  199. package/design-system/components/Panel/README.md +109 -51
  200. package/design-system/components/Panel/preview.html +118 -20
  201. package/design-system/components/Panel/style.css +51 -0
  202. package/design-system/components/PasswordInput/README.md +50 -18
  203. package/design-system/components/PasswordInput/preview.html +71 -21
  204. package/design-system/components/PasswordInput/style.css +31 -0
  205. package/design-system/components/Plate/README.md +75 -17
  206. package/design-system/components/Plate/preview.html +40 -7
  207. package/design-system/components/Plate/style.css +37 -0
  208. package/design-system/components/Popover/README.md +70 -49
  209. package/design-system/components/Popover/preview.html +44 -22
  210. package/design-system/components/Popover/style.css +41 -0
  211. package/design-system/components/PricingTable/README.md +69 -49
  212. package/design-system/components/PricingTable/preview.html +21 -21
  213. package/design-system/components/PricingTable/style.css +21 -0
  214. package/design-system/components/ProgressPetals/README.md +31 -3
  215. package/design-system/components/ProgressPetals/preview.html +14 -15
  216. package/design-system/components/ProgressPetals/style.css +27 -0
  217. package/design-system/components/README.md +151 -0
  218. package/design-system/components/Radio/README.md +40 -17
  219. package/design-system/components/Radio/preview.html +16 -1
  220. package/design-system/components/Radio/style.css +21 -0
  221. package/design-system/components/RankBar/README.md +29 -2
  222. package/design-system/components/RankBar/preview.html +14 -12
  223. package/design-system/components/RankBar/style.css +18 -0
  224. package/design-system/components/Ring/README.md +61 -11
  225. package/design-system/components/Ring/preview.html +55 -10
  226. package/design-system/components/Ring/style.css +49 -0
  227. package/design-system/components/ScoreHero/README.md +91 -0
  228. package/design-system/components/ScoreHero/preview.html +104 -0
  229. package/design-system/components/ScoreHero/style.css +32 -0
  230. package/design-system/components/Section/README.md +72 -33
  231. package/design-system/components/Section/preview.html +46 -16
  232. package/design-system/components/Section/style.css +18 -0
  233. package/design-system/components/Segmented/README.md +100 -55
  234. package/design-system/components/Segmented/preview.html +107 -26
  235. package/design-system/components/Segmented/style.css +94 -0
  236. package/design-system/components/SegmentedProgress/README.md +64 -0
  237. package/design-system/components/SegmentedProgress/preview.html +69 -0
  238. package/design-system/components/SegmentedProgress/style.css +11 -0
  239. package/design-system/components/Select/README.md +47 -12
  240. package/design-system/components/Select/preview.html +28 -2
  241. package/design-system/components/Select/style.css +22 -0
  242. package/design-system/components/ShareBar/README.md +69 -0
  243. package/design-system/components/ShareBar/preview.html +72 -0
  244. package/design-system/components/ShareBar/style.css +25 -0
  245. package/design-system/components/SideList/README.md +147 -0
  246. package/design-system/components/SideList/preview.html +139 -0
  247. package/design-system/components/SideList/style.css +94 -0
  248. package/design-system/components/Skeleton/README.md +53 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +17 -0
  251. package/design-system/components/Slider/README.md +95 -0
  252. package/design-system/components/Slider/preview.html +49 -0
  253. package/design-system/components/Slider/style.css +13 -0
  254. package/design-system/components/Split/README.md +112 -0
  255. package/design-system/components/Split/preview.html +105 -0
  256. package/design-system/components/Split/style.css +30 -0
  257. package/design-system/components/Starter/README.md +21 -9
  258. package/design-system/components/Starter/preview.html +5 -5
  259. package/design-system/components/Stat/README.md +64 -43
  260. package/design-system/components/Stat/preview.html +3 -3
  261. package/design-system/components/Stat/style.css +15 -0
  262. package/design-system/components/StatTiles/README.md +88 -44
  263. package/design-system/components/StatTiles/preview.html +142 -71
  264. package/design-system/components/StatTiles/style.css +64 -0
  265. package/design-system/components/StatusLine/README.md +85 -0
  266. package/design-system/components/StatusLine/preview.html +49 -0
  267. package/design-system/components/StatusLine/style.css +14 -0
  268. package/design-system/components/StatusScreen/README.md +49 -35
  269. package/design-system/components/StatusScreen/preview.html +20 -5
  270. package/design-system/components/StatusScreen/style.css +9 -0
  271. package/design-system/components/StepLine/README.md +97 -0
  272. package/design-system/components/StepLine/preview.html +108 -0
  273. package/design-system/components/StepLine/style.css +62 -0
  274. package/design-system/components/Stepper/README.md +35 -13
  275. package/design-system/components/Stepper/style.css +13 -0
  276. package/design-system/components/StreakCalendar/README.md +22 -1
  277. package/design-system/components/StreakCalendar/preview.html +10 -10
  278. package/design-system/components/StreakCalendar/style.css +12 -0
  279. package/design-system/components/SuggestionChip/README.md +87 -0
  280. package/design-system/components/SuggestionChip/preview.html +42 -0
  281. package/design-system/components/SuggestionChip/style.css +20 -0
  282. package/design-system/components/Switch/README.md +44 -24
  283. package/design-system/components/Switch/preview.html +23 -8
  284. package/design-system/components/Switch/style.css +31 -0
  285. package/design-system/components/Table/README.md +129 -58
  286. package/design-system/components/Table/preview.html +106 -72
  287. package/design-system/components/Table/style.css +104 -0
  288. package/design-system/components/Tabs/README.md +71 -46
  289. package/design-system/components/Tabs/preview.html +56 -24
  290. package/design-system/components/Tabs/style.css +44 -0
  291. package/design-system/components/Testimonial/README.md +48 -32
  292. package/design-system/components/Testimonial/preview.html +14 -14
  293. package/design-system/components/Testimonial/style.css +12 -0
  294. package/design-system/components/TextArea/README.md +27 -11
  295. package/design-system/components/TextArea/preview.html +8 -2
  296. package/design-system/components/TextArea/style.css +12 -0
  297. package/design-system/components/ThemeSwitch/README.md +116 -0
  298. package/design-system/components/ThemeSwitch/preview.html +57 -0
  299. package/design-system/components/ThemeSwitch/style.css +6 -0
  300. package/design-system/components/TickRow/README.md +52 -36
  301. package/design-system/components/TickRow/preview.html +64 -41
  302. package/design-system/components/TickRow/style.css +23 -0
  303. package/design-system/components/TickStrip/README.md +95 -0
  304. package/design-system/components/TickStrip/preview.html +88 -0
  305. package/design-system/components/TickStrip/style.css +42 -0
  306. package/design-system/components/Tile/README.md +79 -18
  307. package/design-system/components/Tile/preview.html +91 -40
  308. package/design-system/components/Tile/style.css +36 -0
  309. package/design-system/components/Timeline/README.md +68 -48
  310. package/design-system/components/Timeline/preview.html +27 -15
  311. package/design-system/components/Timeline/style.css +25 -0
  312. package/design-system/components/Toast/README.md +70 -38
  313. package/design-system/components/Toast/preview.html +43 -8
  314. package/design-system/components/Toast/style.css +25 -0
  315. package/design-system/components/Tooltip/README.md +93 -35
  316. package/design-system/components/Tooltip/preview.html +69 -15
  317. package/design-system/components/Tooltip/style.css +78 -0
  318. package/design-system/components/TopBar/README.md +67 -53
  319. package/design-system/components/TopBar/preview.html +14 -27
  320. package/design-system/components/TopBar/style.css +35 -0
  321. package/design-system/components/TopicRail/README.md +108 -0
  322. package/design-system/components/TopicRail/preview.html +58 -0
  323. package/design-system/components/TopicRail/style.css +48 -0
  324. package/design-system/components/TrendBars/README.md +52 -14
  325. package/design-system/components/TrendBars/preview.html +65 -32
  326. package/design-system/components/TrendBars/style.css +25 -0
  327. package/design-system/components/TrendLine/README.md +164 -0
  328. package/design-system/components/TrendLine/preview.html +373 -0
  329. package/design-system/components/TrendLine/style.css +155 -0
  330. package/design-system/components/Well/README.md +64 -22
  331. package/design-system/components/Well/preview.html +14 -14
  332. package/design-system/components/Well/style.css +22 -0
  333. package/design-system/components/_house.css +324 -0
  334. package/design-system/components/bundle.css +4086 -744
  335. package/design-system/tokens.json +1310 -124
  336. package/dist/fello-core.css +2 -2
  337. package/dist/fello.css +6 -1369
  338. package/dist/fello.scoped.css +7 -0
  339. package/dist/index.d.ts +109 -10
  340. package/dist/index.js +781 -96
  341. package/dist/palettes.d.ts +464 -0
  342. package/dist/palettes.js +497 -0
  343. package/dist/scoped.d.ts +3 -0
  344. package/dist/scoped.js +16 -0
  345. package/dist/toast.d.ts +14 -0
  346. package/dist/toast.js +33 -29
  347. package/dist/tokens.d.ts +1686 -62
  348. package/dist/tokens.js +1668 -61
  349. package/package.json +20 -4
  350. package/scripts/check-palette.mjs +295 -0
  351. package/scripts/token-model.mjs +552 -0
  352. package/tokens/_dark.css +173 -0
  353. package/tokens/_palettes.css +46 -0
  354. package/tokens/_product.css +266 -53
  355. package/tokens/_source.hubl.css +39 -19
  356. package/tokens/design-tokens.json +319 -0
  357. package/tokens/palettes.ts +504 -0
  358. package/tokens/shadcn-compat.css +19 -19
  359. package/tokens/shadcn-compat.hsl.css +76 -0
  360. package/tokens/tokens.css +1287 -62
  361. package/tokens/tokens.md +587 -61
  362. package/tokens/tokens.root.css +1293 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -12,7 +12,8 @@
12
12
  <div class="ws-cluster ws-cluster--component ws-cluster--start">
13
13
 
14
14
  <div class="ws-stack">
15
- <span class="ws-muted">Field alone: native, dressed as the system's field</span>
15
+ <span class="ws-muted">Field alone: native, dressed as the system's field; then in error</span>
16
+ <div class="ws-stack ws-stack--component">
16
17
  <label class="ws-field">
17
18
  <span class="ws-label">Call date</span>
18
19
  <span class="ws-date-input">
@@ -22,6 +23,20 @@
22
23
  </svg>
23
24
  </span>
24
25
  </label>
26
+ <div class="ws-field">
27
+ <label class="ws-label" for="di-err">Close date</label>
28
+ <span class="ws-date-input">
29
+ <input class="ws-input" id="di-err" type="date" value="2026-10-02" aria-invalid="true" aria-describedby="di-err-msg">
30
+ <svg class="ws-date-input__icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
31
+ <rect x="2.5" y="3.5" width="11" height="10" rx="1.5"/><path d="M2.5 6.5h11M5 2v3M11 2v3"/>
32
+ </svg>
33
+ </span>
34
+ <p class="ws-field-msg ws-field-msg--error" id="di-err-msg">
35
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 2.3 14.6 13.5H1.4L8 2.3Z"/><path d="M8 6.4v3"/><path d="M8 11.5v.05"/></svg>
36
+ Pick a day after the offer was sent
37
+ </p>
38
+ </div>
39
+ </div>
25
40
  </div>
26
41
 
27
42
  <div class="ws-stack">
@@ -34,16 +49,16 @@
34
49
  </div>
35
50
  <div class="ws-date-input__grid">
36
51
  <span class="ws-date-input__letter">M</span><span class="ws-date-input__letter">T</span><span class="ws-date-input__letter">W</span><span class="ws-date-input__letter">T</span><span class="ws-date-input__letter">F</span><span class="ws-date-input__letter">S</span><span class="ws-date-input__letter">S</span>
37
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">28</button>
38
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">29</button>
39
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">30</button>
52
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">28</button>
53
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">29</button>
54
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">30</button>
40
55
  <button type="button" class="ws-date-input__cell">1</button><button type="button" class="ws-date-input__cell">2</button><button type="button" class="ws-date-input__cell">3</button><button type="button" class="ws-date-input__cell">4</button>
41
56
  <button type="button" class="ws-date-input__cell">5</button><button type="button" class="ws-date-input__cell">6</button><button type="button" class="ws-date-input__cell">7</button><button type="button" class="ws-date-input__cell">8</button><button type="button" class="ws-date-input__cell">9</button><button type="button" class="ws-date-input__cell">10</button><button type="button" class="ws-date-input__cell">11</button>
42
57
  <button type="button" class="ws-date-input__cell">12</button><button type="button" class="ws-date-input__cell">13</button><button type="button" class="ws-date-input__cell">14</button><button type="button" class="ws-date-input__cell">15</button><button type="button" class="ws-date-input__cell">16</button><button type="button" class="ws-date-input__cell">17</button><button type="button" class="ws-date-input__cell">18</button>
43
58
  <button type="button" class="ws-date-input__cell">19</button><button type="button" class="ws-date-input__cell">20</button><button type="button" class="ws-date-input__cell">21</button>
44
- <button type="button" class="ws-date-input__cell ws-date-input__cell--chosen" aria-current="date" aria-selected="true">22</button>
59
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--chosen" aria-pressed="true">22</button>
45
60
  <button type="button" class="ws-date-input__cell">23</button><button type="button" class="ws-date-input__cell">24</button><button type="button" class="ws-date-input__cell">25</button>
46
- <button type="button" class="ws-date-input__cell ws-date-input__cell--today" aria-label="Today, Oct 26">26</button>
61
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--today" aria-current="date">26</button>
47
62
  <button type="button" class="ws-date-input__cell">27</button><button type="button" class="ws-date-input__cell">28</button><button type="button" class="ws-date-input__cell">29</button><button type="button" class="ws-date-input__cell">30</button><button type="button" class="ws-date-input__cell">31</button>
48
63
  <button type="button" class="ws-date-input__cell ws-date-input__cell--muted">1</button>
49
64
  </div>
@@ -60,20 +75,20 @@
60
75
  </div>
61
76
  <div class="ws-date-input__grid">
62
77
  <span class="ws-date-input__letter">M</span><span class="ws-date-input__letter">T</span><span class="ws-date-input__letter">W</span><span class="ws-date-input__letter">T</span><span class="ws-date-input__letter">F</span><span class="ws-date-input__letter">S</span><span class="ws-date-input__letter">S</span>
63
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">28</button>
64
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">29</button>
65
- <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled">30</button>
78
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">28</button>
79
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">29</button>
80
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--muted ws-date-input__cell--disabled" aria-disabled="true">30</button>
66
81
  <button type="button" class="ws-date-input__cell">1</button><button type="button" class="ws-date-input__cell">2</button><button type="button" class="ws-date-input__cell">3</button><button type="button" class="ws-date-input__cell">4</button>
67
82
  <button type="button" class="ws-date-input__cell">5</button><button type="button" class="ws-date-input__cell">6</button><button type="button" class="ws-date-input__cell">7</button><button type="button" class="ws-date-input__cell">8</button><button type="button" class="ws-date-input__cell">9</button><button type="button" class="ws-date-input__cell">10</button><button type="button" class="ws-date-input__cell">11</button>
68
- <button type="button" class="ws-date-input__cell ws-date-input__cell--range-start" aria-selected="true">12</button>
83
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--range-start" aria-pressed="true">12</button>
69
84
  <button type="button" class="ws-date-input__cell ws-date-input__cell--range">13</button>
70
85
  <button type="button" class="ws-date-input__cell ws-date-input__cell--range">14</button>
71
86
  <button type="button" class="ws-date-input__cell ws-date-input__cell--range">15</button>
72
87
  <button type="button" class="ws-date-input__cell ws-date-input__cell--range">16</button>
73
88
  <button type="button" class="ws-date-input__cell ws-date-input__cell--range">17</button>
74
- <button type="button" class="ws-date-input__cell ws-date-input__cell--range-end" aria-selected="true">18</button>
89
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--range-end" aria-pressed="true">18</button>
75
90
  <button type="button" class="ws-date-input__cell">19</button><button type="button" class="ws-date-input__cell">20</button><button type="button" class="ws-date-input__cell">21</button><button type="button" class="ws-date-input__cell">22</button><button type="button" class="ws-date-input__cell">23</button><button type="button" class="ws-date-input__cell">24</button><button type="button" class="ws-date-input__cell">25</button>
76
- <button type="button" class="ws-date-input__cell ws-date-input__cell--today" aria-label="Today, Oct 26">26</button>
91
+ <button type="button" class="ws-date-input__cell ws-date-input__cell--today" aria-current="date">26</button>
77
92
  <button type="button" class="ws-date-input__cell">27</button><button type="button" class="ws-date-input__cell">28</button><button type="button" class="ws-date-input__cell">29</button><button type="button" class="ws-date-input__cell">30</button><button type="button" class="ws-date-input__cell">31</button>
78
93
  <button type="button" class="ws-date-input__cell ws-date-input__cell--muted">1</button>
79
94
  </div>
@@ -0,0 +1,38 @@
1
+ /* ---- DateInput: the native date field with a calendar mark, and a month grid in a menu for picking by eye. Days abut
2
+ across a row (2 px between weeks), so a range reads as one band; the chosen day is the navy act. On touch the grid
3
+ fills its column and loses its gaps, so a day is 40 tall and as wide as seven fit (40 or more from a 280 px column). ---- */
4
+ .ws-date-input { position: relative; display: flex; min-width: 0; }
5
+ .ws-date-input .ws-input { padding-right: var(--space-xl); }
6
+ /* The native picker's own mark stays where it is and still opens the sheet; only the kit's mark shows. */
7
+ .ws-date-input .ws-input::-webkit-calendar-picker-indicator { opacity: 0; cursor: pointer; }
8
+ .ws-date-input__icon { position: absolute; right: var(--space-xs); top: 50%; width: var(--ws-icon); height: var(--ws-icon); transform: translateY(-50%); color: var(--ws-field-mark, var(--color-text-heading)); pointer-events: none; }
9
+ /* The picker is a menu: it grows from its top left, under the field's left edge (written on .ws-menu so it outweighs
10
+ Menu's corner). */
11
+ .ws-date-input__picker { width: calc(var(--space-9xl) + var(--space-4xl) - var(--space-xxs)); max-width: 100%; padding: var(--space-xxs); }
12
+ .ws-menu.ws-date-input__picker { transform-origin: top left; }
13
+ .ws-date-input__head { display: flex; align-items: center; justify-content: space-between; height: var(--ws-control-h); padding: 0 var(--space-xxs); }
14
+ .ws-date-input__month { font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 500; color: var(--color-text-heading); }
15
+ .ws-date-input__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-3xs) 0; padding: var(--space-xxs); }
16
+ .ws-date-input__letter { text-align: center; font-size: var(--ws-text-micro); line-height: var(--space-md); color: var(--color-text-muted); }
17
+ .ws-date-input__cell { position: relative; display: flex; align-items: center; justify-content: center; height: var(--ws-control-h); padding: 0; border: 0; border-radius: var(--ws-radius-control); background: none; font-size: var(--ws-text-control); line-height: var(--ws-leading-control); color: var(--color-text-heading); font-variant-numeric: tabular-nums; cursor: pointer; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
18
+ .ws-date-input__cell:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
19
+ /* A navy day keeps a visible focus: the ring in its numeral colour, 2 px further in (a navy ring on navy vanishes). */
20
+ .ws-date-input__cell:is(.ws-date-input__cell--chosen, .ws-date-input__cell--range-start, .ws-date-input__cell--range-end):focus-visible { outline-color: var(--ws-on-act); outline-offset: calc(var(--ws-focus-width) * -2); }
21
+ @media (hover: hover) { .ws-date-input__cell:not(.ws-date-input__cell--disabled, .ws-date-input__cell--chosen, .ws-date-input__cell--range-start, .ws-date-input__cell--range-end):hover { background-color: var(--ws-hover); } }
22
+ .ws-date-input__cell--muted { color: var(--color-text-muted); }
23
+ /* Today: a 1 px ring in the salmon's AA step (the salmon itself is 2.6:1 on the cream, under the 3:1 a mark asks). */
24
+ .ws-date-input__cell--today { box-shadow: inset 0 0 0 var(--ws-line) var(--ws-word-needs); }
25
+ .ws-date-input__cell--chosen { background: var(--color-text-heading); color: var(--ws-on-act); }
26
+ .ws-date-input__cell--disabled { opacity: 0.4; cursor: default; }
27
+ .ws-date-input__cell--range { background: var(--ws-surface-sunk); border-radius: 0; }
28
+ .ws-date-input__cell--range-start { background: var(--color-text-heading); color: var(--ws-on-act); border-radius: var(--ws-radius-control) 0 0 var(--ws-radius-control); }
29
+ .ws-date-input__cell--range-end { background: var(--color-text-heading); color: var(--ws-on-act); border-radius: 0 var(--ws-radius-control) var(--ws-radius-control) 0; }
30
+ /* Touch: the grid and the head lose their padding so the days fill the picker and the month buttons sit on the outer
31
+ days' edges. Those buttons are 40 px boxes there (a 40 px head), so their target is their box: a 24 px button's hit
32
+ area spilled 8 px past it, out of the picker, and let a finger drag the calendar sideways. */
33
+ @media (pointer: coarse) {
34
+ .ws-date-input__picker { width: min(100%, calc(var(--ws-touch) * 8)); }
35
+ .ws-date-input__grid, .ws-date-input__head { padding: 0; }
36
+ .ws-date-input__head { height: var(--ws-touch); }
37
+ .ws-date-input__head > .ws-icon-btn { width: var(--ws-touch); height: var(--ws-touch); }
38
+ }
@@ -1,68 +1,101 @@
1
- A modal, built on the browser's own `<dialog>`: a small question in the centre of the screen, or a drawer sliding from an edge.
1
+ A modal, built on the browser's own `<dialog>`: a short task in the centre of the screen, or a drawer from the right edge.
2
2
 
3
3
  ## Use it when
4
4
 
5
- - A short task needs the person's full attention before they can go back to what they were doing (confirm, assign, name something).
5
+ - A short task needs the person's full attention before they go back (confirm, assign, name something).
6
6
  - A focused piece of content belongs over the page rather than beside it, and should trap focus and close on Escape.
7
- - A drawer reads naturally from a screen's edge (`from="right"` or `"left"`) rather than floating in the centre.
7
+ - A drawer reads naturally from the screen's edge (`ws-dialog--drawer`) rather than floating in the centre.
8
8
 
9
9
  ## Not for
10
10
 
11
- - A thing opened from the chat that the person still needs the page beside (a lead, a draft, a chart): use `Panel`.
11
+ - A thing opened from the chat that the person still needs the page beside (a lead, a draft, a check): use `Panel`.
12
12
  - A menu of short actions near a button: use `Menu`.
13
- - A brief, dismissible confirmation of something that already happened: use a toast (the kit's `Toaster`).
14
- - A name shown on hover: use `Tooltip` (`Tip`).
13
+ - A short note or a one-field form beside its control: use `Popover`.
14
+ - A receipt for something that already happened: use `Toast`.
15
15
 
16
16
  ## Anatomy
17
17
 
18
- - The dialog itself: the native `<dialog>` element, the card's cream (`--color-bg-page`) at `--ws-radius-card` (8 px, drawn here larger for a dialog or drawer at `--ws-radius-panel`, 16 px where the dialog is the whole floating thing), `--ws-shadow-lift` as the one lift a dialog keeps, since the product is otherwise flat.
19
- - `DialogHead`: a 20 px padded header, a 22 px navy title (`ws-title`) and one 14 px sentence under it, an optional aside (usually the close button) top right.
20
- - Content: the dialog's own body, padded 20 px at the sides.
21
- - `DialogFoot`: the footer band (`ws-band`), 28 px at the sides, an optional note on the left, its buttons on the right with the one primary last, each a large (36 px) button.
22
- - Behind it: a navy scrim at 35% (`--ws-scrim`), drawn on the native dialog's `::backdrop`.
18
+ - The pane: the native `<dialog>`, `--ws-raised` ground inside a 1 px `--ws-tray` rim (`--ws-rim`), 12 px corners
19
+ (`--ws-radius-drawer`, 11 inside), and one lift, `--ws-shadow-float`, because it sits over a scrim. Up to 42rem wide,
20
+ `calc(100% - 32px)` on a narrow screen, never taller than the window less 32.
21
+ - One inset: the head, the content and the foot all sit 28 in from the sides (`--ws-band-inset`), so the title, a field
22
+ and the foot's note share one edge.
23
+ - Head (`.ws-head`): 20 above, 16 below (20 when the foot follows it, as in a confirm). The 22 / 28 title (`ws-title`), at most one 14 / 20 line under it, 4 apart.
24
+ The close is Seth's 32 px square on the tray (`ws-dialog__close`, 6 px corners, navy 16 px x), centred on the title's
25
+ first line, 12 from the title block (40 px on touch, centred the same way). The head never wraps: a long title
26
+ wraps beside the close, which stays top right at any width.
27
+ - Content (`ws-dialog__content`): its parts 16 apart, 4 on top (room for a first field's focus ring), 20 at the foot.
28
+ A plate or a well in it sits half a step above the pane (`--ws-surface-sunk` is set from raised to press here), so it
29
+ still shows in dark.
30
+ It scrolls on its own when the dialog meets the window's height; focused as a keyboard scroller, its ring is drawn
31
+ inside it.
32
+ - Foot (`.ws-band`): the darker cream band, 16 / 28 inside, at least 80 tall, its bottom corners rounded to the rim.
33
+ An optional note on the left (`ws-band__words`), the acts in one group on the right (`ws-dialog__acts`, 8 apart),
34
+ the one primary last.
35
+ - Behind it: a navy scrim at 35% (`--ws-scrim`) on the dialog's `::backdrop`.
23
36
 
24
37
  ## Variants and sizes
25
38
 
26
- | `from` | Behaviour |
39
+ | Class | Behaviour |
27
40
  | --- | --- |
28
- | `center` (default) | A dialog: rises 6 px and grows from 98% as it opens |
29
- | `right` | A drawer sliding in from the right edge |
30
- | `left` | A drawer sliding in from the left edge |
41
+ | `ws-dialog` | In the centre: rises 14 px out of .98 as the scrim fades in |
42
+ | `ws-dialog--drawer` | 440 wide (`--ws-thing-width`), floating 12 in from the window's top, right and bottom edges with 12 px corners; slides in from the right |
43
+ | `ws-dialog--drawer ws-dialog--drawer-start` | The same from the left edge |
31
44
 
32
45
  ## States
33
46
 
34
- - **Closed**: not rendered to the eye; the dialog element is not open.
35
- - **Opening**: the scrim fades in; a centre dialog rises and grows, a drawer slides from its edge.
36
- - **Open**: focus is trapped inside it; Escape and a click on the scrim both close it.
37
- - **Closing**: it keeps showing what it last showed (frozen, not re-rendered with the closed state) for `--ws-duration-gentle` (200 ms) while it leaves, faster than it arrived.
38
- - **Error** (inside its content): a field shows its own error state (`aria-invalid`, `ws-field-msg--error`); the dialog itself has no error state of its own.
39
- - **Narrow**: on a small screen the dialog's width is `calc(100% - var(--space-xl))`, so it never touches the screen's edges; a drawer always takes the full height of the screen.
47
+ - **Closed**: not shown; the dialog element is not open.
48
+ - **Opening** (North's window, js@540954): the scrim fades in over `--ws-duration-hover` (.2 s); a centre dialog grows
49
+ 14 px up out of .98 (`--ws-open-scale-pane`) on the settle spring (`--ws-spring-settle`, .32 / .1); a drawer slides
50
+ in from its edge over `--ws-duration-grow` (.55 s) on `--ws-ease-grow` (North's "Card grows open"). Then its details
51
+ settle in after it, as an opened tile's do: the head, the content and the foot each rise 6 px out of a 3 px blur
52
+ (`ws-settle`) over `--ws-duration-settle` on `--ws-ease-soft`, .08 s after the pane (`--ws-dialog-after`) and 22 ms
53
+ apart (`--ws-stagger-detail`, where the browser counts siblings; together elsewhere).
54
+ - **Open**: focus is trapped inside; Escape and a click on the scrim both close it (`closedby="any"`).
55
+ - **Closing**: it fades and drops 8 px to .98 over `--ws-duration-exit` (120 ms); a drawer slides back over
56
+ `--ws-duration-shrink` (.4 s) on `--ws-ease-grow` (North's "Card closes back into place"). Both leave faster than
57
+ they came.
58
+ - **Tall content**: the head and the foot stay; the content scrolls between them (K4).
59
+ - **Short window or phone** (under 40rem tall or wide): the whole pane scrolls as one and only the head stays, so the
60
+ content gets the screen and the close stays in reach (K6); the foot comes at the end of the content. A drawer's foot
61
+ still sits at its bottom when the content is short.
62
+ - **Error**: a field shows its own error (`aria-invalid`, `ws-field-msg--error`); the dialog has no error state of its own.
63
+ - **Phone** (under 40rem wide): a centre dialog keeps 16 from each edge and its acts fill the width in equal halves;
64
+ where a half would be under 160 or a label would break, they stack full width, the primary at the bottom (Seth's
65
+ pane foot, as `ws-btn-split`). A drawer is the whole screen, no rim, no corners (K5).
40
66
 
41
67
  ## Behaviour
42
68
 
43
- - Keyboard: the native `<dialog>` traps focus and closes on Escape by itself; focus returns to what opened it when it closes.
44
- - Pointer: a click on the scrim (outside the dialog's own content) closes it, the same as Escape.
45
- - Touch: the same close behaviours apply; buttons in the foot are 36 px (`large`), above the touch floor.
46
- - Motion: a centre dialog rises 6 px and grows from 98%; a drawer slides from its edge; the scrim fades in, all on `--ws-ease-soft`. Leaving is faster (`--ws-duration-instant`, 120 ms) than arriving.
47
- - Reduced motion: opening and closing cross-fade instead of moving.
69
+ - Keyboard: `showModal()` traps focus and closes on Escape by itself; focus goes back to what opened it.
70
+ - Pointer: a click on the scrim (outside the pane) closes it, the same as Escape. That is `closedby="any"` on the
71
+ `<dialog>`; a browser that does not know it needs the app to close the dialog on a click whose target is the dialog
72
+ element itself (the scrim).
73
+ - Touch: the close and the acts are 40 tall.
74
+ - Motion: the browser's own `[open]` change with `@starting-style`, `overlay` and `display` kept for the exit, so no
75
+ script is needed. North's numbers: rise 14, exit 8, scale .98.
76
+ - Reduced motion: it appears and goes at once; so does a browser without `@starting-style`.
77
+ - The preview's last stack is live: open the dialog and the drawer.
78
+ - Menus inside it open in the top layer (see `Menu`), so the pane never cuts them.
48
79
 
49
80
  ## Content
50
81
 
51
- - The title says what the dialog is for in a few words, sentence case, no em dash.
52
- - One sentence under the title says what it means or what will happen.
53
- - The footer's note (if any) says something the person should know before acting, not a repeat of the title.
54
- - The one primary button is last and is the only solid navy button in the dialog; every other button is secondary (cream, fine edge) or a text action.
82
+ - The title says what the dialog is for in a few words, sentence case.
83
+ - One line under the title, at most: what it means or what will happen.
84
+ - The head holds the title, that line, the close and at most two icon acts. Facts, chips and buttons go in the content.
85
+ - The foot holds one row: a note, then at most two acts, the one primary last.
55
86
 
56
87
  ## Props
57
88
 
89
+ The reference implementation's React pieces (the kit ships the CSS; these names are how the product wraps it).
90
+
58
91
  **`Dialog`**
59
92
 
60
93
  | Name | Type | Meaning |
61
94
  | --- | --- | --- |
62
- | `open` | boolean | Drives whether it is open. |
63
- | `onClose` | `() => void` | Hears every way it closes: Escape, the scrim, a choice made inside. |
64
- | `label` | string | Its accessible name. |
65
- | `from` | `"center"` \| `"right"` \| `"left"` | Where it comes from. Default `center`. |
95
+ | `open` | boolean | Drives whether it is open (`showModal()` and `close()`). |
96
+ | `onClose` | `() => void` | Hears every way it closes: Escape, the scrim, the close, a choice made inside. |
97
+ | `label` | string | Its accessible name, when no title is wired with `aria-labelledby`. |
98
+ | `from` | `"center"` \| `"right"` \| `"left"` | Where it comes from: `ws-dialog`, `--drawer`, `--drawer --drawer-start`. Default `center`. |
66
99
  | `className` | string | Extra layout classes. |
67
100
  | `children` | `ReactNode` | Its content. |
68
101
 
@@ -72,25 +105,60 @@ A modal, built on the browser's own `<dialog>`: a small question in the centre o
72
105
  | --- | --- | --- |
73
106
  | `title` | `ReactNode` | The 22 px title. |
74
107
  | `line` | `ReactNode` | The one sentence under it. |
75
- | `aside` | `ReactNode` | Sits top right, usually the close button. |
108
+ | `aside` | `ReactNode` | Top right: the close, and at most two icon acts. |
76
109
  | `titleId` | string | For `aria-labelledby`. |
77
110
 
78
111
  **`DialogFoot`**
79
112
 
80
113
  | Name | Type | Meaning |
81
114
  | --- | --- | --- |
82
- | `note` | `ReactNode` | A line on the left, before the buttons. |
83
- | `children` | `ReactNode` | The buttons, the one primary last. |
115
+ | `note` | `ReactNode` | A line on the left, before the acts. |
116
+ | `children` | `ReactNode` | The acts, inside `ws-dialog__acts`, the one primary last. |
84
117
 
85
118
  ## Rules
86
119
 
87
- - Never `outline-none` without the focus ring: a dialog's edge or ring carries the focus state, never hidden outright.
88
- - One navy primary button per dialog, last in the footer; every other act is secondary or a text action (the system's rule).
89
- - A dialog's head and foot follow the chart cards' language exactly: `DialogHead` mirrors a card's head (`.ws-head`, see `Card`), `DialogFoot` mirrors its band (`.ws-band`) (14 Oct 2026, the chart cards' own design board).
90
- - No side popups: the system's dialogs open in place, never stacked over one another.
120
+ - One navy primary act per dialog, last in the foot; every other act is secondary or a text act.
121
+ - The close is the 32 px tray square with an x (Seth, 301:2021), centred on the title's first line.
122
+ - Never `overflow: hidden` on the pane: the foot rounds its own corners, and a menu inside must not be cut.
123
+ - No dialog over a dialog.
91
124
 
92
125
  ## Source
93
126
 
94
- **Derived from**: the native `<dialog>` element, the card's cream surface and radius tokens, and the chart card's
95
- own header and footer-band language (`DialogHead` mirrors a card's head, `DialogFoot` its band; see `Card`).
96
- **Precedent**: the first product built on the system.
127
+ **Derived from**: Seth's check drawer (Figma 301:2011: the tray rim, 12 / 11 corners, 28 px sides, the square close),
128
+ North's window motion (js@540954), Revenue OS K4, K5 and K6, and the geometry check (the close dropping under a short
129
+ title at 320, the foot's labels breaking in halves on a phone). **Precedent**: the first product built on the system.
130
+
131
+ ## Markup
132
+
133
+ ```html
134
+ <dialog class="ws-dialog" aria-labelledby="assign-title" closedby="any">
135
+ <header class="ws-head">
136
+ <div>
137
+ <h2 id="assign-title" class="ws-title">Assign this call</h2>
138
+ <p class="ws-body">Choose who calls them next.</p>
139
+ </div>
140
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" onclick="this.closest('dialog').close()">
141
+ <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
142
+ </button>
143
+ </header>
144
+ <div class="ws-dialog__content">
145
+ <label class="ws-field">
146
+ <span class="ws-label">Team member</span>
147
+ <input class="ws-input" value="Priya Nair">
148
+ </label>
149
+ </div>
150
+ <footer class="ws-band">
151
+ <div class="ws-band__words"><p class="ws-band__how">Dana sees this in her chat.</p></div>
152
+ <div class="ws-dialog__acts">
153
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Cancel</button>
154
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Assign</button>
155
+ </div>
156
+ </footer>
157
+ </dialog>
158
+ <!-- open it: document.querySelector('.ws-dialog').showModal(); a drawer adds ws-dialog--drawer -->
159
+ ```
160
+
161
+ ## Styles
162
+
163
+ `Dialog/style.css`, built into `bundle.css` and `fello.css`. Tokens only, so it turns dark with the page. The head and
164
+ the foot are the house `.ws-head` and `.ws-band`; this file sets their inset inside a dialog.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Overlays" height=452 -->
1
+ <!-- @dsCard group="Overlays" height=960 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -10,16 +10,16 @@
10
10
  <body>
11
11
  <div class="ws-stage">
12
12
 
13
- <div class="ws-stack">
14
- <span class="ws-muted">Dialog: rises from the centre over a 35% navy scrim, 16 px corners</span>
15
- <div style="display: grid; place-items: center; width: 640px; max-width: 100%; height: 380px; overflow: hidden; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
16
- <div style="display: grid; width: 392px; max-width: 100%; justify-items: center;"><div class="ws-dialog" role="dialog" aria-modal="true" aria-labelledby="dlg-title">
13
+ <div class="ws-stack" style="width: 560px;">
14
+ <span class="ws-muted">Dialog: a title line, one field, a note and two acts in the foot</span>
15
+ <div style="display: grid; place-items: center; padding: var(--space-xl) 0; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
16
+ <div class="ws-dialog" role="dialog" aria-modal="true" aria-labelledby="dlg-title" style="max-width: 420px;">
17
17
  <header class="ws-head">
18
18
  <div>
19
19
  <h2 id="dlg-title" class="ws-title">Assign this call</h2>
20
- <p class="ws-body" style="margin-top: var(--space-xxs);">Choose who calls them next.</p>
20
+ <p class="ws-body">Choose who calls them next.</p>
21
21
  </div>
22
- <button type="button" class="ws-icon-btn" aria-label="Close">
22
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
23
23
  <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
24
24
  </button>
25
25
  </header>
@@ -30,38 +30,161 @@
30
30
  </label>
31
31
  </div>
32
32
  <footer class="ws-band">
33
- <p class="ws-meta" style="margin-right: auto;">Dana sees this in her chat.</p>
34
- <button type="button" class="ws-btn ws-btn--secondary">Cancel</button>
35
- <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Assign</button>
33
+ <div class="ws-band__words"><p class="ws-band__how">Dana sees this in her chat.</p></div>
34
+ <div class="ws-dialog__acts">
35
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Cancel</button>
36
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Assign</button>
37
+ </div>
36
38
  </footer>
37
- </div></div>
39
+ </div>
38
40
  </div>
39
41
  </div>
40
42
 
41
- <div class="ws-stack">
42
- <span class="ws-muted">Drawer: slides in from the right, 440 px wide, full height</span>
43
- <div style="display: flex; width: 480px; max-width: 100%; height: 380px; overflow: hidden; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
43
+ <div class="ws-stack" style="width: 560px;">
44
+ <span class="ws-muted">A long title wraps; a field that was refused shows its own error</span>
45
+ <div style="display: grid; place-items: center; padding: var(--space-xl) 0; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
46
+ <div class="ws-dialog" role="dialog" aria-modal="true" aria-labelledby="dlg-long" style="max-width: 420px;">
47
+ <header class="ws-head">
48
+ <div>
49
+ <h2 id="dlg-long" class="ws-title">Move every open lead from Dana's list to the new team</h2>
50
+ </div>
51
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
52
+ <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
53
+ </button>
54
+ </header>
55
+ <div class="ws-dialog__content">
56
+ <label class="ws-field">
57
+ <span class="ws-label">New team</span>
58
+ <input class="ws-input" value="North side" aria-invalid="true" aria-describedby="dlg-err" readonly>
59
+ <span id="dlg-err" class="ws-field-msg ws-field-msg--error">
60
+ <svg viewBox="0 0 12 12" fill="none"><circle cx="6" cy="6" r="5" stroke="currentColor"/><path d="M6 3.5v3M6 8.5v.01" stroke="currentColor" stroke-linecap="round"/></svg>
61
+ That team is full. Pick another, or add a seat first.
62
+ </span>
63
+ </label>
64
+ </div>
65
+ <footer class="ws-band">
66
+ <div class="ws-dialog__acts">
67
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Cancel</button>
68
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Move 14 leads</button>
69
+ </div>
70
+ </footer>
71
+ </div>
72
+ </div>
73
+ </div>
74
+
75
+ <div class="ws-stack" style="width: 560px;">
76
+ <span class="ws-muted">Tall content scrolls between the head and the foot (drawn here as if the window were short); on a phone the whole pane scrolls under its head</span>
77
+ <div style="display: grid; place-items: center; padding: var(--space-xl) 0; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
78
+ <div class="ws-dialog" role="dialog" aria-modal="true" aria-labelledby="dlg-tall" style="max-width: 420px; max-height: 320px;">
79
+ <header class="ws-head">
80
+ <div>
81
+ <h2 id="dlg-tall" class="ws-title">What changes on Monday</h2>
82
+ </div>
83
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
84
+ <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
85
+ </button>
86
+ </header>
87
+ <div class="ws-dialog__content" tabindex="0" aria-label="What changes">
88
+ <p class="ws-body">Calls are shared out by who answered fastest last month, not by who is free first.</p>
89
+ <p class="ws-body">Leads with no reply in nine days move to the team list, so someone new can try them.</p>
90
+ <p class="ws-body">Scores reset on the first of each month. The old month stays in your history.</p>
91
+ <p class="ws-body">Your chat sends one summary each evening instead of a message per call.</p>
92
+ </div>
93
+ <footer class="ws-band">
94
+ <div class="ws-dialog__acts">
95
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Got it</button>
96
+ </div>
97
+ </footer>
98
+ </div>
99
+ </div>
100
+ </div>
101
+
102
+ <div class="ws-stack" style="width: 560px;">
103
+ <span class="ws-muted">Drawer: 440 wide, 12 in from the window's edges; the whole screen on a phone</span>
104
+ <div style="display: flex; height: 520px; border-radius: var(--ws-radius-panel); background: linear-gradient(var(--ws-scrim), var(--ws-scrim)), var(--ws-page);">
44
105
  <div class="ws-dialog ws-dialog--drawer" role="dialog" aria-modal="true" aria-labelledby="drw-title">
45
106
  <header class="ws-head">
46
107
  <div>
47
108
  <h2 id="drw-title" class="ws-title">Priya Nair</h2>
48
- <p class="ws-body" style="margin-top: var(--space-xxs);">A complicated sale, cold call.</p>
109
+ <p class="ws-body">A complicated sale, cold call.</p>
49
110
  </div>
50
- <button type="button" class="ws-icon-btn" aria-label="Close">
111
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close">
51
112
  <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
52
113
  </button>
53
114
  </header>
54
115
  <div class="ws-dialog__content">
55
116
  <p class="ws-body">Twelve years in the neighbourhood, referred by two agents on the team.</p>
117
+ <div class="ws-plate">
118
+ <p class="ws-meta">Stage</p>
119
+ <p class="ws-row-name">Qualified</p>
120
+ </div>
56
121
  </div>
57
122
  <footer class="ws-band">
58
- <button type="button" class="ws-btn ws-btn--secondary">Not now</button>
59
- <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Start</button>
123
+ <div class="ws-dialog__acts">
124
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Not now</button>
125
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Start the call</button>
126
+ </div>
60
127
  </footer>
61
128
  </div>
62
129
  </div>
63
130
  </div>
64
131
 
132
+ <div class="ws-stack" style="width: 560px;" data-live>
133
+ <span class="ws-muted">Live: open either. The dialog grows 14 px up out of .98 on the settle spring as the scrim fades in, then its head, content and foot settle in after it; the drawer slides in over .55 s on the grow curve and back over .4 s. Each leaves faster than it came</span>
134
+ <div class="ws-cluster">
135
+ <button type="button" class="ws-btn ws-btn--secondary" onclick="document.getElementById('dlg-live').showModal()">Open the dialog</button>
136
+ <button type="button" class="ws-btn ws-btn--secondary" onclick="document.getElementById('drw-live').showModal()">Open the drawer</button>
137
+ </div>
138
+ <dialog id="dlg-live" class="ws-dialog" aria-labelledby="dlg-live-title" closedby="any" style="max-width: 420px;">
139
+ <header class="ws-head">
140
+ <div>
141
+ <h2 id="dlg-live-title" class="ws-title">Assign this call</h2>
142
+ <p class="ws-body">Choose who calls them next.</p>
143
+ </div>
144
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" onclick="this.closest('dialog').close()">
145
+ <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
146
+ </button>
147
+ </header>
148
+ <div class="ws-dialog__content">
149
+ <label class="ws-field">
150
+ <span class="ws-label">Team member</span>
151
+ <input class="ws-input" value="Priya Nair" readonly>
152
+ </label>
153
+ </div>
154
+ <footer class="ws-band">
155
+ <div class="ws-band__words"><p class="ws-band__how">Dana sees this in her chat.</p></div>
156
+ <div class="ws-dialog__acts">
157
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" onclick="this.closest('dialog').close()">Cancel</button>
158
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg" onclick="this.closest('dialog').close()">Assign</button>
159
+ </div>
160
+ </footer>
161
+ </dialog>
162
+ <dialog id="drw-live" class="ws-dialog ws-dialog--drawer" aria-labelledby="drw-live-title" closedby="any">
163
+ <header class="ws-head">
164
+ <div>
165
+ <h2 id="drw-live-title" class="ws-title">Priya Nair</h2>
166
+ <p class="ws-body">A complicated sale, cold call.</p>
167
+ </div>
168
+ <button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" onclick="this.closest('dialog').close()">
169
+ <svg viewBox="0 0 16 16" fill="none"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
170
+ </button>
171
+ </header>
172
+ <div class="ws-dialog__content">
173
+ <p class="ws-body">Twelve years in the neighbourhood, referred by two agents on the team.</p>
174
+ <div class="ws-plate">
175
+ <p class="ws-meta">Stage</p>
176
+ <p class="ws-row-name">Qualified</p>
177
+ </div>
178
+ </div>
179
+ <footer class="ws-band">
180
+ <div class="ws-dialog__acts">
181
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" onclick="this.closest('dialog').close()">Not now</button>
182
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--lg" onclick="this.closest('dialog').close()">Start the call</button>
183
+ </div>
184
+ </footer>
185
+ </dialog>
186
+ </div>
187
+
65
188
  </div>
66
189
  </body>
67
190
  </html>