@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="Actions" height=428 -->
1
+ <!-- @dsCard group="Actions" height=1060 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -11,51 +11,124 @@
11
11
  <div class="ws-stage ws-stage--column">
12
12
 
13
13
  <div class="ws-stack">
14
- <span class="ws-muted">Primary, secondary, ghost, link, text (medium, 32px)</span>
14
+ <span class="ws-muted">Primary, secondary, well, ghost (32 px, 6 px corners, 13 px words)</span>
15
15
  <div class="ws-cluster ws-cluster--loose">
16
- <button class="ws-btn ws-btn--primary">Start the call</button>
17
- <button class="ws-btn ws-btn--secondary">Edit criteria</button>
18
- <button class="ws-btn ws-btn--ghost">Dismiss</button>
19
- <button class="ws-btn ws-btn--link">See them on the board</button>
20
- <button class="ws-btn ws-btn--text">All your calls</button>
16
+ <button type="button" class="ws-btn ws-btn--primary">Start the call</button>
17
+ <button type="button" class="ws-btn ws-btn--secondary">Edit criteria</button>
18
+ <button type="button" class="ws-btn ws-btn--well">Send to my web person</button>
19
+ <button type="button" class="ws-btn ws-btn--ghost">Dismiss</button>
21
20
  </div>
22
21
  </div>
23
22
 
24
23
  <div class="ws-stack">
25
- <span class="ws-muted">Small (28px) and large (36px, a card's or a form's one act)</span>
24
+ <span class="ws-muted">With an icon (6 px apart): Seth's header acts</span>
26
25
  <div class="ws-cluster ws-cluster--loose">
27
- <button class="ws-btn ws-btn--sm ws-btn--primary">Approve</button>
28
- <button class="ws-btn ws-btn--sm ws-btn--secondary">Move</button>
29
- <button class="ws-btn ws-btn--lg ws-btn--primary">Send the offer</button>
30
- <button class="ws-btn ws-btn--lg ws-btn--secondary">Not now</button>
26
+ <button type="button" class="ws-btn ws-btn--secondary">
27
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 8a5 5 0 1 1-1.5-3.6M13 3v2.5h-2.5"/></svg>
28
+ Refresh
29
+ </button>
30
+ <button type="button" class="ws-btn ws-btn--secondary">
31
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="2"/><path d="M8 1.8v1.6M8 12.6v1.6M14.2 8h-1.6M3.4 8H1.8M12.4 3.6l-1.1 1.1M4.7 11.3l-1.1 1.1M12.4 12.4l-1.1-1.1M4.7 4.7 3.6 3.6"/></svg>
32
+ Settings
33
+ </button>
34
+ <button type="button" class="ws-btn ws-btn--primary">
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 13V3M4 7l4-4 4 4"/></svg>
36
+ Send the offer
37
+ </button>
31
38
  </div>
32
39
  </div>
33
40
 
34
41
  <div class="ws-stack">
35
- <span class="ws-muted">Selected (a toggle that is on)</span>
36
- <div class="ws-cluster ws-cluster--loose" role="group" aria-label="Call kind">
37
- <button class="ws-btn ws-btn--secondary" aria-pressed="false">Live transfer</button>
38
- <button class="ws-btn ws-btn--secondary" aria-pressed="true">Cold calls</button>
39
- <button class="ws-btn ws-btn--secondary" aria-pressed="false">Follow-up</button>
42
+ <span class="ws-muted">Small (28 px) and large (40 px, 14 px sides: a pane's or a form's acts)</span>
43
+ <div class="ws-cluster ws-cluster--loose">
44
+ <button type="button" class="ws-btn ws-btn--sm ws-btn--primary">Approve</button>
45
+ <button type="button" class="ws-btn ws-btn--sm ws-btn--well">Move</button>
46
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--primary">Copy reply</button>
47
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--well">Open your Zillow reviews</button>
48
+ </div>
49
+ </div>
50
+
51
+ <div class="ws-stack" style="max-width: 440px;">
52
+ <span class="ws-muted">A split pair: two acts in equal halves, the primary last</span>
53
+ <div class="ws-btn-split">
54
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--well">Send to my web person</button>
55
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--primary">Review Grow's rewrite</button>
40
56
  </div>
41
57
  </div>
42
58
 
43
59
  <div class="ws-stack">
44
- <span class="ws-muted">Pending (its answer is on the way) and disabled</span>
60
+ <span class="ws-muted">Words that act: link (goes somewhere) and text (acts in place), 24 px targets on touch</span>
61
+ <p class="ws-body">Two leads came in overnight. <button type="button" class="ws-btn ws-btn--link">See them on the board</button></p>
62
+ <p class="ws-body">Nothing else is waiting. <button type="button" class="ws-btn ws-btn--text">All your calls</button></p>
63
+ <div class="ws-cluster">
64
+ <button type="button" class="ws-btn ws-btn--link">HubSpot account</button>
65
+ <button type="button" class="ws-btn ws-btn--link is-focus">Open the deal</button>
66
+ </div>
67
+ </div>
68
+
69
+ <div class="ws-stack">
70
+ <span class="ws-muted">States, pictured (is-hover, is-pressed, is-focus): rest, hover (a colour change, no lift), pressed (0.97), focus (2 px navy ring, 2 px out)</span>
45
71
  <div class="ws-cluster ws-cluster--loose">
46
- <button class="ws-btn ws-btn--primary" aria-busy="true" aria-disabled="true">
47
- <span class="ws-dot ws-working" aria-hidden="true"></span>
48
- Saving…
49
- </button>
50
- <button class="ws-btn ws-btn--secondary" disabled>Archive the lead</button>
72
+ <button type="button" class="ws-btn ws-btn--primary">Rest</button>
73
+ <button type="button" class="ws-btn ws-btn--primary is-hover">Hover</button>
74
+ <button type="button" class="ws-btn ws-btn--primary is-hover is-pressed">Pressed</button>
75
+ <button type="button" class="ws-btn ws-btn--primary is-focus">Focus</button>
76
+ </div>
77
+ <div class="ws-cluster ws-cluster--loose">
78
+ <button type="button" class="ws-btn ws-btn--secondary">Rest</button>
79
+ <button type="button" class="ws-btn ws-btn--secondary is-hover">Hover</button>
80
+ <button type="button" class="ws-btn ws-btn--secondary is-hover is-pressed">Pressed</button>
81
+ <button type="button" class="ws-btn ws-btn--secondary is-focus">Focus</button>
82
+ </div>
83
+ <div class="ws-cluster ws-cluster--loose">
84
+ <button type="button" class="ws-btn ws-btn--well">Rest</button>
85
+ <button type="button" class="ws-btn ws-btn--well is-hover">Hover</button>
86
+ <button type="button" class="ws-btn ws-btn--ghost">Ghost</button>
87
+ <button type="button" class="ws-btn ws-btn--ghost is-hover">Ghost hover</button>
88
+ </div>
89
+ </div>
90
+
91
+ <div class="ws-stack">
92
+ <span class="ws-muted">Selected (a toggle that is on)</span>
93
+ <div class="ws-cluster" role="group" aria-label="Call kind">
94
+ <button type="button" class="ws-btn ws-btn--secondary" aria-pressed="false">Live transfer</button>
95
+ <button type="button" class="ws-btn ws-btn--secondary" aria-pressed="true">Cold calls</button>
96
+ <button type="button" class="ws-btn ws-btn--secondary" aria-pressed="false">Follow-up</button>
51
97
  </div>
52
98
  </div>
53
99
 
54
100
  <div class="ws-stack">
55
- <span class="ws-muted">A long label (the button expands, the words never wrap mid-word)</span>
101
+ <span class="ws-muted">Pending (its answer is on the way: the same size, full colour) and disabled</span>
56
102
  <div class="ws-cluster ws-cluster--loose">
57
- <button class="ws-btn ws-btn--primary">Nudge Dana and Sam to get a cold call in this week</button>
103
+ <button type="button" class="ws-btn ws-btn--primary" aria-busy="true" aria-disabled="true"><span class="ws-dot ws-working" aria-hidden="true"></span>Saving</button>
104
+ <button type="button" class="ws-btn ws-btn--well" aria-busy="true" aria-disabled="true"><span class="ws-dot ws-working" aria-hidden="true"></span>Checking</button>
105
+ <button type="button" class="ws-btn ws-btn--secondary" disabled>Archive the lead</button>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="ws-stack" style="max-width: 440px;">
110
+ <span class="ws-muted">A pending act in a split pair (stacked full width on a phone): the dot stays beside its words</span>
111
+ <div class="ws-btn-split">
112
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--well">Keep the lead</button>
113
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--primary" aria-busy="true" aria-disabled="true"><span class="ws-dot ws-working" aria-hidden="true"></span>Deleting</button>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="ws-stack" style="max-width: 360px;">
118
+ <span class="ws-muted">LinkPending: a link card whose page is on its way (the edge arrives after a beat and breathes)</span>
119
+ <a href="#lead" class="ws-card ws-card--inset" aria-busy="true" style="position: relative; display: block; text-decoration: none;">
120
+ <span class="ws-row-name">Priya Nair</span>
121
+ <span class="ws-meta" style="display: block;">Opening her lead page</span>
122
+ <span class="ws-link-pending" aria-hidden="true"></span>
123
+ </a>
124
+ </div>
125
+
126
+ <div class="ws-stack">
127
+ <span class="ws-muted">A long label: one line by default; with --wrap, a label wider than its column wraps, balanced, never cut</span>
128
+ <div class="ws-cluster">
129
+ <button type="button" class="ws-btn ws-btn--primary ws-btn--wrap">Nudge Dana and Sam to get a cold call in this week</button>
58
130
  </div>
131
+ <p class="ws-body" style="max-width: 240px;"><button type="button" class="ws-btn ws-btn--link ws-btn--wrap">Resend the quote before it expires on Nov 2</button></p>
59
132
  </div>
60
133
 
61
134
  </div>
@@ -0,0 +1,86 @@
1
+ /* ---- Button: Seth's control (0.5.0, D1): 6 px corners, 13 / 18 medium words, 6 px to an icon; 32 tall, 28 small,
2
+ 40 large. North's states (D7): hover is a colour change, never a lift; the act goes a shade brighter with a soft light
3
+ under the pointer. This block restates the house's Buttons block (_house.css) in full, so that copy can go. ---- */
4
+
5
+ /* Every outlined or navy control shares North's hover values, global tokens: --ws-edge-hover (the edge a shade darker
6
+ under the pointer), --ws-act-hover and --ws-act-light (the act's brighter navy with a soft light where the pointer is). */
7
+
8
+ /* The box. Its words stay on one line (0.4.0's rule, kept: in a table cell, a fact row or a list row the button holds
9
+ its line and the sentence beside it wraps; the button never shrinks). --wrap opts in for a label that can be longer
10
+ than its whole column: balanced lines, never cut, and a word act or a ghost then reads from its start. */
11
+ .ws-btn { --ws-btn-pad: var(--space-sm); --ws-btn-gap: var(--space-xxs-plus); position: relative; display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; gap: var(--ws-btn-gap); max-width: 100%; height: auto; min-height: var(--ws-control-h); padding: var(--space-xxs) var(--ws-btn-pad); border: 0; border-radius: var(--ws-radius-row); background-color: transparent; font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; text-align: center; text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft), color var(--ws-duration-hover) var(--ws-ease-soft), box-shadow var(--ws-duration-hover) var(--ws-ease-soft), transform var(--ws-duration-hover) var(--ws-ease-soft); }
12
+ .ws-btn--sm { --ws-btn-pad: var(--space-xs); --ws-btn-gap: var(--space-xxs); min-height: var(--ws-control-h-sm); }
13
+ .ws-btn--lg { --ws-btn-pad: var(--space-sm-plus); min-height: var(--space-2xl); }
14
+ .ws-btn--wrap { white-space: normal; text-wrap: balance; }
15
+ .ws-btn--wrap:is(.ws-btn--link, .ws-btn--text, .ws-btn--ghost) { justify-content: flex-start; text-align: start; }
16
+
17
+ /* Looks. primary: the one navy act. secondary: Seth's outlined header act, its 0.5 px edge drawn inside so a scroller
18
+ never clips it. well: Seth's grey act for rows and panes (#EDEDED, no edge). ghost: words only until the pointer.
19
+ A busy button keeps this resting look under the pointer too (the [aria-busy]:hover selectors), since it refuses the
20
+ press a hover would invite. */
21
+ .ws-btn--primary, .ws-btn[aria-pressed="true"], .ws-btn--primary[aria-busy="true"]:hover { isolation: isolate; background-color: var(--color-text-heading); color: var(--ws-on-act); }
22
+ .ws-btn--primary::before, .ws-btn[aria-pressed="true"]::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; background: radial-gradient(var(--space-6xl) circle at var(--mx, 50%) var(--my, 50%), var(--ws-act-light), transparent 70%); opacity: 0; transition: opacity var(--ws-duration-hover) var(--ws-ease-soft); }
23
+ .ws-btn--secondary, .ws-btn--secondary[aria-busy="true"]:hover { background-color: transparent; color: var(--color-text-heading); box-shadow: var(--ws-shadow-hairline-in); }
24
+ .ws-btn--well, .ws-btn--well[aria-busy="true"]:hover { background-color: var(--ws-tray); color: var(--color-text-heading); box-shadow: none; }
25
+ .ws-btn--ghost, .ws-btn--ghost[aria-busy="true"]:hover { background-color: transparent; color: var(--color-text-heading); }
26
+ .ws-btn[aria-busy="true"]:hover { opacity: 1; }
27
+ /* Words that act: no box of their own, the size of the words around them; 4 px of room each side, bled back out of the
28
+ line so the words sit where the sentence puts them (North A3). 24 tall on touch (the house's floor, restated below). */
29
+ .ws-btn--link, .ws-btn--text { --ws-btn-pad: var(--space-xxs); min-height: 0; margin: 0 calc(var(--space-xxs) * -1); padding: 0 var(--ws-btn-pad); background-color: transparent; border-radius: var(--ws-radius-control); font-size: inherit; line-height: inherit; text-underline-offset: var(--ws-ring); }
30
+ .ws-btn--link { color: var(--color-text-interactive); }
31
+ .ws-btn--text { color: var(--color-text-heading); }
32
+ /* Two word acts side by side (links in a cluster): the second keeps 4 px of room before its box instead of bleeding into
33
+ the first, so their words sit 16 apart and one's focus ring never covers the other's first letter. */
34
+ :where(.ws-btn--link, .ws-btn--text) + :is(.ws-btn--link, .ws-btn--text) { margin-inline-start: var(--space-xxs); }
35
+
36
+ /* Hover, on a mouse only, never on a busy button (:where keeps each selector's weight as it was). */
37
+ @media (hover: hover) {
38
+ .ws-btn--primary:not(:where([aria-busy="true"])):hover, .ws-btn[aria-pressed="true"]:not(:where([aria-busy="true"])):hover { background-color: var(--ws-act-hover); opacity: 1; }
39
+ .ws-btn--primary:not(:where([aria-busy="true"])):hover::before, .ws-btn[aria-pressed="true"]:not(:where([aria-busy="true"])):hover::before { opacity: 1; }
40
+ .ws-btn--secondary:not([aria-pressed="true"], :where([aria-busy="true"])):hover { background-color: transparent; box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-hover); }
41
+ .ws-btn--well:not([aria-pressed="true"], :where([aria-busy="true"])):hover { background-color: var(--ws-well-hover); }
42
+ .ws-btn--ghost:not([aria-pressed="true"], :where([aria-busy="true"])):hover { background-color: var(--ws-hover-strong); color: var(--color-text-heading); }
43
+ .ws-btn--link:not(:where([aria-busy="true"])):hover, .ws-btn--text:not(:where([aria-busy="true"])):hover { background-color: transparent; text-decoration: underline; }
44
+ }
45
+ @media (pointer: coarse) { .ws-btn--link, .ws-btn--text { min-height: var(--space-lg); } }
46
+ /* Press: a 0.97 give over the instant beat, released over the hover beat; words that act do not move. */
47
+ @media (prefers-reduced-motion: no-preference) {
48
+ .ws-btn:active, .ws-btn.is-pressed { transform: scale(var(--ws-press-scale)); transition-duration: var(--ws-duration-instant); }
49
+ .ws-btn--link:active, .ws-btn--text:active, .ws-btn--link.is-pressed, .ws-btn--text.is-pressed { transform: none; }
50
+ }
51
+ /* States drawn still, for a preview or a mockup (D14): is-hover, is-pressed (above) and is-focus picture what a pointer
52
+ and a keyboard draw. */
53
+ .ws-btn--primary.is-hover, .ws-btn[aria-pressed="true"].is-hover { background-color: var(--ws-act-hover); }
54
+ .ws-btn--primary.is-hover::before, .ws-btn[aria-pressed="true"].is-hover::before { opacity: 1; }
55
+ .ws-btn--secondary.is-hover { box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-hover); }
56
+ .ws-btn--well.is-hover { background-color: var(--ws-well-hover); }
57
+ .ws-btn--ghost.is-hover { background-color: var(--ws-hover-strong); }
58
+ .ws-btn--link.is-hover, .ws-btn--text.is-hover { text-decoration: underline; }
59
+ .ws-btn.is-focus { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
60
+
61
+ /* Pending: the working dot sits in the left padding, centred in it, so the button keeps its size and its words stay put;
62
+ it stays focusable (aria-disabled) and refuses a second press (aria-busy). The dot is in the flow, its margins taking
63
+ back its own width and the gap, so in a button wider than its words (a full-width act on a phone) it stays beside the
64
+ label instead of at the far edge. --ws-dot-side: the room each side of the dot. */
65
+ .ws-btn > .ws-dot { --ws-dot-side: calc((var(--ws-btn-pad) - var(--space-xxs) * 1.5) / 2); flex-shrink: 0; margin-inline: calc((var(--space-xxs) * 1.5 + var(--ws-dot-side)) * -1) calc(var(--ws-dot-side) - var(--ws-btn-gap)); }
66
+ /* Small's 8 px side is too narrow for the 6 px dot (it sat 1 px from the edge, touching the words): its sides trade 4 px,
67
+ so the dot gets 3 each side and the button keeps its width. */
68
+ .ws-btn--sm:has(> .ws-dot) { padding-inline: calc(var(--ws-btn-pad) + var(--space-xxs)) calc(var(--ws-btn-pad) - var(--space-xxs)); }
69
+ .ws-btn--sm > .ws-dot { --ws-dot-side: calc((var(--ws-btn-pad) + var(--space-xxs) - var(--space-xxs) * 1.5) / 2); }
70
+ .ws-btn[aria-busy="true"] { cursor: progress; }
71
+ .ws-btn:disabled, .ws-btn[aria-disabled="true"]:not([aria-busy="true"]) { opacity: 0.4; pointer-events: none; }
72
+
73
+ /* A split pair (Seth's pane foot): two acts in equal halves across the width, the primary last. They stack, the primary
74
+ at the bottom under the thumb, where a half would be under 160 px (a phone) or narrower than either label on its one
75
+ line: a half is never narrower than its words (fit-content: the one-line width, or the column's with --wrap). */
76
+ .ws-btn-split { display: flex; flex-wrap: wrap; gap: var(--space-xs); width: 100%; }
77
+ .ws-btn-split > .ws-btn { flex: 1 1 var(--space-8xl); min-width: fit-content; }
78
+
79
+ /* LinkPending: a link card or a ButtonLink whose page is on its way. Its 1 px navy edge arrives after a beat (a quick
80
+ answer shows nothing) and breathes until the page answers; it leaves at once. The link holds it (position: relative). */
81
+ .ws-link-pending { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; }
82
+ .ws-link-pending::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 var(--ws-line) var(--color-text-heading); }
83
+ [aria-busy="true"] > .ws-link-pending { opacity: 1; transition: opacity var(--ws-duration-gentle) var(--ws-ease-soft) var(--ws-duration-instant); }
84
+ @media (prefers-reduced-motion: no-preference) {
85
+ [aria-busy="true"] > .ws-link-pending::after { animation: ws-pulse var(--ws-loop) var(--ws-ease-loop) infinite; }
86
+ }
@@ -1,71 +1,104 @@
1
- The one card: the page's cream on a fine inside edge, 8 px corners, flat, that every other surface builds on.
1
+ The one card: Seth's tray card. The page's cream sits inside a 1 px tray rim, 8 px outside and 7 px inside, flat, and
2
+ every other surface builds on it.
2
3
 
3
4
  ## Use it when
4
5
 
5
6
  - Something needs a bounded surface on the page: a chart, a list, a form, a single fact.
6
- - A chart or a dashboard card needs a title that answers a question, one body, and at most one footer act (a compound card, `ws-card--compound`, with its head, body and band).
7
- - A whole block should be a link or a button: pass `href` or `onClick` and the card itself becomes the target.
8
- - A person needs to see which of several cards is chosen: pass `selected`.
9
- - A quiet aside or inset block is needed inside another card: use `tone="sunk"`.
7
+ - A chart card needs a title that answers a question, one body and at most one footer act (a compound card,
8
+ `ws-card--compound`, with its head, body and band).
9
+ - A tile or a fact needs a short line under it on the grey (a foot): the count it comes from, when it was checked, or
10
+ the one door it opens.
11
+ - A list of things to open sits in one card, its rows joined by hairlines (Seth's checks list).
12
+ - A whole block should be a link or a button: the card itself becomes the target.
13
+ - A person needs to see which card of a row is chosen: `ws-card--selected`.
10
14
 
11
15
  ## Not for
12
16
 
13
- - A row in a list with a hover state: use a `Well` row (`.ws-well-row`) or a `Table` row.
17
+ - A grey plate of prompts to tap: use `Well`.
14
18
  - A block of facts set apart inside a card: use `Plate`.
15
- - A disclosure that opens and closes: use `Fold` (its `card` look is built on this component, but it carries its own behaviour).
19
+ - A disclosure that opens and closes: use `Fold`.
20
+ - A card in the chat (a suggestion, a reminder, a chart answer): use `ChatCard`.
16
21
  - A floating surface that covers the page: use `Dialog` or `Panel`.
17
- - A quiet strip of suggestions: use `Well`.
18
22
 
19
23
  ## Anatomy
20
24
 
21
- - The card itself: `--ws-radius-card` (8 px) corners, `--color-bg-page` (the cream) background, a `--ws-hairline` (0.5 px) edge drawn inside in `--ws-edge-card` (so it never pushes the content).
22
- - No float shadow at rest: the product is flat. A chosen card adds `--ws-ring-selected`, a 2 px navy ring at 55% opacity, drawn beside the edge, never replacing it.
23
- - Padding is the card's own choice, not fixed: `none` (the default, for a compound card, `ws-card--compound`, that pads its own head, body and band), `sm` 12 px, `md` 16 px, `lg` 20 px.
24
- - A pressable card (`href` or `onClick`, or `interactive`) tints to `--ws-surface-sunk` under the pointer and `--ws-surface-press` under a press or tap, with no lift; a link card also carries a faint navy edge pulse while its page loads.
25
+ - The rim: a `--ws-rim` (1 px) border in `--ws-tray` (#EDEDED), 8 px corners (`--ws-radius-card`). The cream
26
+ (`--color-bg-page`) inside has 7 px corners (`--ws-radius-card-inner`), so the two are concentric. No outline, no
27
+ shadow at rest.
28
+ - A card with a foot: the cream is its own surface (`ws-card__surface`, 7 px corners; `ws-card__surface--pad` gives it
29
+ Seth's 16 px inside) and the card shows the tray round it and under it.
30
+ - The foot (`ws-card__foot`): on the tray, no fill of its own, 36 px tall at least (`--ws-control-h-md`), 16 px sides
31
+ (the surface's own, so the words line up), 12 px between its parts. Words 13 / 18 medium: the left one in
32
+ `--color-text-body`, a figure or date on the right in `--color-text-muted` (`ws-card__foot-aside`), both AA on the
33
+ tray; the aside keeps one line while it fits and wraps at the end when it is long, never past the card. A foot that is the card's door is an `a.ws-card__foot`: navy words and a 16 px chevron at the end, 40 px tall
34
+ on touch. Inside a card that is itself the link (a tile), the foot is a `span` and says what it is: `ws-card__foot--door`
35
+ (navy words, the chevron) or `ws-card__foot--waits` (muted words: the step the tile waits on, not a target).
36
+ - Rows (`ws-card__list-row`): cream, edge to edge, 48 px tall at least (`--ws-row-h`), 12 px top and bottom, 20 px on
37
+ the left (the card's one content edge, `--ws-card-inset`) and 16 px on the right; joined by 0.5 px dividers that
38
+ run the card's full width (`--ws-divider`). The row's first part takes the room and wraps; its aside
39
+ (`ws-card__list-aside`: a status, a figure, a 16 px navy chevron (`ws-card__chevron`), 12 apart) never wraps; a
40
+ figure alone at a row's end is `ws-card__value` (semibold navy, tabular). Rows at the card's corners take its 7 px
41
+ inner corners. A plain list's own small head (`ws-card__list-head`) sits over the rows: 16 px above and on the right,
42
+ 20 on the left, 4 under it.
43
+ - A compound card's head (`ws-head`) is 20 px in, the 22 px title and one 14 px line (`ws-card__line`) in its first
44
+ `div`. An aside after it keeps its own width and layout and drops under the title, as one piece, when the title would
45
+ get under 200 px; put controls that may drop in one element (a `ws-cluster`). Icon acts (a close, an expand) never
46
+ drop: loose in the head, they stay top right on the title's line and the title wraps instead. The body (`ws-card__body`) is 20 px at the sides. The band (`ws-band`) is the
47
+ darker cream with its inset shade, 80 px tall, 28 px sides; its acts sit in one group at the end (`ws-band__acts`).
48
+ - The padding steps for a plain card: `ws-card--pad-sm` 12 px, `ws-card--pad-md` 16 px, `ws-card--inset` 20 px.
49
+ - A sample drawing for previews and recipes (`ws-card__bars` holding `ws-card__bar`s, each at its own height): a short
50
+ run of teal bars on the dots. A real chart uses its chart component.
25
51
 
26
52
  ## Variants and sizes
27
53
 
28
- | Tone | Look | Use |
54
+ | Variant | Class | Look |
29
55
  | --- | --- | --- |
30
- | `card` (default) | Cream, 8 px corners, hairline edge | The default surface |
31
- | `sunk` | The cream a shade darker (`--ws-surface-sunk`), no edge | A quiet block or aside inside a card |
32
- | `plain` | 8 px corners, no fill, no edge | A card shell that another frame (such as a chart drawn without an edge of its own) draws its own background for |
56
+ | Card | `ws-card` | The rim round the cream |
57
+ | Tray card with a foot | `ws-card` > `ws-card__surface` + `ws-card__foot` | The cream on the tray, the foot on the grey under it |
58
+ | Rows | `ws-card` > `ul` > `li` > `ws-card__list-row` | Cream rows joined by 0.5 px dividers |
59
+ | Compound | `ws-card--compound` | Head, body and band in a column |
60
+ | Snug | `ws-card--compound ws-card--snug` | Head, body and band 12 px in (20 top, 16 under the head), the band 16 px above and under and only as tall as its content, so every part shares one edge: a card in a chat column (issue #10) |
61
+ | Compact | `ws-card--compound ws-card--compact` | Head 16 / 16 / 8 with a 16 / 20 title, body 12 / 16 (its sides on the title's edge), band 8 / 16 |
33
62
 
34
- | Padding | Value |
35
- | --- | --- |
36
- | `none` | 0 (the default; the card's own sections pad themselves) |
37
- | `sm` | `--ws-card-padding` (12 px) |
38
- | `md` | `--ws-card-padding-lg` (16 px) |
39
- | `lg` | 20 px (`--ws-card-inset`) |
63
+ The band's sizes also stand alone: `ws-band--snug` (16 round) and `ws-band--compact` (8 / 16), both with no minimum
64
+ height. A band under 26rem wide (it measures itself) gives its acts the whole line and splits it between them.
40
65
 
41
66
  ## States
42
67
 
43
- - **Default**: flat, the hairline edge, no shadow.
44
- - **Hover** (only when `href`, `onClick` or `interactive`): background to `--ws-surface-sunk`.
45
- - **Focus**: the card's edge becomes the shadow focus ring (`--shadow-focus-ring`); never `outline: none` without it.
46
- - **Pressed**: background a step further to `--ws-surface-press`, so a tap answers on a touch screen where hover never shows.
47
- - **Selected**: `--ws-ring-selected`, a 2 px navy ring at 55% opacity, beside the edge.
48
- - **Pending** (a link card only): the edge pulses navy while its page loads, so a slow open never looks like a missed tap.
49
- - **Disabled**: 60% opacity, no pointer events (only reachable as a button card).
50
- - **Empty / missing data**: there is no empty variant of a card. A card whose data does not exist is left out entirely, never shown empty or faked.
51
- - **Narrow**: the card has no fixed width of its own; a board (`CardBoard`) gives it 556 px down to 480 px before wrapping, and one column on a phone.
68
+ - **Default**: flat, the rim, no shadow.
69
+ - **Hover** (a link or button card only, on a pointer that hovers): the rim darkens to `--ws-well-hover` (#E4E2DF) over
70
+ `--ws-duration-hover`; the cream stays and nothing lifts.
71
+ - **Pressed**: the cream goes to `--ws-surface-press` at once, so a tap answers on a touch screen; a foot that is the
72
+ door darkens to `--ws-well-hover` (under the pointer too), and a muted aside on it takes `--color-text-body`, since
73
+ the muted grey is under AA on that grey.
74
+ - **Focus**: the 2 px navy outline, 2 px out (`--ws-focus-*`). A focused row or foot draws it inside itself.
75
+ - **Selected** (in a row of cards): the rim darkens and a 2 px navy tab sits 8 px under the card, 16 px in from each
76
+ side. Say it in the markup too (`aria-pressed`, `aria-current` or `aria-selected`).
77
+ - **Open row**: a row whose detail is showing (`aria-expanded="true"` or `aria-current`) takes the sunk cream
78
+ (`--ws-surface-sunk`); nothing moves. A hovered row takes the faint navy wash (`--ws-hover-faint`); the open row keeps its sunk cream under the
79
+ wash, so hovering it never lightens it.
80
+ - **Pending** (a link card): a navy edge pulses on the rim while its page loads, so a slow open never looks like a
81
+ missed tap.
82
+ - **Disabled** (a button card): 60% opacity, no pointer.
83
+ - **Long words**: a row's name wraps to a second line and the row grows; its aside stays on one line. A head's aside
84
+ drops under the title as one piece; a head's icon acts stay beside it.
85
+ - **Empty / missing data**: there is no empty card. A card whose data does not exist is left out, never drawn empty.
86
+ - **Narrow**: the card has no width of its own. A board gives it 556 px down to 480 px, then one column.
87
+ - **Dark**: the rim, the foot and the hover all follow the theme (`--ws-tray`, `--ws-well-hover` are dark-safe).
52
88
 
53
89
  ## Behaviour
54
90
 
55
- - Keyboard: a link card is a real `<a>`/`Link`, a button card a real `<button type="button">`; both take focus in document order and show the focus ring.
56
- - Pointer: hover tints only pressable cards; a static card never reacts to the pointer.
57
- - Touch: the press tint (`--ws-surface-press`) is how a tap answers, since there is no hover on touch; a pressable card inherits the 40 px touch floor from its content, not the card shell itself.
58
- - Motion: no animation of its own; a card that arrives in a list uses `ws-rise` on the outer element, not the card's internal transition (which is only for colour and shadow, at `--ws-duration-gentle`).
59
- - Reduced motion: the colour and shadow transitions are disabled (`motion-reduce:transition-none`); nothing moves.
91
+ - Keyboard: a link card is a real `<a>`, a button card a real `<button type="button">`; rows that open something are
92
+ buttons too. All take focus in document order.
93
+ - Touch: rows are 48 px; the foot's door is the whole width and 40 px tall (36 with a pointer).
94
+ - Motion: colour only, over `--ws-duration-hover`, a press at once. Reduced motion: every change is instant.
60
95
 
61
96
  ## Content
62
97
 
63
- - One title that answers the question the card exists for, not a label for the topic ("On pace for 40 calls by Oct 22", not "Calls").
64
- - One sentence under the title, sentence case, no em dash (use a comma, colon or period).
65
- - At most one footer band with one primary action; any other act is a secondary button or a text action.
66
- - The band's primary is the page's one primary: a page has one navy button, so a band on any other card uses a
67
- secondary button (as in this preview).
68
- - A card whose underlying data does not exist is left out of the page, never rendered empty or with placeholder numbers.
98
+ - One title that answers the question the card exists for ("On pace for 40 calls by Oct 22", not "Calls").
99
+ - One sentence under the title, sentence case, no em dash.
100
+ - A foot holds a fact and its source, or one door. A band holds one act line with at most one primary; a page keeps
101
+ its one navy button, so a band elsewhere uses a secondary.
69
102
 
70
103
  ## Props
71
104
 
@@ -82,13 +115,89 @@ The one card: the page's cream on a fine inside edge, 8 px corners, flat, that e
82
115
 
83
116
  ## Rules
84
117
 
85
- - "A card is one component everywhere, never its styles again" (owner's rule, 16 Oct 2026): a screen never redraws a card's edge, radius or background by hand.
86
- - No white cards, no float shadows, no corners other than 8 px on a card (the owner's rule, 15 Oct 2026 re-base).
87
- - A card's edge is always drawn, never `outline-none`, because the edge doubles as the focus ring's anchor.
88
- - A card whose data does not exist is left out, never faked (the system's honesty rule).
89
- - Change the look only: the words, the data, the acts and their order stay as they are (the system's own rule).
118
+ - A card is one component everywhere: a screen never redraws its rim, corners or ground by hand.
119
+ - No white cards, no shadow at rest, no corners other than 8 outside and 7 inside.
120
+ - Never `overflow: hidden` on a card: it squashes in a scroller and cuts every menu inside. Its first and last parts
121
+ take its corners instead (a band that ends even a plain card takes the 7 px inner corners).
122
+ - On a page, a card's act goes in its foot; the 80 px band is for a chart card's act line that needs a title and a how,
123
+ and for the chat (`ChatCard`).
124
+ - A card whose data does not exist is left out, never faked.
90
125
 
91
126
  ## Source
92
127
 
93
- **Derived from**: the system's card rules (the cream surface, 8 px corners, the inside-drawn hairline edge, the
94
- navy selected ring) and the chart card built on top of it. **Precedent**: the first product built on the system.
128
+ **Derived from**: Seth's tray card (Fia frames 308:2506, 313:2687, 319:3351; Grow 301:1728) and North's well card
129
+ (style1.css:128-133, hover :268, selected :1032-1033). Issue #10 (snug band). Kit 0.4.0's hairline card, replaced (D5).
130
+
131
+ ## Markup
132
+
133
+ ```html
134
+ <!-- A tray card with a foot -->
135
+ <div class="ws-card">
136
+ <div class="ws-card__surface ws-card__surface--pad ws-stack">
137
+ <span class="ws-control-words">Zillow rating</span>
138
+ <span class="ws-figure ws-figure--tile">5.0</span>
139
+ </div>
140
+ <div class="ws-card__foot">
141
+ <span>10 reviews</span>
142
+ <span class="ws-card__foot-aside">Checked Nov 2</span>
143
+ </div>
144
+ </div>
145
+
146
+ <!-- Rows in a card -->
147
+ <ul class="ws-card" aria-label="Your checks">
148
+ <li>
149
+ <button type="button" class="ws-card__list-row" aria-expanded="false">
150
+ <span class="ws-row-name">Website</span>
151
+ <span class="ws-card__list-aside">
152
+ <span class="ws-control-words">2 fixes</span>
153
+ <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>
154
+ </span>
155
+ </button>
156
+ </li>
157
+ </ul>
158
+
159
+ <!-- A chart card -->
160
+ <section class="ws-card ws-card--compound">
161
+ <header class="ws-head"><div>
162
+ <h3 class="ws-title">On pace for 40 calls by Oct 22</h3>
163
+ <p class="ws-body ws-card__line">Nine days early. Cold calls did most of the work.</p>
164
+ </div></header>
165
+ <div class="ws-card__body ws-dots"><!-- the drawing --></div>
166
+ <footer class="ws-band">
167
+ <div class="ws-band__words">
168
+ <p class="ws-band__title">Next up: Priya Nair</p>
169
+ <p class="ws-band__how">A complicated sale</p>
170
+ </div>
171
+ <div class="ws-band__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Start the call</button></div>
172
+ </footer>
173
+ </section>
174
+
175
+ <!-- A head with an aside (drops under the title as one row) and a head with icon acts (they stay top right) -->
176
+ <header class="ws-head">
177
+ <div>
178
+ <h3 class="ws-title">Vendors</h3>
179
+ <p class="ws-body ws-card__line">12 paid this month</p>
180
+ </div>
181
+ <div class="ws-cluster"><!-- selects, a chip: what may drop, together --></div>
182
+ </header>
183
+ <header class="ws-head">
184
+ <div><h3 class="ws-title">New email to Priya Nair</h3></div>
185
+ <button type="button" class="ws-icon-btn" aria-label="Close"><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
186
+ </header>
187
+
188
+ <!-- A plain list card with its own small head and a figure per row -->
189
+ <section class="ws-card">
190
+ <header class="ws-card__list-head"><h3 class="ws-section">Where they came from</h3></header>
191
+ <ul>
192
+ <li class="ws-card__list-row"><span class="ws-body">Referrals</span><span class="ws-body ws-card__value">12</span></li>
193
+ </ul>
194
+ </section>
195
+ ```
196
+
197
+ ## Styles
198
+
199
+ `Card/style.css`, built into `bundle.css` and `fello.css`. It restyles the house `.ws-card` (rim instead of outline,
200
+ selected, the compound corners) and `.ws-head` (wraps; the aside keeps its own layout; icon acts stay on the title's
201
+ line), and adds the band's sizes and acts. Tokens: `--ws-rim`,
202
+ `--ws-tray`, `--ws-well-hover`, `--ws-radius-card`, `--ws-radius-card-inner`, `--ws-divider`, `--ws-hover-faint`,
203
+ `--ws-surface-sunk`, `--ws-surface-press`, `--ws-control-h-md`, `--ws-row-h`, `--ws-card-inset`, `--ws-focus-*`.