@felloinnovations/brand-kit 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +197 -0
  3. package/README.md +34 -7
  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 +134 -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 +357 -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 +52 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +22 -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 +4091 -744
  335. package/design-system/tokens.json +1314 -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 +110 -11
  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 +174 -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 +1292 -62
  361. package/tokens/tokens.md +588 -61
  362. package/tokens/tokens.root.css +1298 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Cards" height=482 -->
1
+ <!-- @dsCard group="Cards" height=980 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -8,10 +8,10 @@
8
8
  <link rel="stylesheet" href="../bundle.css">
9
9
  </head>
10
10
  <body>
11
- <div class="ws-stage ws-stage--grey">
11
+ <div class="ws-stage">
12
12
 
13
- <div class="ws-stack" style="width: var(--ws-chart-card-w); max-width: 100%;">
14
- <span class="ws-muted">Default: title answers the question, one line, drawing on dots, one band (its act secondary: the page keeps its one navy primary)</span>
13
+ <div class="ws-stack" style="width: var(--ws-chart-card-w);">
14
+ <span class="ws-muted">Chart card: a title that answers, one line, the drawing on dots, the act in its band</span>
15
15
  <section class="ws-card ws-card--compound">
16
16
  <header class="ws-head">
17
17
  <div>
@@ -19,8 +19,8 @@
19
19
  <p class="ws-body ws-card__line">Nine days early. Cold calls did most of the work.</p>
20
20
  </div>
21
21
  </header>
22
- <div class="ws-card__body ws-card__bars ws-dots">
23
- <div class="ws-card__bar ws-grow-up" style="height: 30%; animation-delay: 0ms;"></div>
22
+ <div class="ws-card__body ws-card__bars ws-dots" aria-hidden="true">
23
+ <div class="ws-card__bar ws-grow-up" style="height: 30%;"></div>
24
24
  <div class="ws-card__bar ws-grow-up" style="height: 55%; animation-delay: 30ms;"></div>
25
25
  <div class="ws-card__bar ws-grow-up" style="height: 40%; animation-delay: 60ms;"></div>
26
26
  <div class="ws-card__bar ws-grow-up" style="height: 70%; animation-delay: 90ms;"></div>
@@ -33,14 +33,53 @@
33
33
  <p class="ws-band__title">Next up: Priya Nair</p>
34
34
  <p class="ws-band__how">A complicated sale &middot; Cold call</p>
35
35
  </div>
36
- <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Start the call</button>
36
+ <div class="ws-band__acts">
37
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Not now</button>
38
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Start the call</button>
39
+ </div>
37
40
  </footer>
38
41
  </section>
39
42
  </div>
40
43
 
44
+ <div class="ws-stack" style="width: 340px;">
45
+ <span class="ws-muted">Tray card with a foot: the cream on the tray, the foot on the grey under it</span>
46
+ <div class="ws-card">
47
+ <div class="ws-card__surface ws-card__surface--pad ws-stack">
48
+ <span class="ws-control-words">Zillow rating</span>
49
+ <span class="ws-figure ws-figure--tile">5.0</span>
50
+ </div>
51
+ <div class="ws-card__foot">
52
+ <span>10 reviews</span>
53
+ <span class="ws-card__foot-aside">Checked Nov 2</span>
54
+ </div>
55
+ </div>
56
+
57
+ <span class="ws-muted">The foot as the card's door</span>
58
+ <div class="ws-card">
59
+ <div class="ws-card__surface ws-card__surface--pad ws-stack">
60
+ <span class="ws-control-words">Google reviews</span>
61
+ <span class="ws-figure ws-figure--tile" style="color: var(--color-text-muted);">Not connected</span>
62
+ </div>
63
+ <a class="ws-card__foot" href="#" onclick="return false;">
64
+ <span>Connect Google</span>
65
+ <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
66
+ </a>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="ws-stack" style="width: 340px;">
71
+ <h3 class="ws-section">Your checks</h3>
72
+ <ul class="ws-card" aria-label="Your checks">
73
+ <li><button type="button" class="ws-card__list-row" aria-expanded="true"><span class="ws-row-name">Local search</span><span class="ws-card__list-aside"><span class="ws-control-words">2 fixes</span><svg class="ws-card__chevron" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></button></li>
74
+ <li><button type="button" class="ws-card__list-row" aria-expanded="false"><span class="ws-row-name">Website</span><span class="ws-card__list-aside"><span class="ws-control-words">2 fixes</span><svg class="ws-card__chevron" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></button></li>
75
+ <li><button type="button" class="ws-card__list-row" aria-expanded="false"><span class="ws-row-name">Your Google Business Profile and the towns it names</span><span class="ws-card__list-aside"><span class="ws-control-words" style="color: var(--color-text-muted);">Could not check</span><svg class="ws-card__chevron" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></button></li>
76
+ </ul>
77
+ <span class="ws-muted">Rows: 48 at least, 0.5 px dividers edge to edge, the open row sunk</span>
78
+ </div>
79
+
41
80
  <div class="ws-stack ws-stack--loose" style="width: 260px;">
42
81
  <div class="ws-stack">
43
- <span class="ws-muted">Plain list card: no dots, no band, one row per fact</span>
82
+ <span class="ws-muted">Plain list card: a small head, one row per fact</span>
44
83
  <section class="ws-card">
45
84
  <header class="ws-card__list-head">
46
85
  <h3 class="ws-section">Where they came from</h3>
@@ -53,14 +92,6 @@
53
92
  </section>
54
93
  </div>
55
94
 
56
- <div class="ws-stack">
57
- <span class="ws-muted">Selected: the mid-blue ring beside the edge</span>
58
- <div class="ws-card ws-card--selected ws-card--pad-md">
59
- <h3 class="ws-section">Cold calls</h3>
60
- <p class="ws-body ws-card__line">This week's focus for the team's outreach.</p>
61
- </div>
62
- </div>
63
-
64
95
  <div class="ws-stack">
65
96
  <span class="ws-muted">Link card: the whole card is the target</span>
66
97
  <a href="#" class="ws-card ws-card--pad-md" onclick="return false;">
@@ -68,13 +99,104 @@
68
99
  <p class="ws-body ws-card__line">Open the lead.</p>
69
100
  </a>
70
101
  </div>
102
+
103
+ <div class="ws-stack" style="padding-bottom: var(--space-sm);">
104
+ <span class="ws-muted">Selected: the rim darkens, a navy tab under it</span>
105
+ <button type="button" class="ws-card ws-card--selected ws-card--pad-md" aria-pressed="true">
106
+ <h3 class="ws-section">Cold calls</h3>
107
+ <p class="ws-body ws-card__line">This week's focus for the team.</p>
108
+ </button>
109
+ </div>
110
+ </div>
111
+
112
+ <div class="ws-stack" style="width: 340px;">
113
+ <span class="ws-muted">Snug: a card in a chat column, every part 12 in, the band 16 above and under</span>
114
+ <section class="ws-card ws-card--compound ws-card--snug">
115
+ <header class="ws-head">
116
+ <div>
117
+ <h3 class="ws-title">Your week, if Coach runs it</h3>
118
+ <p class="ws-body ws-card__line">From your own calls last week.</p>
119
+ </div>
120
+ </header>
121
+ <div class="ws-card__body">
122
+ <p class="ws-body">Six follow-ups a day, two of them to sellers who asked to wait.</p>
123
+ </div>
124
+ <footer class="ws-band">
125
+ <div class="ws-band__words">
126
+ <p class="ws-band__title">Set up Coach</p>
127
+ <p class="ws-band__how">About two minutes</p>
128
+ </div>
129
+ <div class="ws-band__acts">
130
+ <button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Set up</button>
131
+ </div>
132
+ </footer>
133
+ </section>
134
+
135
+ <span class="ws-muted">Compact: a small card, a 16 / 20 title, the band 8 / 16</span>
136
+ <section class="ws-card ws-card--compound ws-card--compact">
137
+ <header class="ws-head">
138
+ <div>
139
+ <h3 class="ws-title">Two sellers asked to wait</h3>
140
+ </div>
141
+ </header>
142
+ <div class="ws-card__body">
143
+ <p class="ws-body">Dana and Sam both said spring.</p>
144
+ </div>
145
+ <footer class="ws-band">
146
+ <div class="ws-band__acts">
147
+ <button type="button" class="ws-btn ws-btn--secondary">Remind me in March</button>
148
+ </div>
149
+ </footer>
150
+ </section>
151
+ </div>
152
+
153
+ <div class="ws-stack" style="width: 340px;">
154
+ <span class="ws-muted">A head with an aside: its controls stay one row and drop under the title together when they would squeeze it</span>
155
+ <section class="ws-card ws-card--compound">
156
+ <header class="ws-head">
157
+ <div>
158
+ <h3 class="ws-title">Vendors</h3>
159
+ <p class="ws-body ws-card__line">12 paid this month</p>
160
+ </div>
161
+ <div class="ws-cluster">
162
+ <span class="ws-select-wrap">
163
+ <select class="ws-select ws-select--sm" aria-label="Period"><option>This month</option><option>Last month</option></select>
164
+ <svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4.5l3 3 3-3"/></svg>
165
+ </span>
166
+ <span class="ws-select-wrap">
167
+ <select class="ws-select ws-select--sm" aria-label="Status"><option>All vendors</option><option>Cancelled</option></select>
168
+ <svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4.5l3 3 3-3"/></svg>
169
+ </span>
170
+ </div>
171
+ </header>
172
+ <div class="ws-card__body">
173
+ <p class="ws-body">Three renew next week.</p>
174
+ </div>
175
+ </section>
176
+
177
+ <span class="ws-muted">Icon acts in a head stay top right on the title's line; the title wraps instead</span>
178
+ <section class="ws-card ws-card--compound">
179
+ <header class="ws-head">
180
+ <div>
181
+ <h3 class="ws-title">New email to Priya Nair</h3>
182
+ <p class="ws-body ws-card__line">Draft saved</p>
183
+ </div>
184
+ <button type="button" class="ws-icon-btn" aria-label="Open full size" title="Open full size">
185
+ <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="M9.5 3H13v3.5M6.5 13H3V9.5M13 3L9 7M3 13l4-4"/></svg>
186
+ </button>
187
+ <button type="button" class="ws-icon-btn" aria-label="Close" title="Close">
188
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>
189
+ </button>
190
+ </header>
191
+ <div class="ws-card__body">
192
+ <p class="ws-body">Hi Priya, following up on the Oak Street offer.</p>
193
+ </div>
194
+ </section>
71
195
  </div>
72
196
 
73
197
  <div class="ws-stack" style="max-width: 260px;">
74
198
  <span class="ws-muted">A card whose data does not exist is left out, never faked</span>
75
- <p class="ws-body" style="font-style: italic; color: var(--color-text-muted);">
76
- Profile views this week: no card here. The data does not exist yet, so nothing is drawn in its place, not even an empty shell.
77
- </p>
199
+ <p class="ws-body">Profile views this week: no card here. The data does not exist yet, so nothing is drawn in its place, not even an empty shell.</p>
78
200
  </div>
79
201
 
80
202
  </div>
@@ -0,0 +1,115 @@
1
+ /* ---- Card: Seth's tray card (D5), the cream inside a 1 px tray rim with 8 / 7 corners, its rows joined by 0.5 px
2
+ dividers and its foot on the tray; the pressable, selected, snug and compact looks; the band's sizes and its acts ---- */
3
+ /* The rim. The house card was a 0.5 px outline; Seth's is the tray seen 1 px round the cream (a border in the tray
4
+ colour), so the cream's corners are 8 - 1 = 7, concentric. Flat, no shadow at rest. Existing markup upgrades in place. */
5
+ .ws-card { border: var(--ws-rim) solid var(--ws-tray); outline: 0; }
6
+ .ws-card:focus-visible { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
7
+ /* A card with a foot: the cream is its own surface (__surface) and the card shows the tray round it and under it. */
8
+ .ws-card:has(> .ws-card__surface) { background: var(--ws-tray); }
9
+ .ws-card__surface { border-radius: var(--ws-radius-card-inner); background: var(--color-bg-page); }
10
+ /* The foot on the tray (Seth's tiles, bill and vendor cards; North's well card): no fill of its own, 36 tall, words
11
+ 13 / 18 medium, the words left, a figure or a door right. Its sides are the surface's 16, so the words line up. */
12
+ .ws-card__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm); min-height: var(--ws-control-h-md); padding: var(--space-xxs) var(--space-md); font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; color: var(--color-text-body); }
13
+ .ws-card__foot > :first-child { min-width: 0; }
14
+ /* The aside (a figure or a date) keeps its one line while it fits; a long one wraps at the end instead of leaving the card. */
15
+ .ws-card__foot-aside { min-width: 0; text-align: right; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
16
+ .ws-card__surface--pad { padding: var(--space-md); }
17
+ /* A foot that is the card's door: navy words, a 16 chevron at the end; hover darkens the tray under it, and a muted
18
+ aside on it takes the body grey (the muted grey is 4.44:1 on Seth's hover tray, under AA). */
19
+ /* A door (navy words, the 16 chevron at the end) or the step a tile waits on (muted, not a target). */
20
+ .ws-card__foot--door { color: var(--color-text-heading); }
21
+ .ws-card__foot--waits { color: var(--color-text-muted); }
22
+ a.ws-card__foot { border-radius: 0 0 var(--ws-radius-card-inner) var(--ws-radius-card-inner); color: var(--color-text-heading); text-decoration: none; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
23
+ @media (hover: hover) { a.ws-card__foot:hover { --color-text-muted: var(--color-text-body); background-color: var(--ws-well-hover); } a.ws-card__foot:hover > :first-child { text-decoration: underline; } }
24
+ a.ws-card__foot:active { --color-text-muted: var(--color-text-body); background-color: var(--ws-well-hover); transition-duration: var(--ws-duration-instant); }
25
+ a.ws-card__foot:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
26
+ /* The door is a boxed, full-width target: 40 on touch (K10). */
27
+ @media (pointer: coarse) { a.ws-card__foot { min-height: var(--ws-touch); } }
28
+ .ws-card__foot > svg { flex-shrink: 0; width: var(--ws-icon); height: var(--ws-icon); }
29
+ /* A card that is a link or a button: the whole card is the target. Hover darkens the rim (North), the cream stays and
30
+ nothing lifts; a press tints the cream; a slow open pulses a navy edge. */
31
+ a.ws-card, button.ws-card { display: block; width: 100%; text-align: left; text-decoration: none; color: inherit; cursor: pointer; transition: border-color var(--ws-duration-hover) var(--ws-ease-soft), background-color var(--ws-duration-hover) var(--ws-ease-soft); }
32
+ @media (hover: hover) { a.ws-card:hover, button.ws-card:hover { border-color: var(--ws-well-hover); } }
33
+ a.ws-card:active, button.ws-card:active { background-color: var(--ws-surface-press); transition-duration: var(--ws-duration-instant); }
34
+ button.ws-card:disabled { opacity: 0.6; cursor: default; pointer-events: none; }
35
+ a.ws-card[aria-busy="true"] { position: relative; }
36
+ a.ws-card[aria-busy="true"]::before { content: ""; position: absolute; inset: calc(var(--ws-rim) * -1); border: var(--ws-rim) solid var(--color-text-heading); border-radius: inherit; pointer-events: none; }
37
+ @media (prefers-reduced-motion: no-preference) { a.ws-card[aria-busy="true"]::before { animation: ws-pulse var(--ws-loop) var(--ws-ease-loop) infinite; } }
38
+ /* Selected, in a row of cards (North): the rim darkens and a 2 px navy tab sits 8 under the card, 16 in from each side. */
39
+ .ws-card--selected { position: relative; border-color: var(--ws-well-hover); box-shadow: none; }
40
+ .ws-card--selected::after { content: ""; position: absolute; left: var(--space-md); right: var(--space-md); top: calc(100% + var(--ws-rim) + var(--space-xs)); height: var(--ws-ring); border-radius: var(--ws-radius-chip); background: var(--color-text-heading); }
41
+ /* The card's own padding steps. */
42
+ .ws-card--pad-sm { padding: var(--ws-card-padding); }
43
+ .ws-card--pad-md { padding: var(--ws-card-padding-lg); }
44
+ /* A compound card (head, body, band): a column. Not clipped (K1: a clip squashed it in a scroller and cut every menu
45
+ inside); its first and last parts take the inner corners instead, so the band's shade stays inside the rim. */
46
+ .ws-card--compound { display: flex; flex-direction: column; }
47
+ .ws-card--compound > :first-child { border-top-left-radius: var(--ws-radius-card-inner); border-top-right-radius: var(--ws-radius-card-inner); }
48
+ .ws-card--compound > :last-child { border-bottom-left-radius: var(--ws-radius-card-inner); border-bottom-right-radius: var(--ws-radius-card-inner); }
49
+ /* A band that ends a plain card (an empty state) takes the inner corners too, or its shade squares them off. */
50
+ .ws-card > .ws-band:last-child { border-bottom-left-radius: var(--ws-radius-card-inner); border-bottom-right-radius: var(--ws-radius-card-inner); }
51
+ /* A card's head wraps: the aside drops under the title, as one piece, instead of squeezing it under 200 (guide 05).
52
+ The words are the head's first div; an aside after them keeps its own width and its own layout (a cluster stays a
53
+ row: the house gives every div in a head the words' column). Icon acts (a close, an expand) never drop: a head that
54
+ carries them loose keeps them top right on the title's line and its title wraps instead. Put controls that may drop
55
+ in one element (a ws-cluster). */
56
+ .ws-head { flex-wrap: wrap; column-gap: var(--space-md); row-gap: var(--space-sm); }
57
+ .ws-head > div:first-of-type { min-width: min(100%, var(--space-9xl)); }
58
+ .ws-head > div ~ div { flex: initial; }
59
+ .ws-head > div ~ .ws-cluster { flex-direction: row; }
60
+ .ws-head:has(> .ws-icon-btn) { flex-wrap: nowrap; }
61
+ .ws-head:has(> .ws-icon-btn) > div:first-of-type { min-width: 0; }
62
+ /* An icon act (the default 32, 40 on touch) centres on the title's first line, on its letters (a hairline above the
63
+ line's middle), as the dialog's close does with its own rule (no specificity, so a component's own wins). A compact
64
+ head's title line is 20. */
65
+ :where(.ws-head > .ws-icon-btn:not(.ws-icon-btn--xs, .ws-icon-btn--sm, .ws-icon-btn--lg)) { --ws-head-act: var(--ws-control-h); margin-block: calc((var(--ws-head-line, var(--ws-leading-title)) - var(--ws-head-act)) / 2 - var(--ws-hairline)) calc((var(--ws-head-line, var(--ws-leading-title)) - var(--ws-head-act)) / 2 + var(--ws-hairline)); }
66
+ @media (pointer: coarse) { :where(.ws-head > .ws-icon-btn) { --ws-head-act: var(--ws-touch); } }
67
+ /* The one line under a card's title or a section title. */
68
+ .ws-card__line { margin-top: var(--space-xxs); }
69
+ .ws-card__body { padding: 0 var(--ws-card-inset) var(--space-md); }
70
+ /* Snug (issue #10): a card in a chat column. The head and body sit 12 in so they line up with the column's edge; the
71
+ title stays 22; the band is 16 above and under and sized to its content. In the snug card its sides are 12 too, so
72
+ its words sit on the title's edge (Ignite's 16 put them 4 px in, as compact's 12 did); alone it is 16 all round. */
73
+ .ws-card--snug > .ws-head { padding: var(--ws-card-inset) var(--space-sm) var(--space-md); }
74
+ .ws-card--snug > .ws-card__body { padding-inline: var(--space-sm); }
75
+ .ws-card--snug > .ws-band, .ws-band--snug { min-height: 0; padding: var(--space-md); }
76
+ .ws-card--snug > .ws-band { padding-inline: var(--space-sm); }
77
+ /* Compact: a small card. The head 16 / 16 / 8 with a 16 / 20 title, the body 12 / 16 (Ignite's 12 round put the
78
+ words 4 px left of the title; 16 at the sides keeps one content edge), the band 8 / 16. */
79
+ .ws-card--compact > .ws-head { --ws-head-line: var(--ws-leading-row); padding: var(--space-md) var(--space-md) var(--space-xs); }
80
+ .ws-card--compact > .ws-head .ws-title { font-size: var(--ws-text-value); line-height: var(--ws-leading-row); }
81
+ .ws-card--compact > .ws-card__body { padding: var(--space-sm) var(--space-md); }
82
+ .ws-card--compact > .ws-band, .ws-band--compact { min-height: 0; column-gap: var(--space-xs); padding: var(--space-xs) var(--space-md); }
83
+ /* The band's acts: one group at the end that wraps as one (the primary never drops alone onto a line of its own). The
84
+ band measures itself, so in a narrow card (under 26rem) the acts take the whole line and share it. */
85
+ .ws-band { container: ws-band / inline-size; }
86
+ .ws-band__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs); margin-left: auto; }
87
+ @container ws-band (max-width: 26rem) {
88
+ .ws-band__acts { width: 100%; }
89
+ .ws-band__acts > * { flex: 1 1 0; }
90
+ }
91
+ /* Rows in a card (Seth's checks list): cream rows edge to edge, joined by 0.5 px dividers that run the full width, 48
92
+ at least, the content 20 in on the left (the card's one content edge) and 16 on the right. */
93
+ .ws-card__list-head { padding: var(--space-md) var(--space-md) var(--space-xxs) var(--ws-card-inset); }
94
+ .ws-card__list-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm); min-height: var(--ws-row-h); padding: var(--space-sm) var(--space-md) var(--space-sm) var(--ws-card-inset); }
95
+ .ws-card__list-row > :first-child { flex: 1; min-width: 0; }
96
+ .ws-card__list-aside { display: inline-flex; flex-shrink: 0; align-items: center; gap: var(--space-sm); white-space: nowrap; }
97
+ .ws-card__list-row + .ws-card__list-row, li + li > .ws-card__list-row { border-top: var(--ws-divider); }
98
+ a.ws-card__list-row, button.ws-card__list-row { width: 100%; border: 0; background: none; text-align: left; text-decoration: none; color: inherit; cursor: pointer; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
99
+ @media (hover: hover) { a.ws-card__list-row:hover, button.ws-card__list-row:hover { background-color: var(--ws-hover-faint); } }
100
+ a.ws-card__list-row:active, button.ws-card__list-row:active { background-color: var(--ws-surface-press); transition-duration: var(--ws-duration-instant); }
101
+ a.ws-card__list-row:focus-visible, button.ws-card__list-row:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
102
+ /* The open row (its detail shows elsewhere): the sunk cream, nothing else moves. */
103
+ .ws-card__list-row[aria-current], .ws-card__list-row[aria-expanded="true"] { background-color: var(--ws-surface-sunk); }
104
+ /* Under the pointer the open row keeps its sunk cream with the faint wash on it (the plain wash replaced the sunk ground,
105
+ so hovering the open row lightened it). */
106
+ @media (hover: hover) { :is(a, button).ws-card__list-row:is([aria-current], [aria-expanded="true"]):hover:not(:active) { background-color: color-mix(in srgb, var(--ws-surface-sunk), var(--ws-ink) 3%); } }
107
+ /* Rows at the card's corners take its inner corners, so a tinted row never squares them off (the card itself may be
108
+ the list: ul.ws-card > li > row). */
109
+ .ws-card > ul:first-child > li:first-child > .ws-card__list-row, .ws-card > li:first-child > .ws-card__list-row, .ws-card > .ws-card__list-row:first-child { border-top-left-radius: var(--ws-radius-card-inner); border-top-right-radius: var(--ws-radius-card-inner); }
110
+ .ws-card > ul:last-child > li:last-child > .ws-card__list-row, .ws-card > li:last-child > .ws-card__list-row, .ws-card > .ws-card__list-row:last-child { border-bottom-left-radius: var(--ws-radius-card-inner); border-bottom-right-radius: var(--ws-radius-card-inner); }
111
+ .ws-card__chevron { flex-shrink: 0; width: var(--ws-icon); height: var(--ws-icon); color: var(--color-text-heading); }
112
+ .ws-card__value { font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; text-align: right; }
113
+ /* The sample drawing in this preview: a short run of bars on the dots. */
114
+ .ws-card__bars { display: flex; align-items: flex-end; gap: var(--space-xxs); height: calc(var(--space-4xl) + var(--space-xs)); }
115
+ .ws-card__bar { width: calc(var(--space-md) + var(--space-3xs)); border-radius: var(--ws-radius-bar) var(--ws-radius-bar) 0 0; background: var(--color-stat-positive); transform-origin: bottom; }
@@ -1,75 +1,96 @@
1
- Lays a page of cards out as columns side by side, each card at the board's own width, down to one column on a phone in the same order.
1
+ Lays a page of cards out as columns side by side, each card at the board's own width, down to one column on a phone in
2
+ the same order.
2
3
 
3
4
  ## Use it when
4
5
 
5
- - A page shows several independent chart or dashboard cards (an activity app's "How you show up", a pipeline's progress page, a team summary).
6
+ - A page shows several independent chart or dashboard cards (an activity app's "How you show up", a pipeline's
7
+ progress page, a team summary).
6
8
  - The cards have no natural grid position and should flow into columns that balance themselves.
7
9
  - The page must read the same way on a phone, a tablet and a wide screen, without a separate mobile layout.
8
10
 
9
11
  ## Not for
10
12
 
11
- - A grid of small, same-sized cards or tiles (one, two, then four across): use `.ws-board--4` (see `Page`) with `Tile`.
12
- - Two regions of unequal, specific jobs (a form beside its history): two regions sized to their jobs, not a board of like cards.
13
- - A single card or a short list that never needs to wrap into columns: just stack the cards directly.
13
+ - A grid of small, same-sized cards or tiles (one, two, then four across): use `.ws-board--4` (see `Page`).
14
+ - A main column and the detail beside it: `Split`.
15
+ - A single card or a short list that never needs to wrap into columns: just stack the cards.
14
16
  - Rows of facts inside one card: use `Plate` or a plain list.
15
17
 
16
18
  ## Anatomy
17
19
 
18
- - The board: a row of columns that wraps by its own width, gapped at `--ws-gap-component` (16 px), at most two columns
19
- and the gap wide (1128), centred.
20
- - Each column: a flex column of cards, also gapped at `--ws-gap-component`, capped at `--ws-chart-card-w` (556 px) and never narrower than it can help before wrapping under the column before it, down to `--ws-chart-card-min` (480 px).
21
- - Below that width, columns stack into one column that fills the board's width (so it lines up with the page bar and
22
- tiles above it), the one column a phone gets, in the same DOM order the columns were given (the first column's cards first), so Tab and a screen reader follow the same order a phone shows.
23
- - In fello.css: `.ws-board` is the board and `.ws-board__column` a column of cards; a card can also sit in the board
24
- directly when columns are not needed. It wraps by its own width, so it needs no breakpoint and works in any region.
25
- Two 556 columns and the gap are also the page's width (`.ws-page`, see `Page`), so a board fills the page exactly.
26
- For small cards that should go one, two, then four across, see `.ws-board--4` in `Page`.
20
+ - The board (`.ws-board`): a grid that wraps by its own width, its cards 16 apart (`--ws-gap-component`), at most two
21
+ columns and the gap wide (1128), on the content's start edge (it never centres itself, K12).
22
+ - Each column (`.ws-board__column`): a flex column of cards, 16 apart, up to `--ws-chart-card-w` (556) and never
23
+ narrower than `--ws-chart-card-min` (480) before the next column wraps under it.
24
+ - Below that width, one column that fills the board's width, in DOM order (the first column's cards first), so Tab, a
25
+ screen reader and a phone follow the same order.
26
+ - A card can also sit in the board directly when columns are not needed. It needs no breakpoint, so it works in any
27
+ region: a page, the shell's body, a pane.
27
28
 
28
29
  ## Variants and sizes
29
30
 
30
31
  | Context | Column width |
31
32
  | --- | --- |
32
- | Wide board | Up to `--ws-chart-card-w` (556 px) per column |
33
- | Narrowing board | Gives down to `--ws-chart-card-min` (480 px) before the next column wraps underneath |
34
- | Under 976 px (a tablet, a narrow artifact, a phone) | One column, full width, cards in column order |
33
+ | Wide board | Up to 556 per column |
34
+ | Narrowing board | Gives down to 480 before the next column wraps underneath |
35
+ | Under 976 (a tablet, a narrow pane, a phone) | One column, full width, cards in column order |
35
36
 
36
37
  ## States
37
38
 
38
39
  - **Default**: columns side by side, each card its own height (rows do not line up card to card).
39
- - **Arriving**: each card rises in (`ws-rise`) with a small stagger between items (`--ws-stagger`, 30 ms, first paint only, at most 6 items before the stagger caps).
40
- - **Narrow**: columns wrap one under another as the board's width falls; at the narrowest, one column.
41
- - **Empty**: a column with no cards is simply not given; `CardBoard` never draws a placeholder column.
42
- - **Long content**: a card in a tall column pushes its column taller; other columns are unaffected, since each column sizes to its own content.
40
+ - **Arriving**: each card settles in (`ws-settle`: up 6 px out of a 3 px blur over `--ws-duration-settle`), 22 ms
41
+ apart (`--ws-i` on each card, first paint only, at most six).
42
+ - **Narrow**: columns wrap one under another; at the narrowest, one column.
43
+ - **Empty**: a column with no cards is not given; the board never draws a placeholder column.
44
+ - **Long content**: a tall card pushes only its own column down.
45
+ - **Loading**: each card's own ghosts (`.ws-shimmer`), at its own size.
43
46
 
44
47
  ## Behaviour
45
48
 
46
- - Keyboard: no interactivity of its own; Tab moves through the cards in DOM order, the same order a phone reads.
47
- - Pointer: none; it is a pure layout wrapper.
48
- - Touch: the phone layout is one column, so nothing needs a horizontal swipe or scroll.
49
- - Motion: cards use `ws-rise` to arrive (`--ws-duration-settle`, `--ws-ease-soft`), staggered by 30 ms per item; nothing else about the board moves.
50
- - Reduced motion: cards appear in place without rising.
49
+ - Keyboard: no interactivity of its own; Tab moves through the cards in DOM order.
50
+ - Touch: one column on a phone, so nothing needs a sideways swipe.
51
+ - Motion: only the arrival above. Reduced motion: cards appear in place.
51
52
 
52
53
  ## Content
53
54
 
54
- - Each column is given as a list of already-built cards (a `Card` with its head, body and band, or similar); `CardBoard` does not know what is inside them.
55
- - Column order is deliberate: put the most important card's column first, since it is also first on a phone.
56
- - No card is invented to fill a column; an empty data point means that card, and only that card, is left out.
55
+ - Each column is a list of built cards (a `Card` with its head, body and band); the board does not know what is inside.
56
+ - Put the most important card's column first: it is also first on a phone.
57
+ - No card is invented to fill a column.
57
58
 
58
59
  ## Props
59
60
 
60
61
  | Name | Type | Meaning |
61
62
  | --- | --- | --- |
62
- | `columns` | `ReactNode[]` | One entry per column, each entry the already-stacked cards for that column, top to bottom. |
63
+ | `columns` | `ReactNode[]` | One entry per column, each the stacked cards for that column, top to bottom |
63
64
 
64
65
  ## Rules
65
66
 
66
- - "A page of cards is a board" (the system's rule): never a bespoke CSS grid for a page of chart cards.
67
- - Columns give room before they wrap (556 down to 480 px), so a laptop window keeps two columns a little longer than a hard breakpoint would.
68
- - The phone's one column keeps the exact DOM order of the wide layout's columns, so keyboard and screen-reader order never jumps around at different widths.
69
- - A card that has no data is never placed in a column as a stand-in; it is left off the board entirely.
67
+ - "A page of cards is a board": never a bespoke grid for a page of chart cards.
68
+ - Columns give room before they wrap (556 down to 480), so a laptop keeps two columns a little longer than a hard
69
+ breakpoint would.
70
+ - The phone's one column keeps the DOM order of the wide layout.
71
+ - A card with no data is left off the board, never placed as a stand-in.
70
72
 
71
73
  ## Source
72
74
 
73
- **Derived from**: the system's board layout rule, "a page of cards is a board," and the chart card's own width and
74
- gap tokens (`--ws-chart-card-w`, `--ws-chart-card-min`, `--ws-gap-component`). **Precedent**: the first product
75
- built on the system.
75
+ **Derived from**: the system's board rule, the chart card's width and gap tokens, North's settle-in (D7) and Revenue OS
76
+ fault K12 (a board centred inside the shell's body left two start edges 244 px apart at 1920). **Precedent**: the
77
+ first product built on the system.
78
+
79
+ ## Markup
80
+
81
+ ```html
82
+ <div class="ws-board">
83
+ <div class="ws-board__column">
84
+ <section class="ws-card ws-settle" style="--ws-i: 0;" aria-labelledby="c1"><!-- a card --></section>
85
+ <section class="ws-card ws-settle" style="--ws-i: 2;" aria-labelledby="c3"><!-- a card --></section>
86
+ </div>
87
+ <div class="ws-board__column">
88
+ <section class="ws-card ws-settle" style="--ws-i: 1;" aria-labelledby="c2"><!-- a card --></section>
89
+ </div>
90
+ </div>
91
+ ```
92
+
93
+ ## Styles
94
+
95
+ `.ws-board` and `.ws-board__column` are in `_house.css` (it has no `style.css` of its own); the arrival is the house's
96
+ `ws-settle`. Tokens: `--ws-gap-component`, `--ws-chart-card-w`, `--ws-chart-card-min`, `--ws-stagger-detail`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Layout" height=888 -->
1
+ <!-- @dsCard group="Layout" height=732 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -11,50 +11,47 @@
11
11
  <div class="ws-stage ws-stage--grey ws-stage--column">
12
12
 
13
13
  <div class="ws-stack">
14
- <span class="ws-muted">Two columns once the board has room for two at 480 (976 px and up), each up to 556; narrower, the second wraps under the first. Cards rise in, staggered</span>
14
+ <span class="ws-muted">Two columns once the board has room for two at 480 (976 px and up), each up to 556, on the content's start edge; narrower, the second wraps under the first. Cards settle in, 22 ms apart</span>
15
15
  <div class="ws-board">
16
16
  <div class="ws-board__column">
17
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 0ms;">
18
- <h3 class="ws-section">Calls this week</h3>
19
- <p class="ws-figure">26</p>
17
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-settle" style="--ws-i: 0;" aria-labelledby="cb-1">
18
+ <h3 class="ws-section" id="cb-1">Calls this week</h3>
19
+ <p class="ws-figure ws-figure--tile">26</p>
20
20
  </section>
21
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 60ms;">
22
- <h3 class="ws-section">Live transfers</h3>
23
- <p class="ws-figure">8</p>
21
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-settle" style="--ws-i: 2;" aria-labelledby="cb-2">
22
+ <h3 class="ws-section" id="cb-2">Live transfers</h3>
23
+ <p class="ws-figure ws-figure--tile">8</p>
24
+ <p class="ws-body">A taller card pushes only its own column down; the other column keeps its height.</p>
24
25
  </section>
25
26
  </div>
26
27
  <div class="ws-board__column">
27
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 30ms;">
28
- <h3 class="ws-section">Follow-ups</h3>
29
- <p class="ws-figure">4</p>
28
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-settle" style="--ws-i: 1;" aria-labelledby="cb-3">
29
+ <h3 class="ws-section" id="cb-3">Follow-ups</h3>
30
+ <p class="ws-figure ws-figure--tile">4</p>
30
31
  </section>
31
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 90ms;">
32
- <h3 class="ws-section">New leads</h3>
33
- <p class="ws-figure">3</p>
32
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-settle" style="--ws-i: 3;" aria-labelledby="cb-4">
33
+ <h3 class="ws-section" id="cb-4">New leads</h3>
34
+ <p class="ws-figure ws-figure--tile">3</p>
34
35
  </section>
35
36
  </div>
36
37
  </div>
37
38
  </div>
38
39
 
39
- <div class="ws-stack" style="width: 400px; max-width: 100%; align-self: center;">
40
- <span class="ws-muted">Four cards in a 400 px box, given as one column: DOM order is the phone's order</span>
40
+ <div class="ws-stack" style="width: 400px; max-width: 100%;">
41
+ <span class="ws-muted">Three cards in a 400 px box, given as one column: DOM order is the phone's order</span>
41
42
  <div class="ws-board">
42
43
  <div class="ws-board__column">
43
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 0ms;">
44
- <h3 class="ws-section">Calls this week</h3>
45
- <p class="ws-figure">26</p>
44
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight" aria-labelledby="cb-5">
45
+ <h3 class="ws-section" id="cb-5">Calls this week</h3>
46
+ <p class="ws-figure ws-figure--tile">26</p>
46
47
  </section>
47
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 30ms;">
48
- <h3 class="ws-section">Follow-ups</h3>
49
- <p class="ws-figure">4</p>
48
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight" aria-labelledby="cb-6">
49
+ <h3 class="ws-section" id="cb-6">Follow-ups</h3>
50
+ <p class="ws-figure ws-figure--tile">4</p>
50
51
  </section>
51
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 60ms;">
52
- <h3 class="ws-section">Live transfers</h3>
53
- <p class="ws-figure">8</p>
54
- </section>
55
- <section class="ws-card ws-card--inset ws-stack ws-stack--tight ws-rise" style="animation-delay: 90ms;">
56
- <h3 class="ws-section">New leads</h3>
57
- <p class="ws-figure">3</p>
52
+ <section class="ws-card ws-card--inset ws-stack ws-stack--tight" aria-labelledby="cb-7">
53
+ <h3 class="ws-section" id="cb-7">Live transfers</h3>
54
+ <p class="ws-figure ws-figure--tile">8</p>
58
55
  </section>
59
56
  </div>
60
57
  </div>