@felloinnovations/brand-kit 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +221 -0
  3. package/README.md +38 -9
  4. package/design-system/01-how-claude-decides.md +26 -17
  5. package/design-system/02-principles.md +11 -6
  6. package/design-system/03-colour.md +135 -47
  7. package/design-system/04-type.md +45 -23
  8. package/design-system/05-space-and-layout.md +175 -52
  9. package/design-system/06-sizing-profiles.md +4 -4
  10. package/design-system/07-scrolling.md +66 -20
  11. package/design-system/08-choosing-components.md +50 -22
  12. package/design-system/09-charts.md +71 -28
  13. package/design-system/10-patterns.md +33 -10
  14. package/design-system/11-page-recipes.md +110 -23
  15. package/design-system/12-content.md +2 -1
  16. package/design-system/13-motion.md +330 -47
  17. package/design-system/14-accessibility.md +47 -24
  18. package/design-system/15-ai-experiences.md +11 -6
  19. package/design-system/16-creativity.md +1 -1
  20. package/design-system/17-decisions.md +367 -1
  21. package/design-system/18-checklist.md +79 -16
  22. package/design-system/19-public-pages.md +6 -4
  23. package/design-system/20-palettes.md +275 -0
  24. package/design-system/README.md +30 -17
  25. package/design-system/components/ActionList/README.md +96 -10
  26. package/design-system/components/ActionList/preview.html +52 -7
  27. package/design-system/components/ActionList/style.css +64 -0
  28. package/design-system/components/ActivityGrid/README.md +38 -2
  29. package/design-system/components/ActivityGrid/preview.html +1 -1
  30. package/design-system/components/ActivityGrid/style.css +35 -0
  31. package/design-system/components/AppShell/README.md +205 -75
  32. package/design-system/components/AppShell/preview.html +339 -58
  33. package/design-system/components/AppShell/style.css +154 -0
  34. package/design-system/components/Avatar/README.md +37 -10
  35. package/design-system/components/Avatar/preview.html +13 -4
  36. package/design-system/components/Avatar/style.css +14 -0
  37. package/design-system/components/Badge/README.md +41 -19
  38. package/design-system/components/Badge/preview.html +13 -10
  39. package/design-system/components/Badge/style.css +23 -0
  40. package/design-system/components/Banner/README.md +30 -9
  41. package/design-system/components/Banner/preview.html +1 -1
  42. package/design-system/components/Banner/style.css +19 -0
  43. package/design-system/components/Breadcrumb/README.md +58 -46
  44. package/design-system/components/Breadcrumb/preview.html +16 -16
  45. package/design-system/components/Breadcrumb/style.css +17 -0
  46. package/design-system/components/Button/README.md +113 -55
  47. package/design-system/components/Button/preview.html +98 -25
  48. package/design-system/components/Button/style.css +86 -0
  49. package/design-system/components/Card/README.md +158 -49
  50. package/design-system/components/Card/preview.html +141 -19
  51. package/design-system/components/Card/style.css +115 -0
  52. package/design-system/components/CardBoard/README.md +58 -37
  53. package/design-system/components/CardBoard/preview.html +26 -29
  54. package/design-system/components/ChatCard/README.md +115 -29
  55. package/design-system/components/ChatCard/preview.html +149 -32
  56. package/design-system/components/ChatCard/style.css +49 -0
  57. package/design-system/components/ChatShell/README.md +116 -0
  58. package/design-system/components/ChatShell/preview.html +201 -0
  59. package/design-system/components/ChatShell/style.css +86 -0
  60. package/design-system/components/ChatTurn/README.md +78 -35
  61. package/design-system/components/ChatTurn/preview.html +60 -28
  62. package/design-system/components/ChatTurn/style.css +50 -0
  63. package/design-system/components/CheckRow/README.md +141 -0
  64. package/design-system/components/CheckRow/preview.html +140 -0
  65. package/design-system/components/CheckRow/style.css +88 -0
  66. package/design-system/components/Checkbox/README.md +58 -22
  67. package/design-system/components/Checkbox/preview.html +112 -50
  68. package/design-system/components/Checkbox/style.css +45 -0
  69. package/design-system/components/Chip/README.md +78 -47
  70. package/design-system/components/Chip/preview.html +29 -4
  71. package/design-system/components/Chip/style.css +17 -0
  72. package/design-system/components/Combobox/README.md +44 -11
  73. package/design-system/components/Combobox/preview.html +35 -12
  74. package/design-system/components/Combobox/style.css +54 -0
  75. package/design-system/components/Composer/README.md +137 -35
  76. package/design-system/components/Composer/preview.html +115 -40
  77. package/design-system/components/Composer/style.css +81 -0
  78. package/design-system/components/ConfirmDialog/README.md +73 -52
  79. package/design-system/components/ConfirmDialog/preview.html +70 -26
  80. package/design-system/components/ConfirmDialog/style.css +5 -0
  81. package/design-system/components/Cover/preview.html +3 -3
  82. package/design-system/components/Cover/style.css +19 -0
  83. package/design-system/components/DateInput/README.md +77 -12
  84. package/design-system/components/DateInput/preview.html +27 -12
  85. package/design-system/components/DateInput/style.css +38 -0
  86. package/design-system/components/Dialog/README.md +112 -44
  87. package/design-system/components/Dialog/preview.html +141 -18
  88. package/design-system/components/Dialog/style.css +74 -0
  89. package/design-system/components/EmptyState/README.md +42 -12
  90. package/design-system/components/EmptyState/preview.html +11 -11
  91. package/design-system/components/EmptyState/style.css +9 -0
  92. package/design-system/components/EntryShell/README.md +73 -48
  93. package/design-system/components/EntryShell/preview.html +60 -27
  94. package/design-system/components/EntryShell/style.css +19 -0
  95. package/design-system/components/FeatureGrid/README.md +61 -39
  96. package/design-system/components/FeatureGrid/preview.html +2 -2
  97. package/design-system/components/FeatureGrid/style.css +20 -0
  98. package/design-system/components/FileUpload/README.md +33 -3
  99. package/design-system/components/FileUpload/preview.html +18 -4
  100. package/design-system/components/FileUpload/style.css +23 -0
  101. package/design-system/components/FilterBar/README.md +114 -0
  102. package/design-system/components/FilterBar/preview.html +82 -0
  103. package/design-system/components/FilterBar/style.css +22 -0
  104. package/design-system/components/Fold/README.md +84 -26
  105. package/design-system/components/Fold/preview.html +77 -34
  106. package/design-system/components/Fold/style.css +48 -0
  107. package/design-system/components/Footer/README.md +62 -39
  108. package/design-system/components/Footer/preview.html +5 -5
  109. package/design-system/components/Footer/style.css +30 -0
  110. package/design-system/components/FunnelBars/README.md +24 -3
  111. package/design-system/components/FunnelBars/preview.html +5 -5
  112. package/design-system/components/FunnelBars/style.css +13 -0
  113. package/design-system/components/GoalBars/README.md +54 -10
  114. package/design-system/components/GoalBars/preview.html +69 -28
  115. package/design-system/components/GoalBars/style.css +51 -0
  116. package/design-system/components/GoalTicks/README.md +74 -58
  117. package/design-system/components/GoalTicks/preview.html +41 -118
  118. package/design-system/components/GoalTicks/style.css +37 -0
  119. package/design-system/components/GoalTubes/README.md +29 -3
  120. package/design-system/components/GoalTubes/preview.html +6 -6
  121. package/design-system/components/GoalTubes/style.css +23 -0
  122. package/design-system/components/Heatmap/README.md +133 -0
  123. package/design-system/components/Heatmap/preview.html +168 -0
  124. package/design-system/components/Heatmap/style.css +119 -0
  125. package/design-system/components/Hero/README.md +58 -40
  126. package/design-system/components/Hero/preview.html +1 -1
  127. package/design-system/components/Hero/style.css +19 -0
  128. package/design-system/components/HoverCard/README.md +114 -0
  129. package/design-system/components/HoverCard/preview.html +107 -0
  130. package/design-system/components/HoverCard/style.css +59 -0
  131. package/design-system/components/IconButton/README.md +69 -38
  132. package/design-system/components/IconButton/preview.html +77 -43
  133. package/design-system/components/IconButton/style.css +45 -0
  134. package/design-system/components/Input/README.md +36 -11
  135. package/design-system/components/Input/preview.html +1 -1
  136. package/design-system/components/Input/style.css +23 -0
  137. package/design-system/components/KanbanBoard/README.md +93 -45
  138. package/design-system/components/KanbanBoard/preview.html +159 -43
  139. package/design-system/components/KanbanBoard/style.css +53 -0
  140. package/design-system/components/Kbd/README.md +25 -9
  141. package/design-system/components/Kbd/preview.html +6 -2
  142. package/design-system/components/Kbd/style.css +9 -0
  143. package/design-system/components/KitButton/README.md +81 -47
  144. package/design-system/components/KitButton/preview.html +35 -13
  145. package/design-system/components/KitButton/style.css +46 -0
  146. package/design-system/components/KitCard/README.md +75 -44
  147. package/design-system/components/KitCard/preview.html +18 -10
  148. package/design-system/components/KitCard/style.css +15 -0
  149. package/design-system/components/KitInput/README.md +54 -39
  150. package/design-system/components/KitInput/preview.html +7 -7
  151. package/design-system/components/KitInput/style.css +23 -0
  152. package/design-system/components/Leaderboard/README.md +76 -49
  153. package/design-system/components/Leaderboard/preview.html +61 -26
  154. package/design-system/components/Leaderboard/style.css +44 -0
  155. package/design-system/components/ListDetail/README.md +222 -0
  156. package/design-system/components/ListDetail/preview.html +213 -0
  157. package/design-system/components/ListDetail/style.css +148 -0
  158. package/design-system/components/LoadBar/README.md +79 -0
  159. package/design-system/components/LoadBar/preview.html +40 -0
  160. package/design-system/components/LoadBar/style.css +17 -0
  161. package/design-system/components/MarketingNav/README.md +76 -42
  162. package/design-system/components/MarketingNav/preview.html +37 -8
  163. package/design-system/components/MarketingNav/style.css +45 -0
  164. package/design-system/components/Matrix/README.md +129 -0
  165. package/design-system/components/Matrix/preview.html +99 -0
  166. package/design-system/components/Matrix/style.css +84 -0
  167. package/design-system/components/Menu/README.md +117 -41
  168. package/design-system/components/Menu/preview.html +85 -23
  169. package/design-system/components/Menu/style.css +61 -0
  170. package/design-system/components/Meter/README.md +39 -4
  171. package/design-system/components/Meter/preview.html +18 -1
  172. package/design-system/components/Meter/style.css +23 -0
  173. package/design-system/components/MetricTile/README.md +237 -0
  174. package/design-system/components/MetricTile/preview.html +241 -0
  175. package/design-system/components/MetricTile/style.css +129 -0
  176. package/design-system/components/Morph/README.md +106 -0
  177. package/design-system/components/Morph/preview.html +103 -0
  178. package/design-system/components/Morph/style.css +31 -0
  179. package/design-system/components/Motion/README.md +164 -0
  180. package/design-system/components/Motion/preview.html +2537 -0
  181. package/design-system/components/NumberInput/README.md +27 -8
  182. package/design-system/components/NumberInput/preview.html +21 -5
  183. package/design-system/components/NumberInput/style.css +34 -0
  184. package/design-system/components/PaceBar/README.md +75 -0
  185. package/design-system/components/PaceBar/preview.html +67 -0
  186. package/design-system/components/PaceBar/style.css +25 -0
  187. package/design-system/components/Page/README.md +57 -18
  188. package/design-system/components/Page/preview.html +15 -17
  189. package/design-system/components/Page/style.css +7 -0
  190. package/design-system/components/PageBar/README.md +90 -34
  191. package/design-system/components/PageBar/preview.html +60 -19
  192. package/design-system/components/PageBar/style.css +35 -0
  193. package/design-system/components/PageHero/README.md +87 -51
  194. package/design-system/components/PageHero/preview.html +35 -6
  195. package/design-system/components/PageHero/style.css +31 -0
  196. package/design-system/components/Pagination/README.md +70 -49
  197. package/design-system/components/Pagination/preview.html +24 -15
  198. package/design-system/components/Pagination/style.css +12 -0
  199. package/design-system/components/Panel/README.md +109 -51
  200. package/design-system/components/Panel/preview.html +118 -20
  201. package/design-system/components/Panel/style.css +51 -0
  202. package/design-system/components/PasswordInput/README.md +50 -18
  203. package/design-system/components/PasswordInput/preview.html +71 -21
  204. package/design-system/components/PasswordInput/style.css +31 -0
  205. package/design-system/components/Plate/README.md +75 -17
  206. package/design-system/components/Plate/preview.html +40 -7
  207. package/design-system/components/Plate/style.css +37 -0
  208. package/design-system/components/Popover/README.md +70 -49
  209. package/design-system/components/Popover/preview.html +44 -22
  210. package/design-system/components/Popover/style.css +41 -0
  211. package/design-system/components/PricingTable/README.md +69 -49
  212. package/design-system/components/PricingTable/preview.html +21 -21
  213. package/design-system/components/PricingTable/style.css +21 -0
  214. package/design-system/components/ProgressPetals/README.md +31 -3
  215. package/design-system/components/ProgressPetals/preview.html +14 -15
  216. package/design-system/components/ProgressPetals/style.css +27 -0
  217. package/design-system/components/README.md +151 -0
  218. package/design-system/components/Radio/README.md +40 -17
  219. package/design-system/components/Radio/preview.html +16 -1
  220. package/design-system/components/Radio/style.css +21 -0
  221. package/design-system/components/RankBar/README.md +29 -2
  222. package/design-system/components/RankBar/preview.html +14 -12
  223. package/design-system/components/RankBar/style.css +18 -0
  224. package/design-system/components/Ring/README.md +61 -11
  225. package/design-system/components/Ring/preview.html +55 -10
  226. package/design-system/components/Ring/style.css +49 -0
  227. package/design-system/components/ScoreHero/README.md +91 -0
  228. package/design-system/components/ScoreHero/preview.html +104 -0
  229. package/design-system/components/ScoreHero/style.css +32 -0
  230. package/design-system/components/Section/README.md +72 -33
  231. package/design-system/components/Section/preview.html +46 -16
  232. package/design-system/components/Section/style.css +18 -0
  233. package/design-system/components/Segmented/README.md +100 -55
  234. package/design-system/components/Segmented/preview.html +107 -26
  235. package/design-system/components/Segmented/style.css +94 -0
  236. package/design-system/components/SegmentedProgress/README.md +64 -0
  237. package/design-system/components/SegmentedProgress/preview.html +69 -0
  238. package/design-system/components/SegmentedProgress/style.css +11 -0
  239. package/design-system/components/Select/README.md +47 -12
  240. package/design-system/components/Select/preview.html +28 -2
  241. package/design-system/components/Select/style.css +22 -0
  242. package/design-system/components/ShareBar/README.md +69 -0
  243. package/design-system/components/ShareBar/preview.html +72 -0
  244. package/design-system/components/ShareBar/style.css +25 -0
  245. package/design-system/components/SideList/README.md +147 -0
  246. package/design-system/components/SideList/preview.html +139 -0
  247. package/design-system/components/SideList/style.css +94 -0
  248. package/design-system/components/Skeleton/README.md +53 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +17 -0
  251. package/design-system/components/Slider/README.md +95 -0
  252. package/design-system/components/Slider/preview.html +49 -0
  253. package/design-system/components/Slider/style.css +13 -0
  254. package/design-system/components/Split/README.md +112 -0
  255. package/design-system/components/Split/preview.html +105 -0
  256. package/design-system/components/Split/style.css +30 -0
  257. package/design-system/components/Starter/README.md +21 -9
  258. package/design-system/components/Starter/preview.html +5 -5
  259. package/design-system/components/Stat/README.md +64 -43
  260. package/design-system/components/Stat/preview.html +3 -3
  261. package/design-system/components/Stat/style.css +15 -0
  262. package/design-system/components/StatTiles/README.md +88 -44
  263. package/design-system/components/StatTiles/preview.html +142 -71
  264. package/design-system/components/StatTiles/style.css +64 -0
  265. package/design-system/components/StatusLine/README.md +85 -0
  266. package/design-system/components/StatusLine/preview.html +49 -0
  267. package/design-system/components/StatusLine/style.css +14 -0
  268. package/design-system/components/StatusScreen/README.md +49 -35
  269. package/design-system/components/StatusScreen/preview.html +20 -5
  270. package/design-system/components/StatusScreen/style.css +9 -0
  271. package/design-system/components/StepLine/README.md +97 -0
  272. package/design-system/components/StepLine/preview.html +108 -0
  273. package/design-system/components/StepLine/style.css +62 -0
  274. package/design-system/components/Stepper/README.md +35 -13
  275. package/design-system/components/Stepper/style.css +13 -0
  276. package/design-system/components/StreakCalendar/README.md +22 -1
  277. package/design-system/components/StreakCalendar/preview.html +10 -10
  278. package/design-system/components/StreakCalendar/style.css +12 -0
  279. package/design-system/components/SuggestionChip/README.md +87 -0
  280. package/design-system/components/SuggestionChip/preview.html +42 -0
  281. package/design-system/components/SuggestionChip/style.css +20 -0
  282. package/design-system/components/Switch/README.md +44 -24
  283. package/design-system/components/Switch/preview.html +23 -8
  284. package/design-system/components/Switch/style.css +31 -0
  285. package/design-system/components/Table/README.md +129 -58
  286. package/design-system/components/Table/preview.html +106 -72
  287. package/design-system/components/Table/style.css +104 -0
  288. package/design-system/components/Tabs/README.md +71 -46
  289. package/design-system/components/Tabs/preview.html +56 -24
  290. package/design-system/components/Tabs/style.css +44 -0
  291. package/design-system/components/Testimonial/README.md +48 -32
  292. package/design-system/components/Testimonial/preview.html +14 -14
  293. package/design-system/components/Testimonial/style.css +12 -0
  294. package/design-system/components/TextArea/README.md +27 -11
  295. package/design-system/components/TextArea/preview.html +8 -2
  296. package/design-system/components/TextArea/style.css +12 -0
  297. package/design-system/components/ThemeSwitch/README.md +116 -0
  298. package/design-system/components/ThemeSwitch/preview.html +57 -0
  299. package/design-system/components/ThemeSwitch/style.css +6 -0
  300. package/design-system/components/TickRow/README.md +52 -36
  301. package/design-system/components/TickRow/preview.html +64 -41
  302. package/design-system/components/TickRow/style.css +23 -0
  303. package/design-system/components/TickStrip/README.md +95 -0
  304. package/design-system/components/TickStrip/preview.html +88 -0
  305. package/design-system/components/TickStrip/style.css +42 -0
  306. package/design-system/components/Tile/README.md +79 -18
  307. package/design-system/components/Tile/preview.html +91 -40
  308. package/design-system/components/Tile/style.css +36 -0
  309. package/design-system/components/Timeline/README.md +68 -48
  310. package/design-system/components/Timeline/preview.html +27 -15
  311. package/design-system/components/Timeline/style.css +25 -0
  312. package/design-system/components/Toast/README.md +70 -38
  313. package/design-system/components/Toast/preview.html +43 -8
  314. package/design-system/components/Toast/style.css +25 -0
  315. package/design-system/components/Tooltip/README.md +93 -35
  316. package/design-system/components/Tooltip/preview.html +69 -15
  317. package/design-system/components/Tooltip/style.css +78 -0
  318. package/design-system/components/TopBar/README.md +67 -53
  319. package/design-system/components/TopBar/preview.html +14 -27
  320. package/design-system/components/TopBar/style.css +35 -0
  321. package/design-system/components/TopicRail/README.md +108 -0
  322. package/design-system/components/TopicRail/preview.html +58 -0
  323. package/design-system/components/TopicRail/style.css +48 -0
  324. package/design-system/components/TrendBars/README.md +52 -14
  325. package/design-system/components/TrendBars/preview.html +65 -32
  326. package/design-system/components/TrendBars/style.css +25 -0
  327. package/design-system/components/TrendLine/README.md +164 -0
  328. package/design-system/components/TrendLine/preview.html +373 -0
  329. package/design-system/components/TrendLine/style.css +155 -0
  330. package/design-system/components/Well/README.md +64 -22
  331. package/design-system/components/Well/preview.html +14 -14
  332. package/design-system/components/Well/style.css +22 -0
  333. package/design-system/components/_house.css +324 -0
  334. package/design-system/components/bundle.css +4086 -744
  335. package/design-system/tokens.json +1310 -124
  336. package/dist/fello-core.css +2 -2
  337. package/dist/fello.css +6 -1369
  338. package/dist/fello.scoped.css +7 -0
  339. package/dist/index.d.ts +109 -10
  340. package/dist/index.js +781 -96
  341. package/dist/palettes.d.ts +464 -0
  342. package/dist/palettes.js +497 -0
  343. package/dist/scoped.d.ts +3 -0
  344. package/dist/scoped.js +16 -0
  345. package/dist/toast.d.ts +14 -0
  346. package/dist/toast.js +33 -29
  347. package/dist/tokens.d.ts +1686 -62
  348. package/dist/tokens.js +1668 -61
  349. package/package.json +20 -4
  350. package/scripts/check-palette.mjs +295 -0
  351. package/scripts/token-model.mjs +552 -0
  352. package/tokens/_dark.css +173 -0
  353. package/tokens/_palettes.css +46 -0
  354. package/tokens/_product.css +266 -53
  355. package/tokens/_source.hubl.css +39 -19
  356. package/tokens/design-tokens.json +319 -0
  357. package/tokens/palettes.ts +504 -0
  358. package/tokens/shadcn-compat.css +19 -19
  359. package/tokens/shadcn-compat.hsl.css +76 -0
  360. package/tokens/tokens.css +1287 -62
  361. package/tokens/tokens.md +587 -61
  362. package/tokens/tokens.root.css +1293 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -1,6 +1,7 @@
1
1
  The kit's marketing piece: for a public page, never a product screen.
2
2
 
3
- The sticky header of a marketing site: the wordmark, five links and a CTA, collapsing to a menu on a phone.
3
+ The sticky header of a marketing site: the wordmark, five links and a CTA; under 60rem the links fold behind a menu
4
+ button by themselves and the CTA stays in the bar.
4
5
 
5
6
  ## Use it when
6
7
 
@@ -9,56 +10,67 @@ The sticky header of a marketing site: the wordmark, five links and a CTA, colla
9
10
  ## Not for
10
11
 
11
12
  - Any product screen inside a product built on this system: a signed-in workspace has no top nav; it has a
12
- sidebar (`NavItem`) and, on a page that is not chat-first, `AppShell`'s 56px top bar, both different components
13
- for a signed-in product.
13
+ sidebar (`AppShell`) and, on a page that is not chat-first, a 56px top bar, both different components.
14
14
  - A page with no reason to stay reachable while scrolling: a one-screen dialog or a step in a flow does not need
15
15
  a sticky nav.
16
16
 
17
17
  ## Anatomy
18
18
 
19
- - Bar: 72px tall, `--color-white` background, a 1px `--color-border-default` bottom edge, `--layout-margin`
20
- (48px) side padding, sticky at `top: 0` with `--z-header` (100) so it stays above page content while scrolling.
21
- - Wordmark: at the left, `--font-size-lg2` (20px) semibold, `--color-brand-navy`.
22
- - Links: five, centred, `--font-size-sm` (14px) medium, `--color-text-primary`, `--space-lg` (24px) apart, each
23
- with `--color-nav-hover-bg` behind it on hover.
24
- - CTA: a `KitButton` `primary`, `medium`, at the right.
25
- - Phone: the five links and their centred row disappear; a 40px menu button (a hamburger icon) appears at the
26
- right in their place, `aria-expanded="false"` until opened.
19
+ - Bar: 72px tall, full width, `--color-surface`, a 1px `--color-border-default` bottom edge, `--layout-margin` (48px)
20
+ sides (16px under 40rem), its content capped at `--layout-content-max` (1344px) and centred like the bands under it,
21
+ sticky at `top: 0` on `--z-header` (100).
22
+ - Wordmark (`__brand`): a link home, `--font-size-lg2` (20px) semibold, `--color-text-heading`, 44px tall target.
23
+ - Links (`__links`): centred, `--space-lg` (24px) apart. Each link (`__link`) is 14/20 medium, `--color-text-primary`,
24
+ `--space-xs` by `--space-sm` padding (36px tall), 6px corners, `--color-nav-hover-bg` behind it on hover; 44px tall
25
+ on touch.
26
+ - CTA (`__cta`): a `KitButton` `primary` `medium` at the right (an `<a>` when it goes to a page). On touch it takes
27
+ the 44px hit area `KitButton` gives medium.
28
+ - Menu button (`__menu-btn`): 36 by 36, the CTA's height, so the two share a top and bottom edge; 6px corners, a 1px
29
+ `--color-border-hairline` edge, a 20px icon in `--color-text-heading`; a 44px hit area on touch. Shown only when
30
+ the bar is folded.
31
+ - Sheet (folded and open): the links in a column under the bar, full width, `--color-surface`, a 1px rule above and
32
+ below, `--shadow-card-hover`; each link a 44px row at 16px, its words on the wordmark's edge.
27
33
 
28
34
  ## Variants and sizes
29
35
 
30
- One height (72px), two layouts: the full desktop row, and the phone row (wordmark plus menu button only). There
31
- is no tablet-specific state named in the brief; a page in between picks whichever the available width allows the
32
- links to fit without crowding.
36
+ One height (72px), two layouts:
37
+
38
+ - **Full** (60rem and wider): wordmark, links, CTA.
39
+ - **Folded** (under 60rem, on its own; or forced at any width with `--phone`): wordmark, CTA, menu button.
40
+
41
+ The breakpoint is the viewport's, because the bar spans the page. Five short links and the CTA fit down to about
42
+ 50rem; 60rem leaves room for longer labels.
33
43
 
34
44
  ## States
35
45
 
36
- - **Default (desktop):** all five links, the CTA, visible.
37
- - **Hover:** a link's background tints to `--color-nav-hover-bg`; the CTA follows `KitButton`'s own hover.
38
- - **Focus:** a link or the menu button shows the kit's standard focus treatment; the CTA shows `--shadow-focus-ring`.
39
- - **Phone (collapsed):** the links are hidden behind the menu button, not removed; `aria-expanded` on the button
40
- reflects whether they are shown.
41
- - **Selected:** not applicable; a marketing nav does not mark a "current" link the way the product's sidebar does.
46
+ - **Default (full):** all five links and the CTA.
47
+ - **Hover:** a link or the menu button tints to `--color-nav-hover-bg`; the CTA follows `KitButton`.
48
+ Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
49
+ - **Focus:** every link, the wordmark, the CTA and the menu button take the house ring, 2px navy, 2px out.
50
+ - **Folded, closed:** the links are hidden behind the menu button, which says `aria-expanded="false"`.
51
+ - **Folded, open:** `aria-expanded="true"` on the menu button opens the sheet, which rises in over 200ms, and the
52
+ button keeps the hover tint while it is open. The open state is read from the button itself (`:has()`), so the
53
+ page's script only toggles `aria-expanded`, the label and the glyph: three bars closed, a cross open, so what the
54
+ button shows matches what it says ("Close menu").
55
+ - **Selected:** not applicable; a marketing nav does not mark a "current" link.
42
56
  - **Pending / disabled / error / empty:** not applicable.
43
- - **Long label:** a longer link label is accepted as-is; five short, fixed labels are expected, not variable data.
44
- - **Narrow:** below the point the five links and the CTA no longer fit, the layout switches to the phone state
45
- rather than wrapping the links onto a second line.
57
+ - **Long label:** links do not wrap (`white-space: nowrap`); a set too long for the full bar should fold earlier.
46
58
 
47
59
  ## Behaviour
48
60
 
49
- - Keyboard: the wordmark link, five nav links, and the CTA (or the menu button on a phone) are focusable in
50
- document order; opening the phone menu would move focus into it (not shown here, since the brief asks for no
51
- script beyond what a component cannot be shown without, and a static menu button demonstrates the collapsed
52
- state without needing to open it).
53
- - Pointer / touch: hover applies only on desktop; the phone's menu button is a 40px target, clearing the touch floor.
54
- - Motion: none in this static state; a real implementation would slide the phone menu open, matching the
55
- product's own panel-opening motion rather than a custom one.
61
+ - Keyboard: wordmark, links, CTA, then the menu button, in document order. Opening the sheet should move focus to its
62
+ first link and Escape should close it and return focus to the button; that is the page's script, not CSS.
63
+ - Pointer / touch: every act is a 44px target on touch: links and wordmark by their height, the menu button and the
64
+ CTA by their hit area.
65
+ - Motion: the sheet fades in on a small rise (`ws-rise`, 200ms), only under `prefers-reduced-motion: no-preference`.
56
66
 
57
67
  ## Content
58
68
 
59
69
  - Links: one word each, sentence case ("Product", "Pricing", "Customers", "Resources", "About").
60
- - CTA: the same short, imperative phrase as the hero's primary action ("Book a demo"), so a visitor sees one
61
- consistent next step everywhere on the page.
70
+ - CTA: the same short, imperative phrase as the hero's primary act ("Book a demo"). It stays in the folded bar, so
71
+ booking is one tap away on a phone; do not add a second booking button beside it.
72
+ - Menu button: `aria-label` "Open menu" over three bars, and "Close menu" over a cross while open; `aria-controls`
73
+ names the links' id. The open glyph: `<path d="M4 4l8 8M12 4l-8 8" .../>` on the same 16 by 16 box.
62
74
 
63
75
  ## Props
64
76
 
@@ -71,18 +83,40 @@ Not a kit export; composed from `KitButton` and tokens. A reusable version would
71
83
 
72
84
  ## Rules
73
85
 
74
- - **Intentional addition, decided from the system (26 Oct 2026):** the kit ships no nav component; every public
75
- page needs one, built here from the kit's own header height, z-index and hover tokens rather than a new set.
76
- - Sticky at `--z-header`, the token `tokens/tokens.md` itself names for exactly this job ("Z-index," `z-header:
77
- 100`), ahead of ordinary content but below a dropdown, modal or toast, so a marketing nav slots into the same
78
- stacking order the rest of the system already defines.
79
- - The hover tint is `--color-nav-hover-bg`, the one token in `tokens/tokens.md` named for a nav link's hover
80
- (`color-mix(in srgb, var(--color-brand-mid-blue) 5%, transparent)`), not an invented tint.
81
- - The CTA is `KitButton primary`, matching "a `KitButton` primary at the right," rather than the product's own
82
- navy button, since this bar belongs to the public site.
86
+ - **On the page's edge** (4 Nov 2026): the bar's content ran to the window's 48px margin at any width, so on a screen
87
+ wider than 1440px its wordmark and act sat outside the edge the hero, the cards and the footer share (240px out at
88
+ 1920). The sides are the larger of the 48px margin and what centres a 1344px content column.
89
+ - **Folds by itself** (4 Nov 2026): it used to fold only with the `--phone` class, so at 390px the full bar ran 316px
90
+ past the screen. A media query now folds it under 60rem; `--phone` stays as a way to force the folded bar.
91
+ - **The CTA stays when folded**: public pages keep "always one way to book within reach on a phone"
92
+ (`19-public-pages.md`), and the bar is where it is.
93
+ - **44px for every act on a public page** (`14-accessibility.md`): the menu button was 40 and the links 36 on touch.
94
+ The menu button keeps the CTA's 36px look and takes the rest as a hit area, so the folded bar's two controls line up.
95
+ - Sticky at `--z-header`, ahead of ordinary content but below a dropdown, modal or toast.
96
+ - The hover tint is `--color-nav-hover-bg`, the token named for a nav link's hover.
83
97
 
84
98
  ## Source
85
99
 
86
100
  - **Derived from**: the system's header height, z-index and hover tokens (`z-header`, `color-nav-hover-bg`,
87
- `layout-margin`, `font-size-lg2`, `font-size-sm`) and `KitButton` for the CTA.
101
+ `layout-margin`, `font-size-lg2`, `font-size-sm`), `KitButton` for the CTA, the geometry check at 320 and 390, and
102
+ the public page rules (`19-public-pages.md`).
88
103
  - **Precedent**: an intentional addition decided from the system, 26 Oct 2026.
104
+
105
+ ## Markup
106
+
107
+ ```html
108
+ <nav class="ws-marketing-nav" aria-label="Main">
109
+ <a class="ws-marketing-nav__brand" href="/">Fello</a>
110
+ <div class="ws-marketing-nav__links" id="site-menu">
111
+ <a class="ws-marketing-nav__link" href="/product">Product</a>
112
+ <a class="ws-marketing-nav__link" href="/pricing">Pricing</a>
113
+ <a class="ws-marketing-nav__link" href="/customers">Customers</a>
114
+ </div>
115
+ <div class="ws-marketing-nav__cta"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--primary" href="/demo">Book a demo</a></div>
116
+ <button class="ws-marketing-nav__menu-btn" type="button" aria-label="Open menu" aria-expanded="false" aria-controls="site-menu">
117
+ <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
118
+ </button>
119
+ </nav>
120
+ ```
121
+
122
+ Styles: the `MarketingNav` block (`components/MarketingNav/style.css`), plus `KitButton` for the CTA.
@@ -1,6 +1,6 @@
1
- <!-- @dsCard group="Marketing" height=248 -->
1
+ <!-- @dsCard group="Marketing" height=632 -->
2
2
  <!doctype html>
3
- <html>
3
+ <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
6
6
  <title>MarketingNav</title>
@@ -11,9 +11,9 @@
11
11
  <div class="ws-stage ws-stage--column" style="padding: 0 0 var(--ws-gap-component) 0;">
12
12
 
13
13
  <div class="ws-stack">
14
- <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Desktop, 72px, sticky at --z-header</span>
14
+ <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Desktop, 72px, sticky at --z-header; under 60rem it folds by itself</span>
15
15
  <nav class="ws-marketing-nav" aria-label="Main">
16
- <div class="ws-marketing-nav__brand">Fello</div>
16
+ <a class="ws-marketing-nav__brand" href="#" onclick="return false;">Fello</a>
17
17
  <div class="ws-marketing-nav__links">
18
18
  <a class="ws-marketing-nav__link" href="#" onclick="return false;">Product</a>
19
19
  <a class="ws-marketing-nav__link" href="#" onclick="return false;">Pricing</a>
@@ -21,20 +21,49 @@
21
21
  <a class="ws-marketing-nav__link" href="#" onclick="return false;">Resources</a>
22
22
  <a class="ws-marketing-nav__link" href="#" onclick="return false;">About</a>
23
23
  </div>
24
- <div class="ws-marketing-nav__cta"><button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary">Book a demo</button></div>
24
+ <div class="ws-marketing-nav__cta"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--primary" href="#" onclick="return false;">Book a demo</a></div>
25
+ <button class="ws-marketing-nav__menu-btn" type="button" aria-label="Open menu" aria-expanded="false">
26
+ <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
27
+ </button>
25
28
  </nav>
26
29
  </div>
27
30
 
28
31
  <div class="ws-stack">
29
- <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Phone: the links collapse behind a menu</span>
32
+ <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Folded (forced here with --phone): the links behind the menu, the act stays in the bar</span>
30
33
  <nav class="ws-marketing-nav ws-marketing-nav--phone" aria-label="Main">
31
- <div class="ws-marketing-nav__brand">Fello</div>
32
- <button class="ws-marketing-nav__menu-btn" aria-label="Open menu" aria-expanded="false">
34
+ <a class="ws-marketing-nav__brand" href="#" onclick="return false;">Fello</a>
35
+ <div class="ws-marketing-nav__links">
36
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Product</a>
37
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Pricing</a>
38
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Customers</a>
39
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Resources</a>
40
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">About</a>
41
+ </div>
42
+ <div class="ws-marketing-nav__cta"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--primary" href="#" onclick="return false;">Book a demo</a></div>
43
+ <button class="ws-marketing-nav__menu-btn" type="button" aria-label="Open menu" aria-expanded="false">
33
44
  <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
34
45
  </button>
35
46
  </nav>
36
47
  </div>
37
48
 
49
+ <div class="ws-stack" style="min-height: 360px;">
50
+ <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Folded and open: aria-expanded="true" drops the links in a sheet under the bar, 44px rows; the glyph is a cross</span>
51
+ <nav class="ws-marketing-nav ws-marketing-nav--phone" aria-label="Main">
52
+ <a class="ws-marketing-nav__brand" href="#" onclick="return false;">Fello</a>
53
+ <div class="ws-marketing-nav__links" id="mn-menu">
54
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Product</a>
55
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Pricing</a>
56
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Customers</a>
57
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">Resources</a>
58
+ <a class="ws-marketing-nav__link" href="#" onclick="return false;">About</a>
59
+ </div>
60
+ <div class="ws-marketing-nav__cta"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--primary" href="#" onclick="return false;">Book a demo</a></div>
61
+ <button class="ws-marketing-nav__menu-btn" type="button" aria-label="Close menu" aria-expanded="true" aria-controls="mn-menu">
62
+ <svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
63
+ </button>
64
+ </nav>
65
+ </div>
66
+
38
67
  </div>
39
68
  </body>
40
69
  </html>
@@ -0,0 +1,45 @@
1
+ /* ---- MarketingNav: the public site's 72 px top bar, sticky; under 60rem its links fold behind a menu button and the act stays ---- */
2
+ /* The bar is full width, its content inside the same 1344 px cap as the bands under it, so on a wide screen the wordmark
3
+ and the act stay on the hero's, the cards' and the footer's edges instead of riding out to the window's. */
4
+ .ws-marketing-nav { position: sticky; top: 0; z-index: var(--z-header); width: 100%; height: calc(var(--space-4xl) + var(--space-xs)); display: flex; align-items: center; gap: var(--space-xs); padding: 0 max(var(--layout-margin), calc((100% - var(--layout-content-max)) / 2)); background: var(--color-surface); border-bottom: var(--ws-line) solid var(--color-border-default); }
5
+ .ws-marketing-nav__brand { flex: 0 0 auto; display: inline-flex; align-items: center; min-height: var(--ws-touch-public); font-size: var(--font-size-lg2); line-height: var(--ws-leading-title); font-weight: 600; color: var(--color-text-heading); text-decoration: none; }
6
+ .ws-marketing-nav__links { display: flex; align-items: center; gap: var(--space-lg); margin: 0 auto; }
7
+ .ws-marketing-nav__link { display: inline-flex; align-items: center; padding: var(--space-xs) var(--space-sm); border-radius: var(--ws-radius-row); font-size: var(--font-size-sm); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 500; color: var(--color-text-primary); text-decoration: none; white-space: nowrap; }
8
+ .ws-marketing-nav__menu-btn[aria-expanded="true"] { background: var(--color-nav-hover-bg); }
9
+ @media (hover: hover) { .ws-marketing-nav__link:hover, .ws-marketing-nav__menu-btn:hover { background: var(--color-nav-hover-bg); } }
10
+ .ws-marketing-nav__cta { flex: 0 0 auto; }
11
+ /* The menu button is the CTA's height (KitButton medium, 36), so the two sit on one top and bottom edge; on touch it
12
+ takes a 44 px hit area the way the CTA does. Open, it keeps the hover tint. */
13
+ .ws-marketing-nav__menu-btn { position: relative; display: none; flex: 0 0 auto; align-items: center; justify-content: center; width: calc(var(--space-xl) + var(--space-xxs)); height: calc(var(--space-xl) + var(--space-xxs)); padding: 0; border-radius: var(--ws-radius-row); border: var(--ws-line) solid var(--color-border-hairline); background: var(--color-surface); color: var(--color-text-heading); cursor: pointer; }
14
+ .ws-marketing-nav__menu-btn svg { width: var(--ws-icon-lg); height: var(--ws-icon-lg); }
15
+ @media (pointer: coarse) {
16
+ .ws-marketing-nav__link { min-height: var(--ws-touch-public); }
17
+ .ws-marketing-nav__menu-btn::after { content: ""; position: absolute; inset: min(0px, calc((100% - var(--ws-touch-public)) / 2)); }
18
+ }
19
+
20
+ /* Folded (under 60rem on its own, or forced with --phone): the links go behind the menu button; the act stays in the bar,
21
+ so booking is always one tap away. The button's aria-expanded="true" opens the links as a sheet under the bar. */
22
+ @media (max-width: 60rem) {
23
+ .ws-marketing-nav > .ws-marketing-nav__links { display: none; }
24
+ .ws-marketing-nav > .ws-marketing-nav__brand { margin-right: auto; }
25
+ .ws-marketing-nav > .ws-marketing-nav__menu-btn { display: inline-flex; }
26
+ .ws-marketing-nav:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) > .ws-marketing-nav__links { position: absolute; top: 100%; left: 0; right: 0; display: flex; flex-direction: column; align-items: stretch; gap: 0; margin: 0; padding-block: var(--space-xs) var(--space-md); padding-inline: inherit; background: var(--color-surface); border-block: var(--ws-line) solid var(--color-border-default); box-shadow: var(--shadow-card-hover); }
27
+ .ws-marketing-nav:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) .ws-marketing-nav__link { min-height: var(--ws-touch-public); margin-inline: calc(var(--space-sm) * -1); padding-block: 0; font-size: var(--font-size-md); }
28
+ }
29
+ .ws-marketing-nav--phone > .ws-marketing-nav__links { display: none; }
30
+ .ws-marketing-nav--phone > .ws-marketing-nav__brand { margin-right: auto; }
31
+ .ws-marketing-nav--phone > .ws-marketing-nav__menu-btn { display: inline-flex; }
32
+ .ws-marketing-nav--phone:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) > .ws-marketing-nav__links { position: absolute; top: 100%; left: 0; right: 0; display: flex; flex-direction: column; align-items: stretch; gap: 0; margin: 0; padding-block: var(--space-xs) var(--space-md); padding-inline: inherit; background: var(--color-surface); border-block: var(--ws-line) solid var(--color-border-default); box-shadow: var(--shadow-card-hover); }
33
+ .ws-marketing-nav--phone:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) .ws-marketing-nav__link { min-height: var(--ws-touch-public); margin-inline: calc(var(--space-sm) * -1); padding-block: 0; font-size: var(--font-size-md); }
34
+ /* The sheet fades in on a small rise. */
35
+ @media (prefers-reduced-motion: no-preference) and (max-width: 60rem) {
36
+ .ws-marketing-nav:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) > .ws-marketing-nav__links { animation: ws-rise var(--transition-default) backwards; }
37
+ }
38
+ @media (prefers-reduced-motion: no-preference) {
39
+ .ws-marketing-nav--phone:has(> .ws-marketing-nav__menu-btn[aria-expanded="true"]) > .ws-marketing-nav__links { animation: ws-rise var(--transition-default) backwards; }
40
+ }
41
+ /* A phone's 16 px page margin. */
42
+ @media (max-width: 40rem) {
43
+ .ws-marketing-nav { padding: 0 var(--space-md); }
44
+ }
45
+ .ws-marketing-nav--phone { padding: 0 var(--space-md); }
@@ -0,0 +1,129 @@
1
+ A grid of yes-or-no answers: one row per question, one column per source, each cell lit when the answer is yes. Seth's
2
+ answers grid (305:2341): which AI assistants named you, for each of the questions a buyer might ask.
3
+
4
+ ## Use it when
5
+
6
+ - The same few questions are put to the same few sources, and the pattern of yes and no is the finding ("Gemini names
7
+ you for every question; ChatGPT only by name").
8
+ - There are up to about six columns and eight rows: a grid read at a glance.
9
+
10
+ ## Not for
11
+
12
+ - Records with real values in their columns: use `Table`.
13
+ - One score per check: use `CheckRow`.
14
+ - A dense field of values in tones (a week by hour): use `Heatmap`.
15
+
16
+ ## Anatomy
17
+
18
+ - A rim (`.ws-matrix`): the tray grey (`--ws-tray`), 1 px of it round the rows (`--ws-rim`), 8 px corners outside and 7
19
+ inside (`--ws-radius-card-inner`) on the first and last row. No outline, no shadow.
20
+ - One column template for the head and every row: 20 in, 16 out, a 200 px question column, then equal columns 2 apart
21
+ (`--ws-matrix-first`, `--ws-matrix-cols`, default 4). The heads centre over their cells because both use it.
22
+ - Rows: cream, joined by 0.5 px lines (`--ws-edge`), full width, drawn inside the top of the row (an inset line), so a
23
+ row's 48 includes its line as in Seth's frame.
24
+ - Head (`__head`): 16 above and below (54 tall); "Question" in 13 / 18 medium muted (`__corner`); each source a 20 px mark
25
+ (`__mark`, paste the source's official mark) and its name, 15 / 22 semibold navy, 8 apart, centred (`__col`, which
26
+ also carries the name as its `aria-label`).
27
+ - Body rows: at least 48, 1 px above and below, so each cell is 46 tall.
28
+ - The question (`__q`, a button in `__q-wrap`): 14 / 20 medium navy with a 1 px dotted underline, the cue that the whole
29
+ question shows; it wraps rather than hiding words.
30
+ - A cell (`__cell`): 2 px corners; named (`--yes`) the strong tone (`--ws-rating-strong`, teal), not named the empty
31
+ track (`--ws-track`); the source's mark centred in it, dimmed to 0.3 (`--ws-dim`) on the empty track. Its words
32
+ ("Named you", "Not named") are for a screen reader (`ws-sr`).
33
+ - The note (`__tip`, Seth's navy tip 305:2272): the act fill (`--color-text-heading`), 4 px corners, 10 / 12 inside,
34
+ 14 / 20 words in `--ws-on-act` that wrap at 300, left-anchored so its words start on the question's, a 12 x 6 caret over
35
+ the word, 3 above it. No shadow.
36
+ - Foot (`__foot`, a `details`): Seth's "Behind the answers", a folded row in the rim, 16 above and below, 20 in and 16 out;
37
+ the title 15 / 22 semibold, a 13 / 18 medium muted line, a 16 px chevron that turns when open.
38
+
39
+ ## Variants and sizes
40
+
41
+ | Part | Value |
42
+ | --- | --- |
43
+ | Question column | 200 (`--ws-matrix-first`) |
44
+ | Source columns | equal (`--ws-matrix-cols`), 2 apart |
45
+ | Head | 54 |
46
+ | Row | 48, cells 46 |
47
+ | Dim | 0.2 (`--ws-matrix-dim`) |
48
+ | Note | wraps at 300, caret 12 x 6 |
49
+ | Narrow (under 40rem) | the question column takes the room, each source 32 wide, its mark only; the foot's line under its title |
50
+
51
+ ## States
52
+
53
+ - **Default**: as above.
54
+ - **Hover a row** (Seth 305:2143): every other body row's question and cells drop to 0.2; row grounds, lines, the head
55
+ and the foot stay; the hovered row does not change. The whole question shows in the note.
56
+ - **Focus** (keyboard, or a tap that focuses the question): the same dim and the same note. A page script may set
57
+ `aria-expanded="true"` on the question to keep the note open after a tap where the browser does not focus buttons.
58
+ - **Loading**: every cell a ghost under the shimmer (`__cell ws-shimmer`), the questions and sources shown at
59
+ once; still under reduced motion.
60
+ - **Narrow**: source names drop to their marks in 32 px columns (a screen reader still hears each source through the
61
+ head's label), and the foot's line drops under its title.
62
+ - **Long question**: it wraps and its row grows; keep questions to a few words ("A buyer") and put the full question
63
+ in the note.
64
+
65
+ ## Behaviour
66
+
67
+ - Keyboard: each question is a button, in row order; focusing it dims the other rows and shows the note
68
+ (`aria-describedby` points at the note, so a screen reader hears the full question). Under keyboard focus the note sits
69
+ 4 px higher, so its caret clears the focus ring. The note covers the row above, so Escape must hide it (WCAG 1.4.13):
70
+ a page script sets `data-tip="hidden"` on the row (the note hides while the pointer stays) and clears it when the
71
+ pointer or focus leaves.
72
+ - Pointer: hovering anywhere on a row does the same.
73
+ - Motion: the dim and the note fade on hover's 200 ms after North's 40 ms hover intent; the note leaves on the 120 ms
74
+ exit. Under reduced motion both change at once.
75
+
76
+ ## Content
77
+
78
+ - A question is a short label for a longer question ("A buyer" for "I'm thinking of buying a home in Chagrin Falls, OH.
79
+ Which real estate agent or team should I talk to?"); the note holds the long one.
80
+ - A source is its own name, with its official mark.
81
+ - No em dashes.
82
+
83
+ ## Rules
84
+
85
+ - **One template for head and body**: never size a head cell on its own.
86
+ - **The full question is never hover-only** (`14-accessibility.md`): focus and tap show it too.
87
+ - **A cell's state is never colour alone**: its screen-reader words say it, and the lit and empty grounds differ in
88
+ lightness, not only hue.
89
+ - **No clip**: the note may cover the head and the row above; the rim never cuts it.
90
+
91
+ ## Source
92
+
93
+ **Derived from**: Seth's Grow audit report, "Which AI platforms mention you" (305:2280, the grid 305:2341, the hover
94
+ 305:2143, the tip 305:2272), on the kit's rim (D5), rating tones (D10) and hover timing (D7). **Precedent**: new in
95
+ 0.5.0 (4 Nov 2026).
96
+
97
+ ## Markup
98
+
99
+ ```html
100
+ <div class="ws-matrix">
101
+ <div class="ws-matrix__table" role="table" aria-label="Which AI assistants named you, by question">
102
+ <div class="ws-matrix__head" role="rowgroup">
103
+ <div class="ws-matrix__row" role="row">
104
+ <span class="ws-matrix__corner" role="columnheader">Question</span>
105
+ <span class="ws-matrix__col" role="columnheader" aria-label="Gemini"><svg class="ws-matrix__mark" viewBox="0 0 20 20" aria-hidden="true"><!-- the official mark --></svg><span class="ws-matrix__name" aria-hidden="true">Gemini</span></span>
106
+ </div>
107
+ </div>
108
+ <div class="ws-matrix__body" role="rowgroup">
109
+ <div class="ws-matrix__row" role="row">
110
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q" aria-describedby="mx-buyer">A buyer</button><span class="ws-matrix__tip" role="tooltip" id="mx-buyer">I'm thinking of buying a home in Chagrin Falls, OH. Which real estate agent or team should I talk to?</span></span></span>
111
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" aria-hidden="true"><!-- the official mark --></svg><span class="ws-sr">Named you</span></span>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ <details class="ws-matrix__foot">
116
+ <summary><span class="ws-matrix__foot-title">Behind the answers</span><span class="ws-matrix__foot-line">What to fix first, where they looked</span><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg></summary>
117
+ <div class="ws-matrix__foot-body"><p class="ws-body">What they read, and what to fix first.</p></div>
118
+ </details>
119
+ </div>
120
+ ```
121
+
122
+ Set `style="--ws-matrix-cols: 3"` on `.ws-matrix` for three sources.
123
+
124
+ ## Styles
125
+
126
+ `design-system/components/Matrix/style.css`, in `bundle.css` and `fello.css`. Dark and the navy ground come from the
127
+ tokens (`--ws-tray`, `--ws-edge`, `--ws-track`, `--ws-rating-strong`; the note is `--color-text-heading` with
128
+ `--ws-on-act` words, so it turns light with dark words in dark). In dark a mark on a named cell takes the ground's dark
129
+ (`--color-bg-page`), since the strong teal turns light there. The rim is a size container named `ws-matrix`.
@@ -0,0 +1,99 @@
1
+ <!-- @dsCard group="Data" height=720 -->
2
+ <!doctype html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <title>Matrix</title>
7
+ <link rel="stylesheet" href="../../tokens.css">
8
+ <link rel="stylesheet" href="../bundle.css">
9
+ </head>
10
+ <body>
11
+ <div class="ws-stage ws-stage--column">
12
+
13
+ <div class="ws-stack">
14
+ <span class="ws-muted">Seth's answers grid: one column template for the head and every row, so each source's name centres over its cells; hover or focus a question to dim the other rows and read it whole (the marks here are stand-ins: paste each source's official mark in __mark)</span>
15
+ <div class="ws-matrix">
16
+ <div class="ws-matrix__table" role="table" aria-label="Which AI assistants named you, by question">
17
+ <div class="ws-matrix__head" role="rowgroup">
18
+ <div class="ws-matrix__row" role="row">
19
+ <span class="ws-matrix__corner" role="columnheader">Question</span>
20
+ <span class="ws-matrix__col" role="columnheader" aria-label="ChatGPT"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-matrix__name" aria-hidden="true">ChatGPT</span></span>
21
+ <span class="ws-matrix__col" role="columnheader" aria-label="Gemini"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-matrix__name" aria-hidden="true">Gemini</span></span>
22
+ <span class="ws-matrix__col" role="columnheader" aria-label="Claude"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-matrix__name" aria-hidden="true">Claude</span></span>
23
+ <span class="ws-matrix__col" role="columnheader" aria-label="Perplexity"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-matrix__name" aria-hidden="true">Perplexity</span></span>
24
+ </div>
25
+ </div>
26
+ <div class="ws-matrix__body" role="rowgroup">
27
+ <div class="ws-matrix__row" role="row">
28
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q" aria-describedby="mx-q1">Finding an agent</button><span class="ws-matrix__tip" role="tooltip" id="mx-q1">Who are the best real estate agents in Chagrin Falls, OH?</span></span></span>
29
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-sr">Not named</span></span>
30
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-sr">Named you</span></span>
31
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-sr">Not named</span></span>
32
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-sr">Not named</span></span>
33
+ </div>
34
+ <div class="ws-matrix__row" role="row">
35
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q" aria-describedby="mx-q2">A buyer</button><span class="ws-matrix__tip" role="tooltip" id="mx-q2">I'm thinking of buying a home in Chagrin Falls, OH. Which real estate agent or team should I talk to?</span></span></span>
36
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-sr">Not named</span></span>
37
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-sr">Named you</span></span>
38
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-sr">Named you</span></span>
39
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-sr">Named you</span></span>
40
+ </div>
41
+ <div class="ws-matrix__row" role="row">
42
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q" aria-describedby="mx-q3">A seller</button><span class="ws-matrix__tip" role="tooltip" id="mx-q3">I want to sell my house in Chagrin Falls, OH this spring. Who should list it?</span></span></span>
43
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-sr">Not named</span></span>
44
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-sr">Named you</span></span>
45
+ <span class="ws-matrix__cell" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-sr">Not named</span></span>
46
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-sr">Named you</span></span>
47
+ </div>
48
+ <div class="ws-matrix__row" role="row">
49
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q" aria-describedby="mx-q4">You by name, with your team's name and the brokerage</button><span class="ws-matrix__tip" role="tooltip" id="mx-q4">What do people say about Priya Nair and the Nair Group at Howard Hanna?</span></span></span>
50
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-sr">Named you</span></span>
51
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-sr">Named you</span></span>
52
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-sr">Named you</span></span>
53
+ <span class="ws-matrix__cell ws-matrix__cell--yes" role="cell"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-sr">Named you</span></span>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ <details class="ws-matrix__foot">
58
+ <summary><span class="ws-matrix__foot-title">Behind the answers</span><span class="ws-matrix__foot-line">What to fix first, where they looked</span><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg></summary>
59
+ <div class="ws-matrix__foot-body"><p class="ws-body">ChatGPT looked at Zillow and two brokerage pages; none of them name your service area. Start with your Google Business Profile.</p></div>
60
+ </details>
61
+ </div>
62
+ </div>
63
+
64
+ <div class="ws-stack" style="width: 420px;">
65
+ <span class="ws-muted">Loading: every cell a ghost under the shimmer, the questions and sources shown at once</span>
66
+ <div class="ws-matrix" aria-busy="true">
67
+ <div class="ws-matrix__table" role="table" aria-label="Which AI assistants named you, checking">
68
+ <div class="ws-matrix__head" role="rowgroup">
69
+ <div class="ws-matrix__row" role="row">
70
+ <span class="ws-matrix__corner" role="columnheader">Question</span>
71
+ <span class="ws-matrix__col" role="columnheader" aria-label="ChatGPT"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="10" cy="10" r="6"/></svg><span class="ws-matrix__name" aria-hidden="true">ChatGPT</span></span>
72
+ <span class="ws-matrix__col" role="columnheader" aria-label="Gemini"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M10 3l1.8 5.2L17 10l-5.2 1.8L10 17l-1.8-5.2L3 10l5.2-1.8z"/></svg><span class="ws-matrix__name" aria-hidden="true">Gemini</span></span>
73
+ <span class="ws-matrix__col" role="columnheader" aria-label="Claude"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" aria-hidden="true"><path d="M10 4l6 12H4z"/></svg><span class="ws-matrix__name" aria-hidden="true">Claude</span></span>
74
+ <span class="ws-matrix__col" role="columnheader" aria-label="Perplexity"><svg class="ws-matrix__mark" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="4.5" y="4.5" width="11" height="11" rx="1"/></svg><span class="ws-matrix__name" aria-hidden="true">Perplexity</span></span>
75
+ </div>
76
+ </div>
77
+ <div class="ws-matrix__body" role="rowgroup">
78
+ <div class="ws-matrix__row" role="row">
79
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q">A buyer</button></span></span>
80
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
81
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
82
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
83
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
84
+ </div>
85
+ <div class="ws-matrix__row" role="row">
86
+ <span class="ws-matrix__q-cell" role="rowheader"><span class="ws-matrix__q-wrap"><button type="button" class="ws-matrix__q">A seller</button></span></span>
87
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
88
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
89
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
90
+ <span class="ws-matrix__cell ws-shimmer" role="cell"><span class="ws-sr">Checking</span></span>
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
+ </div>
98
+ </body>
99
+ </html>