@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
@@ -15,39 +15,60 @@ The one disclosure: something folded away until wanted, in three looks, built on
15
15
 
16
16
  ## Anatomy
17
17
 
18
- - Built on the native `<details>`/`<summary>`, so the keyboard and a screen reader already know what it is; no script drives its open state unless the page wants to control it.
19
- - `card` look: the one `Card`, a 44 px summary line (`calc(--space-2xl + --space-xxs)`) with a muted chevron, a 14 px semibold navy title and an optional note that wraps, 16 px inside (`--ws-card-padding-lg`); the body sits below with no rule between.
20
- - `quiet` look: words that act (navy, medium, underlined on hover), the chevron after them, the body underneath; never a card.
21
- - `row` look: a full-width row, 16 px sides, 12 px top and bottom, the chevron at the end pointing down.
22
- - In every look the body eases open to its height and rises in as it appears; the chevron turns with it (only its own, not a nested fold's).
18
+ - Built on the native `<details>`/`<summary>`, so the keyboard and a screen reader already know what it is; no script
19
+ drives its open state unless the page wants to control it.
20
+ - The chevron: 16 px (`--ws-icon`), navy, a 1.5 stroke (Seth's). A right chevron turns down when open; a down chevron
21
+ turns up.
22
+ - The title (`ws-fold__title`): 15 / 22 semibold navy, Seth's row and section title. A line under it
23
+ (`ws-fold__line`): 13 / 18 medium in `--color-text-muted`.
24
+ - `card` look: the one `Card` (the rim round the cream), a 44 px summary line, 4 px top and bottom and 16 px at the
25
+ sides, the chevron before the title and an optional note after it; the body 4 / 16 / 16 below, no rule between.
26
+ - `quiet` look (`ws-fold__summary--quiet`): words that act (navy, medium, underlined on hover), the chevron after
27
+ them, 24 px tall at every pointer; the body underneath (`ws-fold__body--quiet`: a column 4 px apart, 4 px under
28
+ the words); never a card.
29
+ - `row` look: a row of Seth's rim list (`ws-fold__list`: the 1 px tray rim round cream rows joined by 0.5 px
30
+ dividers). Each summary is 48 px at least, 12 / 16 / 12 / 20, its parts 12 apart, the words (`ws-fold__words`: title
31
+ and line) taking the room and the chevron at the end. The body sits under the words' column, 0 / 16 / 16 / 20, and
32
+ may hold a cream panel (`ws-fold__panel`: 6 px corners, 24 px inside).
23
33
 
24
34
  ## Variants and sizes
25
35
 
26
- | Look | Chevron position | Ground | Use |
36
+ | Look | Chevron | Ground | Use |
27
37
  | --- | --- | --- | --- |
28
- | `card` (default) | Before the title | A full `Card` | A self-contained block of extra detail |
29
- | `quiet` | After the words | None | A short reasoning trail beside other content |
30
- | `row` | After the words, pointing down | A list row | A chapter or section inside a list |
31
-
32
- `dense` (on `quiet` only) sets the words to 12 px instead of 14 px, for a smaller word button.
38
+ | `card` (default) | Before the title, right, turns down | A full `Card` | A self-contained block of extra detail |
39
+ | `quiet` | After the words, right, turns down | None | A short reasoning trail beside other content |
40
+ | `row` | At the end, down, turns up | A row of a rim list; open, the sunk cream | A chapter or step inside a list |
33
41
 
34
42
  ## States
35
43
 
36
- - **Closed**: the default; only the summary line shows.
37
- - **Open**: the body is visible, the chevron turned (90 degrees for `card`/`quiet`, 180 for `row`).
38
- - **Hover** (`card`, `row`): the summary tints to `--ws-surface-sunk`; (`quiet`): the words underline.
39
- - **Focus**: the summary shows the shadow focus ring (`--shadow-focus-ring`); native `<details>`/`<summary>` keyboard behaviour is kept, not replaced.
40
- - **Controlled**: with `onOpenChange`, the page decides whether it is open (a link that opens one specific chapter); without it, the fold manages itself.
41
- - **Long label**: the note wraps rather than being cut off, dropping under the title on a narrow card rather than squeezing it.
42
- - **Touch**: the summary line is tall enough (44 px on `card`) to meet the touch floor; `row` and `quiet` should be given enough padding by their context to reach 40 px.
44
+ - **Closed**: only the summary line shows.
45
+ - **Open**: the body shows and the chevron has turned. In a rim list the open row and its body take the sunk cream
46
+ (`--ws-surface-sunk`); nothing else moves.
47
+ - **Hover** (pointers that hover): the card summary tints to `--ws-surface-sunk`, a row to the faint navy wash
48
+ (`--ws-hover-faint`), the quiet words underline.
49
+ - **Pressed**: the card and row summaries take `--ws-surface-press` at once, as a card's rows do, so a tap answers on a
50
+ touch screen.
51
+ - **Focus**: the 2 px navy outline; on the card and row summaries it is drawn inside, so the rim and the dividers stay
52
+ clear. Native `<details>` keyboard behaviour is kept.
53
+ - **Controlled**: the page may set `open` itself (a link that opens one chapter).
54
+ - **Long label**: the title wraps beside its chevron; a note drops to the far end and under the title when there is no
55
+ room. Nothing is cut off.
56
+ - **Touch**: card and row summaries are at least 40 px (44 and 48), the quiet look 24.
57
+ - **Dark**: every ground and line is a token that follows the theme.
43
58
 
44
59
  ## Behaviour
45
60
 
46
- - Keyboard: native `<details>` behaviour, Enter or Space on the focused summary toggles it; no custom key handling needed.
47
- - Pointer: a click anywhere on the summary line toggles the fold.
48
- - Touch: the whole summary line is the target.
49
- - Motion: the body's height eases open (`ws-fold` in `globals.css`) and its content rises in (`ws-rise`, `--ws-duration-gentle`); the chevron rotates over `--ws-duration-settle` on `--ws-ease-soft`.
50
- - Reduced motion: the body appears and disappears without easing or rising; the chevron still shows its final rotation, without the transition.
61
+ - Keyboard: Enter or Space on the focused summary toggles it; no custom key handling.
62
+ - Pointer and touch: the whole summary line is the target.
63
+ - Motion (North "Sidebar sections open / close", the fold spring: visualDuration .32 s, bounce 0): the body grows from
64
+ 0 to its height and fades in, and the chevron turns on the same spring (`transition: ... var(--ws-spring-fold-duration)
65
+ var(--ws-spring-fold)`, the spring as a `linear()` curve, 600 ms to settle); closing runs it back on the same spring.
66
+ The grow is the house's fold, on every kit `<details>` (`::details-content` with `interpolate-size`), so a fold needs
67
+ nothing of its own; try it in the preview by opening and closing any title. A browser without `::details-content`
68
+ or `interpolate-size` opens at once.
69
+ - The opening body is clipped while it grows (4 px of room for a focus ring); a menu inside a fold body would be cut,
70
+ so open menus from outside it.
71
+ - Reduced motion: it opens and closes at once, the chevron jumps to its turn.
51
72
 
52
73
  ## Content
53
74
 
@@ -64,7 +85,6 @@ The one disclosure: something folded away until wanted, in three looks, built on
64
85
  | `open` | boolean | How it starts. |
65
86
  | `onOpenChange` | `(open: boolean) => void` | The page keeps the open state and hears every change. |
66
87
  | `look` | `"card"` \| `"quiet"` \| `"row"` | Which of the three looks to draw. Default `card`. |
67
- | `dense` | boolean | On `quiet` only: 12 px words instead of 14 px. |
68
88
  | `label` | string | The summary's accessible name when its words are a shorthand ("3 steps, 4 s"). |
69
89
  | `className` | string | Layout only. |
70
90
  | `children` | `ReactNode` | The folded body. |
@@ -77,5 +97,43 @@ The one disclosure: something folded away until wanted, in three looks, built on
77
97
 
78
98
  ## Source
79
99
 
80
- **Derived from**: the native `<details>`/`<summary>` element, with the system's card, quiet-link and row looks
81
- applied to its summary and body. **Precedent**: the first product built on the system.
100
+ **Derived from**: the native `<details>`/`<summary>`; Seth's fold row inside a rim list (Grow 305:2405, Fixes 308:2508
101
+ to 308:2530: 20 / 16 sides, a 16 px navy chevron, the open row sunk, the cream panel 6 / 24); North's fold motion
102
+ (js@779818). Field fixes: the card summary's 44 px (Ignite surfaces.tsx:335-344), the height motion (globals.css:671-686).
103
+
104
+ ## Markup
105
+
106
+ ```html
107
+ <!-- Card look -->
108
+ <details class="ws-card">
109
+ <summary class="ws-fold__summary ws-fold__summary--card">
110
+ <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
111
+ <span class="ws-fold__title">Why this lead</span>
112
+ <span class="ws-muted">2 reasons</span>
113
+ </summary>
114
+ <div class="ws-fold__body--card"><p class="ws-body">Twelve years in the neighbourhood.</p></div>
115
+ </details>
116
+
117
+ <!-- Row look, in a rim list -->
118
+ <ul class="ws-fold__list">
119
+ <li>
120
+ <details>
121
+ <summary class="ws-fold__summary ws-fold__summary--row">
122
+ <span class="ws-fold__words">
123
+ <span class="ws-fold__title">Name the towns you serve</span>
124
+ <span class="ws-fold__line">Google Business Profile</span>
125
+ </span>
126
+ <svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
127
+ </summary>
128
+ <div class="ws-fold__body--row"><div class="ws-fold__panel"><p class="ws-body">Why it matters.</p></div></div>
129
+ </details>
130
+ </li>
131
+ </ul>
132
+ ```
133
+
134
+ ## Styles
135
+
136
+ `Fold/style.css`, built into `bundle.css` and `fello.css`. The card look's rim is `Card`'s. Tokens: `--ws-icon`,
137
+ `--ws-text-section`, `--ws-leading-section`, `--ws-text-control`, `--ws-rim`, `--ws-tray`, `--ws-divider`,
138
+ `--ws-radius-card-inner`, `--ws-radius-row`, `--ws-surface-sunk`, `--ws-hover-faint`, `--ws-row-h`, `--ws-card-inset`,
139
+ `--ws-duration-settle`, `--ws-ease-settle`, `--ws-focus-*`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Cards" height=180 -->
1
+ <!-- @dsCard group="Cards" height=340 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -8,52 +8,95 @@
8
8
  <link rel="stylesheet" href="../bundle.css">
9
9
  </head>
10
10
  <body>
11
- <div class="ws-stage ws-stage--grey">
12
-
13
- <div class="ws-stack" style="width: 320px; max-width: 100%;">
14
- <span class="ws-muted">Card look, open: a disclosure that is a card</span>
15
- <details class="ws-card" open>
16
- <summary class="ws-fold__summary ws-fold__summary--card">
17
- <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none"><path d="M6 3.5L11 8l-5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
18
- <span class="ws-body ws-fold__title">Why this lead</span>
19
- </summary>
20
- <div class="ws-fold__body--card">
21
- <p class="ws-body">Twelve years in the neighbourhood, referred by two agents already on the team.</p>
22
- </div>
23
- </details>
24
- </div>
25
-
26
- <div class="ws-stack" style="width: 320px; max-width: 100%;">
27
- <span class="ws-muted">Quiet look, closed: words that act, no card</span>
28
- <details>
29
- <summary class="ws-fold__summary ws-fold__summary--quiet">
30
- <span>Why this move</span>
31
- <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none"><path d="M6 3.5L11 8l-5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
32
- </summary>
33
- <div class="ws-fold__body--quiet">
34
- <p class="ws-body">Dana hasn't made a cold call in nine days.</p>
35
- </div>
36
- </details>
11
+ <div class="ws-stage">
12
+ <div class="ws-stack ws-stack--loose" style="width: 340px;">
13
+ <div class="ws-stack">
14
+ <span class="ws-muted">Card look, open: a disclosure that is a card</span>
15
+ <details class="ws-card" open>
16
+ <summary class="ws-fold__summary ws-fold__summary--card">
17
+ <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
18
+ <span class="ws-fold__title">Why this lead</span>
19
+ <span class="ws-muted">2 reasons</span>
20
+ </summary>
21
+ <div class="ws-fold__body--card">
22
+ <p class="ws-body">Twelve years in the neighbourhood, referred by two agents already on the team.</p>
23
+ </div>
24
+ </details>
25
+ </div>
26
+ <div class="ws-stack">
27
+ <span class="ws-muted">Card look, closed, a long title that wraps</span>
28
+ <details class="ws-card">
29
+ <summary class="ws-fold__summary ws-fold__summary--card">
30
+ <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
31
+ <span class="ws-fold__title">Everything Coach read before it picked Priya Nair for today</span>
32
+ </summary>
33
+ <div class="ws-fold__body--card">
34
+ <p class="ws-body">Her last four calls, two open offers and the note from Tuesday.</p>
35
+ </div>
36
+ </details>
37
+ </div>
38
+ <div class="ws-stack">
39
+ <span class="ws-muted">Quiet look: words that act, no card</span>
40
+ <details>
41
+ <summary class="ws-fold__summary ws-fold__summary--quiet">
42
+ <span>Why this move</span>
43
+ <svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
44
+ </summary>
45
+ <div class="ws-fold__body--quiet">
46
+ <p class="ws-body">Dana hasn't made a cold call in nine days.</p>
47
+ </div>
48
+ </details>
49
+ </div>
37
50
  </div>
38
51
 
39
- <div class="ws-stack" style="width: 320px; max-width: 100%;">
40
- <span class="ws-muted">Row look, closed: a list's row that opens below itself</span>
52
+ <div class="ws-stack" style="width: 556px;">
53
+ <span class="ws-muted">Row look, in a rim list: the open row and its body sunk, a cream panel inside</span>
41
54
  <ul class="ws-fold__list">
55
+ <li>
56
+ <details open>
57
+ <summary class="ws-fold__summary ws-fold__summary--row">
58
+ <span class="ws-fold__words">
59
+ <span class="ws-fold__title">Name the towns you serve</span>
60
+ <span class="ws-fold__line">Google Business Profile &middot; a few minutes</span>
61
+ </span>
62
+ <svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
63
+ </summary>
64
+ <div class="ws-fold__body--row">
65
+ <div class="ws-fold__panel">
66
+ <p class="ws-body">Buyers near you see you in 5 of 9 spots, never in the top three. Naming the towns puts you in the searches you miss.</p>
67
+ </div>
68
+ </div>
69
+ </details>
70
+ </li>
42
71
  <li>
43
72
  <details>
44
73
  <summary class="ws-fold__summary ws-fold__summary--row">
45
- <span class="ws-row__title">Follow-up plan</span>
46
- <span class="ws-muted">4 steps</span>
47
- <svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none"><path d="M3.5 6L8 11l4.5-5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
74
+ <span class="ws-fold__words">
75
+ <span class="ws-fold__title">Add photos of sold homes</span>
76
+ <span class="ws-fold__line">Website &middot; a few days</span>
77
+ </span>
78
+ <svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
48
79
  </summary>
49
80
  <div class="ws-fold__body--row">
50
- <p class="ws-body">Cold call: a complicated sale.</p>
81
+ <p class="ws-body">Three of your last ten listings have no photos after they sold.</p>
82
+ </div>
83
+ </details>
84
+ </li>
85
+ <li>
86
+ <details>
87
+ <summary class="ws-fold__summary ws-fold__summary--row">
88
+ <span class="ws-fold__words">
89
+ <span class="ws-fold__title">Ask your last five buyers for a review on the page they found you on</span>
90
+ </span>
91
+ <svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
92
+ </summary>
93
+ <div class="ws-fold__body--row">
94
+ <p class="ws-body">Zillow, Google and your own site each count on their own.</p>
51
95
  </div>
52
96
  </details>
53
97
  </li>
54
98
  </ul>
55
99
  </div>
56
-
57
100
  </div>
58
101
  </body>
59
102
  </html>
@@ -0,0 +1,48 @@
1
+ /* ---- Fold: a disclosure in three looks (a card, quiet words that act, a list's row), the chevron turning ---- */
2
+ .ws-fold__summary { display: flex; align-items: center; cursor: pointer; list-style: none; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
3
+ .ws-fold__summary::-webkit-details-marker { display: none; }
4
+ /* Card look: the summary is 44 tall, 4 / 16 (16 all round made it 48 and more); the body 4 / 16 / 16 under it. */
5
+ .ws-fold__summary--card { min-height: calc(var(--space-2xl) + var(--space-xxs)); flex-wrap: wrap; gap: var(--space-xs); border-radius: var(--ws-radius-card-inner); padding: var(--space-xxs) var(--ws-card-padding-lg); }
6
+ .ws-fold__summary--card > .ws-fold__title { flex: 1 1 0; min-width: min(100%, var(--space-8xl)); }
7
+ details[open] > .ws-fold__summary--card { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
8
+ .ws-fold__summary--card:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
9
+ .ws-fold__body--card { padding: var(--space-xxs) var(--ws-card-padding-lg) var(--ws-card-padding-lg); }
10
+ /* Quiet look: words that act, 24 tall at every pointer, the chevron after them. */
11
+ .ws-fold__summary--quiet { width: fit-content; min-height: var(--space-lg); gap: var(--space-xxs); font-weight: 500; color: var(--color-text-heading); }
12
+ .ws-fold__body--quiet { display: flex; flex-direction: column; gap: var(--space-xxs); padding-top: var(--space-xxs); }
13
+ /* Row look, in Seth's rim list: cream rows inside the 1 px tray rim, joined by 0.5 px dividers; each row 48 at least,
14
+ 12 / 16 / 12 / 20, its parts 12 apart; an open row and its body take the sunk cream. */
15
+ .ws-fold__list { border: var(--ws-rim) solid var(--ws-tray); border-radius: var(--ws-radius-card); background: var(--color-bg-page); }
16
+ .ws-fold__list > li + li { border-top: var(--ws-divider); }
17
+ .ws-fold__list > li > details { border-radius: inherit; }
18
+ .ws-fold__list > li:first-child > details { border-top-left-radius: var(--ws-radius-card-inner); border-top-right-radius: var(--ws-radius-card-inner); }
19
+ .ws-fold__list > li:last-child > details { border-bottom-left-radius: var(--ws-radius-card-inner); border-bottom-right-radius: var(--ws-radius-card-inner); }
20
+ .ws-fold__list details[open] { background: var(--ws-surface-sunk); }
21
+ .ws-fold__summary--row { width: 100%; min-height: var(--ws-row-h); gap: var(--space-sm); padding: var(--space-sm) var(--space-md) var(--space-sm) var(--ws-card-inset); border-radius: inherit; }
22
+ .ws-fold__summary--row:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
23
+ .ws-fold__body--row { padding: 0 var(--space-md) var(--space-md) var(--ws-card-inset); }
24
+ /* A cream panel inside an open row's body (Seth's open fix): 6 px corners, 24 inside. */
25
+ .ws-fold__panel { border-radius: var(--ws-radius-row); background: var(--color-bg-page); padding: var(--space-lg); }
26
+ /* Hover: the card and row summaries take a faint navy wash, the quiet words underline (pointers that hover only). */
27
+ @media (hover: hover) {
28
+ .ws-fold__summary--card:hover { background-color: var(--ws-surface-sunk); }
29
+ .ws-fold__summary--row:hover { background-color: var(--ws-hover-faint); }
30
+ .ws-fold__summary--quiet:hover > span { text-decoration: underline; }
31
+ }
32
+ /* A press tints the card and row summaries at once, as a card's rows do, so a tap answers on a touch screen. */
33
+ :is(.ws-fold__summary--card, .ws-fold__summary--row):active { background-color: var(--ws-surface-press); transition-duration: var(--ws-duration-instant); }
34
+ /* Words: a 15 / 22 semibold title (Seth's row and section title), an optional 13 / 18 line under it in the muted grey. */
35
+ .ws-fold__title { font-size: var(--ws-text-section); line-height: var(--ws-leading-section); font-weight: 600; color: var(--color-text-heading); }
36
+ .ws-fold__words { display: flex; flex: 1; min-width: 0; flex-direction: column; }
37
+ .ws-fold__line { font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; color: var(--color-text-muted); }
38
+ .ws-fold__summary--row .ws-row__title { flex: 1; }
39
+ /* The chevron: 16, navy, 1.5 stroke (Seth). Right turns down when open, down turns up. */
40
+ .ws-fold__chevron { width: var(--ws-icon); height: var(--ws-icon); flex-shrink: 0; color: var(--color-text-heading); }
41
+ details[open] > summary > .ws-fold__chevron--right { transform: rotate(90deg); }
42
+ details[open] > summary > .ws-fold__chevron--down { transform: rotate(180deg); }
43
+ /* Motion (North "Sidebar sections open / close", the fold spring .32 / 0): the body grows from 0 to its height and fades
44
+ in (the house's fold on every kit <details>), the chevron turns on the same spring; closing runs it back. Browsers
45
+ without ::details-content open at once. Reduced motion: everything is instant. */
46
+ @media (prefers-reduced-motion: no-preference) {
47
+ .ws-fold__chevron { transition: transform var(--ws-spring-fold-duration) var(--ws-spring-fold); }
48
+ }
@@ -1,6 +1,6 @@
1
1
  The kit's marketing piece: for a public page, never a product screen.
2
2
 
3
- The closing band of a marketing page: the wordmark, four columns of links and a legal line, on navy.
3
+ The closing band of a marketing page: the wordmark, columns of links and a legal line, on navy.
4
4
 
5
5
  ## Use it when
6
6
 
@@ -8,52 +8,56 @@ The closing band of a marketing page: the wordmark, four columns of links and a
8
8
 
9
9
  ## Not for
10
10
 
11
- - Any product screen: the main workspace has no footer; its navigation is the sidebar, and there is nothing
12
- to legally disclose inside a signed-in workspace.
11
+ - Any product screen: the main workspace has no footer; its navigation is the sidebar.
13
12
  - A short confirmation or status line: use a `Toast` or a plain sentence instead of the full footer band.
14
13
 
15
14
  ## Anatomy
16
15
 
17
- - Band: full width, `--color-bg-dark` (navy) background, `--space-4xl` (64px) padding on every side.
18
- - Inner column: capped at `--layout-content-max` (1344px), centred.
19
- - Top row: the wordmark at the left, four link columns at the right, `--space-3xl` (48px) apart, wrapping to
20
- stack on a narrow page.
21
- - Column heading: `--font-size-2xs` (12px) semibold uppercase, `--letter-spacing-overline` tracking, white at 70%
22
- opacity (`rgba(255, 255, 255, 0.7)`; see Rules for why this is a literal value rather than a token).
23
- - Link: `--font-size-sm` (14px), the same white-at-70% as the headings, turning fully white and underlining on
24
- hover.
25
- - Legal line: `--space-3xl` above it, a 1px white-at-15% rule, then `--font-size-2xs` (12px) white-at-70% text.
16
+ - Band: full width, `--ws-inverse` (the act's navy in light, the brand navy in dark), `--space-4xl` (64px) top and bottom, `--layout-margin` (48px) sides.
17
+ - Inner column (`__inner`): capped at `--layout-content-max` (1344px), centred.
18
+ - Top row (`__top`): the wordmark (`__brand`, 20/28 semibold white) at the left, the link columns (`__cols`) at the
19
+ right, `--space-3xl` (48px) apart. Columns are at least 140px wide, `--space-3xl` apart.
20
+ - Column (`__col`): a heading and its links, `--space-sm` (12px) apart.
21
+ - Heading (`__heading`): an `<h2>`, 12/16 semibold, uppercase, `--letter-spacing-overline`, white at 70%. A real heading,
22
+ so a screen reader can list and jump between the groups (WCAG 1.3.1); the class sets its size, not the element.
23
+ - Link (`__link`): 14/20, white at 70%, turning white and underlined on hover.
24
+ - Legal line (`__legal`): `--space-3xl` above it, a 1px white-at-15% rule, `--space-lg` (24px) to 12/16 white-at-70% words.
26
25
 
27
26
  ## Variants and sizes
28
27
 
29
- One layout. The number of columns (four here) is a page's choice; the pattern itself does not fix it at four.
28
+ One layout. The number of columns is a page's choice. Under 60rem (where `MarketingNav` folds): the wordmark above the
29
+ columns, and the columns from the left edge, `--space-lg` (24px) apart and `--space-xl` (32px) between rows, so four fit
30
+ a tablet and a fifth starts a row under the first. Under 40rem (a phone): 48px top and bottom, 16px sides, and the
31
+ columns in a grid of two.
30
32
 
31
33
  ## States
32
34
 
33
35
  - **Default:** as above.
34
- - **Hover:** a link brightens to full white and underlines; nothing else in the footer reacts.
35
- - **Focus:** a link shows the kit's own visible focus outline (inherited from the browser default on a white-on-
36
- navy background, since the kit defines no footer-specific focus treatment).
37
- - **Selected / pending / disabled / error:** not applicable; a footer is navigation, not a form or a control.
38
- - **Empty:** not applicable; a footer is not shown with no links.
39
- - **Long label:** a longer link label wraps within its 140px-minimum column rather than pushing the column wider.
40
- - **Narrow:** the wordmark and the four columns wrap to a stacked column at their own widths, the wordmark first.
36
+ - **Hover:** a link brightens to white and underlines; nothing else reacts. Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
37
+ - **Focus:** a link takes the house ring in white (`--ws-focus-color` is set to white on the band), 2px, 2px out.
38
+ - **Selected / pending / disabled / error / empty:** not applicable.
39
+ - **Long label:** on a wide screen a longer link widens its column (the columns are as wide as their words, at least
40
+ 140px); in the phone's grid of two it wraps within its column. Keep links to two or three words.
41
+ - **Touch:** each link is a 44px row the width of its column (`--ws-touch-public`), so the rows touch instead of
42
+ sitting 12px apart.
43
+ - **Dark:** the band stays navy in every theme (white 12.71:1, links 6.99:1).
41
44
 
42
45
  ## Behaviour
43
46
 
44
- - Keyboard: every link is a real `<a>`, in document order, left to right then wordmark-to-columns.
47
+ - Keyboard: every link is a real `<a>`, in document order, column by column. The wordmark is not a link here (the
48
+ `MarketingNav` wordmark already goes home); make it an `<a>` if a page has no nav.
45
49
  - Pointer / touch: only the links react.
46
50
  - Motion: none.
47
51
 
48
52
  ## Content
49
53
 
50
- - Column headings: one word, sentence case shown as uppercase by the component ("Product", "Company", "Resources", "Legal").
54
+ - Column headings: one word, written in sentence case and shown uppercase ("Product", "Company", "Resources", "Legal").
51
55
  - Links: short, sentence case, no em dash.
52
56
  - Legal line: the copyright year and the company's full legal name.
53
57
 
54
58
  ## Props
55
59
 
56
- Not a kit export; composed directly from tokens. A reusable version would take:
60
+ Not a kit export. A reusable version would take:
57
61
 
58
62
  | Prop | Type | Meaning |
59
63
  | --- | --- | --- |
@@ -62,22 +66,41 @@ Not a kit export; composed directly from tokens. A reusable version would take:
62
66
 
63
67
  ## Rules
64
68
 
65
- - **Intentional addition, decided from the system (26 Oct 2026):** the kit ships no footer pattern at all; every
66
- public marketing page needs one, built here from the kit's one dark surface and its layout tokens.
67
- - Navy is the kit's only dark surface: `AGENTS.md`'s known gaps say plainly "No dark mode. Marketing DS 3.0
68
- defines one dark surface (navy) and no dark palette. Do not invent one here," so the footer reaches for
69
- `--color-bg-dark` rather than a second, invented dark tone.
70
- - Padding is `--space-4xl` (64px), the exact value named in the task for this band, and the step `tokens/tokens.md`
71
- lists directly after the 48px step the hero and pricing sections use, keeping the footer's rhythm one step
72
- larger and clearly a closing band.
73
- - Link colour is white at 70% opacity rather than a token, because no token in `tokens/tokens.md` expresses "white
74
- at a given opacity on navy"; the value is stated explicitly here instead of being silently invented: white at 70%
75
- on `--color-brand-navy` computes to roughly 7:1 contrast, comfortably past the WCAG AA 4.5:1 floor (and close to
76
- the AAA 7:1 floor), which is why 70% and not a lower opacity was chosen.
69
+ - **The focus ring is white on the band** (4 Nov 2026): the house ring is navy, which vanished on the navy footer.
70
+ - **44px rows on touch** (`14-accessibility.md`): the links were 20px tall, 12px apart.
71
+ - **Column headings are `<h2>`s** (WCAG 1.3.1): a word styled as a heading must be one, or a screen reader hears 13
72
+ links in a row with nothing to group them.
73
+ - **Two columns from the left on a phone**: the old row of four pushed to the right edge left half the band empty.
74
+ - **From the left under 60rem** (4 Nov 2026): at 768px the row of four wrapped its last column to the right edge, under
75
+ the third, with nothing beside it. The wordmark now sits above and the columns start at the left.
76
+ - Navy is the kit's one marketing dark surface, so the footer uses `--ws-inverse` (words `--ws-on-inverse`) and stays navy in dark mode
77
+ rather than turning into a light band nobody designed.
78
+ - White at 70% on navy is 6.99:1, past AA; no token expresses "white at an opacity on navy", so it is a `color-mix`.
77
79
 
78
80
  ## Source
79
81
 
80
- **Derived from**: the kit's one dark surface (`color-bg-dark`) and its layout and type tokens (`space-4xl`,
81
- `layout-content-max`, `layout-margin`, `font-size-sm`, `font-size-2xs`, `letter-spacing-overline`), plus plain CSS
82
- for the link opacity, which no token in this system expresses. **Precedent**: an intentional addition decided from
83
- the system, 26 Oct 2026 (no product source and no kit component built a footer before).
82
+ **Derived from**: the kit's one dark surface (`ws-inverse`), its layout and type tokens (`space-4xl`,
83
+ `layout-content-max`, `layout-margin`, `font-size-sm`, `font-size-2xs`, `letter-spacing-overline`), the house focus ring,
84
+ the touch floors and the geometry check at 390. **Precedent**: an intentional addition decided from the system, 26 Oct 2026.
85
+
86
+ ## Markup
87
+
88
+ ```html
89
+ <footer class="ws-footer">
90
+ <div class="ws-footer__inner">
91
+ <div class="ws-footer__top">
92
+ <div class="ws-footer__brand">Fello</div>
93
+ <div class="ws-footer__cols">
94
+ <div class="ws-footer__col">
95
+ <h2 class="ws-footer__heading">Product</h2>
96
+ <a class="ws-footer__link" href="/scoring">Call scoring</a>
97
+ <a class="ws-footer__link" href="/pricing">Pricing</a>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <p class="ws-footer__legal">&copy; 2026 Fello Innovations. All rights reserved.</p>
102
+ </div>
103
+ </footer>
104
+ ```
105
+
106
+ Styles: the `Footer` block (`components/Footer/style.css`). Nothing else.
@@ -1,6 +1,6 @@
1
1
  <!-- @dsCard group="Marketing" height=385 -->
2
2
  <!doctype html>
3
- <html>
3
+ <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
6
6
  <title>Footer</title>
@@ -15,26 +15,26 @@
15
15
  <div class="ws-footer__brand">Fello</div>
16
16
  <div class="ws-footer__cols">
17
17
  <div class="ws-footer__col">
18
- <span class="ws-footer__heading">Product</span>
18
+ <h2 class="ws-footer__heading">Product</h2>
19
19
  <a class="ws-footer__link" href="#" onclick="return false;">Call scoring</a>
20
20
  <a class="ws-footer__link" href="#" onclick="return false;">Pipeline</a>
21
21
  <a class="ws-footer__link" href="#" onclick="return false;">Content</a>
22
22
  <a class="ws-footer__link" href="#" onclick="return false;">Pricing</a>
23
23
  </div>
24
24
  <div class="ws-footer__col">
25
- <span class="ws-footer__heading">Company</span>
25
+ <h2 class="ws-footer__heading">Company</h2>
26
26
  <a class="ws-footer__link" href="#" onclick="return false;">About</a>
27
27
  <a class="ws-footer__link" href="#" onclick="return false;">Careers</a>
28
28
  <a class="ws-footer__link" href="#" onclick="return false;">Blog</a>
29
29
  </div>
30
30
  <div class="ws-footer__col">
31
- <span class="ws-footer__heading">Resources</span>
31
+ <h2 class="ws-footer__heading">Resources</h2>
32
32
  <a class="ws-footer__link" href="#" onclick="return false;">Help centre</a>
33
33
  <a class="ws-footer__link" href="#" onclick="return false;">Case studies</a>
34
34
  <a class="ws-footer__link" href="#" onclick="return false;">Webinars</a>
35
35
  </div>
36
36
  <div class="ws-footer__col">
37
- <span class="ws-footer__heading">Legal</span>
37
+ <h2 class="ws-footer__heading">Legal</h2>
38
38
  <a class="ws-footer__link" href="#" onclick="return false;">Privacy</a>
39
39
  <a class="ws-footer__link" href="#" onclick="return false;">Terms</a>
40
40
  <a class="ws-footer__link" href="#" onclick="return false;">Security</a>
@@ -0,0 +1,30 @@
1
+ /* ---- Footer: the public site's navy footer, the wordmark, link columns and the legal line ---- */
2
+ /* The band is navy in every theme, so its focus ring is white: the house navy ring would vanish on it. */
3
+ .ws-footer { --ws-focus-color: var(--ws-on-inverse); width: 100%; background: var(--ws-inverse); padding: var(--space-4xl) var(--layout-margin); }
4
+ .ws-footer__inner { max-width: var(--layout-content-max); margin: 0 auto; }
5
+ .ws-footer__top { display: flex; flex-wrap: wrap; gap: var(--space-3xl); justify-content: space-between; }
6
+ .ws-footer__brand { font-size: var(--font-size-lg2); line-height: var(--ws-leading-title); font-weight: 600; color: var(--ws-on-inverse); flex: 0 0 auto; }
7
+ .ws-footer__cols { display: flex; flex-wrap: wrap; gap: var(--space-3xl); flex: 1 1 auto; justify-content: flex-end; }
8
+ .ws-footer__col { min-width: calc(var(--space-7xl) + var(--space-md) + var(--space-xxs)); display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-sm); }
9
+ .ws-footer__heading { font-size: var(--font-size-2xs); line-height: var(--space-md); font-weight: 600; text-transform: uppercase; letter-spacing: var(--letter-spacing-overline); color: color-mix(in srgb, var(--ws-on-inverse) 70%, transparent); }
10
+ .ws-footer__link { font-size: var(--font-size-sm); line-height: calc(var(--space-md) + var(--space-xxs)); color: color-mix(in srgb, var(--ws-on-inverse) 70%, transparent); text-decoration: none; }
11
+ @media (hover: hover) { .ws-footer__link:hover { color: var(--ws-on-inverse); text-decoration: underline; } }
12
+ .ws-footer__legal { margin-top: var(--space-3xl); padding-top: var(--space-lg); border-top: var(--ws-line) solid color-mix(in srgb, var(--ws-on-inverse) 15%, transparent); font-size: var(--font-size-2xs); line-height: var(--space-md); color: color-mix(in srgb, var(--ws-on-inverse) 70%, transparent); }
13
+ /* Touch: each link is a 44 px row the width of its column, so the rows touch instead of sitting 12 apart. */
14
+ @media (pointer: coarse) {
15
+ .ws-footer__col { gap: 0; align-items: stretch; }
16
+ .ws-footer__heading { margin-bottom: var(--space-xxs); }
17
+ .ws-footer__link { display: flex; align-items: center; min-height: var(--ws-touch-public); }
18
+ }
19
+ /* Under 60rem (where the nav folds): the wordmark above the columns and the columns from the left edge, 24 apart, so four
20
+ fit a tablet and one that wraps starts under the first instead of hanging at the right. */
21
+ @media (max-width: 60rem) {
22
+ .ws-footer__top { flex-direction: column; gap: var(--space-xl); }
23
+ .ws-footer__cols { justify-content: flex-start; gap: var(--space-xl) var(--space-lg); }
24
+ }
25
+ /* A phone: the 16 px margin and a grid of two columns. */
26
+ @media (max-width: 40rem) {
27
+ .ws-footer { padding: var(--space-3xl) var(--space-md); }
28
+ .ws-footer__cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
29
+ .ws-footer__col { min-width: 0; }
30
+ }
@@ -19,8 +19,9 @@ conversion between each pair of stages called out as a chip.
19
19
  - One card (`ws-card`), a 22 px title that states the answer ("Losing them at Contacted", not "Funnel"), one sentence
20
20
  under it.
21
21
  - The drawing sits on the dotted field (`ws-dots`), the system's rule for every chart's body.
22
- - A bar: height 24 px, `--ws-radius-control` (4 px) corners on the first bar's top and the rest flattened at the bottom
23
- to read as a stack narrowing down (rounded only where it is the widest, the first).
22
+ - A bar: height 24 px, `--ws-radius-control` (4 px) corners all round, the same on every bar (the bars stand apart,
23
+ a step's share between them, so none is flattened against another). The old `__fill--first` class is no longer
24
+ needed.
24
25
  - Width: the bar's share of the first stage's count, drawn to scale, never a fixed minimum width that would misstate a
25
26
  tiny share.
26
27
  - Colour: the first bar solid navy; each bar after it one of the four tones' fades (`--ws-chart-navy-fade`,
@@ -43,7 +44,8 @@ conversion between each pair of stages called out as a chip.
43
44
  ## States
44
45
 
45
46
  - **Default**: as above, bars extend in from the left on first paint (`ws-grow`, staggered).
46
- - **Arriving**: bars extend left to right, top to bottom, over `--ws-sweep`, matching the chart system's arrival rule.
47
+ - **Arriving**: bars extend left to right, top to bottom, each over 700 ms on the settle curve (`--ws-duration-fill`,
48
+ `--ws-ease-settle`), 45 ms apart (`--ws-stagger-row`, `--i` on each fill), as North fills its bars.
47
49
  - **Live or changed**: a bar eases to its new width over `--ws-duration-settle`, its figure counting on.
48
50
  - **Zero at a stage**: the bar is drawn at its true, possibly very thin, width; it is never hidden or rounded up to be
49
51
  visible, per the chart system's "zero is drawn" rule.
@@ -87,3 +89,22 @@ conversion between each pair of stages called out as a chip.
87
89
  `ChangeChip` for the between-bar conversion mark. **Precedent**: an intentional addition decided from the system,
88
90
  26 Oct 2026 (a pipeline's conversion is a different question from a category comparison, and no product tracked a
89
91
  multi-stage funnel before).
92
+
93
+ ## Markup
94
+
95
+ ```html
96
+ <div class="ws-dots ws-funnel-bars__body" role="img" aria-label="New leads 500, contacted 310">
97
+ <div class="ws-funnel-bars__row" aria-hidden="true">
98
+ <div class="ws-funnel-bars__track"><div class="ws-funnel-bars__fill ws-grow" style="width: 100%; background: var(--color-text-heading);"></div></div>
99
+ <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">500</span><span class="ws-funnel-bars__label">New leads</span></span>
100
+ </div>
101
+ <div class="ws-funnel-bars__between"><span class="ws-change ws-change--down">62% to next</span></div>
102
+ <div class="ws-funnel-bars__row" aria-hidden="true">
103
+ <div class="ws-funnel-bars__track"><div class="ws-funnel-bars__fill ws-grow" style="width: 62%; background: var(--ws-chart-navy-fade); --i: 1;"></div></div>
104
+ <span class="ws-funnel-bars__figure"><span class="ws-funnel-bars__count">310</span><span class="ws-funnel-bars__label">Contacted</span></span>
105
+ </div>
106
+ </div>
107
+ ```
108
+
109
+ **Styles**: `FunnelBars/style.css`, in `bundle.css` and `fello.css` as `.ws-funnel-bars`. Every value is a token. `.ws-funnel-bars` itself has no styles: it is the hook that
110
+ names the chart (and the root for its modifiers); its parts carry the styles.