@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
package/README.md CHANGED
@@ -54,13 +54,14 @@ folder trust prompt once, and needs GitHub access to FelloInnovations, since the
54
54
  }
55
55
  ```
56
56
 
57
- The plugin carries the same `fello-brand-kit` skill as claude.ai, plus three commands:
57
+ The plugin carries the same `fello-brand-kit` skill as claude.ai, plus four commands:
58
58
 
59
59
  | Command | What it does |
60
60
  | --- | --- |
61
61
  | `/brand-kit:brand-audit` | Read-only report: raw values, drift from tokens, pages that cannot scroll, fields with no white ground, small targets, contrast, console errors. |
62
62
  | `/brand-kit:brand-adopt` | Migrates an existing app onto the kit, in stages, building between each. |
63
63
  | `/brand-kit:brand-new` | Scaffolds a new app already on the kit. |
64
+ | `/brand-kit:brand-feedback` | Sends what the kit was missing or got wrong as one issue per gap on this repo. The other skills offer it when they finish. |
64
65
 
65
66
  Audit before adopt, so someone who does not read code sees what is wrong before anything is rewritten.
66
67
 
@@ -74,12 +75,33 @@ bun add @felloinnovations/brand-kit
74
75
  ```
75
76
 
76
77
  ```css
78
+ /* the font first: after Tailwind's rules a browser drops an @import, so fello.css's own one never loads here */
79
+ @import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400..700&display=swap");
77
80
  @import "tailwindcss";
78
81
  @import "@felloinnovations/brand-kit/tokens.css"; /* tokens as a Tailwind v4 @theme */
79
- @import "@felloinnovations/brand-kit/fello.css"; /* the whole kit: font, tokens, ws-* component classes */
82
+ @import "@felloinnovations/brand-kit/fello.css"; /* the whole kit: tokens, ws-* component classes */
80
83
  @source "../node_modules/@felloinnovations/brand-kit/dist";
81
84
  ```
82
85
 
86
+ `fello.css` sits inside Tailwind's own layers, so your utilities still win. Beyond `html` and `body`, it touches only
87
+ elements with a `ws-*` class or inside one. Any unlayered CSS of yours (a bare `button` or `body` rule) also beats the
88
+ kit now; keep such rules in a layer, or take the scoped build below.
89
+
90
+ An app that lives inside a host it does not own (a platform's guest app, a bundle shared with other apps), or any
91
+ Tailwind v3 app, takes the scoped build instead: every rule under a `.fello` root, nothing outside it changed.
92
+
93
+ ```tsx
94
+ import { felloScopedCss } from '@felloinnovations/brand-kit/scoped';
95
+
96
+ <div className="fello"><style>{felloScopedCss}</style>{/* the app */}</div>
97
+ ```
98
+
99
+ The scoped build carries no font `@import`: link Instrument Sans in the app's head. `class="fello"` also goes on the root
100
+ of every portal (a menu, a tooltip, a dialog rendered outside the app).
101
+
102
+ Dark is opt-in: `<html data-theme="dark">`, or `data-theme="system"` to follow the person's setting; a page that sets
103
+ nothing stays light.
104
+
83
105
  Then point the repo's agents at the guide: paste the block at the end of [AGENTS.md](AGENTS.md) into its `CLAUDE.md`.
84
106
 
85
107
  > A `github:FelloInnovations/brand-kit` git dependency does **not** work: the repo is private and bun resolves that
@@ -90,12 +112,12 @@ Then point the repo's agents at the guide: paste the block at the end of [AGENTS
90
112
  One line, pinned to a version:
91
113
 
92
114
  ```html
93
- <link rel="stylesheet" href="https://brand-kit-site-production.up.railway.app/v/0.4.0/fello.css">
115
+ <link rel="stylesheet" href="https://brand-kit-site-production.up.railway.app/v/0.5.1/fello.css">
94
116
  ```
95
117
 
96
118
  Then use the `ws-*` classes and `var(--token)`; the markup for each component is in the gallery. `/latest/` exists
97
119
  too, but a live page should pin. A claude.ai artifact cannot link it (artifacts load stylesheets only from Google
98
- Fonts), which is why the skill carries `fello.css` and inlines it.
120
+ Fonts), which is why the skill carries `fello-core.css` and each component's blocks, and inlines only those.
99
121
 
100
122
  ---
101
123
 
@@ -105,7 +127,9 @@ Fonts), which is why the skill carries `fello.css` and inlines it.
105
127
  the component catalog (`components/<Name>/README.md` and `preview.html`). Started from Lokesh's design system,
106
128
  built from the first product on the kit.
107
129
  - **`tokens/`**: generated token files. Every token and its value is in `tokens/tokens.md`.
108
- - **`dist/fello.css`**: the one stylesheet. **`tokens/tokens.css`**: tokens only, Tailwind v4.
130
+ - **`dist/fello.css`**: the one stylesheet, in cascade layers. **`dist/fello.scoped.css`** and
131
+ `@felloinnovations/brand-kit/scoped`: the same under a `.fello` root. **`tokens/tokens.css`**: tokens only, Tailwind
132
+ v4. **`tokens/shadcn-compat.css`** and **`shadcn-compat.hsl.css`**: shadcn's variables pointed at the kit.
109
133
  - **React components**: `Button` · `Badge` · `Card` · `Input` · `Label` · `Checkbox` · `Radio` / `RadioGroup` ·
110
134
  `Tabs` · `Skeleton` · `Stat`, and `Toaster` from `@felloinnovations/brand-kit/toast` (needs `sonner`). Most are the
111
135
  marketing layer; product screens are built from the catalog. See [AGENTS.md](AGENTS.md) for which is which.
@@ -133,7 +157,8 @@ Two navies and two fonts, all shipping as "Fello". This package is the one copy.
133
157
 
134
158
  ## Known gaps
135
159
 
136
- - **No dark mode.** None was designed. Do not invent one.
160
+ - **Dark is derived, not drawn.** The dark theme is Fello's shipped night and navy grounds; Seth has drawn no dark
161
+ frames, so the glass stage and the frame gradient in dark are a flat interim.
137
162
  - **Feedback colours are provisional.** `--color-feedback-*`, `--color-alert` and `--color-stat-positive` came from
138
163
  the HubSpot boilerplate and will change.
139
164
  - **The kit `Button`'s `tertiary` and `clean` themes are placeholders**: the Figma capture never specified their
@@ -158,11 +183,13 @@ is no longer maintained. Only the kit's owners (Amit and Arpan) change tokens.
158
183
 
159
184
  ## Releasing
160
185
 
161
- CI publishes. Bump `version` in `package.json` (and `plugin/.claude-plugin/plugin.json`, and the pinned `/v/` links
162
- in `skill/SKILL.md`), run `yarn build` and `yarn skill`, commit, then push a tag that matches:
186
+ CI publishes. Before the bump, keep the released hosted tree: `yarn hosted`, then copy `site-dist/v/<released
187
+ version>` to `hosted/v/` (the gallery serves every snapshot there, so pinned links keep working). Bump `version` in
188
+ `package.json` and the pinned `/v/` links (`AGENTS.md`, `skill/SKILL.md`, this README, `Starter`, guide 01; the plugin is
189
+ unversioned), run `yarn build` and `yarn skill`, commit, then push a tag that matches:
163
190
 
164
191
  ```sh
165
- git tag v0.4.0 && git push origin v0.4.0
192
+ git tag v0.5.1 && git push origin v0.5.1
166
193
  ```
167
194
 
168
195
  `.github/workflows/publish.yml` checks the tag matches `package.json`, builds, and publishes to npm through npm's
@@ -179,4 +206,6 @@ yarn build # tokens + dist
179
206
  yarn skill # the skill zip and plugin/skills/brand-kit/
180
207
  yarn build:site # static gallery into site-dist/
181
208
  yarn typecheck
209
+ yarn check:geometry # every preview at 320, 390 and 1440 (--theme dark, --hover, --only Name1,Name2)
210
+ yarn check:scope # proves the scoped build changes nothing outside .fello, and fello.css's resets miss the host
182
211
  ```
@@ -14,10 +14,10 @@ below.
14
14
  3. **Pick components** from the tables in Choosing components and copy their preview markup: the kit's CSS styles every
15
15
  one (in an artifact, `fello-core.css` plus the styles each component's card lists). Never redraw a catalog piece.
16
16
  4. **Keep the five firm rules**: tokens only, never an invented value; one face per surface; colour means something
17
- (salmon never a button or a word, never red, no AI colours outside the orb); one primary per card and per page;
18
- honest data and plain words (no faked card or number, sentence case, no em dashes).
17
+ (salmon never a button or a word, red only for an alert, no AI colours outside the orb); one primary per card and
18
+ per page; honest data and plain words (no faked card or number, sentence case, no em dashes).
19
19
  5. **Run the quick check** in a browser at desktop (1440×900) and phone (390×844): no sideways scroll, nothing clipped,
20
- your own text AA on its surface, one primary.
20
+ one content edge, your own text AA on its surface, one primary, focus visible.
21
21
 
22
22
  Open another chapter only when the job needs it: a chart, Charts; a form, Patterns; a public page, Public pages; a layout
23
23
  to start from, Page recipes.
@@ -44,10 +44,10 @@ rest; a mockup about to ship takes all steps.
44
44
  | | Product layer | Marketing layer |
45
45
  | --- | --- | --- |
46
46
  | When | after sign-in, or anything used to do work | before sign-in, or anything that sells |
47
- | Surface | the cream page and cream cards, a 0.5 px edge, 8 px corners, flat | the cream page, white `KitCard`s at 4 px, flat unless clickable |
48
- | The one act | a solid navy `Button`, 4 px corners | the salmon gradient `KitButton`, large (45 px), with its 3 px lift |
47
+ | Surface | the cream page and rimmed cream cards (a 1 px grey rim, 8 px corners), flat | the cream page, white `KitCard`s at 4 px, flat unless clickable |
48
+ | The one act | a solid navy `Button`, 6 px corners | the salmon gradient `KitButton`, large (45 px), with its 3 px lift |
49
49
  | Words | 14 px body, 22 px titles | 16 px body, an 18 px lead, headings on the kit's big steps (48 to 64) |
50
- | Targets | 32 px controls, 40 on touch | 44 px at least |
50
+ | Targets | 32 px controls, 40 on touch, 24 for words that act | 44 px at least |
51
51
  | Pieces | the product components | `MarketingNav`, `Hero`, `FeatureGrid`, `Testimonial`, `PricingTable`, `Footer`, `KitButton`, `KitCard`, `KitInput`, `Stat` |
52
52
  | Decoration | none: colour is spent on data | the Felix orb and the dot grid only |
53
53
  | Rules | Colour to Checklist | Public pages, then Content, Accessibility, Checklist |
@@ -57,10 +57,13 @@ rest; a mockup about to ship takes all steps.
57
57
  | Where | Setup |
58
58
  | --- | --- |
59
59
  | A claude.ai artifact | inline `fello-core.css` plus the styles of only the components used, in one `<style>` (an artifact loads stylesheets only from Google Fonts; the whole `fello.css` is too big to paste) |
60
- | A plain HTML page or a static site | link the pinned file: `https://brand-kit-site-production.up.railway.app/v/0.4.0/fello.css` |
61
- | A Next, Vite or Turbo app | install `@felloinnovations/brand-kit`, import `fello.css` or `tokens.css` (Tailwind v4), read its `AGENTS.md` |
60
+ | A plain HTML page or a static site | link the pinned file: `https://brand-kit-site-production.up.railway.app/v/0.5.1/fello.css` |
61
+ | A Next, Vite or Turbo app that owns its page | install `@felloinnovations/brand-kit`, import `fello.css` (it sits in Tailwind's layers, so utilities win) or `tokens.css` (Tailwind v4), with the Instrument Sans `@import` first (before `@import "tailwindcss"`) or a `<link>`; read its `AGENTS.md` |
62
+ | An app inside a host it does not own (a shared bundle, a platform's guest app), or any Tailwind v3 app | the scoped build: `fello.scoped.css`, or the string from `@felloinnovations/brand-kit/scoped` injected in a `<style>`, under `class="fello"` on the app's root and on every portal's root; nothing outside it changes; it carries no font, so link Instrument Sans (the `brand-adopt` skill has the steps) |
62
63
  | Claude Design or Slides | this system is the organisation's default; nothing to load |
63
64
  | An email | literal values from the kit's `tokens.ts`, inlined on each element (email clients drop custom properties) |
65
+ | Dark (any of the above) | opt-in on the root: `data-theme="dark"`, or `"system"` to follow the person's setting; an artifact writes `"system"`. A page that sets nothing stays light (Colour) |
66
+ | A palette (any of the above) | an app with its own slightly different colours: `data-palette="cool"` or `"warm"` on the root or the app's container, or its own palette from the contract, checked with `check-palette` and shipped as its `--emit` writes it (Palettes). Never its own values on `:root` |
64
67
  | The HubSpot site theme | out of scope: it carries its own tokens and rules |
65
68
 
66
69
  ## 1. Start from a real reference
@@ -111,14 +114,16 @@ Decisions with the rules it derives from, so the kit's owners can take it.
111
114
  ## 5. Apply the foundations
112
115
 
113
116
  Tokens for every value (Colour, Type, Space and layout); never invent one, and say so when none fits. The face's sizing
114
- profile (Sizing profiles). The scrolling rule (Scrolling): every page scrolls, and nothing is trapped behind an
115
- `overflow: hidden` or a fixed-height parent. Fields white on the cream (`ws-field`). One primary per card and per page. Say
116
- each thing once.
117
+ profile (Sizing profiles). The scrolling rule (Scrolling): every page scrolls, the shell's body owns the scroll, nothing
118
+ is squashed or trapped behind an `overflow: hidden` or a fixed-height parent. One content edge per surface and numbers in
119
+ fixed columns (Space and layout). Fields white on the cream (`ws-field`). One primary per card and per page. Say each
120
+ thing once.
117
121
 
118
122
  ## 6. Cover every state
119
123
 
120
- Default, loading (a skeleton, not a spinner), empty (first use, no matches, unavailable), error with recovery, pending on a
121
- press, success, long labels, narrow width, touch, reduced motion, keyboard. A public page adds the form's error and its
124
+ Default, the interaction states (hover, press, focus, selected, pending, disabled: Patterns), loading (a shimmer over the
125
+ ghost, not a spinner), empty (first use, no matches, unavailable), error with recovery, success, long labels, narrow
126
+ width, touch, dark, reduced motion, keyboard. A public page adds the form's error and its
122
127
  success (with what happens next), a slow network, an image that fails, and a refused microphone or camera (how to allow it
123
128
  in that browser, and Try again). A screen with only its happy path is half a screen.
124
129
 
@@ -126,20 +131,24 @@ in that browser, and Try again). A screen with only its happy path is half a scr
126
131
 
127
132
  A screenshot proves how something looks, not that it works. Open it in a real browser at desktop 1440×900 and phone
128
133
  390×844 (a workspace also at 1280×800, 1920×1080 and the panel width; a Figma build at its frame sizes and the three sizes
129
- in step 1) and run the Checklist. An app with sign-in is crawled page by page as each role at both sizes; the bar is no
130
- console errors, no failed requests, no broken pages.
134
+ in step 1) and run the Checklist, in light and, when the page opts in, dark. A component or a preview also passes the
135
+ geometry check at 320, 390 and 1440 (`node scripts/check-geometry.mjs --only <Name>`, with `--theme dark`,
136
+ `--hover`, then `--hover --motion`): open every screenshot it writes. An app with sign-in is crawled page by page as each role at both sizes; the bar is no console errors, no failed
137
+ requests, no broken pages.
131
138
 
132
139
  ## 8. Show it back
133
140
 
134
141
  Build first, then show: the link, screenshots at desktop and phone, the rationale. Lead with the choice and the reason; name
135
142
  the face, the recipe and the components; list the states covered and what was measured; name what you left out and why;
136
- flag anything the system did not cover so it can be added. Never present a guess as a rule.
143
+ flag anything the system did not cover so it can be added (offer to send each gap as an issue:
144
+ `https://github.com/FelloInnovations/brand-kit/issues/new?template=feedback.yml`). Never present a guess as a rule.
137
145
 
138
146
  ## Three levels of freedom
139
147
 
140
148
  - **Firm** (never bend): tokens and their meanings; the two layers kept apart; the colour rules (salmon small in a product,
141
149
  the gradient only on the marketing act, no AI colours outside the orb, navy for the one product button, AA words beside
142
- exact marks); native semantics; touch floors and focus; honest data from one source; no em dashes; nothing
150
+ exact marks); native semantics; touch floors and the visible focus ring; still under reduced motion; dark only when
151
+ the page opts in; honest data from one source; no em dashes; nothing
143
152
  developer-facing; one home per thing, one act per card; the performance budget on a public page.
144
153
  - **Defaults** (bend with a reason in the rationale): densities, gaps, widths, the number of cards, what sits above the
145
154
  fold, whether a region scrolls, which chart draws a figure, a public page's section rhythm.
@@ -19,10 +19,12 @@ What the system optimises for, in the order it breaks ties. Each has a test.
19
19
  with it? If not, it should not have been coloured.
20
20
  6. **Compact components, breathing room between them** (the numbers are in Space and layout). Density comes from
21
21
  prioritising and grouping, never from shrinking words or clipping content. A public page is roomier (13).
22
- 7. **Flat, with fine edges.** No float; lift is a signal reserved for a menu or a dialog (and a clickable card on a
23
- public page).
24
- 8. **Motion explains, never decorates**: short, from where the thing belongs, nothing looping but the one working beat,
25
- still under reduced motion (Motion).
22
+ 7. **Flat, rimmed, one edge.** A cream surface in a fine grey rim, no float; lift is a signal reserved for what floats
23
+ (a menu, a tip, a dialog, a tile opened out of its slot, and a clickable card on a public page). Every block in a
24
+ surface starts on one edge, and numbers line up in their columns.
25
+ 8. **Motion explains, never decorates**: things grow from where they were and go back the same way, details settle
26
+ after their frame, hover is a colour, nothing that carries data loops, and everything is still under reduced motion
27
+ (Motion).
26
28
  9. **Words are AA, marks are exact.** The designer's salmon and teal stay on bars and dots; the words beside them take the
27
29
  AA step. A screen is not done until every text pair passes.
28
30
  10. **Honest data, one source** (How Claude decides, step 3). A comparison with a teammate is a role ("Team best"), never
@@ -32,7 +34,8 @@ What the system optimises for, in the order it breaks ties. Each has a test.
32
34
  13. **Fit the reader and the device**: compact for daily work at a desk, roomy and thumb-sized for a public page read
33
35
  once on a phone (Sizing profiles). Test: on a 390 px phone, can a thumb hit every act and the eye read every word?
34
36
  14. **Measured, not eyeballed.** "Matches the design" and "works" are claims proven in a browser at the sizes people use.
35
- Test: was it run at desktop and phone, nothing clipped, every target and text pair checked?
37
+ Test: did the geometry check run at 320, 390 and 1440, light and dark, and was every screenshot looked at: nothing
38
+ clipped, every target and text pair checked?
36
39
  15. **Undo beats confirm; a skeleton beats a spinner; a banner beats a popup; a word beats an icon alone.**
37
40
 
38
41
  ## Anti-patterns (seen and removed)
@@ -41,4 +44,6 @@ White cards on the cream in a product; float shadows on every card; navy pills,
41
44
  buttons; a grey plate holding white rows; two lists of the same calls; a headline that repeats the card under it; a tab row
42
45
  with its own styles; a styled `<button>`; a purple glow or a rainbow ring to mean "AI"; red for a falling number; an
43
46
  "assistant" box on a page; a spinner where a skeleton belongs; a card invented to fill a gap in the data; an em dash; a total on screen that differs from the one sent; a field with no
44
- white ground; a page that cannot scroll; a reveal only on hover; two booking buttons on one phone screen.
47
+ white ground; a page that cannot scroll; a reveal only on hover; two booking buttons on one phone screen; a card squashed
48
+ to nothing by the scroller it sits in; insets that nearly agree (14, 16, 17 and 20 in one card); figures that do not line
49
+ up down a list; a focus ring taken away; a hover that lifts a button; a dash standing in for a missing number.
@@ -1,37 +1,74 @@
1
1
  # Colour
2
2
 
3
3
  The palette is the kit's; the rules are the product's. The balance fello.ai keeps is the rule: about 84% warm neutrals,
4
- navy for headings and a few large pieces, salmon small but on every screen, mid blue only as secondary text, teal for
5
- positive.
4
+ navy for headings and a few large pieces, salmon small but on every screen, mid blue as secondary words, teal for
5
+ positive. Marks keep Seth's exact tones; a word in a tone takes its AA step on the ground it sits on (D2).
6
6
 
7
7
  ## By role
8
8
 
9
- | Role | Token | Value |
9
+ | Role | Token | Light |
10
10
  | --- | --- | --- |
11
- | The page, every card, a secondary button, a field at rest | `color-bg-page` | #FEFBF9 |
12
- | A plate, a track, a hover, the person's bubble, the footer band | `ws-surface-sunk`, `ws-chart-foot` | #F3F1EF |
11
+ | The page, every card's surface, a secondary button, a filter's chip select | `color-bg-page` | #FEFBF9 |
12
+ | What is white: a marketing card, a well row under the pointer, the person's chat bubble | `color-surface` | white |
13
+ | A menu, a dialog, a panel, a popover, a tooltip | `ws-raised` | the cream |
14
+ | A plate, the footer band | `ws-surface-sunk`, `ws-chart-foot` | #F3F1EF |
13
15
  | A row under a press | `ws-surface-press` | #E9E6E4 |
14
- | A field | `ws-field` | white |
15
- | A well behind rows | `ws-well` | #EDEDED |
16
+ | The tray a card sits in (its rim and its foot), a well behind rows | `ws-tray`, `ws-well` | #EDEDED |
17
+ | A rimmed card's rim under the pointer | `ws-well-hover` | #E4E2DF |
18
+ | An empty track (a meter, an empty tick, an upload bar) | `ws-track` | #EDEDED |
19
+ | A field's ground, also when focused | `ws-field` | white |
20
+ | A field's words | `ws-field-ink` | #292929 |
16
21
  | The grey around the stage | `ws-page` | #E8E8E8 |
17
- | A card's, field's, tab track's edge | `ws-edge-card` at `ws-hairline` | #D3D3D3, 0.5 px |
18
- | A chip's edge | `ws-edge-chip` | #D9D5D0 |
19
- | A day cell's or empty tick's edge | `ws-edge-slot` | #E2E2E2 |
20
- | The band's top edge | `ws-edge-tray` | #D9D3CB |
21
- | Titles, a row's name, figures, the primary button, the tab thumb | `color-text-heading` | navy #093555 |
22
+ | A divider between rows, a field's or control's edge, a chip's edge, a slot's edge | `ws-edge`, `ws-edge-card`, `ws-edge-chip`, `ws-edge-slot` | 0.5 px |
23
+ | Titles, a row's name, figures, the primary button's fill, the thumb, navy marks | `color-text-heading` | navy #093555 |
24
+ | Words and marks on the navy act fill | `ws-on-act` | white |
22
25
  | Body, a card's line, rows | `color-text-body` | #545454 |
23
- | Meta, labels, captions | `color-text-muted` | #6E6E6E |
24
- | A field's placeholder | `color-text-placeholder` | #6E6E6E |
25
- | Links, words that act, a falling number, "working", a field's focus edge | `color-text-interactive` | mid blue #495883 |
26
- | Good news in words | `ws-word-positive` | #09787F |
27
- | Something to fix in words | `ws-word-needs` | #B35040 |
28
- | Done, passed, positive marks | `ws-chart-finished` / `color-stat-positive` | teal #098486 |
26
+ | Meta, labels, captions, placeholders | `color-text-muted`, `color-text-placeholder` | #666666, #6E6E6E |
27
+ | Links, words that go somewhere, a falling number, "working", "getting there" | `color-text-interactive` | mid blue #495883 |
28
+ | Good news in words | `ws-word-positive` | #09717A |
29
+ | Something to fix in words, needs you | `ws-word-needs` | #A84B3C |
30
+ | Needs work in words | `ws-word-needs-work` | #B42D68 |
31
+ | An alert in words | `ws-word-alert` | #B1042F |
32
+ | Past halfway in words | `ws-word-past-half` | #6D4FC2 |
33
+ | Done, passed, positive marks | `ws-chart-finished`, `color-stat-positive` | teal #098486 |
29
34
  | Past halfway marks | `ws-chart-past-half` | purple #6D4FC2 |
30
- | Under halfway marks, needs-you dots | `ws-chart-under-half` / `color-brand-salmon` | salmon #FF725C |
31
- | A needs-you chip's tint | `ws-tint-needs` | #FFF1EF |
32
- | A done chip's tint | `ws-tint-live` | #E1F0F0 |
35
+ | Under halfway marks, needs-you dots | `ws-chart-under-half`, `color-brand-salmon` | salmon #FF725C |
36
+ | Needs work marks | `ws-chart-needs-work` | pink #F370A4 |
37
+ | Alert marks | `ws-chart-alert` | #B1042F |
38
+ | Chip tints: needs you, done, needs work | `ws-tint-needs`, `ws-tint-live`, `ws-tint-needs-work` | |
39
+ | Hover washes (navy at .03, .05, .06) | `ws-hover-faint`, `ws-hover`, `ws-hover-strong` | |
40
+ | The ink of a wash, a ring or a line of your own; the tint of a drop | `ws-ink`, `ws-shade` | navy (in dark, the heading's light ink and black) |
41
+ | A floating navy message (a toast, the note tip) and the footer, and their words | `ws-inverse`, `ws-on-inverse` | the act and its words; in dark the brand navy and white |
42
+ | An off control (a switch's track at rest) | `ws-control-off` | #7F7F7F |
43
+ | The loading shimmer's ground: the ghost grey, with a lighter pass of the same grey (never a chart hue) | `ws-shimmer-ground` | #E3DFDB (`ws-ghost`) |
44
+ | A hero's glows, an assistant's working orb | `ws-glow-rose`, `ws-glow-pink`, `ws-glow-blue`, `ws-orb` | from the chart tones |
45
+ | Focus | `ws-focus-color` | navy |
33
46
  | Behind a dialog | `ws-scrim` | navy 35% |
34
47
 
48
+ For your own wash or shadow, write `color-mix(in srgb, var(--ws-ink) 5%, transparent)` and the same with `--ws-shade`:
49
+ they follow the theme and the palette. The 0.4 channels (`rgba(var(--ws-ink-rgb), a)`, `--ws-shade-rgb`) still paint,
50
+ but follow only the theme, never a palette. Never `--color-white` for a surface, `--color-gray-2` for a track or
51
+ `--color-brand-navy` for a mark; the semantic name is what turns in dark and in a palette. Brand artwork keeps the brand
52
+ navy.
53
+
54
+ Four kit names are aliases of product tokens, so they follow a palette too: `color-border-default` is `ws-edge`,
55
+ `color-border-hairline` is `ws-edge-card`, `color-stat-positive` is `ws-chart-finished` and `color-text-brand-strong`
56
+ is `ws-word-needs`.
57
+
58
+ ## Rating tones
59
+
60
+ One scale for a rating (a score, a check, a grade), the same on every screen (D10).
61
+
62
+ | Band | Mark | Words | Example |
63
+ | --- | --- | --- | --- |
64
+ | Strong | `ws-rating-strong` (teal) | `ws-word-positive` | "Strong", 72 of 100 |
65
+ | Getting there (the middle) | `ws-rating-middle` (mid blue) | `color-text-interactive` | "Getting there" |
66
+ | Needs work | `ws-rating-needs-work` (pink) | `ws-word-needs-work` | "Needs work", 39 of 100 |
67
+ | Not checked | every mark on `ws-track` | `color-text-muted` | "Could not check" |
68
+
69
+ A strip of ticks or a bar takes the band's one tone; its words take the band's word token. Salmon stays "needs you"
70
+ (acts and alerts that wait on the person), never a rating.
71
+
35
72
  ## States, in colour and a word
36
73
 
37
74
  | State | How it shows |
@@ -41,42 +78,93 @@ positive.
41
78
  | Done, passed | teal mark, `ws-word-positive` words ("Passed") |
42
79
  | Not yet | mid blue words ("Not yet"), never red |
43
80
  | Settled, the same | grey |
81
+ | Alert (something is wrong now) | an alert mark (`ws-chart-alert`) and `ws-word-alert` words |
44
82
  | Error | a salmon border on the field, a warning mark and `ws-word-needs` words under it |
45
83
 
46
84
  Never a state by colour alone: a word or a mark goes with it.
47
85
 
48
86
  ## Rules
49
87
 
50
- - **Navy is for words and the one button.** No navy pills, chips, badges or card buttons. The tab thumb and a selected
51
- toggle are the two navy fills a control may wear.
52
- - **Salmon is a data tone and small marks.** Never a button, a wash, a card, a strip or a word.
88
+ - **Navy is for words, the one button and a few named fills**: the tab or segmented thumb, a selected toggle, a checked
89
+ box, the navy note (a tooltip holding a question's full words), a count in the nav and a floating message (a toast, a
90
+ selection's ask). No navy pills, chips or badges scattered through content.
91
+ - **Salmon is a data tone and small marks.** Never a button, a wash, a card or a strip. A word in salmon's hue is
92
+ `ws-word-needs`, never the raw salmon.
53
93
  - **Mid blue is never a fill.**
54
- - **Teal, purple and salmon are the goal gradient**: a strip of ticks runs salmon (start) through purple (past halfway) to
55
- teal (finished); rows carry a stretch of it (`TickRow`). Never other gradients.
94
+ - **The goal gradient** (salmon, purple, teal) belongs to `GoalTicks` and `TickRow`: a strip of ticks running from the
95
+ start to finished. A strip that shows a rating takes one tone (Rating tones); `TickStrip` is one tone. Never other
96
+ gradients.
97
+ - **A falling number is mid blue**, never red. Alert red is for something wrong now (a count of reviews needing a
98
+ reply, a failed check), as a mark with its word.
56
99
  - **An assistant's mark** takes one of the four tones and keeps it; no other colour names it.
57
- - **The AI colours** (`color-ai-*`) exist only inside an assistant's orb mark, if the product has one, and as faint washes in
58
- `ws-cool-glow` and `ws-team-glow` behind a page hero. No conic rings, purple glows or gradient text anywhere.
100
+ - **The AI colours** (`color-ai-*`) exist only inside an assistant's orb mark, if the product has one, and as faint washes
101
+ in `ws-cool-glow` and `ws-team-glow` behind a page hero. No conic rings, purple glows or gradient text, except the
102
+ status line's word while an answer works (`StatusLine`, in the chart colours). The loading shimmer is one neutral
103
+ tone, the ghost grey and a lighter pass of it, never the chart colours (0.5.1).
59
104
  - **People are neutral**: a disc of `ws-surface-sunk` with navy initials.
60
105
  - **Marketing pages** keep the kit's own marketing colours (its gradient button, `color-text-primary`); they never enter a
61
106
  product screen.
107
+ - **Map Figma by value, never by name**: Seth's variable "Gray 5" (#7F7F7F) is the kit's `color-gray-6` and his "Gray 6"
108
+ (#545454) is the kit's `color-gray-7`.
62
109
 
63
- ## Contrast, measured on the cream (#FEFBF9)
110
+ ## Contrast: words AA on every ground
64
111
 
65
- | Pair | Ratio | Verdict |
66
- | --- | --- | --- |
67
- | navy on cream | 12.3 | AA, AAA |
68
- | gray-7 (#545454) on cream | 7.4 | AA, AAA |
69
- | mid blue on cream | 6.8 | AA |
70
- | purple #6D4FC2 on cream | 5.7 | AA (a word in purple is allowed) |
71
- | `ws-word-positive` #09787F on cream | 5.1 | AA |
72
- | `ws-word-needs` #B35040 on cream | 4.9 | AA |
73
- | teal #098486 on cream | 4.4 | marks only, not words |
74
- | `color-text-muted` #6E6E6E on cream | 4.95 | AA (5.1 on white, 4.5 on the sunk surface) |
75
- | gray-6 (#7F7F7F) on cream | 3.9 | a mark or a disabled control only, never words |
76
- | salmon #FF725C on cream | 2.6 | marks only |
77
- | `color-feedback-error` #EF6B51 on cream | 2.9 | a border only |
78
- | `color-text-placeholder` #6E6E6E on white | 5.1 | AA; still never the only label |
79
- | white on navy | 12.7 | AA, AAA |
80
-
81
- Every pair marked AA may carry words at any size, so muted words carry 12 and 13 px meta. gray-6 and the lighter greys
82
- are for marks, rules and disabled controls only, never words.
112
+ Every word token passes 4.5:1 on all eight grounds a word can sit on, in light, night and the navy ground. The token
113
+ generator computes it and stops the build on a fail; the full tables are in tokens.md. The light ratios:
114
+
115
+ | Word | cream | white | plate | tray | raised | shell | press | well |
116
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- |
117
+ | `color-text-heading` | 12.34 | 12.71 | 11.28 | 10.86 | 12.34 | 10.37 | 10.23 | 10.86 |
118
+ | `color-text-body` | 7.35 | 7.57 | 6.72 | 6.47 | 7.35 | 6.18 | 6.10 | 6.47 |
119
+ | `color-text-muted` | 5.57 | 5.74 | 5.10 | 4.90 | 5.57 | 4.69 | 4.62 | 4.90 |
120
+ | `color-text-interactive` | 6.78 | 6.98 | 6.20 | 5.97 | 6.78 | 5.70 | 5.62 | 5.97 |
121
+ | `ws-word-needs` | 5.45 | 5.62 | 4.99 | 4.80 | 5.45 | 4.59 | 4.52 | 4.80 |
122
+ | `ws-word-positive` | 5.58 | 5.75 | 5.10 | 4.91 | 5.58 | 4.69 | 4.63 | 4.91 |
123
+ | `ws-word-needs-work` | 5.80 | 5.97 | 5.30 | 5.10 | 5.80 | 4.87 | 4.81 | 5.10 |
124
+ | `ws-word-alert` | 6.96 | 7.17 | 6.37 | 6.13 | 6.96 | 5.85 | 5.77 | 6.13 |
125
+ | `ws-word-past-half` | 5.74 | 5.92 | 5.25 | 5.06 | 5.74 | 4.83 | 4.76 | 5.06 |
126
+
127
+ On their own tints: needs words 5.11, positive words 4.90, needs-work words 4.80. A placeholder on a field 5.10. White
128
+ on navy 12.71.
129
+
130
+ - **A mark keeps its exact tone** and needs 3:1 where it carries meaning: teal #098486, salmon #FF725C, pink #F370A4 and
131
+ the alert red stay marks; the words beside them take the word token.
132
+ - **Below AA is never a word**: Seth's #7F7F7F, #8A8A8A, #929292, raw teal, salmon and pink words become
133
+ `color-text-muted` or the tone's word token. `color-gray-6` and lighter greys are for marks, rules and disabled
134
+ controls only.
135
+ - **A word on the tray's foot** uses these tokens; each one passes there.
136
+
137
+ ## Dark theme
138
+
139
+ Opt-in, never automatic (D12). A page that sets nothing stays light.
140
+
141
+ | Want | Set on `<html>`, or on any container |
142
+ | --- | --- |
143
+ | Light (the default) | nothing, or `data-theme="light"` |
144
+ | Night, always | `data-theme="dark"` |
145
+ | Follow the person's system | `data-theme="system"` |
146
+ | The navy ground, for brand and event pages | `data-ground="navy"` beside `dark` or `system` |
147
+
148
+ - **Night** is the product's dark: shell #0A1118, stage #0F1922, raised #16222D. **Navy** is for brand and event pages:
149
+ the ground #021A32 with white mixed in as things lift. Product apps use night. On a container, the theme holds for
150
+ everything inside it, and the nearest one wins (light inside dark works, and the reverse).
151
+ - **Brand colours stay literal** in every theme: white is white, navy is navy, salmon is salmon. Only the semantic tokens
152
+ turn, which is why a component says `color-surface`, `ws-raised`, `ws-track`, `ws-field-ink`, `ws-on-act` and
153
+ `color-text-heading` rather than a palette colour.
154
+ - **Prefer a token over a theme selector.** If a component must write one, it uses `[data-theme="dark"] .ws-x` (on any
155
+ element, not only `:root`) and repeats it for `system` inside `@media (prefers-color-scheme: dark)`. Never a colour
156
+ literal in a component's styles: `build-bundle --check` fails on one.
157
+ - **Every word pair is AA in dark too** (the tables in tokens.md). In dark a navy mark is the heading's light ink; a
158
+ floating navy message (a note, a toast) keeps the brand navy with a faint light rim; the footer stays the navy band.
159
+ - **Floating things in dark** sit on `ws-raised` with a 0.5 px light rim and a black shadow (the floating shadows carry
160
+ it). Cards stay flat with their rim.
161
+ - **A person's choice** (System, Light, Dark) is `ThemeSwitch`: it reads the choice before first paint and turns every
162
+ surface at once.
163
+ - **Check it**: `node scripts/check-geometry.mjs --theme dark` (Checklist).
164
+
165
+ ## Palettes
166
+
167
+ An app with its own slightly different colours sets a palette, never its own values on `:root`: a built-in
168
+ (`data-palette="cool"` or `"warm"`) or one it writes from the contract, checks with `check-palette` and ships as
169
+ `check-palette --emit` writes it. A palette works on any element, light or dark, and every rule in this chapter holds
170
+ in it (Palettes).
@@ -1,41 +1,63 @@
1
1
  # Type
2
2
 
3
- One family, Instrument Sans (`--font-body`), from Google Fonts. Three weights: 400 body, 500 rows, buttons and values,
4
- 600 titles. Nothing bold (700). Tabular numerals on every figure.
3
+ One family, Instrument Sans (`--font-body`), from Google Fonts. Three weights: 400 body and figures, 500 rows, controls
4
+ and values, 600 titles. Nothing bold (700). Tabular numerals on every figure. Seth's steps (D6) are in the table.
5
5
 
6
6
  ## The hierarchy, by role
7
7
 
8
8
  | Role | Style | Size / line | Weight | Where |
9
9
  | --- | --- | --- | --- | --- |
10
- | A page's headline | `headline` | 26 / 32 | 600 | the app page's bar |
11
- | A hero's headline | `hero` | 40 / 48 | 600 | grows from 26 at the `lg` area (PageHero) |
12
- | The home greeting | `greeting` | 24 / 32 | 600 | "Morning, Ryan." |
13
- | A card's, pane's or dialog's title | `title` | 22 / 28, -0.5% | 600 | every card, side pane, panel |
14
- | A section inside a card, a tile's title | `section` | 16 / 20, -0.5% | 600 | "Where they came from" |
10
+ | A report's score | `ws-figure--score` | 96 / 96, -3% | 400 | the one hero figure on a report (`ScoreHero`) |
11
+ | A card's one number | `ws-display` | 72 / 80, -3% | 400 | GoalTicks; one per card |
12
+ | A pane's figure | `ws-figure--pane` | 44 / 48, untracked | 400 | a drawer's score, "1 of 6", a vendor's yearly cost |
13
+ | A big figure in a stat | `ws-figure` | 40 / 40, -3% | 400 | a metric tile, a card's stat |
14
+ | A tile's figure | `ws-figure--tile` | 32 / 38, -3% | 400 | a `StatTiles` tile, an inbox tile ("5.0", "10") |
15
+ | A row's figure | `ws-figure--row` | 28 / 32, -3% | 400 | a check row's score, right-aligned in its column |
16
+ | A hero's headline | `hero` | 40 / 48 | 600 | grows from 26 at the `lg` area (PageHero); a dashboard home's greeting |
17
+ | A page's headline | `headline` | 26 / 32 | 600 | a `PageHero` below the `lg` area |
18
+ | The home greeting | `greeting` | 24 / 32 | 600 | "Morning, Ryan." on a chat-first home |
19
+ | A card's, pane's or dialog's title | `ws-title` | 22 / 28, untracked, balanced | 600 | every card, drawer, panel; an area heading over its cards |
20
+ | A thread or app page's title | `thread` | 16 / 22 | 600 | the 56 px header ("Audit report") |
21
+ | A section, a finding, a fix, a column name, a stat's value | `ws-section` | 15 / 22, untracked, balanced | 600 | "Your AI visibility checks", "5 of 9" |
22
+ | A row's name | `ws-row-name` | 15 / 20 | 500 | "Local search" in a check row |
15
23
  | A value in a row, a chart row's number, a band's line | `value` | 16 / 20 | 600 (500 on the band) | charts, bands |
16
24
  | A chart's values and labels | `chart` | 15 / 20 | 400 | "26 Total calls" |
17
- | The chat's words | `message` | 15 / 24 | 400 | an agent's plain text, the person's bubble |
18
- | A row's title | `row-title` | 14 / 20 | 600 | a person, a fix, an idea |
19
- | Body, a card's line, a field's words | `body` | 14 / 20 | 400 | everywhere |
20
- | A button's or link's words | `button` | 14 / 16 | 500 | every button |
21
- | A time, a header's second word, the band's "how" | `meta` | 13 / 16 | 400 | muted |
22
- | Labels, chips, a row's detail, field labels | `dense` | 12 / 16 | 400 (500 in a chip or a field label) | ws-muted |
23
- | The uppercase label above a group | `eyebrow` | 12 / 16, +1.2 px | 600 | ws-eyebrow |
24
- | A chart's axis letters | `micro` | 11 / 16 | 400 | M T W; the floor |
25
- | A big figure in a tile or score | `figure` | 40 / 40, -3% | 400 | StatTiles |
26
- | A card's one number | `display` | 72 / 80, -3% | 400 | GoalTicks; one per card |
25
+ | The chat's words | `message` | 15 / 22 | 500 | an agent's answer, a step darker than body (`ChatTurn`); the person's bubble is 14 / 20 500 navy |
26
+ | Body, a description, a card's line, a field's words | `ws-body` | 14 / 20 | 400 | everywhere |
27
+ | Control words: tabs, buttons, tags, status words, stat labels | `ws-control-words` | 13 / 18 | 500 | "Refresh", "2 fixes", "Found" |
28
+ | A time, a header's second word, the band's "how" | `ws-meta` | 13 / 16 | 400 | muted |
29
+ | Labels, a row's detail, field labels | `ws-muted` | 12 / 16 | 400 (500 in a field label) | muted |
30
+ | The uppercase label above a group | `ws-eyebrow` | 12 / 16, +1.2 px | 600 | muted |
31
+ | A small sub-line under a name or a figure | `micro` | 11 / 13 | 400 or 500 | a list row's sub-line, a seat caption |
32
+ | A chart's axis letters | `micro` | 11 / 16 | 400 | M T W |
33
+
34
+ Tokens: `ws-text-score` and `ws-leading-score`, `ws-text-figure-lg`, `ws-text-figure`, `ws-text-figure-row` and their
35
+ `ws-leading-*`; `ws-text-section` with `ws-leading-section` (and `ws-leading-row` for a row's name); `ws-text-control`
36
+ with `ws-leading-control`; `ws-text-micro` with `ws-leading-micro` for a sub-line.
27
37
 
28
38
  ## Rules
29
39
 
30
40
  - **Every text takes its size from its role**, never from what its container leaves unsized (an unsized line inherits
31
41
  the page's 16 px).
32
- - **Nothing under 11 px**, and 11 only for a chart's axis letters. The kit's 10 px step is marketing only.
42
+ - **Nothing under 11 px.** 11 is only for an axis letter, a sub-line under a name or a figure, a key cap (`Kbd`) and a
43
+ small head, count or note, each passing AA on its ground. The kit's 10 px step is marketing only.
33
44
  - **Titles say the answer**: a sentence in sentence case, no colon, no trailing period. One per card.
34
- - **One 72 px number per card**, regular weight, with its change chip beside it; a second big number is a second card.
35
- - **Links and buttons are medium**, never underlined at rest; underlined under the pointer.
36
- - **Line length**: the chat's column is 656 px; running text elsewhere stays under about 70 characters a line.
45
+ - **Tracking**: only the figures are tightened (-3%: `ws-display`, `ws-figure` and the row, tile and score steps worn
46
+ with it); titles, sections and the pane's 44 are untracked, as Seth draws them. A long title or section balances its lines, so no word sits alone on the last.
47
+ - **One hero figure per card and per screen region**: a 96 px score on a report, or a 72 px number on a card, with its
48
+ change chip or rating word beside or under it. Smaller figures in rows (28) and a pane (44) are allowed alongside,
49
+ each in its own column; a second hero is a second card.
50
+ - **A figure keeps its size** at every width; what gives is the room around it.
51
+ - **Links and quiet acts are medium**, never underlined at rest; underlined under the pointer.
52
+ - **A cell whose full words show on hover or focus** carries a 1 px dotted underline, and the full words also show on
53
+ focus and on a tap (Accessibility).
54
+ - **Line length**: the chat's column is its shell's (Space and layout, Layout widths); running text elsewhere stays
55
+ under about 70 characters a line.
37
56
  - **Truncation**: a row's title truncates with an ellipsis and carries its full words in `title`; a card's title wraps,
38
- never truncates; a number never truncates (give it room or drop a word beside it).
57
+ never truncates; a number never truncates (give it room or drop a word beside it). A row stays one line so a narrow
58
+ column never pushes its button out; a sentence may wrap, its button never does (unless it opts in with `ws-btn--wrap`).
59
+ - **Text in a clipping box** gets a line height that clears its ink (or clips sideways only), so descenders are never cut.
39
60
  - **Long translations and names**: a label may be twice as long; a layout that breaks at that length is wrong, not the
40
61
  label.
41
- - **Marketing pages** use the kit's bigger steps (`kit-lg` to `kit-8xl`); the product never goes above 72.
62
+ - **A selected row keeps its type**: its weight may change, never its size or line height (Space and layout).
63
+ - **Marketing pages** use the kit's bigger steps (`kit-lg` to `kit-8xl`); the product's largest figure is the 96 px score.