@felloinnovations/brand-kit 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +221 -0
  3. package/README.md +38 -9
  4. package/design-system/01-how-claude-decides.md +26 -17
  5. package/design-system/02-principles.md +11 -6
  6. package/design-system/03-colour.md +135 -47
  7. package/design-system/04-type.md +45 -23
  8. package/design-system/05-space-and-layout.md +175 -52
  9. package/design-system/06-sizing-profiles.md +4 -4
  10. package/design-system/07-scrolling.md +66 -20
  11. package/design-system/08-choosing-components.md +50 -22
  12. package/design-system/09-charts.md +71 -28
  13. package/design-system/10-patterns.md +33 -10
  14. package/design-system/11-page-recipes.md +110 -23
  15. package/design-system/12-content.md +2 -1
  16. package/design-system/13-motion.md +330 -47
  17. package/design-system/14-accessibility.md +47 -24
  18. package/design-system/15-ai-experiences.md +11 -6
  19. package/design-system/16-creativity.md +1 -1
  20. package/design-system/17-decisions.md +367 -1
  21. package/design-system/18-checklist.md +79 -16
  22. package/design-system/19-public-pages.md +6 -4
  23. package/design-system/20-palettes.md +275 -0
  24. package/design-system/README.md +30 -17
  25. package/design-system/components/ActionList/README.md +96 -10
  26. package/design-system/components/ActionList/preview.html +52 -7
  27. package/design-system/components/ActionList/style.css +64 -0
  28. package/design-system/components/ActivityGrid/README.md +38 -2
  29. package/design-system/components/ActivityGrid/preview.html +1 -1
  30. package/design-system/components/ActivityGrid/style.css +35 -0
  31. package/design-system/components/AppShell/README.md +205 -75
  32. package/design-system/components/AppShell/preview.html +339 -58
  33. package/design-system/components/AppShell/style.css +154 -0
  34. package/design-system/components/Avatar/README.md +37 -10
  35. package/design-system/components/Avatar/preview.html +13 -4
  36. package/design-system/components/Avatar/style.css +14 -0
  37. package/design-system/components/Badge/README.md +41 -19
  38. package/design-system/components/Badge/preview.html +13 -10
  39. package/design-system/components/Badge/style.css +23 -0
  40. package/design-system/components/Banner/README.md +30 -9
  41. package/design-system/components/Banner/preview.html +1 -1
  42. package/design-system/components/Banner/style.css +19 -0
  43. package/design-system/components/Breadcrumb/README.md +58 -46
  44. package/design-system/components/Breadcrumb/preview.html +16 -16
  45. package/design-system/components/Breadcrumb/style.css +17 -0
  46. package/design-system/components/Button/README.md +113 -55
  47. package/design-system/components/Button/preview.html +98 -25
  48. package/design-system/components/Button/style.css +86 -0
  49. package/design-system/components/Card/README.md +158 -49
  50. package/design-system/components/Card/preview.html +141 -19
  51. package/design-system/components/Card/style.css +115 -0
  52. package/design-system/components/CardBoard/README.md +58 -37
  53. package/design-system/components/CardBoard/preview.html +26 -29
  54. package/design-system/components/ChatCard/README.md +115 -29
  55. package/design-system/components/ChatCard/preview.html +149 -32
  56. package/design-system/components/ChatCard/style.css +49 -0
  57. package/design-system/components/ChatShell/README.md +116 -0
  58. package/design-system/components/ChatShell/preview.html +201 -0
  59. package/design-system/components/ChatShell/style.css +86 -0
  60. package/design-system/components/ChatTurn/README.md +78 -35
  61. package/design-system/components/ChatTurn/preview.html +60 -28
  62. package/design-system/components/ChatTurn/style.css +50 -0
  63. package/design-system/components/CheckRow/README.md +141 -0
  64. package/design-system/components/CheckRow/preview.html +140 -0
  65. package/design-system/components/CheckRow/style.css +88 -0
  66. package/design-system/components/Checkbox/README.md +58 -22
  67. package/design-system/components/Checkbox/preview.html +112 -50
  68. package/design-system/components/Checkbox/style.css +45 -0
  69. package/design-system/components/Chip/README.md +78 -47
  70. package/design-system/components/Chip/preview.html +29 -4
  71. package/design-system/components/Chip/style.css +17 -0
  72. package/design-system/components/Combobox/README.md +44 -11
  73. package/design-system/components/Combobox/preview.html +35 -12
  74. package/design-system/components/Combobox/style.css +54 -0
  75. package/design-system/components/Composer/README.md +137 -35
  76. package/design-system/components/Composer/preview.html +115 -40
  77. package/design-system/components/Composer/style.css +81 -0
  78. package/design-system/components/ConfirmDialog/README.md +73 -52
  79. package/design-system/components/ConfirmDialog/preview.html +70 -26
  80. package/design-system/components/ConfirmDialog/style.css +5 -0
  81. package/design-system/components/Cover/preview.html +3 -3
  82. package/design-system/components/Cover/style.css +19 -0
  83. package/design-system/components/DateInput/README.md +77 -12
  84. package/design-system/components/DateInput/preview.html +27 -12
  85. package/design-system/components/DateInput/style.css +38 -0
  86. package/design-system/components/Dialog/README.md +112 -44
  87. package/design-system/components/Dialog/preview.html +141 -18
  88. package/design-system/components/Dialog/style.css +74 -0
  89. package/design-system/components/EmptyState/README.md +42 -12
  90. package/design-system/components/EmptyState/preview.html +11 -11
  91. package/design-system/components/EmptyState/style.css +9 -0
  92. package/design-system/components/EntryShell/README.md +73 -48
  93. package/design-system/components/EntryShell/preview.html +60 -27
  94. package/design-system/components/EntryShell/style.css +19 -0
  95. package/design-system/components/FeatureGrid/README.md +61 -39
  96. package/design-system/components/FeatureGrid/preview.html +2 -2
  97. package/design-system/components/FeatureGrid/style.css +20 -0
  98. package/design-system/components/FileUpload/README.md +33 -3
  99. package/design-system/components/FileUpload/preview.html +18 -4
  100. package/design-system/components/FileUpload/style.css +23 -0
  101. package/design-system/components/FilterBar/README.md +114 -0
  102. package/design-system/components/FilterBar/preview.html +82 -0
  103. package/design-system/components/FilterBar/style.css +22 -0
  104. package/design-system/components/Fold/README.md +84 -26
  105. package/design-system/components/Fold/preview.html +77 -34
  106. package/design-system/components/Fold/style.css +48 -0
  107. package/design-system/components/Footer/README.md +62 -39
  108. package/design-system/components/Footer/preview.html +5 -5
  109. package/design-system/components/Footer/style.css +30 -0
  110. package/design-system/components/FunnelBars/README.md +24 -3
  111. package/design-system/components/FunnelBars/preview.html +5 -5
  112. package/design-system/components/FunnelBars/style.css +13 -0
  113. package/design-system/components/GoalBars/README.md +54 -10
  114. package/design-system/components/GoalBars/preview.html +69 -28
  115. package/design-system/components/GoalBars/style.css +51 -0
  116. package/design-system/components/GoalTicks/README.md +74 -58
  117. package/design-system/components/GoalTicks/preview.html +41 -118
  118. package/design-system/components/GoalTicks/style.css +37 -0
  119. package/design-system/components/GoalTubes/README.md +29 -3
  120. package/design-system/components/GoalTubes/preview.html +6 -6
  121. package/design-system/components/GoalTubes/style.css +23 -0
  122. package/design-system/components/Heatmap/README.md +133 -0
  123. package/design-system/components/Heatmap/preview.html +168 -0
  124. package/design-system/components/Heatmap/style.css +119 -0
  125. package/design-system/components/Hero/README.md +58 -40
  126. package/design-system/components/Hero/preview.html +1 -1
  127. package/design-system/components/Hero/style.css +19 -0
  128. package/design-system/components/HoverCard/README.md +114 -0
  129. package/design-system/components/HoverCard/preview.html +107 -0
  130. package/design-system/components/HoverCard/style.css +59 -0
  131. package/design-system/components/IconButton/README.md +69 -38
  132. package/design-system/components/IconButton/preview.html +77 -43
  133. package/design-system/components/IconButton/style.css +45 -0
  134. package/design-system/components/Input/README.md +36 -11
  135. package/design-system/components/Input/preview.html +1 -1
  136. package/design-system/components/Input/style.css +23 -0
  137. package/design-system/components/KanbanBoard/README.md +93 -45
  138. package/design-system/components/KanbanBoard/preview.html +159 -43
  139. package/design-system/components/KanbanBoard/style.css +53 -0
  140. package/design-system/components/Kbd/README.md +25 -9
  141. package/design-system/components/Kbd/preview.html +6 -2
  142. package/design-system/components/Kbd/style.css +9 -0
  143. package/design-system/components/KitButton/README.md +81 -47
  144. package/design-system/components/KitButton/preview.html +35 -13
  145. package/design-system/components/KitButton/style.css +46 -0
  146. package/design-system/components/KitCard/README.md +75 -44
  147. package/design-system/components/KitCard/preview.html +18 -10
  148. package/design-system/components/KitCard/style.css +15 -0
  149. package/design-system/components/KitInput/README.md +54 -39
  150. package/design-system/components/KitInput/preview.html +7 -7
  151. package/design-system/components/KitInput/style.css +23 -0
  152. package/design-system/components/Leaderboard/README.md +76 -49
  153. package/design-system/components/Leaderboard/preview.html +61 -26
  154. package/design-system/components/Leaderboard/style.css +44 -0
  155. package/design-system/components/ListDetail/README.md +222 -0
  156. package/design-system/components/ListDetail/preview.html +213 -0
  157. package/design-system/components/ListDetail/style.css +148 -0
  158. package/design-system/components/LoadBar/README.md +79 -0
  159. package/design-system/components/LoadBar/preview.html +40 -0
  160. package/design-system/components/LoadBar/style.css +17 -0
  161. package/design-system/components/MarketingNav/README.md +76 -42
  162. package/design-system/components/MarketingNav/preview.html +37 -8
  163. package/design-system/components/MarketingNav/style.css +45 -0
  164. package/design-system/components/Matrix/README.md +129 -0
  165. package/design-system/components/Matrix/preview.html +99 -0
  166. package/design-system/components/Matrix/style.css +84 -0
  167. package/design-system/components/Menu/README.md +117 -41
  168. package/design-system/components/Menu/preview.html +85 -23
  169. package/design-system/components/Menu/style.css +61 -0
  170. package/design-system/components/Meter/README.md +39 -4
  171. package/design-system/components/Meter/preview.html +18 -1
  172. package/design-system/components/Meter/style.css +23 -0
  173. package/design-system/components/MetricTile/README.md +237 -0
  174. package/design-system/components/MetricTile/preview.html +241 -0
  175. package/design-system/components/MetricTile/style.css +129 -0
  176. package/design-system/components/Morph/README.md +106 -0
  177. package/design-system/components/Morph/preview.html +103 -0
  178. package/design-system/components/Morph/style.css +31 -0
  179. package/design-system/components/Motion/README.md +164 -0
  180. package/design-system/components/Motion/preview.html +2537 -0
  181. package/design-system/components/NumberInput/README.md +27 -8
  182. package/design-system/components/NumberInput/preview.html +21 -5
  183. package/design-system/components/NumberInput/style.css +34 -0
  184. package/design-system/components/PaceBar/README.md +75 -0
  185. package/design-system/components/PaceBar/preview.html +67 -0
  186. package/design-system/components/PaceBar/style.css +25 -0
  187. package/design-system/components/Page/README.md +57 -18
  188. package/design-system/components/Page/preview.html +15 -17
  189. package/design-system/components/Page/style.css +7 -0
  190. package/design-system/components/PageBar/README.md +90 -34
  191. package/design-system/components/PageBar/preview.html +60 -19
  192. package/design-system/components/PageBar/style.css +35 -0
  193. package/design-system/components/PageHero/README.md +87 -51
  194. package/design-system/components/PageHero/preview.html +35 -6
  195. package/design-system/components/PageHero/style.css +31 -0
  196. package/design-system/components/Pagination/README.md +70 -49
  197. package/design-system/components/Pagination/preview.html +24 -15
  198. package/design-system/components/Pagination/style.css +12 -0
  199. package/design-system/components/Panel/README.md +109 -51
  200. package/design-system/components/Panel/preview.html +118 -20
  201. package/design-system/components/Panel/style.css +51 -0
  202. package/design-system/components/PasswordInput/README.md +50 -18
  203. package/design-system/components/PasswordInput/preview.html +71 -21
  204. package/design-system/components/PasswordInput/style.css +31 -0
  205. package/design-system/components/Plate/README.md +75 -17
  206. package/design-system/components/Plate/preview.html +40 -7
  207. package/design-system/components/Plate/style.css +37 -0
  208. package/design-system/components/Popover/README.md +70 -49
  209. package/design-system/components/Popover/preview.html +44 -22
  210. package/design-system/components/Popover/style.css +41 -0
  211. package/design-system/components/PricingTable/README.md +69 -49
  212. package/design-system/components/PricingTable/preview.html +21 -21
  213. package/design-system/components/PricingTable/style.css +21 -0
  214. package/design-system/components/ProgressPetals/README.md +31 -3
  215. package/design-system/components/ProgressPetals/preview.html +14 -15
  216. package/design-system/components/ProgressPetals/style.css +27 -0
  217. package/design-system/components/README.md +151 -0
  218. package/design-system/components/Radio/README.md +40 -17
  219. package/design-system/components/Radio/preview.html +16 -1
  220. package/design-system/components/Radio/style.css +21 -0
  221. package/design-system/components/RankBar/README.md +29 -2
  222. package/design-system/components/RankBar/preview.html +14 -12
  223. package/design-system/components/RankBar/style.css +18 -0
  224. package/design-system/components/Ring/README.md +61 -11
  225. package/design-system/components/Ring/preview.html +55 -10
  226. package/design-system/components/Ring/style.css +49 -0
  227. package/design-system/components/ScoreHero/README.md +91 -0
  228. package/design-system/components/ScoreHero/preview.html +104 -0
  229. package/design-system/components/ScoreHero/style.css +32 -0
  230. package/design-system/components/Section/README.md +72 -33
  231. package/design-system/components/Section/preview.html +46 -16
  232. package/design-system/components/Section/style.css +18 -0
  233. package/design-system/components/Segmented/README.md +100 -55
  234. package/design-system/components/Segmented/preview.html +107 -26
  235. package/design-system/components/Segmented/style.css +94 -0
  236. package/design-system/components/SegmentedProgress/README.md +64 -0
  237. package/design-system/components/SegmentedProgress/preview.html +69 -0
  238. package/design-system/components/SegmentedProgress/style.css +11 -0
  239. package/design-system/components/Select/README.md +47 -12
  240. package/design-system/components/Select/preview.html +28 -2
  241. package/design-system/components/Select/style.css +22 -0
  242. package/design-system/components/ShareBar/README.md +69 -0
  243. package/design-system/components/ShareBar/preview.html +72 -0
  244. package/design-system/components/ShareBar/style.css +25 -0
  245. package/design-system/components/SideList/README.md +147 -0
  246. package/design-system/components/SideList/preview.html +139 -0
  247. package/design-system/components/SideList/style.css +94 -0
  248. package/design-system/components/Skeleton/README.md +53 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +17 -0
  251. package/design-system/components/Slider/README.md +95 -0
  252. package/design-system/components/Slider/preview.html +49 -0
  253. package/design-system/components/Slider/style.css +13 -0
  254. package/design-system/components/Split/README.md +112 -0
  255. package/design-system/components/Split/preview.html +105 -0
  256. package/design-system/components/Split/style.css +30 -0
  257. package/design-system/components/Starter/README.md +21 -9
  258. package/design-system/components/Starter/preview.html +5 -5
  259. package/design-system/components/Stat/README.md +64 -43
  260. package/design-system/components/Stat/preview.html +3 -3
  261. package/design-system/components/Stat/style.css +15 -0
  262. package/design-system/components/StatTiles/README.md +88 -44
  263. package/design-system/components/StatTiles/preview.html +142 -71
  264. package/design-system/components/StatTiles/style.css +64 -0
  265. package/design-system/components/StatusLine/README.md +85 -0
  266. package/design-system/components/StatusLine/preview.html +49 -0
  267. package/design-system/components/StatusLine/style.css +14 -0
  268. package/design-system/components/StatusScreen/README.md +49 -35
  269. package/design-system/components/StatusScreen/preview.html +20 -5
  270. package/design-system/components/StatusScreen/style.css +9 -0
  271. package/design-system/components/StepLine/README.md +97 -0
  272. package/design-system/components/StepLine/preview.html +108 -0
  273. package/design-system/components/StepLine/style.css +62 -0
  274. package/design-system/components/Stepper/README.md +35 -13
  275. package/design-system/components/Stepper/style.css +13 -0
  276. package/design-system/components/StreakCalendar/README.md +22 -1
  277. package/design-system/components/StreakCalendar/preview.html +10 -10
  278. package/design-system/components/StreakCalendar/style.css +12 -0
  279. package/design-system/components/SuggestionChip/README.md +87 -0
  280. package/design-system/components/SuggestionChip/preview.html +42 -0
  281. package/design-system/components/SuggestionChip/style.css +20 -0
  282. package/design-system/components/Switch/README.md +44 -24
  283. package/design-system/components/Switch/preview.html +23 -8
  284. package/design-system/components/Switch/style.css +31 -0
  285. package/design-system/components/Table/README.md +129 -58
  286. package/design-system/components/Table/preview.html +106 -72
  287. package/design-system/components/Table/style.css +104 -0
  288. package/design-system/components/Tabs/README.md +71 -46
  289. package/design-system/components/Tabs/preview.html +56 -24
  290. package/design-system/components/Tabs/style.css +44 -0
  291. package/design-system/components/Testimonial/README.md +48 -32
  292. package/design-system/components/Testimonial/preview.html +14 -14
  293. package/design-system/components/Testimonial/style.css +12 -0
  294. package/design-system/components/TextArea/README.md +27 -11
  295. package/design-system/components/TextArea/preview.html +8 -2
  296. package/design-system/components/TextArea/style.css +12 -0
  297. package/design-system/components/ThemeSwitch/README.md +116 -0
  298. package/design-system/components/ThemeSwitch/preview.html +57 -0
  299. package/design-system/components/ThemeSwitch/style.css +6 -0
  300. package/design-system/components/TickRow/README.md +52 -36
  301. package/design-system/components/TickRow/preview.html +64 -41
  302. package/design-system/components/TickRow/style.css +23 -0
  303. package/design-system/components/TickStrip/README.md +95 -0
  304. package/design-system/components/TickStrip/preview.html +88 -0
  305. package/design-system/components/TickStrip/style.css +42 -0
  306. package/design-system/components/Tile/README.md +79 -18
  307. package/design-system/components/Tile/preview.html +91 -40
  308. package/design-system/components/Tile/style.css +36 -0
  309. package/design-system/components/Timeline/README.md +68 -48
  310. package/design-system/components/Timeline/preview.html +27 -15
  311. package/design-system/components/Timeline/style.css +25 -0
  312. package/design-system/components/Toast/README.md +70 -38
  313. package/design-system/components/Toast/preview.html +43 -8
  314. package/design-system/components/Toast/style.css +25 -0
  315. package/design-system/components/Tooltip/README.md +93 -35
  316. package/design-system/components/Tooltip/preview.html +69 -15
  317. package/design-system/components/Tooltip/style.css +78 -0
  318. package/design-system/components/TopBar/README.md +67 -53
  319. package/design-system/components/TopBar/preview.html +14 -27
  320. package/design-system/components/TopBar/style.css +35 -0
  321. package/design-system/components/TopicRail/README.md +108 -0
  322. package/design-system/components/TopicRail/preview.html +58 -0
  323. package/design-system/components/TopicRail/style.css +48 -0
  324. package/design-system/components/TrendBars/README.md +52 -14
  325. package/design-system/components/TrendBars/preview.html +65 -32
  326. package/design-system/components/TrendBars/style.css +25 -0
  327. package/design-system/components/TrendLine/README.md +164 -0
  328. package/design-system/components/TrendLine/preview.html +373 -0
  329. package/design-system/components/TrendLine/style.css +155 -0
  330. package/design-system/components/Well/README.md +64 -22
  331. package/design-system/components/Well/preview.html +14 -14
  332. package/design-system/components/Well/style.css +22 -0
  333. package/design-system/components/_house.css +324 -0
  334. package/design-system/components/bundle.css +4086 -744
  335. package/design-system/tokens.json +1310 -124
  336. package/dist/fello-core.css +2 -2
  337. package/dist/fello.css +6 -1369
  338. package/dist/fello.scoped.css +7 -0
  339. package/dist/index.d.ts +109 -10
  340. package/dist/index.js +781 -96
  341. package/dist/palettes.d.ts +464 -0
  342. package/dist/palettes.js +497 -0
  343. package/dist/scoped.d.ts +3 -0
  344. package/dist/scoped.js +16 -0
  345. package/dist/toast.d.ts +14 -0
  346. package/dist/toast.js +33 -29
  347. package/dist/tokens.d.ts +1686 -62
  348. package/dist/tokens.js +1668 -61
  349. package/package.json +20 -4
  350. package/scripts/check-palette.mjs +295 -0
  351. package/scripts/token-model.mjs +552 -0
  352. package/tokens/_dark.css +173 -0
  353. package/tokens/_palettes.css +46 -0
  354. package/tokens/_product.css +266 -53
  355. package/tokens/_source.hubl.css +39 -19
  356. package/tokens/design-tokens.json +319 -0
  357. package/tokens/palettes.ts +504 -0
  358. package/tokens/shadcn-compat.css +19 -19
  359. package/tokens/shadcn-compat.hsl.css +76 -0
  360. package/tokens/tokens.css +1287 -62
  361. package/tokens/tokens.md +587 -61
  362. package/tokens/tokens.root.css +1293 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -1,81 +1,93 @@
1
- A thin trail of links above a deep page, saying how it was reached and letting a person step back up it.
1
+ A thin trail of links above a deep page, saying how it was reached and letting a person step back up it. Seth's North
2
+ crumbs: the trail is the bar's name for the page.
2
3
 
3
4
  ## Use it when
4
5
 
5
- - A page sits several levels under its section (a listing under a pipeline under a sales app) and the person benefits from
6
- a way back up, not just "Back".
7
- - `AppShell` is in use and a page is more than two levels under one of its nav rows.
8
- - A detail view wants to confirm what it is a detail of without repeating a full header.
6
+ - A page sits a few levels under its section (a showing under a lead under the pipeline) and a way back up helps.
7
+ - `AppShell`'s bar names the page: the crumbs sit at the bar's left, on the content's 32 px edge.
8
+ - A detail page wants to say what it is the detail of without a second header.
9
9
 
10
10
  ## Not for
11
11
 
12
- - A shallow product (`AppShell`'s own nav already shows where you are): a page one level under its section needs no trail,
13
- just the nav row lit and the page's own title.
14
- - Moving sideways between views of the same thing: use `Tabs` or `Segmented`.
15
- - The current page's own title: the breadcrumb's last item names it but is not a replacement for the page's `ws-title`.
12
+ - A page one level under its nav row: the row is lit and the bar names the page.
13
+ - Moving sideways between views of the same thing: `Tabs` or `Segmented`.
16
14
 
17
15
  ## Anatomy
18
16
 
19
- - Type: 13 px (`--ws-text-meta`), one line, no wrapping.
20
- - A link: `--color-text-interactive` (mid blue), no underline at rest, underlined on hover.
21
- - A chevron: 12 px, `--color-text-muted`, between every pair of items.
22
- - The current item: `--color-text-heading` (navy), medium weight, not a link, marked `aria-current="page"`.
23
- - Truncation: past four levels, the levels between the first and the last two collapse into one ellipsis item; each
24
- individual label beyond about 24 characters truncates with an ellipsis and keeps its full words in the native `title`
25
- attribute.
17
+ - Type: 14 / 20 (`--ws-text-body`, Seth's 14 px crumbs), one line, never wrapping.
18
+ - A link: the body grey (`--color-text-body`), no underline; its hover box is 28 tall (4 above and below, 6 at the
19
+ sides) and bleeds 6 past its words, so the words stay on the column's edge (Seth's rule A3).
20
+ - Between items: a "/" in muted (`__sep`, `aria-hidden`), 8 from each side. The 0.4 chevron (`__chevron`, 12 px) still
21
+ draws.
22
+ - The current page (`__current`): navy, medium, not a link, `aria-current="page"`.
23
+ - The folded middle (`__ellipsis`): a 24 px act that opens the hidden levels in a `Menu`; its box bleeds 7 past the
24
+ "..." on each side, so the trail keeps its 8 px gaps.
25
+ - Giving way: the root crumb never shrinks, the middle ones truncate, the current page gives way first (three times as
26
+ fast); each name that can truncate carries its full words in `title`. A crumb is at most 160 wide.
26
27
 
27
28
  ## Variants and sizes
28
29
 
29
30
  | Variant | When |
30
31
  | --- | --- |
31
32
  | Full trail | Four levels or fewer |
32
- | Collapsed | Over four levels: first item, an ellipsis item (a button that reveals the hidden levels, or itself a menu), the remaining levels up to the current one |
33
+ | Collapsed | Over four: the root, the ellipsis act, then the last levels up to the current page |
34
+ | Phone | The parent and the current page, the ellipsis standing in for the rest above |
33
35
 
34
36
  ## States
35
37
 
36
- - **Default**: as above.
37
- - **Hover** (a link): underline.
38
- - **Focus**: the kit's `--shadow-focus-ring` on the focused link or the ellipsis button.
39
- - **Current**: navy, not a link, `aria-current="page"`.
40
- - **Long label**: truncates with an ellipsis, full words in `title`; never wraps to a second line.
41
- - **Narrow (phone)**: shows only the immediate parent and the current item, with the ellipsis standing in for everything
42
- above it, so the trail never runs off the screen's edge.
38
+ - **Hover** (pointers that hover): Seth's navy wash (`--ws-hover-strong`, 6%) on the link's 4 px corners, its words navy.
39
+ - **Focus**: the house's 2 px navy ring drawn inside the link's 28 px hover box (and the ellipsis's), so it never
40
+ runs over the "/" beside it.
41
+ - **Current**: navy, never responds to the pointer.
42
+ - **Long name**: truncates with an ellipsis, its full words in `title`.
43
+ - **Touch**: every link is 28 tall and the ellipsis 24 by 24, so words that act clear the 24 px floor.
43
44
 
44
45
  ## Behaviour
45
46
 
46
- - Keyboard: links are real `<a>`s in Tab order; the ellipsis, if interactive, is a real `<button>` that opens a small
47
- `Menu` of the hidden levels.
48
- - Pointer: hover underlines a link; the current item never responds to the pointer.
49
- - Touch: a link's tap target expands to the 24 px floor for words that act, same as `Button`'s `link` variant.
50
- - Motion: none; it is a static trail, not an animated piece.
47
+ - Keyboard: links are real `<a>`s; the ellipsis is a real `<button>` that opens a `Menu` of the hidden levels.
48
+ - Motion: the hover wash eases in over 200 ms.
51
49
 
52
50
  ## Content
53
51
 
54
- - Each level's words are the thing's own name or the section's name, sentence case, no trailing punctuation.
55
- - No em dashes; levels are separated by the chevron mark only, never a slash or a dash in the text.
56
- - The current item repeats the page's title exactly, once, so searching the page for its name still finds it in one
57
- place in spirit even though the breadcrumb and the title are necessarily two places on the screen for navigation's sake.
52
+ - Each level is the thing's own name or the section's, sentence case, no punctuation of its own.
53
+ - The current item repeats the page's name exactly.
54
+ - No em dashes.
58
55
 
59
56
  ## Props
60
57
 
61
58
  | Name | Type | Meaning |
62
59
  | --- | --- | --- |
63
- | `items` | `{ label, href }[]` | Every level from the root to the parent of the current page |
64
- | `current` | `string` | The current page's own label, rendered last and unlinked |
65
- | `collapseAfter` | `number` | How many levels show before collapsing the middle into an ellipsis, default 4 |
60
+ | `items` | `{ label, href }[]` | Every level from the root to the current page's parent |
61
+ | `current` | `string` | The current page's name, last and unlinked |
62
+ | `collapseAfter` | `number` | Levels shown before the middle folds, default 4 |
66
63
 
67
64
  ## Rules
68
65
 
69
- - **Links are mid blue, the current item is navy**: the same pairing as every other link-versus-heading distinction in
70
- the system (`color-text-interactive` for "goes somewhere", `color-text-heading` for "where you are"), never a third
71
- colour invented for this piece.
72
- - **13 px meta size**, the same size used for a header's second word and a band's "how" line, so a breadcrumb never
73
- competes with the 22 px card title or the 26 px page headline above it.
74
- - **A number never truncates; a name does**, matching the system's general truncation rule (`04-type.md`).
66
+ - **The current page is navy, the rest the body grey**: Seth's crumbs, links in words not colour.
67
+ - **One line**: a crumb truncates, the trail never wraps or scrolls.
68
+ - **A number never truncates; a name does** (`04-type.md`).
75
69
 
76
70
  ## Source
77
71
 
78
- **Derived from**: `--ws-text-meta` (13 px, the same size as a card header's second word and the band's "how" line),
79
- `color-text-interactive` for links, and the truncation and long-label rules in `04-type.md`. **Precedent**: an
80
- intentional addition decided from the system, 26 Oct 2026 (the first product built on the system reaches its pages
81
- through a chat and a page flyout, not a trail).
72
+ **Derived from**: Seth's North crumbs (`style1.css` 791 to 796: 14 / 17 `#545454`, gap 8, "/" separators, the current
73
+ page navy 500, hover boxes `4 6` bled `-6`, a navy wash) and the geometry check (4 Nov 2026: the root "Leads" truncated
74
+ first, to "Le...", and the ellipsis was 13 wide on touch). **Precedent**: an intentional addition decided from the
75
+ system, 26 Oct 2026.
76
+
77
+ ## Markup
78
+
79
+ ```html
80
+ <nav class="ws-breadcrumb" aria-label="Breadcrumb">
81
+ <a href="/leads">Leads</a>
82
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
83
+ <a href="/leads/pipeline">Pipeline</a>
84
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
85
+ <span class="ws-breadcrumb__current" aria-current="page">Priya Nair</span>
86
+ </nav>
87
+ ```
88
+
89
+ ## Styles
90
+
91
+ `Breadcrumb/style.css`. Tokens: `--ws-text-body`, `--ws-leading-row`, `--space-xs`, `--space-xxs`,
92
+ `--space-xxs-plus`, `--ws-line`, `--space-lg`, `--space-8xl`, `--ws-radius-control`, `--ws-hover-strong`, `--ws-focus-width`, `--ws-icon-sm`,
93
+ `--color-text-body`, `--color-text-heading`, `--color-text-muted`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Navigation" height=200 -->
1
+ <!-- @dsCard group="Navigation" height=252 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -8,39 +8,39 @@
8
8
  <link rel="stylesheet" href="../bundle.css">
9
9
  </head>
10
10
  <body>
11
- <div class="ws-stage ws-stage--grey ws-stage--column" style="align-items: flex-start; gap: var(--ws-gap-component);">
11
+ <div class="ws-stage ws-stage--column">
12
12
 
13
- <div class="ws-stack" style="max-width: 420px;">
14
- <span class="ws-muted">3 levels</span>
13
+ <div class="ws-stack">
14
+ <span class="ws-muted">Three levels: the links in the body grey, a muted slash between, the current page navy</span>
15
15
  <nav class="ws-breadcrumb" aria-label="Breadcrumb">
16
16
  <a href="#" onclick="return false;">Leads</a>
17
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
17
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
18
18
  <a href="#" onclick="return false;">Pipeline</a>
19
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
19
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
20
20
  <span class="ws-breadcrumb__current" aria-current="page">Priya Nair</span>
21
21
  </nav>
22
22
  </div>
23
23
 
24
- <div class="ws-stack" style="max-width: 420px;">
25
- <span class="ws-muted">6 levels, collapsed: the middle folds into an ellipsis item</span>
24
+ <div class="ws-stack">
25
+ <span class="ws-muted">Six levels, collapsed: the middle folds into one act that opens them in a menu</span>
26
26
  <nav class="ws-breadcrumb" aria-label="Breadcrumb">
27
27
  <a href="#" onclick="return false;">Leads</a>
28
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
29
- <button type="button" class="ws-act ws-breadcrumb__ellipsis" aria-label="Show the hidden levels" title="Pipeline, North region, Qualified">&hellip;</button>
30
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
28
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
29
+ <button type="button" class="ws-act ws-breadcrumb__ellipsis" aria-label="Show the hidden levels: Pipeline, North region, Qualified">&hellip;</button>
30
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
31
31
  <a href="#" onclick="return false;">Priya Nair</a>
32
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
32
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
33
33
  <span class="ws-breadcrumb__current" aria-current="page">Showing</span>
34
34
  </nav>
35
35
  </div>
36
36
 
37
- <div class="ws-stack" style="max-width: 420px;">
38
- <span class="ws-muted">A long name truncating with an ellipsis, the full words in the title</span>
37
+ <div class="ws-stack" style="width: 420px; max-width: 100%;">
38
+ <span class="ws-muted">Long names in a 420 px column: the root keeps its word, the current page gives way first, each full name in its title</span>
39
39
  <nav class="ws-breadcrumb" aria-label="Breadcrumb">
40
40
  <a href="#" onclick="return false;">Leads</a>
41
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
41
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
42
42
  <a href="#" title="North region, spring campaign" onclick="return false;">North region, spring campaign</a>
43
- <svg class="ws-breadcrumb__chevron" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 2.5l3 3.5-3 3.5"/></svg>
43
+ <span class="ws-breadcrumb__sep" aria-hidden="true">/</span>
44
44
  <span class="ws-breadcrumb__current" aria-current="page" title="Priya Nair, referred by Dana Alvarez last Tuesday">Priya Nair, referred by Dana Alvarez last Tuesday</span>
45
45
  </nav>
46
46
  </div>
@@ -0,0 +1,17 @@
1
+ /* ---- Breadcrumb: where a page sits, Seth's North crumbs (D1): 14 px words in the body grey, a muted "/" between, the
2
+ current page navy medium; one line. The root crumb never shrinks, the current page gives way first, every link's
3
+ hover box is 28 tall and bleeds 6 past its words so the words stay on the column's edge. ---- */
4
+ .ws-breadcrumb { display: flex; align-items: center; gap: var(--space-xs); min-width: 0; font-size: var(--ws-text-body); line-height: var(--ws-leading-row); color: var(--color-text-body); white-space: nowrap; }
5
+ .ws-breadcrumb a { flex: 0 1 auto; min-width: 0; max-width: var(--space-8xl); overflow: hidden; text-overflow: ellipsis; margin-inline: calc(var(--space-xxs-plus) * -1); padding: var(--space-xxs) var(--space-xxs-plus); border-radius: var(--ws-radius-control); color: inherit; text-decoration: none; }
6
+ .ws-breadcrumb > a:first-child { flex-shrink: 0; }
7
+ @media (hover: hover) { .ws-breadcrumb a:hover { background: var(--ws-hover-strong); color: var(--color-text-heading); } }
8
+ /* The ring goes inside the hover box: outside it would run 10 past the words, over the "/" 8 away. */
9
+ .ws-breadcrumb :is(a, .ws-breadcrumb__ellipsis):focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
10
+ .ws-breadcrumb__current { flex: 0 3 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 500; color: var(--color-text-heading); }
11
+ .ws-breadcrumb__sep { flex-shrink: 0; color: var(--color-text-muted); }
12
+ .ws-breadcrumb__chevron { flex-shrink: 0; width: var(--ws-icon-sm); height: var(--ws-icon-sm); color: var(--color-text-muted); }
13
+ /* The folded middle: a 24 px act that opens the hidden levels in a Menu; its box bleeds 7 each side so the "..." keeps
14
+ the trail's 8 px gaps (it sat 11 from each "/"). */
15
+ .ws-breadcrumb__ellipsis { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; min-width: var(--space-lg); min-height: var(--space-lg); margin-inline: calc((var(--space-xxs-plus) + var(--ws-line)) * -1); padding: 0 var(--space-xxs); border: 0; border-radius: var(--ws-radius-control); background: none; font-size: inherit; color: inherit; cursor: pointer; }
16
+ @media (hover: hover) { .ws-breadcrumb__ellipsis:hover { background: var(--ws-hover-strong); color: var(--color-text-heading); text-decoration: none; } }
17
+ @media (prefers-reduced-motion: no-preference) { .ws-breadcrumb :is(a, .ws-breadcrumb__ellipsis) { transition: background-color var(--ws-duration-hover) var(--ws-ease-soft), color var(--ws-duration-hover) var(--ws-ease-soft); } }
@@ -1,9 +1,10 @@
1
- The one control for every act on the page: a click that does something, in one of five looks, never a styled `<button>`.
1
+ The one control for every act on the page: a click that does something, in one of six looks, never a styled `<button>`.
2
2
 
3
3
  ## Use it when
4
4
 
5
- - A page, a card or a dialog needs its one act (start a call, send an offer, run an audit).
6
- - A toolbar or a row needs a secondary or quiet act (Edit criteria, Approve, Move).
5
+ - A page, a card or a pane needs its one act (start a call, send an offer, review a rewrite).
6
+ - A header or a toolbar needs an outlined act (Refresh, Settings, Edit criteria).
7
+ - A row or a pane needs a quiet grey act beside the navy one (Send to my web person).
7
8
  - A sentence needs a word that acts (a link to the board, a quiet "All your calls").
8
9
  - A form needs a submit (use `SubmitButton`, which is this component wired to the form's pending state).
9
10
  - A filter or an option needs a toggle that shows whether it is on (`selected`).
@@ -17,90 +18,147 @@ The one control for every act on the page: a click that does something, in one o
17
18
 
18
19
  ## Anatomy
19
20
 
20
- - Box: `--ws-radius-control` (4px) corners, flat, no float shadow.
21
- - Height: 28px small (`--ws-control-h-sm`), 32px medium (`--ws-control-h`), 36px large (`--ws-control-h-md`);
22
- every size expands to 40px (`--ws-touch`) on a touch screen.
23
- `link` and `text` have no box or height: they sit on the text line and expand to 24px touch.
24
- - Words: 14px medium, one line, never bold.
25
- - Sides: 12px (`--space-sm`) boxed, 8px (`--space-xs`) for `ghost`, none for `link`/`text`.
26
- - Gap to an inner icon: 8px (`--space-xs`), 4px (`--space-xxs`) at `small`.
27
- - Fill and words by variant (below).
21
+ - Box: 6 px corners (`--ws-radius-row`), flat, no float shadow, no lift on hover.
22
+ - Height: 28 small (`--ws-control-h-sm`), 32 medium (`--ws-control-h`), 40 large (`--space-2xl`); every boxed size is at
23
+ least 40 on a touch screen (`--ws-touch`). `link` and `text` have no box: their words, 24 tall on touch.
24
+ - Words: 13 / 18 medium (`--ws-text-control`, `--ws-leading-control`), Seth's control words, never bold.
25
+ - Sides: 12 (`--space-sm`) medium, 8 (`--space-xs`) small, 14 (`--space-sm-plus`) large; 4 for `link` and `text`, bled
26
+ back out of the line so the words sit where the sentence puts them.
27
+ - Icon: 16 px, 6 px from the words (`--space-xxs-plus`), 4 at small.
28
+ - One line, always (0.4.0's rule): a button never wraps and never shrinks in a row, in a table cell or a fact row (the
29
+ sentence beside it does). A label that can be wider than its whole column opts in with `ws-btn--wrap`: balanced lines,
30
+ never cut, never off a phone; a wrapped `link`, `text` or `ghost` reads from its start, like words.
31
+ - Two word acts side by side keep 16 px between their words, so one's focus ring never covers the other.
28
32
 
29
33
  ## Variants and sizes
30
34
 
31
35
  | Variant | Fill | Words | Edge | Where |
32
36
  | --- | --- | --- | --- | --- |
33
- | `primary` | `--color-text-heading` (navy), solid | white | none | the page's or the card's one act |
34
- | `secondary` | `--color-bg-page` (cream) | navy | `--ws-shadow-hairline` | a second act beside a primary, a header or row act |
35
- | `ghost` | transparent, sunk cream on hover | `--color-text-body` (grey-7), navy on hover | none | a quiet row or corner act |
36
- | `link` | transparent | `--color-text-interactive` (mid blue), underline on hover | none | a word that goes somewhere or shows more |
37
- | `text` | transparent | `--color-text-heading` (navy), underline on hover | none | a quiet word that acts in place (the card language's "All your calls") |
37
+ | `primary` | navy (`--color-text-heading`) | `--ws-on-act` | none | the page's, the card's or the pane's one act |
38
+ | `secondary` | none | navy | 0.5 px `--ws-edge-card`, drawn inside | a header or toolbar act (Seth's Refresh, Settings) |
39
+ | `well` | the tray grey (`--ws-tray`, #EDEDED) | navy | none | a quiet act in a row or a pane, beside the navy one (Seth's Send to my web person) |
40
+ | `ghost` | none until the pointer | navy | none | a corner or row act that should stay out of the way |
41
+ | `link` | none | mid blue (`--color-text-interactive`) | none | a word that goes somewhere or shows more |
42
+ | `text` | none | navy | none | a quiet word that acts in place ("All your calls") |
38
43
 
39
- Sizes: `small` (28px), `medium` (32px, the default), `large` (36px, every form submit and mobile CTA).
44
+ Sizes: `small` 28, `medium` 32 (the default), `large` 40 (a pane's acts, a form's submit, a phone's CTA).
45
+
46
+ A split pair (`ws-btn-split`): two acts in equal halves across the width, the primary last (Seth's pane foot). Where a
47
+ half would be under 160 px, or narrower than either label on its one line, they stack, the primary at the bottom, under
48
+ the thumb.
49
+
50
+ `--wrap`: a label that may be wider than its column wraps in balanced lines (a button's words never wrap otherwise).
40
51
 
41
52
  ## States
42
53
 
43
54
  - **Default:** as the table above.
44
- - **Hover:** `primary` dims to 90% opacity; `secondary` and `ghost` take the sunk cream (`--ws-surface-sunk`); `link` and
45
- `text` underline.
46
- - **Focus:** the kit's focus halo (`--shadow-focus-ring`, salmon at 20%), visible only for keyboard focus.
47
- - **Pressed:** scales to 0.97 (`--ws-press-scale`) and springs back; nothing moves with reduced motion.
48
- - **Selected:** a toggle that is on wears `primary`'s navy regardless of its own variant, and carries `aria-pressed="true"`
49
- (or `aria-current` for a `ButtonLink`).
50
- - **Pending:** its answer is on the way. The button keeps its colour (never greyed), shows the working dot
51
- (`WorkingDot`, `ws-dot ws-working`) before its words, stays focusable (`aria-disabled`, not `disabled`, so the keyboard
52
- stays on it) and refuses a second click (`aria-busy="true"`, `cursor: progress`).
53
- - **Disabled:** 40% opacity, no pointer events.
54
- - **Empty / loading:** not a state of its own; a button's words are always present (use `pending` while an action runs).
55
- - **Long label:** the button expands to fit one line; it never wraps mid-word or clips.
56
- - **Narrow:** on a phone a `large` submit becomes 48px and full width (`SubmitButton`'s own rule).
57
- - **Touch:** every boxed size expands to 40px tall; `link`/`text` to 24px, the WCAG 2.2 target-size floor for words that act.
55
+ - **Hover (a mouse only, never stuck after a tap):** `primary` goes a shade brighter (#0F4A73) with a soft light under
56
+ the pointer (North); `secondary` darkens its edge (#AAA49D), no fill; `well` darkens its grey (`--ws-well-hover`);
57
+ `ghost` takes the navy wash (`--ws-hover-strong`); `link` and `text` underline.
58
+ - **Focus:** the kit's ring, 2 px navy, 2 px out, on keyboard focus only.
59
+ - **Pressed:** gives to 0.97 (`--ws-press-scale`) and springs back, both ways on North's press spring ("Button press",
60
+ .2 s / bounce .3: `--ws-spring-press` over `--ws-spring-press-duration`, the house's press rule); the fill takes the
61
+ press tint at once. Words that act and a busy button do not move; nothing moves with reduced motion.
62
+ - **Selected:** a toggle that is on wears `primary`'s navy whatever its own look, with `aria-pressed="true"` (or
63
+ `aria-current` on a `ButtonLink`).
64
+ - **Pending:** its answer is on the way. Full colour, the same size: the working dot (`ws-dot ws-working`) sits in the
65
+ left padding so the words never move (a small button trades 4 px between its sides to fit it, keeping its width), and
66
+ in a button wider than its words (a full-width act) it stays beside the label, not at the far edge; it
67
+ stays focusable (`aria-disabled`, not `disabled`) and refuses a second press
68
+ (`aria-busy="true"`, `cursor: progress`).
69
+ - **Link pending (`LinkPending`):** a link card or `ButtonLink` whose page is on its way: a 1 px navy edge arrives after
70
+ a beat (so a quick answer shows nothing) and breathes until the page answers; it leaves at once.
71
+ - **Disabled:** 40%, no pointer.
72
+ - **Empty / loading:** not a state of its own; a button's words are always present (use `pending` while an act runs).
73
+ - **Pictured states (a preview or a mockup):** `is-hover`, `is-pressed` and `is-focus` draw the hover, the press and
74
+ the ring still, exactly as a pointer and a keyboard do.
75
+ - **Pending under the pointer:** keeps its resting look (no brighter navy, no light, no wash): it refuses the press a
76
+ hover would invite.
77
+ - **Long label:** one line; with `ws-btn--wrap`, wider than its column, it wraps in balanced lines.
78
+ - **Narrow:** the split pair stacks; a lone large button may take the width.
79
+ - **Touch:** boxed sizes at least 40; `link` and `text` 24 tall.
80
+ - **Dark:** the act is the light ink with dark words; its hover eases a step toward its words and draws no light
81
+ (derived: North has no dark values).
58
82
 
59
83
  ## Behaviour
60
84
 
61
85
  - Keyboard: a normal `<button>`; Enter or Space activates it; Tab order follows the DOM.
62
- - Pointer: hover and active states as above; a press gives 0.97 scale on `ws-ease-soft`.
63
- - Touch: 40px floor (24px for word buttons), per WCAG 2.2.
64
- - Motion: colour and opacity transition over `--ws-duration-instant` (120ms) on `--ws-ease-soft`; the press scale is the
65
- only transform, and it is skipped entirely under `prefers-reduced-motion: reduce`.
86
+ - Pointer: the light follows the pointer when the page sets `--mx` and `--my` on the button (pointermove, in px from its
87
+ corner); without them it sits in the middle.
88
+ - Motion: colours over `--ws-duration-hover` (200 ms) on `--ws-ease-soft`; the press on the press spring (`scale`, 450 ms
89
+ to settle, a little give past 0.97 and past 1 on the way back). In React a press may use `springs.press`. All still
90
+ under reduced motion.
66
91
 
67
92
  ## Content
68
93
 
69
- - Sentence case, an imperative verb where it can ("Start the call", "Send the offer"), never a question.
94
+ - Sentence case, an imperative verb where it can ("Start the call", "Review Grow's rewrite"), never a question.
70
95
  - No em dashes.
71
- - One primary button per card and per page; everything else is secondary, ghost or words.
72
- - A pending button's words may change to say what is happening ("Saving…"); keep it short enough for one line.
96
+ - One primary button per card and per page; everything else is secondary, well, ghost or words.
97
+ - A pending button's words may say what is happening ("Saving"); short enough for one line.
73
98
 
74
99
  ## Props
75
100
 
76
101
  | Name | Type | Meaning |
77
102
  | --- | --- | --- |
78
- | `variant` | `'primary' \| 'secondary' \| 'ghost' \| 'link' \| 'text'` | the look, default `primary` |
103
+ | `variant` | `'primary' \| 'secondary' \| 'well' \| 'ghost' \| 'link' \| 'text'` | the look, default `primary` |
79
104
  | `size` | `'small' \| 'medium' \| 'large'` | the height, default `medium` |
80
105
  | `selected` | `boolean` | a toggle that is on: wears `primary`'s navy, sets `aria-pressed` unless the button has its own role |
81
- | `pending` | `boolean` | its answer is on the way: the working dot, `aria-busy`, refuses a click |
82
- | `pendingLabel` (`SubmitButton` only) | `string` | the words shown while the form submits, default "Saving…" |
106
+ | `pending` | `boolean` | its answer is on the way: the working dot, `aria-busy`, refuses a press |
107
+ | `pendingLabel` (`SubmitButton` only) | `string` | the words shown while the form submits, default "Saving" |
83
108
  | ...rest | native `<button>` props | passed through (`onClick`, `type`, `disabled`, `aria-*`) |
84
109
 
85
- `ButtonLink` takes the same `variant`/`size`/`selected` over `next/link`'s props, and shows the pending dot itself (via
110
+ `ButtonLink` takes the same `variant`/`size`/`selected` over `next/link`'s props, and shows `LinkPending` (via
86
111
  `useLinkStatus`) until its page answers.
87
112
 
88
113
  ## Rules
89
114
 
90
115
  - Every button is `Button` or `ButtonLink` (`SubmitButton` in a form), never a styled `<button>` (24 Oct 2026, "One way to
91
- use buttons", measured on every page, one app's own use as the rule).
92
- - One navy (`primary`) button per card, and one for the page; everything else is secondary, ghost or words.
93
- - A page's one act, a card's or a dialog's footer-band act, and a form's submit are `primary`, `large` (36px); a second
94
- choice beside it is `secondary`, `large`.
95
- - A page's header actions are `secondary`, `small` beside a title, `medium` in a toolbar row of 32px fields.
96
- - A card's corner act is `secondary`, `medium` (unless the card's one act is the primary).
97
- - A row's acts (Done, Approve, Move) are `secondary` or `ghost`, `small`.
98
- - Words that act in a sentence are `link` (mid blue, goes somewhere or shows more) or `text` (navy, a quiet act in place).
99
- - Every form submit and mobile CTA is `size="large"` (house rule).
100
- - Drawn over the kit's tertiary variant so none of the kit's salmon or marketing ledge shows (16 Oct 2026).
116
+ use buttons").
117
+ - One navy (`primary`) button per card, and one for the page; everything else is secondary, well, ghost or words.
118
+ - A pane's or a dialog's acts are `large` (40): the second choice `well`, the primary last (`ws-btn-split` when they
119
+ share the width).
120
+ - A page's or a thread's header acts are `secondary`, `medium`, with an icon where one helps (Seth's Refresh, Settings).
121
+ - A row's act is `well`, `medium`; it turns `primary` while its row is open (Seth's fix row).
122
+ - Words that act in a sentence are `link` (mid blue, goes somewhere) or `text` (navy, acts in place).
123
+ - Hover is a colour change, never a lift or a shadow (North: "no lift, no shadow, just a shade brighter and the light
124
+ under the cursor").
101
125
 
102
126
  ## Source
103
127
 
104
- **Derived from**: the kit's tertiary button variant, redrawn so none of its salmon or marketing ledge shows, and the
105
- "One way to use buttons" rule (24 Oct 2026): every act is `Button`, `ButtonLink` or `SubmitButton`, never a styled
106
- `<button>`. **Precedent**: the first product built on the system.
128
+ **Derived from**: Seth's Fia frames (Grow audit 301:1644, 301:2100; Fixes 308:2514; Review inbox 313:2957): 6 px corners,
129
+ 13 / 18 words, 6 px icon gap, 40 px pane acts with 14 px sides, the #EDEDED secondary, the split pair. Seth's North
130
+ (style1.css:1429-1456): the brighter navy and the light under the cursor, the darker edge on hover. The field's fixes
131
+ (Ignite, Fia feel audit T01, T05, K09): the pending dot in the padding, ghost on its size's padding. Word acts are 24 tall on touch only: on a mouse
132
+ they pass WCAG 2.5.8 by spacing, and a 24 px box round a 20 px line put every head that aligns to box edges 2 px off.
133
+ North's 34 px height is not taken: the Fia frames' 32 / 40 sit on the control ladder.
134
+
135
+ ## Markup
136
+
137
+ ```html
138
+ <button type="button" class="ws-btn ws-btn--primary">Start the call</button>
139
+ <button type="button" class="ws-btn ws-btn--secondary">
140
+ <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>
141
+ Refresh
142
+ </button>
143
+ <button type="button" class="ws-btn ws-btn--well">Send to my web person</button>
144
+ <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>
145
+ <!-- a label that may be wider than its column -->
146
+ <button type="button" class="ws-btn ws-btn--link ws-btn--wrap">Resend the quote before it expires on Nov 2</button>
147
+
148
+ <div class="ws-btn-split">
149
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--well">Send to my web person</button>
150
+ <button type="button" class="ws-btn ws-btn--lg ws-btn--primary">Review Grow's rewrite</button>
151
+ </div>
152
+
153
+ <a href="/leads/priya" class="ws-card ws-card--inset" aria-busy="true" style="position: relative; display: block;">
154
+ Priya Nair <span class="ws-link-pending" aria-hidden="true"></span>
155
+ </a>
156
+ ```
157
+
158
+ ## Styles
159
+
160
+ `design-system/components/Button/style.css` (in `bundle.css` and `fello.css`): `ws-btn` with `--sm`, `--lg`, `--primary`,
161
+ `--secondary`, `--well`, `--ghost`, `--link`, `--text`, `--wrap`, and the pictured states `is-hover`, `is-pressed`,
162
+ `is-focus`; `ws-btn-split`; `ws-link-pending`. It also scopes the shared hover values `--ws-edge-hover`,
163
+ `--ws-act-hover` and `--ws-act-light` for every outlined or navy control (the switch's track too). Touch sizes come from
164
+ the house's touch block; the working dot is the house's `ws-dot`.