@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,6 +1,6 @@
1
- <!-- @dsCard group="Marketing" height=480 -->
1
+ <!-- @dsCard group="Marketing" height=740 -->
2
2
  <!doctype html>
3
- <html>
3
+ <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
6
6
  <title>KitButton</title>
@@ -21,8 +21,19 @@
21
21
  </div>
22
22
  </div>
23
23
 
24
+ <div class="ws-stack" inert>
25
+ <span class="ws-muted">Hover (a picture of the state): a colour change; primary and navy brighten, navy also deepens its shadow, clean underlines</span>
26
+ <div class="ws-cluster ws-cluster--component">
27
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-hover">Book a demo</button>
28
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary is-hover">Talk to sales</button>
29
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--navy is-hover">Start free trial</button>
30
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--tertiary is-hover">Watch the tour</button>
31
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--clean is-hover">See pricing</button>
32
+ </div>
33
+ </div>
34
+
24
35
  <div class="ws-stack">
25
- <span class="ws-muted">Medium (36px) and small (28px)</span>
36
+ <span class="ws-muted">Medium (36px) and small (28px); on touch each takes a 44px hit area</span>
26
37
  <div class="ws-cluster ws-cluster--component">
27
38
  <button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary">Book a demo</button>
28
39
  <button class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary">Talk to sales</button>
@@ -32,7 +43,7 @@
32
43
  </div>
33
44
 
34
45
  <div class="ws-stack">
35
- <span class="ws-muted">Leading and trailing icons, and with shadow</span>
46
+ <span class="ws-muted">Leading and trailing icons (16px, 12px at small), and with shadow</span>
36
47
  <div class="ws-cluster ws-cluster--component">
37
48
  <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary">
38
49
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 1.5a2 2 0 0 0-2 2v4a2 2 0 0 0 4 0v-4a2 2 0 0 0-2-2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M4.5 7.5a3.5 3.5 0 0 0 7 0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 11v2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
@@ -42,27 +53,38 @@
42
53
  Read the case study
43
54
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11 11 5M5.5 5h5.5v5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
44
55
  </button>
45
- <button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary ws-kit-button--shadow">With shadow (shadow prop)</button>
56
+ <button class="ws-kit-button ws-kit-button--small ws-kit-button--secondary">
57
+ Download the guide
58
+ <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 2.5v8M4.5 7 8 10.5 11.5 7M3 13.5h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
59
+ </button>
60
+ <button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary ws-kit-button--shadow">With shadow</button>
46
61
  </div>
47
62
  </div>
48
63
 
49
- <div class="ws-stack">
50
- <span class="ws-muted">Pressed: the 3px lift collapses (primary and navy only)</span>
64
+ <div class="ws-stack" inert>
65
+ <span class="ws-muted">Pressed: the 3px lift collapses (primary and navy only); focus: the 2px navy ring, 2px out</span>
51
66
  <div class="ws-cluster ws-cluster--component">
52
67
  <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-pressed">Book a demo</button>
53
68
  <button class="ws-kit-button ws-kit-button--large ws-kit-button--navy is-pressed">Start free trial</button>
69
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-focus">Book a demo</button>
70
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary is-focus">Talk to sales</button>
54
71
  </div>
55
72
  </div>
56
73
 
57
74
  <div class="ws-stack">
58
- <span class="ws-muted">Disabled, full width, and a long label</span>
59
- <div class="ws-cluster ws-cluster--component ws-cluster--start">
75
+ <span class="ws-muted">Disabled, and a link that looks like the act</span>
76
+ <div class="ws-cluster ws-cluster--component">
60
77
  <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary" disabled>Book a demo</button>
61
78
  <button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary" disabled>Talk to sales</button>
62
- <div style="width: 280px;">
63
- <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary ws-kit-button--full">Book your onboarding call</button>
64
- </div>
65
- <button class="ws-kit-button ws-kit-button--large ws-kit-button--navy">Start the free trial your whole team can run on</button>
79
+ <a class="ws-kit-button ws-kit-button--large ws-kit-button--primary" href="#" onclick="return false;">Book a demo</a>
80
+ </div>
81
+ </div>
82
+
83
+ <div class="ws-stack">
84
+ <span class="ws-muted">Full width (the phone's act), and a label too long for its column: it wraps to two balanced lines</span>
85
+ <div class="ws-stack ws-stack--component" style="width: 320px; max-width: 100%;">
86
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--primary ws-kit-button--full">Book your onboarding call</button>
87
+ <button class="ws-kit-button ws-kit-button--large ws-kit-button--navy ws-kit-button--full">Start the free trial your whole team can run on from day one</button>
66
88
  </div>
67
89
  </div>
68
90
 
@@ -0,0 +1,46 @@
1
+ /* ---- KitButton: the kit's marketing button, the salmon gradient with its lift ---- */
2
+ /* The sizes are floors, not fixed heights: a label too long for its column wraps to a second, balanced line instead of
3
+ running out of the button. Focus is the house ring (2 px navy, 2 px out); nothing here turns it off. */
4
+ .ws-kit-button { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs); max-width: 100%; font-family: var(--font-body); font-weight: 600; text-align: center; text-wrap: balance; text-decoration: none; cursor: pointer; appearance: none; border: 0; }
5
+ @media (prefers-reduced-motion: no-preference) {
6
+ .ws-kit-button { transition: filter var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast), color var(--transition-fast), transform var(--transition-fast); }
7
+ }
8
+ .ws-kit-button:disabled, .ws-kit-button[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
9
+ .ws-kit-button.is-focus { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
10
+ .ws-kit-button svg { width: var(--ws-icon); height: var(--ws-icon); flex-shrink: 0; }
11
+ /* Sizes: large 45, medium 36, small 28 (the kit's own dimensions table). */
12
+ .ws-kit-button--large { min-height: calc(var(--space-2xl) + var(--space-xxs) + var(--ws-line)); min-width: calc(var(--space-5xl) + var(--space-md) + var(--space-xxs)); padding: var(--space-xs) calc(var(--space-md) + var(--space-xxs)); font-size: var(--font-size-md); line-height: calc(var(--space-md) + var(--space-xxs)); border-radius: var(--ws-radius-card); }
13
+ .ws-kit-button--medium { min-height: calc(var(--space-xl) + var(--space-xxs)); min-width: var(--space-5xl); padding: var(--space-xxs-plus) var(--space-md); font-size: var(--font-size-sm); line-height: var(--ws-leading-control); border-radius: var(--ws-radius-card); }
14
+ .ws-kit-button--small { min-height: calc(var(--space-lg) + var(--space-xxs)); min-width: calc(var(--space-3xl) + var(--space-sm)); padding: var(--space-xxs) var(--space-sm); font-size: var(--font-size-2xs); line-height: var(--space-md); font-weight: 500; border-radius: var(--ws-radius-row); }
15
+ .ws-kit-button--small svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
16
+ /* Primary: the salmon gradient and the 3 px lift. Not decoration: pressing collapses it. Its words are white, as
17
+ fello.ai draws them (Amit, 4 Nov 2026: "it should be white on salmon"). White on the gradient is 2.44 to 2.65:1, so
18
+ this is the kit's one logged exception to D2: the act is large, semibold and a few words long. Literal in every theme. */
19
+ .ws-kit-button--primary { background-image: var(--gradient-btn-primary); color: var(--color-white); border-bottom: calc(var(--space-xxs) * 0.75) solid var(--color-button-border); }
20
+ .ws-kit-button--secondary { background: var(--color-bg-page); color: var(--color-text-interactive); border: var(--ws-line) solid var(--color-border-hairline); }
21
+ .ws-kit-button--navy { background-image: linear-gradient(180deg, var(--color-brand-mid-blue), color-mix(in srgb, var(--color-brand-navy) 35%, var(--color-brand-mid-blue))); color: var(--color-white); border-bottom: calc(var(--space-xxs) * 0.75) solid var(--color-brand-navy); box-shadow: var(--shadow-btn); }
22
+ .ws-kit-button--tertiary { background: transparent; color: var(--color-text-heading); border: var(--ws-line) solid var(--color-text-heading); }
23
+ .ws-kit-button--clean { background: transparent; color: var(--color-text-heading); min-width: 0; padding-inline: 0; }
24
+ .ws-kit-button--shadow { box-shadow: var(--shadow-btn); }
25
+ .ws-kit-button--full { width: 100%; }
26
+ /* Hover is a colour change (D7): the two fills brighten 4%, which also shows on a dark ground where a shadow cannot;
27
+ a button that already casts a shadow deepens it as well. Only where the pointer really hovers: a phone keeps :hover
28
+ after a tap, so ungated it stuck on the tapped button. .is-hover draws the state in a static preview on any device. */
29
+ .ws-kit-button--primary.is-hover, .ws-kit-button--navy.is-hover { filter: brightness(1.04); }
30
+ .ws-kit-button--secondary.is-hover { background: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)), var(--color-bg-page); }
31
+ .ws-kit-button--navy.is-hover, .ws-kit-button--shadow.is-hover { box-shadow: var(--shadow-btn-hover); }
32
+ .ws-kit-button--tertiary.is-hover { background: var(--color-text-heading); color: var(--ws-on-act); }
33
+ .ws-kit-button--clean.is-hover { text-decoration: underline; }
34
+ @media (hover: hover) {
35
+ .ws-kit-button--primary:hover, .ws-kit-button--navy:hover { filter: brightness(1.04); }
36
+ .ws-kit-button--secondary:hover { background: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)), var(--color-bg-page); }
37
+ .ws-kit-button--navy:hover, .ws-kit-button--shadow:hover { box-shadow: var(--shadow-btn-hover); }
38
+ .ws-kit-button--tertiary:hover { background: var(--color-text-heading); color: var(--ws-on-act); }
39
+ .ws-kit-button--clean:hover { text-decoration: underline; }
40
+ }
41
+ .ws-kit-button--primary:active, .ws-kit-button--primary.is-pressed, .ws-kit-button--navy:active, .ws-kit-button--navy.is-pressed { transform: translateY(calc(var(--space-xxs) / 2)); border-bottom-color: transparent; }
42
+ .ws-kit-button--navy:active, .ws-kit-button--navy.is-pressed, .ws-kit-button--shadow:active { box-shadow: none; }
43
+ /* Touch: every act on a public page is a 44 px target. Medium and small keep their look and take the rest as a hit area. */
44
+ @media (pointer: coarse) {
45
+ .ws-kit-button--medium::after, .ws-kit-button--small::after { content: ""; position: absolute; inset: min(0px, calc((100% - var(--ws-touch-public)) / 2)) 0; }
46
+ }
@@ -6,95 +6,126 @@ The kit's one bounded surface: white, a 4px ceiling on its corners, flat unless
6
6
 
7
7
  - A feature section, a pricing plan or a testimonial on a public page needs a bounded surface.
8
8
  - The whole block should read as one unit with a header, a body and a footer act (`CardHeader`/`CardContent`/`CardFooter`).
9
- - A card should visibly react to the pointer because the whole thing is a link or a button: pass `interactive`.
9
+ - A card should visibly react to the pointer because the whole thing is a link: pass `interactive` and make it an `<a>`.
10
10
  - A block should recede slightly from the page: `surface="tinted"`, or disappear into it: `surface="transparent"`.
11
11
 
12
12
  ## Not for
13
13
 
14
14
  - Any product screen inside a product built on this system: use the product's own card (`ws-card`), which is
15
- cream, 8px, and never raises a shadow at all, including on hover.
15
+ cream, 8px, rimmed, and never raises a shadow at all, including on hover.
16
16
  - A list row with its own hover state: a row, not a card.
17
17
  - A floating surface over the page: a dialog or a popover, not this.
18
18
 
19
19
  ## Anatomy
20
20
 
21
- - The card: `--radius-sm` (4px) corners, 1px border. White surface borders in `--color-border-default` (the
22
- gray-stroke hairline); so does tinted. Transparent borders in the lighter `--color-border-hairline`.
23
- - `CardHeader`: `--space-lg` (24px) padding on every side, its title and description stacked `--space-xs` (8px) apart.
24
- - `CardTitle`: `--font-size-2xl` (26px), medium weight, 32px line height, `--color-text-heading` (navy).
25
- - `CardDescription`: `--font-size-sm` (14px), 20px line height, `--color-text-muted`.
26
- - `CardContent`: `--space-lg` padding, no top padding (it sits under the header).
27
- - `CardFooter`: `--space-lg` padding, no top padding, its children `--space-sm` (12px) apart in a row.
28
- - No shadow at rest, on any surface. `interactive` adds `--shadow-card-default` on hover only.
21
+ - The card: `--ws-radius-control` (4px) corners, 1px border. White and tinted border in `--color-border-default`;
22
+ transparent in the lighter `--color-border-hairline`. No width of its own; it fills the column it is given.
23
+ - `CardHeader` (`__header`): `--space-lg` (24px) padding on every side, title and description `--space-xs` (8px) apart.
24
+ - `CardTitle` (`__title`): `--font-size-2xl` (26px), medium, 32px line height, `--color-text-heading`. A word wider
25
+ than the card breaks (hyphenated where the page sets `lang`) instead of running out of it.
26
+ - `CardDescription` (`__desc`): `--font-size-sm` (14px), 20px line height, `--color-text-muted`.
27
+ - `CardContent` (`__content`): `--space-lg` padding, no top padding (it sits under the header).
28
+ - `CardFooter` (`__footer`): `--space-lg` padding, no top padding, its acts `--space-sm` (12px) apart, wrapping.
29
+ - No shadow, at rest or on hover, on any surface. `interactive` tints the card on hover: the `--color-nav-hover-bg`
30
+ wash laid over its own surface.
29
31
 
30
32
  ## Variants and sizes
31
33
 
32
34
  | Surface | Fill | Border | Use |
33
35
  | --- | --- | --- | --- |
34
- | `white` (default) | `--color-white` | `--color-border-default` | the default surface for a feature, plan or quote |
35
- | `tinted` | `--color-gray-1` | `--color-border-default` | a block that should recede a little |
36
+ | `white` (default) | `--color-surface` (white; follows the theme) | `--color-border-default` | the default surface for a feature, plan or quote |
37
+ | `tinted` | `--ws-surface-sunk` | `--color-border-default` | a block that should recede a little |
36
38
  | `transparent` | none | `--color-border-hairline` | a block that should all but disappear into the page |
37
39
 
38
- `interactive` is a boolean, not a surface: it layers the hover shadow onto any of the three.
40
+ `interactive` is a boolean, not a surface: it layers the hover tint onto any of the three.
41
+
42
+ Classes: white is the bare `ws-kit-card`; `ws-kit-card--tinted` and `ws-kit-card--transparent` are the other two
43
+ surfaces; `ws-kit-card--interactive` goes on the `<a>` that is the card.
39
44
 
40
45
  ## States
41
46
 
42
47
  - **Default:** flat, the 1px border, no shadow, on every surface.
43
- - **Hover** (`interactive` only): `--shadow-card-default` appears. The kit's own doc comment says `interactive`
44
- "adds the lift on hover for cards that are actually clickable"; its code reaches for `--shadow-card-default` on
45
- that hover, not the stronger `--shadow-card-hover` token (see Rules).
46
- - **Selected / pending / error:** not applicable. The kit's `CardProps` has no such field; a card either is or
47
- is not `interactive`.
48
- - **Disabled:** not applicable; the kit never disables a card itself (disable the link or button inside it).
49
- - **Empty:** not applicable to a marketing card; there is always content to show.
50
- - **Long label:** the title wraps onto a second line inside the fixed padding; nothing clips.
51
- - **Narrow:** the card has no fixed width of its own; it was given one here (180px) to show the title wrapping.
48
+ - **Hover** (`interactive` only): the `--color-nav-hover-bg` tint over the card's own surface, the same wash as
49
+ `KitButton`'s secondary; the edge and words stay. Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
50
+ `.is-hover` draws it in a static preview.
51
+ - **Focus** (`interactive` only): the card is the `<a>`, so it takes the house ring, 2px navy, 2px out.
52
+ - **Selected / pending / error / disabled / empty:** not applicable; disable the link or button inside instead.
53
+ - **Long label:** the title wraps inside the fixed padding; nothing clips.
54
+ - **Narrow:** the card has no fixed width; the preview gives one 200px to show the title wrapping.
55
+ - **Dark:** the surface, edge and words are tokens, so the card follows `data-theme` with nothing extra.
52
56
 
53
57
  ## Behaviour
54
58
 
55
- - Keyboard: the kit renders a plain `<div>`; a clickable card wraps a real `<a>` or `<button>` inside it (or
56
- around it) so it still takes focus and announces correctly. `interactive` alone changes no semantics.
57
- - Pointer: only `interactive` cards react, with the hover shadow; a static card never changes under the pointer.
58
- - Touch: no touch-specific behaviour of its own; the 44px target comes from whatever is actually tappable inside it.
59
- - Motion: `transition-shadow duration-200` (`--transition-default`, 200ms) on the hover shadow; nothing else moves.
59
+ - Keyboard: a static card is a plain `<div>`. A clickable card is an `<a class="ws-kit-card ws-kit-card--interactive">`,
60
+ so it is one target and announces as a link. `interactive` alone changes no semantics.
61
+ - Pointer: only `interactive` cards react, with the hover tint.
62
+ - Touch: no touch rule of its own; the 44px public floor comes from what is tappable inside it (a `KitButton`).
63
+ - Motion: none. The tint is a colour change and lands at once, in every motion setting.
60
64
 
61
65
  ## Content
62
66
 
63
67
  - Sentence case, no em dashes.
64
68
  - One title per card that names the thing, one short description under it.
65
- - One footer act at most; a second act is a text link, not a second button.
69
+ - One footer act at most, a `KitButton`; a second act is a text link. Never the product's `ws-btn` on a public page.
66
70
 
67
71
  ## Props
68
72
 
69
73
  | Name | Type | Meaning |
70
74
  | --- | --- | --- |
71
75
  | `surface` | `'white' \| 'tinted' \| 'transparent'` | the fill, default `white` |
72
- | `interactive` | `boolean` | adds the hover shadow for a card that is a link or a button |
76
+ | `interactive` | `boolean` | adds the hover tint and the house focus ring for a card that is a link |
73
77
  | `className` | string | merged last, via `tailwind-merge` |
74
78
 
75
- `CardHeader`, `CardTitle`, `CardDescription`, `CardContent` and `CardFooter` take no props beyond
76
- `className` and native element attributes; they are plain structural wrappers.
79
+ `CardHeader`, `CardTitle`, `CardDescription`, `CardContent` and `CardFooter` take no props beyond `className` and native
80
+ element attributes; they are plain structural wrappers.
77
81
 
78
82
  ## Rules
79
83
 
80
84
  - "4px radius. That is the ceiling for cards, decided 2026-09-21, and it is deliberately tighter than the kit's
81
- own Feature Card at 8px: a soft corner at card scale reads as a toy, and the testimonial card in the same design
82
- file had already moved to 4px 'tighter than feature cards'. One value, not two." (`dist/index.d.ts`, doc comment
83
- on `cardVariants`.)
84
- - "White by default, not Gray 1. A tinted card on a cream page muddies both... `surface='tinted'` is there for the
85
- cases that genuinely need to recede." (same doc comment.)
85
+ own Feature Card at 8px: a soft corner at card scale reads as a toy." (`dist/index.d.ts`, doc comment on `cardVariants`.)
86
+ - "White by default, not Gray 1. A tinted card on a cream page muddies both." (same doc comment.)
86
87
  - "No shadow by default. Elevation is a signal, and a page where every card is raised has no signal left."
87
- (same doc comment.)
88
- - The product's card diverges on purpose: cream (`--color-bg-page`, not white), 8px corners, never a shadow even
89
- when interactive (the product's own rule, 15 Oct 2026 re-base: "No white cards... corners other than 8 px on a
90
- card"). Both stand: this one scoped to a public page, the product's to everything inside a signed-in workspace.
88
+ - **Hover is a tint, not a lift** (4 Nov 2026, D7, open to Amit's veto): `interactive` used to raise
89
+ `--shadow-card-default` on hover. D7 makes every hover a colour change, and on the dark ground that shadow moved the
90
+ pixels by at most 14 levels of 255, so the hover all but vanished. It is the nav's hover wash now, as `KitButton`'s
91
+ secondary, over whichever surface the card has.
92
+ - **Kit-owned corners** (4 Nov 2026): the corners read `--ws-radius-*`, not Tailwind's `--radius-*`. A shadcn host
93
+ derives `--radius-sm` to `--radius-lg` from its own `--radius` in `@layer theme`, which beats the kit, so in a
94
+ shadcn app the card drew 6px corners, over its 4px ceiling. The `--ws-radius-*` lengths are the kit's alone.
95
+ - **Tinted is the sunk step now** (4 Nov 2026): it was `--color-gray-1` (#F9F9F9), a literal that stayed near white in
96
+ dark. `--ws-surface-sunk` is the house's recede step in both themes; in light it is a touch warmer and deeper.
97
+ - The product's card diverges on purpose: cream, 8px corners, rimmed, never a shadow even when interactive. Both
98
+ stand: this one scoped to a public page, the product's to everything inside a signed-in workspace.
91
99
 
92
100
  ## Source
93
101
 
94
102
  - **Derived from**: the kit's own `cardVariants` and `Card`/`CardHeader`/`CardTitle`/`CardDescription`/
95
- `CardContent`/`CardFooter` (house rules in `README.md`, `tokens/tokens.md`). A contradiction was found and
96
- reported rather than resolved: the kit's own doc comment implies `interactive`'s hover uses a named hover
97
- shadow, but its actual class string reaches for `--shadow-card-default`, leaving `--shadow-card-hover` an
98
- unused token; this preview follows the code, since code is truth.
103
+ `CardContent`/`CardFooter`, the dark-safe surface names (D12) and the geometry check's title overflow at 180px.
99
104
  - **Precedent**: the first product built on the system, whose own card stands apart from this one for every
100
105
  signed-in screen.
106
+
107
+ ## Markup
108
+
109
+ ```html
110
+ <div class="ws-kit-card">
111
+ <div class="ws-kit-card__header">
112
+ <h3 class="ws-kit-card__title">Daily goals</h3>
113
+ <p class="ws-kit-card__desc">Set once, visible to the whole team every morning.</p>
114
+ </div>
115
+ <div class="ws-kit-card__content"><p class="ws-body">Each agent sees their own number before their first call.</p></div>
116
+ <div class="ws-kit-card__footer"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary" href="/goals">Read more</a></div>
117
+ </div>
118
+
119
+ <div class="ws-kit-card ws-kit-card--tinted">
120
+ <div class="ws-kit-card__header"><h3 class="ws-kit-card__title">Seller leads</h3></div>
121
+ </div>
122
+
123
+ <a class="ws-kit-card ws-kit-card--interactive" href="/content">
124
+ <div class="ws-kit-card__header">
125
+ <h3 class="ws-kit-card__title">Content</h3>
126
+ <p class="ws-kit-card__desc">Content that keeps you top of mind.</p>
127
+ </div>
128
+ </a>
129
+ ```
130
+
131
+ Styles: the `KitCard` block (`components/KitCard/style.css`), plus `KitButton` for a footer act.
@@ -1,6 +1,6 @@
1
1
  <!-- @dsCard group="Marketing" height=644 -->
2
2
  <!doctype html>
3
- <html>
3
+ <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
6
6
  <title>KitCard</title>
@@ -21,7 +21,7 @@
21
21
  <p class="ws-body">Each agent sees their own number, next to the team's, before their first call.</p>
22
22
  </div>
23
23
  <div class="ws-kit-card__footer">
24
- <button class="ws-btn ws-btn--primary">Read more</button>
24
+ <button class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary">Read more</button>
25
25
  </div>
26
26
  </div></div>
27
27
  </div>
@@ -47,16 +47,24 @@
47
47
  </div>
48
48
 
49
49
  <div class="ws-stack">
50
- <span class="ws-muted">Interactive: `--shadow-card-default` on hover (shown here as the hover state, since it is a card someone can click)</span>
51
- <div style="width: 260px; max-width: 100%;"><div class="ws-kit-card ws-kit-card--interactive is-hover">
52
- <div class="ws-kit-card__header">
53
- <h3 class="ws-kit-card__title">Content</h3>
54
- <p class="ws-kit-card__desc">Content that keeps you top of mind.</p>
55
- </div>
56
- </div></div>
50
+ <span class="ws-muted">Interactive: the whole card is the link; a tint on hover, never a lift</span>
51
+ <div class="ws-cluster ws-cluster--component ws-cluster--start">
52
+ <a class="ws-kit-card ws-kit-card--interactive" href="#" onclick="return false;" style="width: 260px; max-width: 100%;">
53
+ <div class="ws-kit-card__header">
54
+ <h3 class="ws-kit-card__title">Content</h3>
55
+ <p class="ws-kit-card__desc">At rest: flat, like any card.</p>
56
+ </div>
57
+ </a>
58
+ <a class="ws-kit-card ws-kit-card--interactive is-hover" inert href="#" onclick="return false;" style="width: 260px; max-width: 100%;">
59
+ <div class="ws-kit-card__header">
60
+ <h3 class="ws-kit-card__title">Content</h3>
61
+ <p class="ws-kit-card__desc">Hover: the card tints, nothing lifts.</p>
62
+ </div>
63
+ </a>
64
+ </div>
57
65
  </div>
58
66
 
59
- <div class="ws-stack" style="width: 180px;">
67
+ <div class="ws-stack" style="width: 200px; max-width: 100%;">
60
68
  <span class="ws-muted">Narrow, and a title long enough to wrap</span>
61
69
  <div class="ws-kit-card">
62
70
  <div class="ws-kit-card__header">
@@ -0,0 +1,15 @@
1
+ /* ---- KitCard: the kit's marketing card, white, 4 px corners, the hairline edge; no width of its own ---- */
2
+ .ws-kit-card { min-width: 0; border-radius: var(--ws-radius-control); border: var(--ws-line) solid var(--color-border-default); background: var(--color-surface); }
3
+ .ws-kit-card--tinted { background: var(--ws-surface-sunk); }
4
+ .ws-kit-card--transparent { background: transparent; border-color: var(--color-border-hairline); }
5
+ /* A card that is itself the link: an <a>, so it takes focus (the house ring) and reads as one target. */
6
+ .ws-kit-card--interactive { display: block; color: inherit; text-decoration: none; cursor: pointer; }
7
+ /* Hover is a tint, not a lift (D7): the nav's hover wash laid over whichever surface the card has, as KitButton's
8
+ secondary does. A shadow barely showed on the dark ground. */
9
+ .ws-kit-card--interactive.is-hover { background-image: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)); }
10
+ @media (hover: hover) { .ws-kit-card--interactive:hover { background-image: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)); } }
11
+ .ws-kit-card__header { display: flex; flex-direction: column; gap: var(--space-xs); padding: var(--space-lg); }
12
+ .ws-kit-card__title { font-size: var(--font-size-2xl); line-height: var(--space-xl); font-weight: 500; color: var(--color-text-heading); text-wrap: balance; overflow-wrap: break-word; hyphens: auto; }
13
+ .ws-kit-card__desc { font-size: var(--font-size-sm); line-height: calc(var(--space-md) + var(--space-xxs)); color: var(--color-text-muted); }
14
+ .ws-kit-card__content { padding: 0 var(--space-lg) var(--space-lg); }
15
+ .ws-kit-card__footer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm); padding: 0 var(--space-lg) var(--space-lg); }
@@ -12,48 +12,49 @@ The kit's one text field: for a lead form, a demo request or a waitlist on a pub
12
12
 
13
13
  - Any product screen inside a product built on this system: use the product's own `Input` (32px, 4px radius,
14
14
  white ground, mid-blue focus edge).
15
- - Several lines of text: there is no kit `TextArea`; build one from tokens if a second marketing project needs it.
15
+ - Several lines of text: there is no kit `TextArea`; the product's `TextArea` is the nearest piece.
16
16
  - A checkbox, a radio or a select: the kit ships `Checkbox`, `Radio`/`RadioGroup` and no `Select` at all.
17
17
 
18
18
  ## Anatomy
19
19
 
20
- - Box: 40px tall, `--radius-md` (6px) corners, `--color-white` ground, 1px `--color-border-default` (gray-stroke) edge.
21
- - Padding: 9px top and bottom, 12px (`--space-sm`) left and right.
22
- - Words: `--font-size-sm` (14px), `--color-gray-8`. Placeholder: `--color-gray-5`.
23
- - Label (the kit's `Label`): `--font-size-2xs` (12px), medium weight, `--color-gray-7`, 16px line height.
24
- - Message (hint or error) under the field: `--font-size-2xs` (12px), 16px line height; muted for a hint,
25
- `--color-feedback-error` for an error.
26
- - Focus: the border turns `--color-brand-salmon` and a 3px salmon halo appears (`--shadow-focus-ring`).
20
+ - Box: 40px tall (44 on touch), `--ws-radius-row` (6px) corners, the field ground `--ws-field` (white in light), a 1px
21
+ `--color-border-default` edge.
22
+ - Padding: 0 top and bottom (the height centres the words), 12px (`--space-sm`) left and right.
23
+ - Words: `--font-size-sm` (14px; 16px on touch) in `--ws-field-ink`. Placeholder: `--color-text-placeholder`.
24
+ - Label (`__label`, the kit's `Label`): `--font-size-2xs` (12px), medium, 16px line height, `--color-text-body`,
25
+ `--space-xxs` (4px) above the field.
26
+ - Message (`__msg`, hint or error) under the field: 12/16; `--color-text-muted` for a hint,
27
+ `--color-text-error-strong` for an error.
27
28
 
28
29
  ## Variants and sizes
29
30
 
30
- One size, one look: there is no `size` prop. The only axis is state (default, focus, error, disabled).
31
+ One size, one look: there is no `size` prop. The only axis is state (default, hover, focus, error, disabled).
31
32
 
32
33
  ## States
33
34
 
34
- - **Default:** white ground, gray-stroke edge, gray-5 placeholder.
35
- - **Hover:** border steps to `--color-gray-5`.
36
- - **Focus:** border turns `--color-brand-salmon`, `--shadow-focus-ring` (3px, salmon at 20%) appears. The kit's
37
- own `AGENTS.md` flags this ring as "added for accessibility" and not part of the kit's original marketing
38
- design: no focus state exists in Marketing DS 3.0 at all.
39
- - **Error:** border turns `--color-brand-salmon` too (`error && 'border-[var(--color-brand-salmon)]'` in the kit's
40
- code) and a message appears below in `--color-feedback-error`, wired by `aria-invalid` and `aria-describedby`.
41
- Passing a string, not a boolean, is what the kit's doc comment calls out: "an error state with no message is not
42
- an accessible error state."
35
+ - **Default:** the field ground, the hairline edge, the placeholder word.
36
+ - **Hover:** the edge firms to the muted word mixed 60% into the field: gray-5 in light, a quiet cool step in dark
37
+ (raw `--color-gray-5` was a bright neutral edge on the dark field). A disabled field does not react, and a field in
38
+ error keeps its salmon edge under the pointer. Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
39
+ - **Focus:** the house ring on `:focus-visible`, 2px `--ws-focus-color` (navy), 2px out. The edge does not change, so
40
+ focus never looks like an error. `.is-focus` draws it in a static preview.
41
+ - **Error:** the edge turns salmon (`--ws-chart-under-half`) and a message appears below in `--color-text-error-strong`, wired by
42
+ `aria-invalid` and `aria-describedby`. The message carries the meaning; the edge is the second cue.
43
43
  - **Disabled:** 50% opacity, not editable.
44
44
  - **Empty / loading:** not applicable; a text field has no loading state of its own.
45
- - **Long label / narrow:** the label wraps onto a second line above the field; the field itself keeps its 40px
46
- height and shrinks to its container's width.
47
- - **Touch:** 40px already clears the 44px-adjacent floor comfortably for a single-line field; the kit applies no
48
- separate touch size.
45
+ - **Long label / narrow:** the label wraps onto a second line above the field; the field keeps its height and takes
46
+ its container's width; a long value scrolls inside the field.
47
+ - **Touch:** 44px tall (`--ws-touch-public`), the public page's floor, with 16px words so a phone does not zoom the
48
+ page when the field takes focus.
49
49
 
50
50
  ## Behaviour
51
51
 
52
- - Keyboard: a real `<input>`; Tab moves to and from it in document order; the label's `htmlFor` makes a click on
52
+ - Keyboard: a real `<input>`; Tab moves to and from it in document order; the label's `for` makes a click on
53
53
  the label focus the field.
54
- - Pointer: hover changes the border only; no other reaction.
55
- - Touch: the native input keyboard and autofill behave as the browser provides; nothing is replaced.
56
- - Motion: border-color and box-shadow transition over 150ms ease-out (`--transition-fast`).
54
+ - Pointer: hover changes the edge only.
55
+ - Touch: the native keyboard and autofill behave as the browser provides. Give every field about the person its
56
+ `type` and `autocomplete` (`email`, `organization`, `tel`).
57
+ - Motion: the edge colour moves over 150ms (`--transition-fast`), only under `prefers-reduced-motion: no-preference`.
57
58
 
58
59
  ## Content
59
60
 
@@ -64,7 +65,9 @@ One size, one look: there is no `size` prop. The only axis is state (default, fo
64
65
 
65
66
  ## Props
66
67
 
67
- | Name | Type | Meaning |
68
+ The React `Input` (`@felloinnovations/brand-kit`) renders this field with Tailwind utilities on the same tokens.
69
+
70
+ | Prop | Type | Meaning |
68
71
  | --- | --- | --- |
69
72
  | `label` | `string` | rendered above the field via the kit's `Label` |
70
73
  | `error` | `string` | its presence puts the field in the error state and wires `aria-invalid`/`aria-describedby` |
@@ -73,19 +76,31 @@ One size, one look: there is no `size` prop. The only axis is state (default, fo
73
76
 
74
77
  ## Rules
75
78
 
76
- - "40px tall, 6px radius, 1px Gray Stroke, 9/12 padding, 14px Gray 8 text, Gray 5 placeholder, salmon border + 3px
77
- salmon ring on focus" (`dist/index.d.ts`, doc comment on `Input`, citing `docs-cache/design-system/cards-and-components.md §3`).
79
+ - "40px tall, 6px radius, 1px Gray Stroke, 12px sides, 14px words, salmon border on error" (`dist/index.d.ts`, doc
80
+ comment on `Input`, citing `docs-cache/design-system/cards-and-components.md §3`).
78
81
  - "`error` is a string, not a boolean, because an error state with no message is not an accessible error state."
79
- (same doc comment.)
80
- - **The reported gap:** the salmon focus ring is the same colour as the error state, so a field being typed in can
81
- read as already wrong. The kit's own gap table names this directly: "The focus ring is the error's salmon, so a
82
- field being typed in looks refused" (the first product's stopgap: a mid-blue focus edge instead; suggestion: "A
83
- navy or mid-blue focus ring"). The product's `Input` took that stopgap: 32px, 4px radius, white, mid-blue focus,
84
- which is the divergence this component's README is pointing at.
82
+ - **Focus is the house ring now** (D8, 4 Nov 2026). The old salmon edge and salmon halo were the error's colour, so a
83
+ field being typed in read as refused, and the halo was 1.21:1 on the cream.
84
+ - **44px on touch** (4 Nov 2026): closes the open item "KitInput 40 px against the public page's 44 px floor". The
85
+ desktop field stays 40, the kit's drawn size.
86
+ - The error word is `--color-text-error-strong` (AA); the old `--color-feedback-error` was 3.0:1 on white.
85
87
 
86
88
  ## Source
87
89
 
88
- - **Derived from**: the kit's own `Input` and `Label` (`dist/index.d.ts` doc comment, `tokens/tokens.md`) and its
89
- gap table on the focus-ring contradiction.
90
- - **Precedent**: the first product built on the system, whose own `Input` took the mid-blue focus-ring stopgap
91
- this component's README points at.
90
+ - **Derived from**: the kit's own `Input` and `Label`, its gap table on the focus-ring contradiction, the house focus
91
+ ring (D8), the dark-safe field names (D12) and the touch floors (`14-accessibility.md`).
92
+ - **Precedent**: the first product built on the system, whose own `Input` took the mid-blue focus stopgap.
93
+
94
+ ## Markup
95
+
96
+ ```html
97
+ <div class="ws-kit-input">
98
+ <label class="ws-kit-input__label" for="demo-email">Work email</label>
99
+ <input class="ws-kit-input__control" id="demo-email" type="email" autocomplete="email" placeholder="you@teamname.com" aria-describedby="demo-email-msg">
100
+ <p class="ws-kit-input__msg" id="demo-email-msg">We send the invite here.</p>
101
+ </div>
102
+ ```
103
+
104
+ For an error, add `aria-invalid="true"` to the input and `ws-kit-input__msg--error` to the message.
105
+
106
+ Styles: the `KitInput` block (`components/KitInput/style.css`), in `fello.css`. Nothing else.
@@ -1,6 +1,6 @@
1
1
  <!-- @dsCard group="Marketing" height=316 -->
2
2
  <!doctype html>
3
- <html>
3
+ <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
6
6
  <title>KitInput</title>
@@ -14,15 +14,15 @@
14
14
  <span class="ws-muted">Default, with a label</span>
15
15
  <div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
16
16
  <label class="ws-kit-input__label" for="ki-email">Work email</label>
17
- <input class="ws-kit-input__control" id="ki-email" type="email" placeholder="you@teamname.com">
17
+ <input class="ws-kit-input__control" id="ki-email" type="email" autocomplete="email" placeholder="you@teamname.com">
18
18
  </div></div>
19
19
  </div>
20
20
 
21
- <div class="ws-stack">
22
- <span class="ws-muted">Focus: the 3px salmon ring</span>
21
+ <div class="ws-stack" inert>
22
+ <span class="ws-muted">Focus: the 2px navy ring, 2px out</span>
23
23
  <div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
24
24
  <label class="ws-kit-input__label" for="ki-name">Team name</label>
25
- <input class="ws-kit-input__control is-focus" id="ki-name" value="Nair Realty Group">
25
+ <input class="ws-kit-input__control is-focus" id="ki-name" autocomplete="organization" value="Nair Realty Group">
26
26
  </div></div>
27
27
  </div>
28
28
 
@@ -30,7 +30,7 @@
30
30
  <span class="ws-muted">With a hint</span>
31
31
  <div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
32
32
  <label class="ws-kit-input__label" for="ki-size">Team size</label>
33
- <input class="ws-kit-input__control" id="ki-size" aria-describedby="ki-size-hint" placeholder="12">
33
+ <input class="ws-kit-input__control" id="ki-size" inputmode="numeric" aria-describedby="ki-size-hint" placeholder="12">
34
34
  <p class="ws-kit-input__msg" id="ki-size-hint">Agents on the team today, not counting admin.</p>
35
35
  </div></div>
36
36
  </div>
@@ -39,7 +39,7 @@
39
39
  <span class="ws-muted">Error: a string, not a boolean, so the reason is always on screen</span>
40
40
  <div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
41
41
  <label class="ws-kit-input__label" for="ki-email-err">Work email</label>
42
- <input class="ws-kit-input__control is-error" id="ki-email-err" aria-invalid="true" aria-describedby="ki-email-err-msg" value="priya@">
42
+ <input class="ws-kit-input__control is-error" id="ki-email-err" type="email" autocomplete="email" aria-invalid="true" aria-describedby="ki-email-err-msg" value="priya@">
43
43
  <p class="ws-kit-input__msg ws-kit-input__msg--error" id="ki-email-err-msg">Enter a work email we can reach you at.</p>
44
44
  </div></div>
45
45
  </div>
@@ -0,0 +1,23 @@
1
+ /* ---- KitInput: the kit's marketing field, 40 px (44 and 16 px words on touch), on the field ground, the house focus ring ---- */
2
+ .ws-kit-input { display: flex; flex-direction: column; gap: var(--space-xxs); min-width: 0; }
3
+ .ws-kit-input__label { font-size: var(--font-size-2xs); font-weight: 500; line-height: var(--space-md); color: var(--color-text-body); }
4
+ .ws-kit-input__control { height: var(--space-2xl); width: 100%; border-radius: var(--ws-radius-row); padding: 0 var(--space-sm); background: var(--ws-field); border: var(--ws-line) solid var(--color-border-default); font-size: var(--font-size-sm); color: var(--ws-field-ink); }
5
+ @media (prefers-reduced-motion: no-preference) {
6
+ .ws-kit-input__control { transition: border-color var(--transition-fast); }
7
+ }
8
+ .ws-kit-input__control::placeholder { color: var(--color-text-placeholder); }
9
+ /* Hover firms the edge to the controls' hover edge (--ws-edge-hover: North's warm grey in light, a cool step in dark,
10
+ where raw gray-5 would be a bright neutral edge on the navy-black field). A disabled field does not
11
+ react; :where keeps the selector's weight, so the error edge below still wins. Pointers that hover only: a tap
12
+ would leave the edge firmed. */
13
+ @media (hover: hover) { .ws-kit-input__control:hover:where(:not(:disabled)) { border-color: var(--ws-edge-hover); } }
14
+ /* Focus is the house ring on :focus-visible (2 px navy, 2 px out); .is-focus draws it in a static preview. */
15
+ .ws-kit-input__control.is-focus { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
16
+ .ws-kit-input__control[aria-invalid="true"], .ws-kit-input__control.is-error { border-color: var(--ws-chart-under-half); }
17
+ .ws-kit-input__control:disabled { cursor: not-allowed; opacity: 0.5; }
18
+ .ws-kit-input__msg { font-size: var(--font-size-2xs); line-height: var(--space-md); color: var(--color-text-muted); }
19
+ .ws-kit-input__msg--error { color: var(--color-text-error-strong); }
20
+ /* Touch: the public page's 44 px target, and 16 px words so a phone does not zoom the page when the field takes focus. */
21
+ @media (pointer: coarse) {
22
+ .ws-kit-input__control { height: var(--ws-touch-public); font-size: var(--font-size-md); }
23
+ }