@felloinnovations/brand-kit 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +197 -0
  3. package/README.md +34 -7
  4. package/design-system/01-how-claude-decides.md +26 -17
  5. package/design-system/02-principles.md +11 -6
  6. package/design-system/03-colour.md +134 -47
  7. package/design-system/04-type.md +45 -23
  8. package/design-system/05-space-and-layout.md +175 -52
  9. package/design-system/06-sizing-profiles.md +4 -4
  10. package/design-system/07-scrolling.md +66 -20
  11. package/design-system/08-choosing-components.md +50 -22
  12. package/design-system/09-charts.md +71 -28
  13. package/design-system/10-patterns.md +33 -10
  14. package/design-system/11-page-recipes.md +110 -23
  15. package/design-system/12-content.md +2 -1
  16. package/design-system/13-motion.md +330 -47
  17. package/design-system/14-accessibility.md +47 -24
  18. package/design-system/15-ai-experiences.md +11 -6
  19. package/design-system/16-creativity.md +1 -1
  20. package/design-system/17-decisions.md +357 -1
  21. package/design-system/18-checklist.md +79 -16
  22. package/design-system/19-public-pages.md +6 -4
  23. package/design-system/20-palettes.md +275 -0
  24. package/design-system/README.md +30 -17
  25. package/design-system/components/ActionList/README.md +96 -10
  26. package/design-system/components/ActionList/preview.html +52 -7
  27. package/design-system/components/ActionList/style.css +64 -0
  28. package/design-system/components/ActivityGrid/README.md +38 -2
  29. package/design-system/components/ActivityGrid/preview.html +1 -1
  30. package/design-system/components/ActivityGrid/style.css +35 -0
  31. package/design-system/components/AppShell/README.md +205 -75
  32. package/design-system/components/AppShell/preview.html +339 -58
  33. package/design-system/components/AppShell/style.css +154 -0
  34. package/design-system/components/Avatar/README.md +37 -10
  35. package/design-system/components/Avatar/preview.html +13 -4
  36. package/design-system/components/Avatar/style.css +14 -0
  37. package/design-system/components/Badge/README.md +41 -19
  38. package/design-system/components/Badge/preview.html +13 -10
  39. package/design-system/components/Badge/style.css +23 -0
  40. package/design-system/components/Banner/README.md +30 -9
  41. package/design-system/components/Banner/preview.html +1 -1
  42. package/design-system/components/Banner/style.css +19 -0
  43. package/design-system/components/Breadcrumb/README.md +58 -46
  44. package/design-system/components/Breadcrumb/preview.html +16 -16
  45. package/design-system/components/Breadcrumb/style.css +17 -0
  46. package/design-system/components/Button/README.md +113 -55
  47. package/design-system/components/Button/preview.html +98 -25
  48. package/design-system/components/Button/style.css +86 -0
  49. package/design-system/components/Card/README.md +158 -49
  50. package/design-system/components/Card/preview.html +141 -19
  51. package/design-system/components/Card/style.css +115 -0
  52. package/design-system/components/CardBoard/README.md +58 -37
  53. package/design-system/components/CardBoard/preview.html +26 -29
  54. package/design-system/components/ChatCard/README.md +115 -29
  55. package/design-system/components/ChatCard/preview.html +149 -32
  56. package/design-system/components/ChatCard/style.css +49 -0
  57. package/design-system/components/ChatShell/README.md +116 -0
  58. package/design-system/components/ChatShell/preview.html +201 -0
  59. package/design-system/components/ChatShell/style.css +86 -0
  60. package/design-system/components/ChatTurn/README.md +78 -35
  61. package/design-system/components/ChatTurn/preview.html +60 -28
  62. package/design-system/components/ChatTurn/style.css +50 -0
  63. package/design-system/components/CheckRow/README.md +141 -0
  64. package/design-system/components/CheckRow/preview.html +140 -0
  65. package/design-system/components/CheckRow/style.css +88 -0
  66. package/design-system/components/Checkbox/README.md +58 -22
  67. package/design-system/components/Checkbox/preview.html +112 -50
  68. package/design-system/components/Checkbox/style.css +45 -0
  69. package/design-system/components/Chip/README.md +78 -47
  70. package/design-system/components/Chip/preview.html +29 -4
  71. package/design-system/components/Chip/style.css +17 -0
  72. package/design-system/components/Combobox/README.md +44 -11
  73. package/design-system/components/Combobox/preview.html +35 -12
  74. package/design-system/components/Combobox/style.css +54 -0
  75. package/design-system/components/Composer/README.md +137 -35
  76. package/design-system/components/Composer/preview.html +115 -40
  77. package/design-system/components/Composer/style.css +81 -0
  78. package/design-system/components/ConfirmDialog/README.md +73 -52
  79. package/design-system/components/ConfirmDialog/preview.html +70 -26
  80. package/design-system/components/ConfirmDialog/style.css +5 -0
  81. package/design-system/components/Cover/preview.html +3 -3
  82. package/design-system/components/Cover/style.css +19 -0
  83. package/design-system/components/DateInput/README.md +77 -12
  84. package/design-system/components/DateInput/preview.html +27 -12
  85. package/design-system/components/DateInput/style.css +38 -0
  86. package/design-system/components/Dialog/README.md +112 -44
  87. package/design-system/components/Dialog/preview.html +141 -18
  88. package/design-system/components/Dialog/style.css +74 -0
  89. package/design-system/components/EmptyState/README.md +42 -12
  90. package/design-system/components/EmptyState/preview.html +11 -11
  91. package/design-system/components/EmptyState/style.css +9 -0
  92. package/design-system/components/EntryShell/README.md +73 -48
  93. package/design-system/components/EntryShell/preview.html +60 -27
  94. package/design-system/components/EntryShell/style.css +19 -0
  95. package/design-system/components/FeatureGrid/README.md +61 -39
  96. package/design-system/components/FeatureGrid/preview.html +2 -2
  97. package/design-system/components/FeatureGrid/style.css +20 -0
  98. package/design-system/components/FileUpload/README.md +33 -3
  99. package/design-system/components/FileUpload/preview.html +18 -4
  100. package/design-system/components/FileUpload/style.css +23 -0
  101. package/design-system/components/FilterBar/README.md +114 -0
  102. package/design-system/components/FilterBar/preview.html +82 -0
  103. package/design-system/components/FilterBar/style.css +22 -0
  104. package/design-system/components/Fold/README.md +84 -26
  105. package/design-system/components/Fold/preview.html +77 -34
  106. package/design-system/components/Fold/style.css +48 -0
  107. package/design-system/components/Footer/README.md +62 -39
  108. package/design-system/components/Footer/preview.html +5 -5
  109. package/design-system/components/Footer/style.css +30 -0
  110. package/design-system/components/FunnelBars/README.md +24 -3
  111. package/design-system/components/FunnelBars/preview.html +5 -5
  112. package/design-system/components/FunnelBars/style.css +13 -0
  113. package/design-system/components/GoalBars/README.md +54 -10
  114. package/design-system/components/GoalBars/preview.html +69 -28
  115. package/design-system/components/GoalBars/style.css +51 -0
  116. package/design-system/components/GoalTicks/README.md +74 -58
  117. package/design-system/components/GoalTicks/preview.html +41 -118
  118. package/design-system/components/GoalTicks/style.css +37 -0
  119. package/design-system/components/GoalTubes/README.md +29 -3
  120. package/design-system/components/GoalTubes/preview.html +6 -6
  121. package/design-system/components/GoalTubes/style.css +23 -0
  122. package/design-system/components/Heatmap/README.md +133 -0
  123. package/design-system/components/Heatmap/preview.html +168 -0
  124. package/design-system/components/Heatmap/style.css +119 -0
  125. package/design-system/components/Hero/README.md +58 -40
  126. package/design-system/components/Hero/preview.html +1 -1
  127. package/design-system/components/Hero/style.css +19 -0
  128. package/design-system/components/HoverCard/README.md +114 -0
  129. package/design-system/components/HoverCard/preview.html +107 -0
  130. package/design-system/components/HoverCard/style.css +59 -0
  131. package/design-system/components/IconButton/README.md +69 -38
  132. package/design-system/components/IconButton/preview.html +77 -43
  133. package/design-system/components/IconButton/style.css +45 -0
  134. package/design-system/components/Input/README.md +36 -11
  135. package/design-system/components/Input/preview.html +1 -1
  136. package/design-system/components/Input/style.css +23 -0
  137. package/design-system/components/KanbanBoard/README.md +93 -45
  138. package/design-system/components/KanbanBoard/preview.html +159 -43
  139. package/design-system/components/KanbanBoard/style.css +53 -0
  140. package/design-system/components/Kbd/README.md +25 -9
  141. package/design-system/components/Kbd/preview.html +6 -2
  142. package/design-system/components/Kbd/style.css +9 -0
  143. package/design-system/components/KitButton/README.md +81 -47
  144. package/design-system/components/KitButton/preview.html +35 -13
  145. package/design-system/components/KitButton/style.css +46 -0
  146. package/design-system/components/KitCard/README.md +75 -44
  147. package/design-system/components/KitCard/preview.html +18 -10
  148. package/design-system/components/KitCard/style.css +15 -0
  149. package/design-system/components/KitInput/README.md +54 -39
  150. package/design-system/components/KitInput/preview.html +7 -7
  151. package/design-system/components/KitInput/style.css +23 -0
  152. package/design-system/components/Leaderboard/README.md +76 -49
  153. package/design-system/components/Leaderboard/preview.html +61 -26
  154. package/design-system/components/Leaderboard/style.css +44 -0
  155. package/design-system/components/ListDetail/README.md +222 -0
  156. package/design-system/components/ListDetail/preview.html +213 -0
  157. package/design-system/components/ListDetail/style.css +148 -0
  158. package/design-system/components/LoadBar/README.md +79 -0
  159. package/design-system/components/LoadBar/preview.html +40 -0
  160. package/design-system/components/LoadBar/style.css +17 -0
  161. package/design-system/components/MarketingNav/README.md +76 -42
  162. package/design-system/components/MarketingNav/preview.html +37 -8
  163. package/design-system/components/MarketingNav/style.css +45 -0
  164. package/design-system/components/Matrix/README.md +129 -0
  165. package/design-system/components/Matrix/preview.html +99 -0
  166. package/design-system/components/Matrix/style.css +84 -0
  167. package/design-system/components/Menu/README.md +117 -41
  168. package/design-system/components/Menu/preview.html +85 -23
  169. package/design-system/components/Menu/style.css +61 -0
  170. package/design-system/components/Meter/README.md +39 -4
  171. package/design-system/components/Meter/preview.html +18 -1
  172. package/design-system/components/Meter/style.css +23 -0
  173. package/design-system/components/MetricTile/README.md +237 -0
  174. package/design-system/components/MetricTile/preview.html +241 -0
  175. package/design-system/components/MetricTile/style.css +129 -0
  176. package/design-system/components/Morph/README.md +106 -0
  177. package/design-system/components/Morph/preview.html +103 -0
  178. package/design-system/components/Morph/style.css +31 -0
  179. package/design-system/components/Motion/README.md +164 -0
  180. package/design-system/components/Motion/preview.html +2537 -0
  181. package/design-system/components/NumberInput/README.md +27 -8
  182. package/design-system/components/NumberInput/preview.html +21 -5
  183. package/design-system/components/NumberInput/style.css +34 -0
  184. package/design-system/components/PaceBar/README.md +75 -0
  185. package/design-system/components/PaceBar/preview.html +67 -0
  186. package/design-system/components/PaceBar/style.css +25 -0
  187. package/design-system/components/Page/README.md +57 -18
  188. package/design-system/components/Page/preview.html +15 -17
  189. package/design-system/components/Page/style.css +7 -0
  190. package/design-system/components/PageBar/README.md +90 -34
  191. package/design-system/components/PageBar/preview.html +60 -19
  192. package/design-system/components/PageBar/style.css +35 -0
  193. package/design-system/components/PageHero/README.md +87 -51
  194. package/design-system/components/PageHero/preview.html +35 -6
  195. package/design-system/components/PageHero/style.css +31 -0
  196. package/design-system/components/Pagination/README.md +70 -49
  197. package/design-system/components/Pagination/preview.html +24 -15
  198. package/design-system/components/Pagination/style.css +12 -0
  199. package/design-system/components/Panel/README.md +109 -51
  200. package/design-system/components/Panel/preview.html +118 -20
  201. package/design-system/components/Panel/style.css +51 -0
  202. package/design-system/components/PasswordInput/README.md +50 -18
  203. package/design-system/components/PasswordInput/preview.html +71 -21
  204. package/design-system/components/PasswordInput/style.css +31 -0
  205. package/design-system/components/Plate/README.md +75 -17
  206. package/design-system/components/Plate/preview.html +40 -7
  207. package/design-system/components/Plate/style.css +37 -0
  208. package/design-system/components/Popover/README.md +70 -49
  209. package/design-system/components/Popover/preview.html +44 -22
  210. package/design-system/components/Popover/style.css +41 -0
  211. package/design-system/components/PricingTable/README.md +69 -49
  212. package/design-system/components/PricingTable/preview.html +21 -21
  213. package/design-system/components/PricingTable/style.css +21 -0
  214. package/design-system/components/ProgressPetals/README.md +31 -3
  215. package/design-system/components/ProgressPetals/preview.html +14 -15
  216. package/design-system/components/ProgressPetals/style.css +27 -0
  217. package/design-system/components/README.md +151 -0
  218. package/design-system/components/Radio/README.md +40 -17
  219. package/design-system/components/Radio/preview.html +16 -1
  220. package/design-system/components/Radio/style.css +21 -0
  221. package/design-system/components/RankBar/README.md +29 -2
  222. package/design-system/components/RankBar/preview.html +14 -12
  223. package/design-system/components/RankBar/style.css +18 -0
  224. package/design-system/components/Ring/README.md +61 -11
  225. package/design-system/components/Ring/preview.html +55 -10
  226. package/design-system/components/Ring/style.css +49 -0
  227. package/design-system/components/ScoreHero/README.md +91 -0
  228. package/design-system/components/ScoreHero/preview.html +104 -0
  229. package/design-system/components/ScoreHero/style.css +32 -0
  230. package/design-system/components/Section/README.md +72 -33
  231. package/design-system/components/Section/preview.html +46 -16
  232. package/design-system/components/Section/style.css +18 -0
  233. package/design-system/components/Segmented/README.md +100 -55
  234. package/design-system/components/Segmented/preview.html +107 -26
  235. package/design-system/components/Segmented/style.css +94 -0
  236. package/design-system/components/SegmentedProgress/README.md +64 -0
  237. package/design-system/components/SegmentedProgress/preview.html +69 -0
  238. package/design-system/components/SegmentedProgress/style.css +11 -0
  239. package/design-system/components/Select/README.md +47 -12
  240. package/design-system/components/Select/preview.html +28 -2
  241. package/design-system/components/Select/style.css +22 -0
  242. package/design-system/components/ShareBar/README.md +69 -0
  243. package/design-system/components/ShareBar/preview.html +72 -0
  244. package/design-system/components/ShareBar/style.css +25 -0
  245. package/design-system/components/SideList/README.md +147 -0
  246. package/design-system/components/SideList/preview.html +139 -0
  247. package/design-system/components/SideList/style.css +94 -0
  248. package/design-system/components/Skeleton/README.md +52 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +22 -0
  251. package/design-system/components/Slider/README.md +95 -0
  252. package/design-system/components/Slider/preview.html +49 -0
  253. package/design-system/components/Slider/style.css +13 -0
  254. package/design-system/components/Split/README.md +112 -0
  255. package/design-system/components/Split/preview.html +105 -0
  256. package/design-system/components/Split/style.css +30 -0
  257. package/design-system/components/Starter/README.md +21 -9
  258. package/design-system/components/Starter/preview.html +5 -5
  259. package/design-system/components/Stat/README.md +64 -43
  260. package/design-system/components/Stat/preview.html +3 -3
  261. package/design-system/components/Stat/style.css +15 -0
  262. package/design-system/components/StatTiles/README.md +88 -44
  263. package/design-system/components/StatTiles/preview.html +142 -71
  264. package/design-system/components/StatTiles/style.css +64 -0
  265. package/design-system/components/StatusLine/README.md +85 -0
  266. package/design-system/components/StatusLine/preview.html +49 -0
  267. package/design-system/components/StatusLine/style.css +14 -0
  268. package/design-system/components/StatusScreen/README.md +49 -35
  269. package/design-system/components/StatusScreen/preview.html +20 -5
  270. package/design-system/components/StatusScreen/style.css +9 -0
  271. package/design-system/components/StepLine/README.md +97 -0
  272. package/design-system/components/StepLine/preview.html +108 -0
  273. package/design-system/components/StepLine/style.css +62 -0
  274. package/design-system/components/Stepper/README.md +35 -13
  275. package/design-system/components/Stepper/style.css +13 -0
  276. package/design-system/components/StreakCalendar/README.md +22 -1
  277. package/design-system/components/StreakCalendar/preview.html +10 -10
  278. package/design-system/components/StreakCalendar/style.css +12 -0
  279. package/design-system/components/SuggestionChip/README.md +87 -0
  280. package/design-system/components/SuggestionChip/preview.html +42 -0
  281. package/design-system/components/SuggestionChip/style.css +20 -0
  282. package/design-system/components/Switch/README.md +44 -24
  283. package/design-system/components/Switch/preview.html +23 -8
  284. package/design-system/components/Switch/style.css +31 -0
  285. package/design-system/components/Table/README.md +129 -58
  286. package/design-system/components/Table/preview.html +106 -72
  287. package/design-system/components/Table/style.css +104 -0
  288. package/design-system/components/Tabs/README.md +71 -46
  289. package/design-system/components/Tabs/preview.html +56 -24
  290. package/design-system/components/Tabs/style.css +44 -0
  291. package/design-system/components/Testimonial/README.md +48 -32
  292. package/design-system/components/Testimonial/preview.html +14 -14
  293. package/design-system/components/Testimonial/style.css +12 -0
  294. package/design-system/components/TextArea/README.md +27 -11
  295. package/design-system/components/TextArea/preview.html +8 -2
  296. package/design-system/components/TextArea/style.css +12 -0
  297. package/design-system/components/ThemeSwitch/README.md +116 -0
  298. package/design-system/components/ThemeSwitch/preview.html +57 -0
  299. package/design-system/components/ThemeSwitch/style.css +6 -0
  300. package/design-system/components/TickRow/README.md +52 -36
  301. package/design-system/components/TickRow/preview.html +64 -41
  302. package/design-system/components/TickRow/style.css +23 -0
  303. package/design-system/components/TickStrip/README.md +95 -0
  304. package/design-system/components/TickStrip/preview.html +88 -0
  305. package/design-system/components/TickStrip/style.css +42 -0
  306. package/design-system/components/Tile/README.md +79 -18
  307. package/design-system/components/Tile/preview.html +91 -40
  308. package/design-system/components/Tile/style.css +36 -0
  309. package/design-system/components/Timeline/README.md +68 -48
  310. package/design-system/components/Timeline/preview.html +27 -15
  311. package/design-system/components/Timeline/style.css +25 -0
  312. package/design-system/components/Toast/README.md +70 -38
  313. package/design-system/components/Toast/preview.html +43 -8
  314. package/design-system/components/Toast/style.css +25 -0
  315. package/design-system/components/Tooltip/README.md +93 -35
  316. package/design-system/components/Tooltip/preview.html +69 -15
  317. package/design-system/components/Tooltip/style.css +78 -0
  318. package/design-system/components/TopBar/README.md +67 -53
  319. package/design-system/components/TopBar/preview.html +14 -27
  320. package/design-system/components/TopBar/style.css +35 -0
  321. package/design-system/components/TopicRail/README.md +108 -0
  322. package/design-system/components/TopicRail/preview.html +58 -0
  323. package/design-system/components/TopicRail/style.css +48 -0
  324. package/design-system/components/TrendBars/README.md +52 -14
  325. package/design-system/components/TrendBars/preview.html +65 -32
  326. package/design-system/components/TrendBars/style.css +25 -0
  327. package/design-system/components/TrendLine/README.md +164 -0
  328. package/design-system/components/TrendLine/preview.html +373 -0
  329. package/design-system/components/TrendLine/style.css +155 -0
  330. package/design-system/components/Well/README.md +64 -22
  331. package/design-system/components/Well/preview.html +14 -14
  332. package/design-system/components/Well/style.css +22 -0
  333. package/design-system/components/_house.css +324 -0
  334. package/design-system/components/bundle.css +4091 -744
  335. package/design-system/tokens.json +1314 -124
  336. package/dist/fello-core.css +2 -2
  337. package/dist/fello.css +6 -1369
  338. package/dist/fello.scoped.css +7 -0
  339. package/dist/index.d.ts +110 -11
  340. package/dist/index.js +781 -96
  341. package/dist/palettes.d.ts +464 -0
  342. package/dist/palettes.js +497 -0
  343. package/dist/scoped.d.ts +3 -0
  344. package/dist/scoped.js +16 -0
  345. package/dist/toast.d.ts +14 -0
  346. package/dist/toast.js +33 -29
  347. package/dist/tokens.d.ts +1686 -62
  348. package/dist/tokens.js +1668 -61
  349. package/package.json +20 -4
  350. package/scripts/check-palette.mjs +295 -0
  351. package/scripts/token-model.mjs +552 -0
  352. package/tokens/_dark.css +174 -0
  353. package/tokens/_palettes.css +46 -0
  354. package/tokens/_product.css +266 -53
  355. package/tokens/_source.hubl.css +39 -19
  356. package/tokens/design-tokens.json +319 -0
  357. package/tokens/palettes.ts +504 -0
  358. package/tokens/shadcn-compat.css +19 -19
  359. package/tokens/shadcn-compat.hsl.css +76 -0
  360. package/tokens/tokens.css +1292 -62
  361. package/tokens/tokens.md +588 -61
  362. package/tokens/tokens.root.css +1298 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -22,7 +22,7 @@
22
22
  <div class="ws-dots ws-funnel-bars__body" role="img" aria-label="New leads 500, contacted 310, qualified 140, showing 72, closed 21">
23
23
  <div class="ws-funnel-bars__row" aria-hidden="true">
24
24
  <div class="ws-funnel-bars__track">
25
- <div class="ws-funnel-bars__fill ws-funnel-bars__fill--first ws-grow" style="width: 100%; background: var(--color-brand-navy);"></div>
25
+ <div class="ws-funnel-bars__fill ws-grow" style="width: 100%; background: var(--color-text-heading);"></div>
26
26
  </div>
27
27
  <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">500</span><span class="ws-funnel-bars__label">New leads</span></span>
28
28
  </div>
@@ -35,7 +35,7 @@
35
35
 
36
36
  <div class="ws-funnel-bars__row" aria-hidden="true">
37
37
  <div class="ws-funnel-bars__track">
38
- <div class="ws-funnel-bars__fill ws-grow" style="width: 62%; background: var(--ws-chart-navy-fade); animation-delay: 40ms;"></div>
38
+ <div class="ws-funnel-bars__fill ws-grow" style="width: 62%; background: var(--ws-chart-navy-fade); --i: 1;"></div>
39
39
  </div>
40
40
  <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">310</span><span class="ws-funnel-bars__label">Contacted</span></span>
41
41
  </div>
@@ -48,7 +48,7 @@
48
48
 
49
49
  <div class="ws-funnel-bars__row" aria-hidden="true">
50
50
  <div class="ws-funnel-bars__track">
51
- <div class="ws-funnel-bars__fill ws-grow" style="width: 28%; background: var(--ws-chart-salmon-fade); animation-delay: 80ms;"></div>
51
+ <div class="ws-funnel-bars__fill ws-grow" style="width: 28%; background: var(--ws-chart-salmon-fade); --i: 2;"></div>
52
52
  </div>
53
53
  <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">140</span><span class="ws-funnel-bars__label">Qualified</span></span>
54
54
  </div>
@@ -61,7 +61,7 @@
61
61
 
62
62
  <div class="ws-funnel-bars__row" aria-hidden="true">
63
63
  <div class="ws-funnel-bars__track">
64
- <div class="ws-funnel-bars__fill ws-grow" style="width: 14.4%; background: var(--ws-chart-purple-fade); animation-delay: 120ms;"></div>
64
+ <div class="ws-funnel-bars__fill ws-grow" style="width: 14.4%; background: var(--ws-chart-purple-fade); --i: 3;"></div>
65
65
  </div>
66
66
  <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">72</span><span class="ws-funnel-bars__label">Showing</span></span>
67
67
  </div>
@@ -74,7 +74,7 @@
74
74
 
75
75
  <div class="ws-funnel-bars__row" aria-hidden="true">
76
76
  <div class="ws-funnel-bars__track">
77
- <div class="ws-funnel-bars__fill ws-grow" style="width: 4.2%; background: var(--ws-chart-teal-fade); animation-delay: 160ms;"></div>
77
+ <div class="ws-funnel-bars__fill ws-grow" style="width: 4.2%; background: var(--ws-chart-teal-fade); --i: 4;"></div>
78
78
  </div>
79
79
  <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">21</span><span class="ws-funnel-bars__label">Closed</span></span>
80
80
  </div>
@@ -0,0 +1,13 @@
1
+ /* ---- FunnelBars: a pipeline's stages as bars that narrow, each step's share to the next between them ---- */
2
+ .ws-funnel-bars__body { display: flex; flex-direction: column; padding: var(--space-md) var(--ws-card-inset) var(--space-lg); }
3
+ .ws-funnel-bars__row { display: flex; align-items: center; gap: var(--space-sm); }
4
+ .ws-funnel-bars__track { position: relative; flex: 1; height: var(--space-lg); }
5
+ .ws-funnel-bars__fill { display: flex; align-items: center; height: 100%; border-radius: var(--ws-radius-control); transform-origin: left; }
6
+ .ws-funnel-bars__figure { display: flex; flex-shrink: 0; align-items: baseline; gap: var(--space-xxs); width: calc(var(--space-7xl) + var(--space-md) + var(--space-xxs)); font-size: var(--ws-text-chart); }
7
+ .ws-funnel-bars__count { font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
8
+ .ws-funnel-bars__label { color: var(--color-text-body); }
9
+ .ws-funnel-bars__between { display: flex; align-items: center; gap: var(--space-xxs); padding: var(--space-xxs) 0 var(--space-xxs) var(--space-xxs); }
10
+ /* The fill (North): 700 ms on the settle curve, the stages 45 ms apart (style="--i: n" on each fill). */
11
+ @media (prefers-reduced-motion: no-preference) {
12
+ .ws-funnel-bars__fill.ws-grow { animation-duration: var(--ws-duration-fill); animation-timing-function: var(--ws-ease-settle); animation-delay: calc(var(--i, 0) * var(--ws-stagger-row)); }
13
+ }
@@ -15,13 +15,23 @@ Horizontal goal bars: one pill a row, its fill a tone's gradient, a count and la
15
15
 
16
16
  **Anatomy**
17
17
 
18
- - Row height `calc(--space-lg + --space-xxs)` (28 px): a track (a pill, `--radius-full`, a half-strength tone outline) ending `calc(--space-lg - --space-xxs/8)` short at the right for the leader and dot.
19
- - Fill: `calc(--space-md + --space-xxs/2)` tall (18 px), inset `calc(--space-xxs * 1.25)` from the track's start, a `linear-gradient(90deg, tone-fade, tone-solid)` the row's share of its goal, growing from the left when the card first shows.
20
- - "Not yet": a faint dotted texture in the tone at 40%, from the fill's end to the track's end.
21
- - Leader and dot: a half-strength line from the fill's end out past the track to a small `calc(--space-xs * 0.875)` (7 px) solid dot, so every row's dot sits past its own bar however long.
22
- - Count: 16 px semibold (`--ws-text-value`), centred over two digits; `of` reads in medium muted beside it when the row names what it is out of.
23
- - A 1 px hairline (`--ws-edge-card`) splits the count from the label.
24
- - Label: 16 px medium (`--ws-text-value`), `color-text-heading`, truncates with an ellipsis; a link when the row opens somewhere, plain words otherwise.
18
+ - One grid for every row (issue #5): the rows are subgrid rows, so the columns line up down the card. Columns: the
19
+ bar (the rest), the count (as wide as the widest count, at least 18, right-aligned), the hairline, the label (as
20
+ wide as the widest label, at most 120). 16 between rows; in a card 20 at the top and sides, 40 under the rows.
21
+ - Bar, 28 tall: a track (a pill with a half-strength tone outline) ending 24 short at the right for the leader and
22
+ dot; inside it, 4 in from the start, the fill (18 tall, a `linear-gradient(90deg, tone-fade, tone)`, the row's
23
+ share), and from just past the fill to the track's end the "not yet" dots: two bands 4 tall, 13 apart, dots in the
24
+ tone at 40% (Seth).
25
+ - Leader and dot: a 1 px line in the tone at 50% from the fill's end out past the track to a 7 px dot, so every row's
26
+ dot sits at the same x however long its bar.
27
+ - Count: 16/20 semibold, tabular; "of 20" in medium muted beside it.
28
+ - Hairline: 1 x 20, `--ws-edge-card`, 4 from the count and 4 from the label.
29
+ - Label: 16/20 medium navy, one line with an ellipsis and its `title`; a link when the row opens somewhere. An optional
30
+ line under it (`__words` holding `__label` and `__line`): 12/16 muted, one line, its `title`.
31
+ - Label first (`--label-first`, issue #11): the words (15/20 navy) first, a 12 px bar up to 402 wide with 2 px corners
32
+ (a solid fill in the tone, the rest a 4 px dotted grid in the tone at 55%), the figure in a 36 px right column,
33
+ 16 between columns; rows at least 40 tall with a 0.5 px rule between them (none above the first). In a card under 30rem the bar drops under its
34
+ words (8 between, 12 above and below).
25
35
 
26
36
  **Variants and sizes**
27
37
 
@@ -31,20 +41,32 @@ Horizontal goal bars: one pill a row, its fill a tone's gradient, a count and la
31
41
  | `rows[].of` | The bar is that row's own share of `of`, not of the chart's shared `max`; the count then reads "12 of 15" |
32
42
  | `wide` | The label column takes more room than the bars (a phrase, not a word or two) |
33
43
  | `rows[].href` | The label becomes a link that opens the row's detail |
44
+ | `rows[].line` | A muted second line under the label |
45
+ | `--label-first` | Words first, a thin bar with a dotted remainder, the figure last |
46
+
47
+ **Parts and modifiers**
48
+
49
+ - `.ws-goal-bars--wide`: phrase labels: the label column takes 1.2 of the row to the bar's 0.8 and wraps.
50
+ - `.ws-goal-bars__of`: the muted "of 40" after a count, medium.
51
+ - `.ws-goal-bars__bar`: the label-first 12 px bar (up to 402 wide), its remainder a dotted line in the tone.
52
+ - `.ws-goal-bars__bar-fill`: the label-first bar's fill, `--pct` wide in `--tone`.
34
53
 
35
54
  **States**
36
55
 
37
- - Default: each fill grows from the track's start on `ws-grow`, the rows staggered one after another.
56
+ - Default: with `--draw`, each fill grows from the start over 700 ms on the settle curve, the rows 45 ms apart
57
+ (`--ws-stagger-row`, `--i` on each row).
38
58
  - Empty: a row with nothing counted shows its full "not yet" track and a 0, never an invented share.
39
59
  - Long label: truncates with an ellipsis (plain) or wraps (`wide`), the bar and count never move.
40
- - Linked: the label underlines on hover, shows the focus ring, and (built on `Card`'s link behaviour) a pending edge while its page loads.
60
+ - Linked: the label underlines on hover (with a hovering pointer) and shows the 2 px navy focus ring; the row is not
61
+ `aria-hidden` then, only its bar.
41
62
  - Disabled / error / hover state on the bar itself / pressed / selected: do not apply to the bar; only a linked label has interactive states.
42
63
  - Reduced motion: every fill is simply at its final width.
43
64
 
44
65
  **Behaviour**
45
66
 
46
67
  - The whole chart is one `<figure aria-label="…">` naming every row's count and label; the bars, tracks and dots are `aria-hidden`.
47
- - Motion: each fill grows left to right over `--ws-duration-calm` on the soft curve, staggered by `staggerDelay(i)` so the rows fill in order, not at once; still with reduced motion.
68
+ - Motion: each fill grows left to right over `--ws-duration-fill` on `--ws-ease-settle`, 45 ms apart; still with
69
+ reduced motion.
48
70
  - A linked label is a normal link: Tab reaches it, Enter opens it, focus shows the kit's focus ring.
49
71
 
50
72
  **Content**
@@ -69,4 +91,26 @@ Horizontal goal bars: one pill a row, its fill a tone's gradient, a count and la
69
91
 
70
92
  **Source**
71
93
 
94
+ - **Field fixes**: issue #5 (one grid, the count column as wide as its widest count, from Ignite's `GoalBars`), issue
95
+ #11 (the label-first row with a dotted remainder, Ignite's `AppIntro`), the leader the README promised, Seth's two
96
+ bands of "not yet" dots, the second line, the descender clip (line 20).
72
97
  - **Derived from**: the system's colour and motion rules (tone colours, `ws-grow`, staggered fills). **Precedent**: the first product built on the system.
98
+
99
+ **Markup**
100
+
101
+ ```html
102
+ <div class="ws-dots ws-goal-bars ws-goal-bars--in-card ws-goal-bars--draw" role="img" aria-label="14 cold calls, 8 live transfers">
103
+ <div class="ws-goal-bars__row" style="--i: 0; --tone: var(--ws-chart-under-half); --tone-fade: var(--ws-chart-salmon-fade); --pct: 35%;" aria-hidden="true">
104
+ <span class="ws-goal-bars__meter">
105
+ <span class="ws-goal-bars__track"></span>
106
+ <span class="ws-goal-bars__fillbox"><span class="ws-goal-bars__not-yet"></span><span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span></span>
107
+ <span class="ws-goal-bars__dot"></span>
108
+ </span>
109
+ <span class="ws-goal-bars__count">14</span>
110
+ <span class="ws-goal-bars__divider"></span>
111
+ <span class="ws-goal-bars__label" title="Cold calls">Cold calls</span>
112
+ </div>
113
+ </div>
114
+ ```
115
+
116
+ **Styles**: `GoalBars/style.css`, in `bundle.css` and `fello.css` as `.ws-goal-bars`. Every value is a token.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Charts" height=575 -->
1
+ <!-- @dsCard group="Charts" height=1180 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -20,58 +20,58 @@
20
20
  <p class="ws-body">Nine days early. Cold calls did most of the work.</p>
21
21
  </div>
22
22
  </header>
23
- <div class="ws-dots ws-goal-bars ws-goal-bars--in-card" role="img" aria-label="26 Total calls, 14 Cold calls, 8 Live transfers, 4 Follow-ups">
24
- <div class="ws-goal-bars__row" style="--tone: var(--color-brand-navy); --tone-fade: var(--ws-chart-navy-fade); --pct: 65%;" aria-hidden="true">
23
+ <div class="ws-dots ws-goal-bars ws-goal-bars--in-card ws-goal-bars--draw" role="img" aria-label="26 Total calls, 14 Cold calls, 8 Live transfers, 4 Follow-ups">
24
+ <div class="ws-goal-bars__row" style="--i: 0; --tone: var(--color-text-heading); --tone-fade: var(--ws-chart-navy-fade); --pct: 65%;" aria-hidden="true">
25
25
  <span class="ws-goal-bars__meter">
26
26
  <span class="ws-goal-bars__track"></span>
27
27
  <span class="ws-goal-bars__fillbox">
28
28
  <span class="ws-goal-bars__not-yet"></span>
29
- <span class="ws-goal-bars__fill ws-grow"></span>
29
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
30
30
  </span>
31
31
  <span class="ws-goal-bars__dot"></span>
32
32
  </span>
33
33
  <span class="ws-goal-bars__count">26</span>
34
34
  <span class="ws-goal-bars__divider"></span>
35
- <span class="ws-goal-bars__label">Total calls</span>
35
+ <span class="ws-goal-bars__label" title="Total calls">Total calls</span>
36
36
  </div>
37
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-under-half); --tone-fade: var(--ws-chart-salmon-fade); --pct: 35%;" aria-hidden="true">
37
+ <div class="ws-goal-bars__row" style="--i: 1; --tone: var(--ws-chart-under-half); --tone-fade: var(--ws-chart-salmon-fade); --pct: 35%;" aria-hidden="true">
38
38
  <span class="ws-goal-bars__meter">
39
39
  <span class="ws-goal-bars__track"></span>
40
40
  <span class="ws-goal-bars__fillbox">
41
41
  <span class="ws-goal-bars__not-yet"></span>
42
- <span class="ws-goal-bars__fill ws-grow" style="animation-delay: 40ms;"></span>
42
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
43
43
  </span>
44
44
  <span class="ws-goal-bars__dot"></span>
45
45
  </span>
46
46
  <span class="ws-goal-bars__count">14</span>
47
47
  <span class="ws-goal-bars__divider"></span>
48
- <span class="ws-goal-bars__label">Cold calls</span>
48
+ <span class="ws-goal-bars__label" title="Cold calls">Cold calls</span>
49
49
  </div>
50
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-past-half); --tone-fade: var(--ws-chart-purple-fade); --pct: 20%;" aria-hidden="true">
50
+ <div class="ws-goal-bars__row" style="--i: 2; --tone: var(--ws-chart-past-half); --tone-fade: var(--ws-chart-purple-fade); --pct: 20%;" aria-hidden="true">
51
51
  <span class="ws-goal-bars__meter">
52
52
  <span class="ws-goal-bars__track"></span>
53
53
  <span class="ws-goal-bars__fillbox">
54
54
  <span class="ws-goal-bars__not-yet"></span>
55
- <span class="ws-goal-bars__fill ws-grow" style="animation-delay: 80ms;"></span>
55
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
56
56
  </span>
57
57
  <span class="ws-goal-bars__dot"></span>
58
58
  </span>
59
59
  <span class="ws-goal-bars__count">8</span>
60
60
  <span class="ws-goal-bars__divider"></span>
61
- <span class="ws-goal-bars__label">Live transfers</span>
61
+ <span class="ws-goal-bars__label" title="Live transfers">Live transfers</span>
62
62
  </div>
63
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-finished); --tone-fade: var(--ws-chart-teal-fade); --pct: 10%;" aria-hidden="true">
63
+ <div class="ws-goal-bars__row" style="--i: 3; --tone: var(--ws-chart-finished); --tone-fade: var(--ws-chart-teal-fade); --pct: 10%;" aria-hidden="true">
64
64
  <span class="ws-goal-bars__meter">
65
65
  <span class="ws-goal-bars__track"></span>
66
66
  <span class="ws-goal-bars__fillbox">
67
67
  <span class="ws-goal-bars__not-yet"></span>
68
- <span class="ws-goal-bars__fill ws-grow" style="animation-delay: 120ms;"></span>
68
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
69
69
  </span>
70
70
  <span class="ws-goal-bars__dot"></span>
71
71
  </span>
72
72
  <span class="ws-goal-bars__count">4</span>
73
73
  <span class="ws-goal-bars__divider"></span>
74
- <span class="ws-goal-bars__label">Follow-ups</span>
74
+ <span class="ws-goal-bars__label" title="Follow-ups">Follow-ups</span>
75
75
  </div>
76
76
  </div>
77
77
  <div class="ws-band">
@@ -88,32 +88,32 @@
88
88
  <div class="ws-stack">
89
89
  <span class="ws-muted">You beside others: yours teal, theirs purple, both "of" a shared target</span>
90
90
  <div style="width: 320px; max-width: 100%;">
91
- <div class="ws-card ws-card--inset ws-goal-bars">
92
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-finished); --tone-fade: var(--ws-chart-teal-fade); --pct: 70%;" aria-hidden="true">
91
+ <div class="ws-card ws-card--inset ws-goal-bars ws-goal-bars--draw">
92
+ <div class="ws-goal-bars__row" style="--i: 0; --tone: var(--ws-chart-finished); --tone-fade: var(--ws-chart-teal-fade); --pct: 70%;" aria-hidden="true">
93
93
  <span class="ws-goal-bars__meter">
94
94
  <span class="ws-goal-bars__track"></span>
95
95
  <span class="ws-goal-bars__fillbox">
96
96
  <span class="ws-goal-bars__not-yet"></span>
97
- <span class="ws-goal-bars__fill ws-grow"></span>
97
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
98
98
  </span>
99
99
  <span class="ws-goal-bars__dot"></span>
100
100
  </span>
101
101
  <span class="ws-goal-bars__count">14 <span class="ws-goal-bars__of">of 20</span></span>
102
102
  <span class="ws-goal-bars__divider"></span>
103
- <span class="ws-goal-bars__label">You</span>
103
+ <span class="ws-goal-bars__label" title="You">You</span>
104
104
  </div>
105
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-past-half); --tone-fade: var(--ws-chart-purple-fade); --pct: 45%;" aria-hidden="true">
105
+ <div class="ws-goal-bars__row" style="--i: 1; --tone: var(--ws-chart-past-half); --tone-fade: var(--ws-chart-purple-fade); --pct: 45%;" aria-hidden="true">
106
106
  <span class="ws-goal-bars__meter">
107
107
  <span class="ws-goal-bars__track"></span>
108
108
  <span class="ws-goal-bars__fillbox">
109
109
  <span class="ws-goal-bars__not-yet"></span>
110
- <span class="ws-goal-bars__fill ws-grow" style="animation-delay: 40ms;"></span>
110
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
111
111
  </span>
112
112
  <span class="ws-goal-bars__dot"></span>
113
113
  </span>
114
114
  <span class="ws-goal-bars__count">9 <span class="ws-goal-bars__of">of 20</span></span>
115
115
  <span class="ws-goal-bars__divider"></span>
116
- <span class="ws-goal-bars__label">Team average</span>
116
+ <span class="ws-goal-bars__label" title="Team average">Team average</span>
117
117
  </div>
118
118
  </div>
119
119
  </div>
@@ -123,18 +123,18 @@
123
123
  <span class="ws-muted">Wide labels: a phrase, not a word or two (a set of review themes)</span>
124
124
  <div style="width: 320px; max-width: 100%;">
125
125
  <div class="ws-card ws-card--inset ws-goal-bars ws-goal-bars--wide">
126
- <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-under-half); --tone-fade: var(--ws-chart-salmon-fade); --pct: 55%;" aria-hidden="true">
127
- <span class="ws-goal-bars__meter">
126
+ <div class="ws-goal-bars__row" style="--i: 0; --tone: var(--ws-chart-under-half); --tone-fade: var(--ws-chart-salmon-fade); --pct: 55%;">
127
+ <span class="ws-goal-bars__meter" aria-hidden="true">
128
128
  <span class="ws-goal-bars__track"></span>
129
129
  <span class="ws-goal-bars__fillbox">
130
130
  <span class="ws-goal-bars__not-yet"></span>
131
- <span class="ws-goal-bars__fill ws-grow"></span>
131
+ <span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span>
132
132
  </span>
133
133
  <span class="ws-goal-bars__dot"></span>
134
134
  </span>
135
135
  <span class="ws-goal-bars__count">11 <span class="ws-goal-bars__of">of 20</span></span>
136
136
  <span class="ws-goal-bars__divider"></span>
137
- <a href="#" class="ws-goal-bars__label">Answering what they asked</a>
137
+ <a href="#themes" class="ws-goal-bars__label">Answering what they asked, every time</a>
138
138
  </div>
139
139
  </div>
140
140
  </div>
@@ -143,8 +143,8 @@
143
143
  <div class="ws-stack">
144
144
  <span class="ws-muted">Empty: nothing counted yet</span>
145
145
  <div style="width: 260px; max-width: 100%;">
146
- <div class="ws-card ws-card--inset ws-goal-bars">
147
- <div class="ws-goal-bars__row" style="--tone: var(--color-gray-5); --tone-fade: var(--color-gray-2); --pct: 0%;" aria-hidden="true">
146
+ <div class="ws-card ws-card--inset ws-goal-bars ws-goal-bars--draw">
147
+ <div class="ws-goal-bars__row" style="--i: 0; --tone: var(--ws-edge-card); --tone-fade: var(--ws-track); --pct: 0%;" aria-hidden="true">
148
148
  <span class="ws-goal-bars__meter">
149
149
  <span class="ws-goal-bars__track"></span>
150
150
  <span class="ws-goal-bars__fillbox">
@@ -153,12 +153,53 @@
153
153
  </span>
154
154
  <span class="ws-goal-bars__count">0</span>
155
155
  <span class="ws-goal-bars__divider"></span>
156
- <span class="ws-goal-bars__label">Referrals</span>
156
+ <span class="ws-goal-bars__label" title="Referrals">Referrals</span>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ <div class="ws-stack">
163
+ <span class="ws-muted">A line under each label, and a long one cut with its title</span>
164
+ <div style="width: 400px; max-width: 100%;">
165
+ <div class="ws-card ws-card--inset ws-goal-bars" role="img" aria-label="Listings 6 of 10, Showings 12 of 20">
166
+ <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-finished); --tone-fade: var(--ws-chart-teal-fade); --pct: 60%;" aria-hidden="true">
167
+ <span class="ws-goal-bars__meter"><span class="ws-goal-bars__track"></span><span class="ws-goal-bars__fillbox"><span class="ws-goal-bars__not-yet"></span><span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span></span><span class="ws-goal-bars__dot"></span></span>
168
+ <span class="ws-goal-bars__count">6 <span class="ws-goal-bars__of">of 10</span></span>
169
+ <span class="ws-goal-bars__divider"></span>
170
+ <span class="ws-goal-bars__words"><span class="ws-goal-bars__label" title="Listings">Listings</span><span class="ws-goal-bars__line" title="Two this week">Two this week</span></span>
171
+ </div>
172
+ <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-past-half); --tone-fade: var(--ws-chart-purple-fade); --pct: 60%;" aria-hidden="true">
173
+ <span class="ws-goal-bars__meter"><span class="ws-goal-bars__track"></span><span class="ws-goal-bars__fillbox"><span class="ws-goal-bars__not-yet"></span><span class="ws-goal-bars__leader"></span><span class="ws-goal-bars__fill"></span></span><span class="ws-goal-bars__dot"></span></span>
174
+ <span class="ws-goal-bars__count">12 <span class="ws-goal-bars__of">of 20</span></span>
175
+ <span class="ws-goal-bars__divider"></span>
176
+ <span class="ws-goal-bars__words"><span class="ws-goal-bars__label" title="Showings booked from open houses">Showings booked from open houses</span><span class="ws-goal-bars__line" title="Most from the Saturday open house on Elm Street">Most from the Saturday open house on Elm Street</span></span>
157
177
  </div>
158
178
  </div>
159
179
  </div>
160
180
  </div>
161
181
 
182
+ <div class="ws-stack" style="width: 556px; max-width: 100%;">
183
+ <span class="ws-muted">Label first (issue #11): the words, a 12 px bar with a dotted remainder, the figure; the bar drops under on a narrow card</span>
184
+ <div class="ws-card ws-card--inset">
185
+ <div class="ws-goal-bars ws-goal-bars--label-first ws-goal-bars--draw" role="img" aria-label="Calls 24 of 40, Texts 31 of 40, Emails 9 of 40">
186
+ <div class="ws-goal-bars__row" style="--tone: var(--color-text-heading); --pct: 60%; --i: 0;" aria-hidden="true"><span class="ws-goal-bars__label">Calls</span><span class="ws-goal-bars__bar"><span class="ws-goal-bars__bar-fill"></span></span><span class="ws-goal-bars__count">24</span></div>
187
+ <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-finished); --pct: 77.5%; --i: 1;" aria-hidden="true"><span class="ws-goal-bars__label">Texts</span><span class="ws-goal-bars__bar"><span class="ws-goal-bars__bar-fill"></span></span><span class="ws-goal-bars__count">31</span></div>
188
+ <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-past-half); --pct: 22.5%; --i: 2;" aria-hidden="true"><span class="ws-goal-bars__label">Emails</span><span class="ws-goal-bars__bar"><span class="ws-goal-bars__bar-fill"></span></span><span class="ws-goal-bars__count">9</span></div>
189
+ </div>
190
+ </div>
191
+ </div>
192
+
193
+ <div class="ws-stack" style="width: 300px; max-width: 100%;">
194
+ <span class="ws-muted">Label first in a 300 px card</span>
195
+ <div class="ws-card ws-card--inset">
196
+ <div class="ws-goal-bars ws-goal-bars--label-first" role="img" aria-label="Calls 24 of 40, Texts 31 of 40">
197
+ <div class="ws-goal-bars__row" style="--tone: var(--color-text-heading); --pct: 60%;" aria-hidden="true"><span class="ws-goal-bars__label">Calls</span><span class="ws-goal-bars__bar"><span class="ws-goal-bars__bar-fill"></span></span><span class="ws-goal-bars__count">24</span></div>
198
+ <div class="ws-goal-bars__row" style="--tone: var(--ws-chart-finished); --pct: 77.5%;" aria-hidden="true"><span class="ws-goal-bars__label">Texts</span><span class="ws-goal-bars__bar"><span class="ws-goal-bars__bar-fill"></span></span><span class="ws-goal-bars__count">31</span></div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+
162
203
  </div>
163
204
  </body>
164
205
  </html>
@@ -0,0 +1,51 @@
1
+ /* ---- GoalBars: rows of goal pills, each the share of its goal, its count and label beside it ---- */
2
+ /* Each row carries its tone and share as data: style="--tone: ...; --tone-fade: ...; --pct: 65%". Issue #5: every row
3
+ sits on one grid (subgrid), so the count column is only as wide as the widest count (at least 18) and the counts,
4
+ hairlines and labels line up down the card. Columns: the bar, the count, the hairline, the label (as wide as the
5
+ widest label, at most 120). */
6
+ .ws-goal-bars { display: grid; grid-template-columns: minmax(0, 1fr) minmax(calc(var(--space-md) + var(--space-3xs)), auto) auto fit-content(var(--space-7xl)); row-gap: var(--space-md); container-type: inline-size; }
7
+ .ws-goal-bars--in-card { padding: var(--ws-card-inset) var(--ws-card-inset) var(--space-2xl); }
8
+ .ws-goal-bars__row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; }
9
+ .ws-goal-bars__meter { position: relative; min-width: 0; height: calc(var(--space-lg) + var(--space-xxs)); margin-right: var(--space-xs); }
10
+ .ws-goal-bars__track { position: absolute; inset: 0 var(--space-lg) 0 0; border: var(--ws-line) solid color-mix(in srgb, var(--tone) 50%, transparent); border-radius: var(--radius-full); background: var(--color-bg-page); }
11
+ .ws-goal-bars__fillbox { position: absolute; inset: 0 calc(var(--space-lg) + var(--space-xxs)) 0 var(--space-xxs); }
12
+ /* Not yet (Seth): two bands of dots, 4 tall, 13 apart, from just past the fill to the track's end. */
13
+ .ws-goal-bars__not-yet { position: absolute; top: 50%; right: var(--space-xs); left: calc(var(--pct) + var(--space-xxs)); height: calc(var(--space-md) + var(--ws-line)); translate: 0 -50%; background-image: radial-gradient(circle, color-mix(in srgb, var(--tone) 40%, transparent) calc(var(--ws-hairline) * 1.1), transparent calc(var(--ws-hairline) * 1.5)); background-size: calc(var(--ws-hairline) * 6.82) calc(var(--space-3xs) + var(--ws-line)); -webkit-mask-image: linear-gradient(to bottom, var(--ws-mask) 0 var(--space-xxs), transparent 0 calc(var(--space-sm) + var(--ws-line)), var(--ws-mask) 0); mask-image: linear-gradient(to bottom, var(--ws-mask) 0 var(--space-xxs), transparent 0 calc(var(--space-sm) + var(--ws-line)), var(--ws-mask) 0); }
14
+ /* translate, not transform, so the grow (a transform) never drops the centring. */
15
+ /* "in srgb": a palette's stops are derived (color-mix), and a gradient blends those in Oklab unless told; sRGB is how the kit's own stops have always blended (D15). */
16
+ .ws-goal-bars__fill { position: absolute; left: 0; top: 50%; width: var(--pct); height: calc(var(--space-md) + var(--space-3xs)); translate: 0 -50%; transform-origin: left; border-radius: var(--radius-full); background: linear-gradient(90deg in srgb, var(--tone-fade), var(--tone)); }
17
+ /* The leader (README promise, field fix): a half-strength line from the fill's end out to the dot. */
18
+ .ws-goal-bars__leader { position: absolute; top: calc(50% - var(--ws-line) / 2); left: max(0px, calc(var(--pct) - var(--space-xs))); right: calc(var(--space-lg) * -1); height: var(--ws-line); background: color-mix(in srgb, var(--tone) 50%, transparent); }
19
+ .ws-goal-bars__dot { position: absolute; right: 0; top: 50%; width: calc(var(--space-xs) * 0.875); height: calc(var(--space-xs) * 0.875); translate: 0 -50%; border-radius: var(--radius-full); background: var(--tone); }
20
+ .ws-goal-bars__count { white-space: nowrap; text-align: right; font-size: var(--ws-text-value); font-weight: 600; line-height: var(--ws-leading-row); color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
21
+ .ws-goal-bars__of { font-weight: 500; color: var(--color-text-muted); }
22
+ .ws-goal-bars__divider { width: var(--ws-line); height: calc(var(--space-md) + var(--space-xxs)); margin: 0 var(--space-xxs); background: var(--ws-edge-card); }
23
+ /* The label: 16/20 medium navy, one line with an ellipsis (and its title); an optional muted line under it. */
24
+ .ws-goal-bars__words { display: flex; min-width: 0; flex-direction: column; }
25
+ .ws-goal-bars__label { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--ws-text-value); font-weight: 500; line-height: var(--ws-leading-row); color: var(--color-text-heading); text-decoration: none; }
26
+ .ws-goal-bars__line { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--ws-text-dense); line-height: var(--space-md); color: var(--color-text-muted); }
27
+ a.ws-goal-bars__label { border-radius: var(--ws-radius-chip); }
28
+ @media (hover: hover) { a.ws-goal-bars__label:hover { text-decoration: underline; } }
29
+ @media (prefers-reduced-motion: no-preference) {
30
+ .ws-goal-bars--draw .ws-goal-bars__fill { animation: ws-grow var(--ws-duration-fill) var(--ws-ease-settle) backwards; animation-delay: calc(var(--ws-build-at, 0s) + var(--i, 0) * var(--ws-stagger-row)); }
31
+ }
32
+ /* Phrase labels: the label takes more room than the bar and wraps. */
33
+ .ws-goal-bars--wide { grid-template-columns: minmax(0, 0.8fr) minmax(calc(var(--space-md) + var(--space-3xs)), auto) auto minmax(0, 1.2fr); }
34
+ .ws-goal-bars--wide .ws-goal-bars__label { white-space: normal; }
35
+ /* Label first (issue #11, a first-open card): the words, a 12 px bar up to 402 wide with a dotted remainder, the
36
+ figure in a 36 px right column; rows at least 40 tall with a 0.5 px rule between them (none above the first). On a
37
+ narrow card the bar drops under its words. */
38
+ .ws-goal-bars--label-first { grid-template-columns: minmax(0, 1fr) minmax(0, auto) calc(var(--space-xl) + var(--space-xxs)); row-gap: 0; }
39
+ .ws-goal-bars--label-first .ws-goal-bars__row { column-gap: var(--space-md); min-height: var(--space-2xl); }
40
+ .ws-goal-bars--label-first .ws-goal-bars__row + .ws-goal-bars__row { border-top: var(--ws-divider); }
41
+ .ws-goal-bars--label-first .ws-goal-bars__label { font-size: var(--ws-text-chart); font-weight: 400; }
42
+ .ws-goal-bars__bar { position: relative; width: calc(var(--space-9xl) * 2 + var(--space-3xs)); max-width: 100%; height: var(--space-sm); border-radius: var(--ws-radius-chip); background-image: radial-gradient(circle, color-mix(in srgb, var(--tone) 55%, transparent) var(--ws-line), transparent calc(var(--ws-line) * 1.2)); background-size: var(--space-xxs) var(--space-xxs); }
43
+ .ws-goal-bars__bar-fill { position: absolute; inset: 0 auto 0 0; width: var(--pct); border-radius: var(--ws-radius-chip); background: var(--tone); transform-origin: left; }
44
+ .ws-goal-bars--label-first .ws-goal-bars__count { text-align: right; }
45
+ @container (max-width: 30rem) {
46
+ .ws-goal-bars--label-first .ws-goal-bars__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-xs); padding-block: var(--space-sm); }
47
+ .ws-goal-bars--label-first .ws-goal-bars__bar { grid-column: 1 / -1; grid-row: 2; width: 100%; }
48
+ }
49
+ @media (prefers-reduced-motion: no-preference) {
50
+ .ws-goal-bars--draw .ws-goal-bars__bar-fill { animation: ws-grow var(--ws-duration-fill) var(--ws-ease-settle) backwards; animation-delay: calc(var(--ws-build-at, 0s) + var(--i, 0) * var(--ws-stagger-row)); }
51
+ }
@@ -5,84 +5,100 @@ One card's goal as one big number, a run of ticks carrying the gradient, and a s
5
5
  - A page's one answer is a share of a goal ("65%", "On pace for 40 calls by Oct 22").
6
6
  - The share should read at a glance, not be measured on an axis.
7
7
  - The goal breaks into a few things that made it up (cold calls, live transfers, follow-ups).
8
- - You want the one figure to count up when the card first shows and the strip to sweep in left to right.
9
- - A streak or a plain count needs the same big-number treatment without a share (pass `figure` instead of `percent`).
8
+ - A streak or a plain count needs the same big-number treatment without a share (a number and its caption, no strip).
10
9
 
11
10
  **Not for**
12
11
 
12
+ - A score rated strong, getting there or needs work, with Seth's 96 px figure: use `ScoreHero`.
13
+ - A share across a row in one tone: use `TickStrip`.
13
14
  - Comparing several people or rows against each other: use `GoalBars`.
14
- - A count out of a small whole inside a row (no big number of its own): use `TickRow` alone.
15
- - A sequence of steps that happen in order: use `Stepper`.
16
- - A trend over time: this never draws an axis; if the story is a run of numbers over days, that is a different, line-based chart outside this set.
15
+ - A count out of a small whole inside a row: use `TickRow` alone.
16
+ - A trend over time: use `TrendBars` or `StepLine`.
17
17
 
18
18
  **Anatomy**
19
19
 
20
- - Big number: `calc(--ws-text-display + --space-xs)` (80 px drawn, `--ws-text-display` is 72 px), weight 400, `--ws-tracking-display` (-3%), colour `--color-text-heading`, tabular numerals. Sits with a `-4px` (`--space-xxs`) left pull so the glyph's own side-bearing lines up with the card edge.
21
- - Change chip: `ChangeChip` beside the number, `--space-xs` gap, baseline lifted `calc(--space-xs + --space-xxs/2)`: up arrow in `--ws-word-positive` (teal AA step), down in `--color-text-interactive` (mid blue), "same" a grey minus, never red or salmon.
22
- - Strip: a CSS grid of up to 60 ticks, each `--space-4xl` (64 px) tall, `--radius-xs` (2 px) corners, `--space-xxs` (4 px) apart. A lit tick carries its own slice of one `linear-gradient(90deg, --ws-chart-under-half, --ws-chart-past-half 50%, --ws-chart-finished)` stretched across the whole strip; an empty tick is `--color-bg-page` with a 1 px `--ws-edge-slot` inset edge.
23
- - Rows: up to 14 ticks each (`TickRow`), a hairline (`--ws-edge-slot`) between rows, the label at 15 px (`--ws-text-message`) truncating, the count at 16 px semibold (`--ws-text-value`) tabular, right-aligned in a fixed `calc(--space-lg + --space-xxs/2)` column so every row's number lines up.
24
- - Optional caption beside the number ("week streak") at 14 px medium muted, for a plain count that needs to say what it counts.
25
- - Optional strip key and note under the strip (a filled swatch and an empty one, each named, plus a short note) when the card needs to explain what filled and empty mean.
26
-
27
- **Variants and sizes**
28
-
29
- | Variant | What changes |
30
- | --- | --- |
31
- | `percent` (default) | Big number is `${percent}%`, strip shown by default |
32
- | `figure` | Big number is the given word/number ("3"); strip hidden unless `strip` is forced true (a score over 0 to 100) |
33
- | `rows` | Adds the breakdown block; omit for a bare percent card |
34
- | `change` | `arrowUpRight` (teal), `arrowDownRight` (mid blue), `minus` (grey, "the same"), or omit entirely |
35
- | `live` | The number counts on from what it last showed instead of from nought (something still landing) |
36
- | `stripKey` / `stripNote` | Adds a small legend under the strip |
20
+ - Big number: 80/80 (`--ws-text-display` + 8), weight 400, `--ws-tracking-display` (-3%), navy, proportional
21
+ numerals, its box on the card's content edge with no pull (Seth draws his figures flush), so a chip or caption that
22
+ wraps under it starts on the same edge. The small card's number is 72/72.
23
+ - Change chip: `ChangeChip` 8 after the number, lifted 10 off its foot. Up in `--ws-word-positive`, down in
24
+ `--color-text-interactive`, "same" a grey minus. The number, chip and caption wrap (8 across, 4 down) in a narrow card.
25
+ - Caption (a plain count's words, "week streak"): 14/20 medium muted, on the number's baseline.
26
+ - Strip: a grid of `--n` ticks (20 by default, at most 60, one a unit of the target), 64 tall, 1 px corners, 4 apart.
27
+ A lit tick carries its own slice of one `linear-gradient(90deg, salmon, purple 50%, teal)` stretched across the strip;
28
+ an empty tick is the plain track (`--ws-track`), no edge.
29
+ - Key (optional): 12 under the strip, a gradient swatch and an empty one (10 x 10), each named in 12/16 muted words, 12
30
+ apart, and a short note at the right.
31
+ - Rows: a label (15/20 navy, up to half the row, then an ellipsis with a `title`), a `TickRow`, the count (16/20
32
+ semibold, tabular, right-aligned in a 26 px column so every row's number lines up). 12 above and below each row, a
33
+ 0.5 px divider (`--ws-divider`) between rows.
34
+ - In a card: `--in-card` puts 20 at the sides and 12 under the rows.
35
+
36
+ **Parts and modifiers**
37
+
38
+ - `.ws-goal-ticks__figure--small`: the 72 px number instead of 80 (a phone, a second card).
39
+ - `.ws-goal-ticks__change`: the change chip beside the number, 10 above its foot; it wraps under the number in a narrow card.
40
+ - `.ws-goal-ticks__caption`: muted words on the number's baseline instead of a chip ("week streak").
41
+ - `.ws-goal-ticks__key`: the key under the strip, 12 below it.
42
+ - `.ws-goal-ticks__key-item`: a 10 px swatch in the strip's gradient and its word; `--empty` is the track swatch.
43
+ - `.ws-goal-ticks__key-note`: a short note at the key's right end.
37
44
 
38
45
  **States**
39
46
 
40
- - Default: strip and rows sweep in once, ticks rising from their foot over `--ws-sweep`, each row's own ticks over the same curve.
41
- - Live: `live` is true, the number counts on from its last value (`CountUp`) rather than from zero.
42
- - Empty: real zero is a normal state (0%, every tick the empty cream), not hidden; a card with no data at all is left off the page entirely, never drawn with invented zeros.
43
- - No change: `change.icon` is `null` or `minus`; the chip reads grey, never a tone.
44
- - Long label: a row's label truncates with an ellipsis; the count column never moves.
45
- - Narrow: the strip is `container-type: inline-size`, so a narrower card still lays out its full tick count, just thinner ticks.
46
- - Disabled / error / hover / focus / selected / pressed: do not apply; this is a read-only figure, not a control.
47
- - Reduced motion: every tick, number and chip simply appears at its final state; nothing sweeps or counts.
47
+ - Default: the strip draws once: one 900 ms draw, tick i starting at its share of the first 55% and rising from its
48
+ foot on `--ws-ease-settle`.
49
+ - Empty: a real zero (0%, every tick the track), not hidden. A card with no data is left off the page.
50
+ - No change: the chip is grey with a minus, never a tone.
51
+ - Long label: truncates with an ellipsis and a `title`; the tick row gives way first, the count column never moves.
52
+ - Narrow: the chip wraps under the number; the strip keeps every tick, thinner.
53
+ - Reduced motion: every tick in place.
54
+ - Hover, focus, pressed, selected, disabled: do not apply; this is a read-only figure.
48
55
 
49
56
  **Behaviour**
50
57
 
51
- - No pointer or keyboard interaction; the whole figure is one `<figure aria-label="…">` and every drawn part is `aria-hidden`, so a screen reader gets one sentence instead of dozens of ticks.
52
- - Motion: the number counts up over `--ws-duration-calm` on the soft curve (skipped with reduced motion); the strip's ticks rise with `ws-grow-up`, each delayed by its share of `--ws-sweep` (`sweepDelay`); each row's own ticks sweep the same way, independently timed to their own count.
53
- - Touch and pointer make no difference: nothing here is pressable.
58
+ - The whole figure is one `<figure aria-label="...">`; every drawn part is `aria-hidden`, so a screen reader gets one
59
+ sentence instead of dozens of ticks.
60
+ - Nothing here is pressable.
54
61
 
55
62
  **Content**
56
63
 
57
- - The big number is the one thing the card says; never a second figure beside it except its change chip.
58
- - Row labels are short, sentence case, real words ("Cold calls", not "cold_calls"); the component truncates rather than wraps.
59
- - The change chip's words are short phrases ("12% since Friday"), never a bare number alone unless space forces it.
60
- - No em dashes; a comma or period instead.
61
-
62
- **Props**
63
-
64
- | Name | Type | Meaning |
65
- | --- | --- | --- |
66
- | `percent` | `number` | The whole percent shown big |
67
- | `figure` | `string?` | Words instead of the percent, with no strip unless `strip` is forced |
68
- | `strip` | `boolean?` | Show the tick strip (defaults to true with `percent`, false with `figure`) |
69
- | `change` | `{ icon: 'arrowUpRight' \| 'arrowDownRight' \| 'minus' \| null; words: string } \| null` | The chip beside the number; omit to hide it |
70
- | `done` | `number` | Units done, for the strip's share |
71
- | `target` | `number` | The goal the strip is drawn against |
72
- | `rows` | `{ key, label, value, of }[]` | The short tick rows under the strip |
73
- | `live` | `boolean?` | The number counts on from its last value |
74
- | `caption` | `string?` | A word or two beside the number ("pass rate") |
75
- | `stripKey` | `[string, string]?` | Names a filled tick and an empty one |
76
- | `stripNote` | `string?` | A short note at the key's right |
64
+ - The big number is the one thing the card says; only its chip sits beside it.
65
+ - Row labels are short, sentence case, real words ("Cold calls").
66
+ - The chip's words are short phrases ("12% since Friday").
77
67
 
78
68
  **Rules**
79
69
 
80
- - The designer's exact colours stay on the ticks; words beside them take the AA step (`--ws-word-needs`, `--ws-word-positive`), never the raw salmon or teal (the system's rule, 15 Oct 2026).
70
+ - The ticks keep the exact chart colours; words beside them take the AA step (`--ws-word-positive`, `--ws-word-needs`).
81
71
  - A falling number is mid blue, never red.
82
- - One card, one question, one act: the footer band (the card's `ws-band`, see `Card`, not this component) holds the one next call to action, never a second number.
83
- - A card whose data does not exist is left out, never faked with invented zeros.
84
- - The big number is the only thing counting up; a chart never gets a grid or axis where a tick strip says it plainer.
72
+ - One card, one question, one act: the band under the card holds the next step, never a second number.
73
+ - A card whose data does not exist is left out, never faked with zeros.
85
74
 
86
75
  **Source**
87
76
 
88
- - **Derived from**: the system's chart and motion rules (tone colours, `ws-grow-up`, the one-figure-per-card rule). **Precedent**: the first product built on the system.
77
+ **Derived from**: the system's chart and motion rules; 0.5.0 takes Seth's 1 px tick corners and plain empty tick, North's
78
+ draw, and the field fixes (the strip counts from `--n`, the figure wraps, the caption sits on the baseline, long labels
79
+ carry a title). **Precedent**: the first product built on the system.
80
+
81
+ **Markup**
82
+
83
+ ```html
84
+ <div class="ws-dots ws-goal-ticks ws-goal-ticks--in-card">
85
+ <figure class="ws-goal-ticks__figure" aria-label="65 percent, 65 of 100">
86
+ <span class="ws-goal-ticks__number" aria-hidden="true">65%</span>
87
+ </figure>
88
+ <div class="ws-goal-ticks__strip" style="--n: 20;" aria-hidden="true">
89
+ <span class="ws-goal-ticks__tick ws-goal-ticks__tick--lit" style="--i: 0;"></span>
90
+ <!-- one lit tick a unit done, --i counting up, then the empties -->
91
+ <span class="ws-goal-ticks__tick ws-goal-ticks__tick--empty"></span>
92
+ </div>
93
+ <ul class="ws-goal-ticks__rows" aria-hidden="true">
94
+ <li class="ws-goal-ticks__row">
95
+ <span class="ws-goal-ticks__row-label" title="Cold calls">Cold calls</span>
96
+ <span class="ws-tick-row"><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick ws-tick-row__tick--empty"></span></span>
97
+ <span class="ws-goal-ticks__row-value">14</span>
98
+ </li>
99
+ </ul>
100
+ </div>
101
+ ```
102
+
103
+ **Styles**: `GoalTicks/style.css`, in `bundle.css` and `fello.css` as `.ws-goal-ticks`. Every value is a token. `.ws-goal-ticks` itself has no styles: it is the hook that
104
+ names the chart (and the root for its modifiers); its parts carry the styles.