@felloinnovations/brand-kit 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/AGENTS.md +198 -24
  2. package/CHANGELOG.md +197 -0
  3. package/README.md +34 -7
  4. package/design-system/01-how-claude-decides.md +26 -17
  5. package/design-system/02-principles.md +11 -6
  6. package/design-system/03-colour.md +134 -47
  7. package/design-system/04-type.md +45 -23
  8. package/design-system/05-space-and-layout.md +175 -52
  9. package/design-system/06-sizing-profiles.md +4 -4
  10. package/design-system/07-scrolling.md +66 -20
  11. package/design-system/08-choosing-components.md +50 -22
  12. package/design-system/09-charts.md +71 -28
  13. package/design-system/10-patterns.md +33 -10
  14. package/design-system/11-page-recipes.md +110 -23
  15. package/design-system/12-content.md +2 -1
  16. package/design-system/13-motion.md +330 -47
  17. package/design-system/14-accessibility.md +47 -24
  18. package/design-system/15-ai-experiences.md +11 -6
  19. package/design-system/16-creativity.md +1 -1
  20. package/design-system/17-decisions.md +357 -1
  21. package/design-system/18-checklist.md +79 -16
  22. package/design-system/19-public-pages.md +6 -4
  23. package/design-system/20-palettes.md +275 -0
  24. package/design-system/README.md +30 -17
  25. package/design-system/components/ActionList/README.md +96 -10
  26. package/design-system/components/ActionList/preview.html +52 -7
  27. package/design-system/components/ActionList/style.css +64 -0
  28. package/design-system/components/ActivityGrid/README.md +38 -2
  29. package/design-system/components/ActivityGrid/preview.html +1 -1
  30. package/design-system/components/ActivityGrid/style.css +35 -0
  31. package/design-system/components/AppShell/README.md +205 -75
  32. package/design-system/components/AppShell/preview.html +339 -58
  33. package/design-system/components/AppShell/style.css +154 -0
  34. package/design-system/components/Avatar/README.md +37 -10
  35. package/design-system/components/Avatar/preview.html +13 -4
  36. package/design-system/components/Avatar/style.css +14 -0
  37. package/design-system/components/Badge/README.md +41 -19
  38. package/design-system/components/Badge/preview.html +13 -10
  39. package/design-system/components/Badge/style.css +23 -0
  40. package/design-system/components/Banner/README.md +30 -9
  41. package/design-system/components/Banner/preview.html +1 -1
  42. package/design-system/components/Banner/style.css +19 -0
  43. package/design-system/components/Breadcrumb/README.md +58 -46
  44. package/design-system/components/Breadcrumb/preview.html +16 -16
  45. package/design-system/components/Breadcrumb/style.css +17 -0
  46. package/design-system/components/Button/README.md +113 -55
  47. package/design-system/components/Button/preview.html +98 -25
  48. package/design-system/components/Button/style.css +86 -0
  49. package/design-system/components/Card/README.md +158 -49
  50. package/design-system/components/Card/preview.html +141 -19
  51. package/design-system/components/Card/style.css +115 -0
  52. package/design-system/components/CardBoard/README.md +58 -37
  53. package/design-system/components/CardBoard/preview.html +26 -29
  54. package/design-system/components/ChatCard/README.md +115 -29
  55. package/design-system/components/ChatCard/preview.html +149 -32
  56. package/design-system/components/ChatCard/style.css +49 -0
  57. package/design-system/components/ChatShell/README.md +116 -0
  58. package/design-system/components/ChatShell/preview.html +201 -0
  59. package/design-system/components/ChatShell/style.css +86 -0
  60. package/design-system/components/ChatTurn/README.md +78 -35
  61. package/design-system/components/ChatTurn/preview.html +60 -28
  62. package/design-system/components/ChatTurn/style.css +50 -0
  63. package/design-system/components/CheckRow/README.md +141 -0
  64. package/design-system/components/CheckRow/preview.html +140 -0
  65. package/design-system/components/CheckRow/style.css +88 -0
  66. package/design-system/components/Checkbox/README.md +58 -22
  67. package/design-system/components/Checkbox/preview.html +112 -50
  68. package/design-system/components/Checkbox/style.css +45 -0
  69. package/design-system/components/Chip/README.md +78 -47
  70. package/design-system/components/Chip/preview.html +29 -4
  71. package/design-system/components/Chip/style.css +17 -0
  72. package/design-system/components/Combobox/README.md +44 -11
  73. package/design-system/components/Combobox/preview.html +35 -12
  74. package/design-system/components/Combobox/style.css +54 -0
  75. package/design-system/components/Composer/README.md +137 -35
  76. package/design-system/components/Composer/preview.html +115 -40
  77. package/design-system/components/Composer/style.css +81 -0
  78. package/design-system/components/ConfirmDialog/README.md +73 -52
  79. package/design-system/components/ConfirmDialog/preview.html +70 -26
  80. package/design-system/components/ConfirmDialog/style.css +5 -0
  81. package/design-system/components/Cover/preview.html +3 -3
  82. package/design-system/components/Cover/style.css +19 -0
  83. package/design-system/components/DateInput/README.md +77 -12
  84. package/design-system/components/DateInput/preview.html +27 -12
  85. package/design-system/components/DateInput/style.css +38 -0
  86. package/design-system/components/Dialog/README.md +112 -44
  87. package/design-system/components/Dialog/preview.html +141 -18
  88. package/design-system/components/Dialog/style.css +74 -0
  89. package/design-system/components/EmptyState/README.md +42 -12
  90. package/design-system/components/EmptyState/preview.html +11 -11
  91. package/design-system/components/EmptyState/style.css +9 -0
  92. package/design-system/components/EntryShell/README.md +73 -48
  93. package/design-system/components/EntryShell/preview.html +60 -27
  94. package/design-system/components/EntryShell/style.css +19 -0
  95. package/design-system/components/FeatureGrid/README.md +61 -39
  96. package/design-system/components/FeatureGrid/preview.html +2 -2
  97. package/design-system/components/FeatureGrid/style.css +20 -0
  98. package/design-system/components/FileUpload/README.md +33 -3
  99. package/design-system/components/FileUpload/preview.html +18 -4
  100. package/design-system/components/FileUpload/style.css +23 -0
  101. package/design-system/components/FilterBar/README.md +114 -0
  102. package/design-system/components/FilterBar/preview.html +82 -0
  103. package/design-system/components/FilterBar/style.css +22 -0
  104. package/design-system/components/Fold/README.md +84 -26
  105. package/design-system/components/Fold/preview.html +77 -34
  106. package/design-system/components/Fold/style.css +48 -0
  107. package/design-system/components/Footer/README.md +62 -39
  108. package/design-system/components/Footer/preview.html +5 -5
  109. package/design-system/components/Footer/style.css +30 -0
  110. package/design-system/components/FunnelBars/README.md +24 -3
  111. package/design-system/components/FunnelBars/preview.html +5 -5
  112. package/design-system/components/FunnelBars/style.css +13 -0
  113. package/design-system/components/GoalBars/README.md +54 -10
  114. package/design-system/components/GoalBars/preview.html +69 -28
  115. package/design-system/components/GoalBars/style.css +51 -0
  116. package/design-system/components/GoalTicks/README.md +74 -58
  117. package/design-system/components/GoalTicks/preview.html +41 -118
  118. package/design-system/components/GoalTicks/style.css +37 -0
  119. package/design-system/components/GoalTubes/README.md +29 -3
  120. package/design-system/components/GoalTubes/preview.html +6 -6
  121. package/design-system/components/GoalTubes/style.css +23 -0
  122. package/design-system/components/Heatmap/README.md +133 -0
  123. package/design-system/components/Heatmap/preview.html +168 -0
  124. package/design-system/components/Heatmap/style.css +119 -0
  125. package/design-system/components/Hero/README.md +58 -40
  126. package/design-system/components/Hero/preview.html +1 -1
  127. package/design-system/components/Hero/style.css +19 -0
  128. package/design-system/components/HoverCard/README.md +114 -0
  129. package/design-system/components/HoverCard/preview.html +107 -0
  130. package/design-system/components/HoverCard/style.css +59 -0
  131. package/design-system/components/IconButton/README.md +69 -38
  132. package/design-system/components/IconButton/preview.html +77 -43
  133. package/design-system/components/IconButton/style.css +45 -0
  134. package/design-system/components/Input/README.md +36 -11
  135. package/design-system/components/Input/preview.html +1 -1
  136. package/design-system/components/Input/style.css +23 -0
  137. package/design-system/components/KanbanBoard/README.md +93 -45
  138. package/design-system/components/KanbanBoard/preview.html +159 -43
  139. package/design-system/components/KanbanBoard/style.css +53 -0
  140. package/design-system/components/Kbd/README.md +25 -9
  141. package/design-system/components/Kbd/preview.html +6 -2
  142. package/design-system/components/Kbd/style.css +9 -0
  143. package/design-system/components/KitButton/README.md +81 -47
  144. package/design-system/components/KitButton/preview.html +35 -13
  145. package/design-system/components/KitButton/style.css +46 -0
  146. package/design-system/components/KitCard/README.md +75 -44
  147. package/design-system/components/KitCard/preview.html +18 -10
  148. package/design-system/components/KitCard/style.css +15 -0
  149. package/design-system/components/KitInput/README.md +54 -39
  150. package/design-system/components/KitInput/preview.html +7 -7
  151. package/design-system/components/KitInput/style.css +23 -0
  152. package/design-system/components/Leaderboard/README.md +76 -49
  153. package/design-system/components/Leaderboard/preview.html +61 -26
  154. package/design-system/components/Leaderboard/style.css +44 -0
  155. package/design-system/components/ListDetail/README.md +222 -0
  156. package/design-system/components/ListDetail/preview.html +213 -0
  157. package/design-system/components/ListDetail/style.css +148 -0
  158. package/design-system/components/LoadBar/README.md +79 -0
  159. package/design-system/components/LoadBar/preview.html +40 -0
  160. package/design-system/components/LoadBar/style.css +17 -0
  161. package/design-system/components/MarketingNav/README.md +76 -42
  162. package/design-system/components/MarketingNav/preview.html +37 -8
  163. package/design-system/components/MarketingNav/style.css +45 -0
  164. package/design-system/components/Matrix/README.md +129 -0
  165. package/design-system/components/Matrix/preview.html +99 -0
  166. package/design-system/components/Matrix/style.css +84 -0
  167. package/design-system/components/Menu/README.md +117 -41
  168. package/design-system/components/Menu/preview.html +85 -23
  169. package/design-system/components/Menu/style.css +61 -0
  170. package/design-system/components/Meter/README.md +39 -4
  171. package/design-system/components/Meter/preview.html +18 -1
  172. package/design-system/components/Meter/style.css +23 -0
  173. package/design-system/components/MetricTile/README.md +237 -0
  174. package/design-system/components/MetricTile/preview.html +241 -0
  175. package/design-system/components/MetricTile/style.css +129 -0
  176. package/design-system/components/Morph/README.md +106 -0
  177. package/design-system/components/Morph/preview.html +103 -0
  178. package/design-system/components/Morph/style.css +31 -0
  179. package/design-system/components/Motion/README.md +164 -0
  180. package/design-system/components/Motion/preview.html +2537 -0
  181. package/design-system/components/NumberInput/README.md +27 -8
  182. package/design-system/components/NumberInput/preview.html +21 -5
  183. package/design-system/components/NumberInput/style.css +34 -0
  184. package/design-system/components/PaceBar/README.md +75 -0
  185. package/design-system/components/PaceBar/preview.html +67 -0
  186. package/design-system/components/PaceBar/style.css +25 -0
  187. package/design-system/components/Page/README.md +57 -18
  188. package/design-system/components/Page/preview.html +15 -17
  189. package/design-system/components/Page/style.css +7 -0
  190. package/design-system/components/PageBar/README.md +90 -34
  191. package/design-system/components/PageBar/preview.html +60 -19
  192. package/design-system/components/PageBar/style.css +35 -0
  193. package/design-system/components/PageHero/README.md +87 -51
  194. package/design-system/components/PageHero/preview.html +35 -6
  195. package/design-system/components/PageHero/style.css +31 -0
  196. package/design-system/components/Pagination/README.md +70 -49
  197. package/design-system/components/Pagination/preview.html +24 -15
  198. package/design-system/components/Pagination/style.css +12 -0
  199. package/design-system/components/Panel/README.md +109 -51
  200. package/design-system/components/Panel/preview.html +118 -20
  201. package/design-system/components/Panel/style.css +51 -0
  202. package/design-system/components/PasswordInput/README.md +50 -18
  203. package/design-system/components/PasswordInput/preview.html +71 -21
  204. package/design-system/components/PasswordInput/style.css +31 -0
  205. package/design-system/components/Plate/README.md +75 -17
  206. package/design-system/components/Plate/preview.html +40 -7
  207. package/design-system/components/Plate/style.css +37 -0
  208. package/design-system/components/Popover/README.md +70 -49
  209. package/design-system/components/Popover/preview.html +44 -22
  210. package/design-system/components/Popover/style.css +41 -0
  211. package/design-system/components/PricingTable/README.md +69 -49
  212. package/design-system/components/PricingTable/preview.html +21 -21
  213. package/design-system/components/PricingTable/style.css +21 -0
  214. package/design-system/components/ProgressPetals/README.md +31 -3
  215. package/design-system/components/ProgressPetals/preview.html +14 -15
  216. package/design-system/components/ProgressPetals/style.css +27 -0
  217. package/design-system/components/README.md +151 -0
  218. package/design-system/components/Radio/README.md +40 -17
  219. package/design-system/components/Radio/preview.html +16 -1
  220. package/design-system/components/Radio/style.css +21 -0
  221. package/design-system/components/RankBar/README.md +29 -2
  222. package/design-system/components/RankBar/preview.html +14 -12
  223. package/design-system/components/RankBar/style.css +18 -0
  224. package/design-system/components/Ring/README.md +61 -11
  225. package/design-system/components/Ring/preview.html +55 -10
  226. package/design-system/components/Ring/style.css +49 -0
  227. package/design-system/components/ScoreHero/README.md +91 -0
  228. package/design-system/components/ScoreHero/preview.html +104 -0
  229. package/design-system/components/ScoreHero/style.css +32 -0
  230. package/design-system/components/Section/README.md +72 -33
  231. package/design-system/components/Section/preview.html +46 -16
  232. package/design-system/components/Section/style.css +18 -0
  233. package/design-system/components/Segmented/README.md +100 -55
  234. package/design-system/components/Segmented/preview.html +107 -26
  235. package/design-system/components/Segmented/style.css +94 -0
  236. package/design-system/components/SegmentedProgress/README.md +64 -0
  237. package/design-system/components/SegmentedProgress/preview.html +69 -0
  238. package/design-system/components/SegmentedProgress/style.css +11 -0
  239. package/design-system/components/Select/README.md +47 -12
  240. package/design-system/components/Select/preview.html +28 -2
  241. package/design-system/components/Select/style.css +22 -0
  242. package/design-system/components/ShareBar/README.md +69 -0
  243. package/design-system/components/ShareBar/preview.html +72 -0
  244. package/design-system/components/ShareBar/style.css +25 -0
  245. package/design-system/components/SideList/README.md +147 -0
  246. package/design-system/components/SideList/preview.html +139 -0
  247. package/design-system/components/SideList/style.css +94 -0
  248. package/design-system/components/Skeleton/README.md +52 -16
  249. package/design-system/components/Skeleton/preview.html +35 -23
  250. package/design-system/components/Skeleton/style.css +22 -0
  251. package/design-system/components/Slider/README.md +95 -0
  252. package/design-system/components/Slider/preview.html +49 -0
  253. package/design-system/components/Slider/style.css +13 -0
  254. package/design-system/components/Split/README.md +112 -0
  255. package/design-system/components/Split/preview.html +105 -0
  256. package/design-system/components/Split/style.css +30 -0
  257. package/design-system/components/Starter/README.md +21 -9
  258. package/design-system/components/Starter/preview.html +5 -5
  259. package/design-system/components/Stat/README.md +64 -43
  260. package/design-system/components/Stat/preview.html +3 -3
  261. package/design-system/components/Stat/style.css +15 -0
  262. package/design-system/components/StatTiles/README.md +88 -44
  263. package/design-system/components/StatTiles/preview.html +142 -71
  264. package/design-system/components/StatTiles/style.css +64 -0
  265. package/design-system/components/StatusLine/README.md +85 -0
  266. package/design-system/components/StatusLine/preview.html +49 -0
  267. package/design-system/components/StatusLine/style.css +14 -0
  268. package/design-system/components/StatusScreen/README.md +49 -35
  269. package/design-system/components/StatusScreen/preview.html +20 -5
  270. package/design-system/components/StatusScreen/style.css +9 -0
  271. package/design-system/components/StepLine/README.md +97 -0
  272. package/design-system/components/StepLine/preview.html +108 -0
  273. package/design-system/components/StepLine/style.css +62 -0
  274. package/design-system/components/Stepper/README.md +35 -13
  275. package/design-system/components/Stepper/style.css +13 -0
  276. package/design-system/components/StreakCalendar/README.md +22 -1
  277. package/design-system/components/StreakCalendar/preview.html +10 -10
  278. package/design-system/components/StreakCalendar/style.css +12 -0
  279. package/design-system/components/SuggestionChip/README.md +87 -0
  280. package/design-system/components/SuggestionChip/preview.html +42 -0
  281. package/design-system/components/SuggestionChip/style.css +20 -0
  282. package/design-system/components/Switch/README.md +44 -24
  283. package/design-system/components/Switch/preview.html +23 -8
  284. package/design-system/components/Switch/style.css +31 -0
  285. package/design-system/components/Table/README.md +129 -58
  286. package/design-system/components/Table/preview.html +106 -72
  287. package/design-system/components/Table/style.css +104 -0
  288. package/design-system/components/Tabs/README.md +71 -46
  289. package/design-system/components/Tabs/preview.html +56 -24
  290. package/design-system/components/Tabs/style.css +44 -0
  291. package/design-system/components/Testimonial/README.md +48 -32
  292. package/design-system/components/Testimonial/preview.html +14 -14
  293. package/design-system/components/Testimonial/style.css +12 -0
  294. package/design-system/components/TextArea/README.md +27 -11
  295. package/design-system/components/TextArea/preview.html +8 -2
  296. package/design-system/components/TextArea/style.css +12 -0
  297. package/design-system/components/ThemeSwitch/README.md +116 -0
  298. package/design-system/components/ThemeSwitch/preview.html +57 -0
  299. package/design-system/components/ThemeSwitch/style.css +6 -0
  300. package/design-system/components/TickRow/README.md +52 -36
  301. package/design-system/components/TickRow/preview.html +64 -41
  302. package/design-system/components/TickRow/style.css +23 -0
  303. package/design-system/components/TickStrip/README.md +95 -0
  304. package/design-system/components/TickStrip/preview.html +88 -0
  305. package/design-system/components/TickStrip/style.css +42 -0
  306. package/design-system/components/Tile/README.md +79 -18
  307. package/design-system/components/Tile/preview.html +91 -40
  308. package/design-system/components/Tile/style.css +36 -0
  309. package/design-system/components/Timeline/README.md +68 -48
  310. package/design-system/components/Timeline/preview.html +27 -15
  311. package/design-system/components/Timeline/style.css +25 -0
  312. package/design-system/components/Toast/README.md +70 -38
  313. package/design-system/components/Toast/preview.html +43 -8
  314. package/design-system/components/Toast/style.css +25 -0
  315. package/design-system/components/Tooltip/README.md +93 -35
  316. package/design-system/components/Tooltip/preview.html +69 -15
  317. package/design-system/components/Tooltip/style.css +78 -0
  318. package/design-system/components/TopBar/README.md +67 -53
  319. package/design-system/components/TopBar/preview.html +14 -27
  320. package/design-system/components/TopBar/style.css +35 -0
  321. package/design-system/components/TopicRail/README.md +108 -0
  322. package/design-system/components/TopicRail/preview.html +58 -0
  323. package/design-system/components/TopicRail/style.css +48 -0
  324. package/design-system/components/TrendBars/README.md +52 -14
  325. package/design-system/components/TrendBars/preview.html +65 -32
  326. package/design-system/components/TrendBars/style.css +25 -0
  327. package/design-system/components/TrendLine/README.md +164 -0
  328. package/design-system/components/TrendLine/preview.html +373 -0
  329. package/design-system/components/TrendLine/style.css +155 -0
  330. package/design-system/components/Well/README.md +64 -22
  331. package/design-system/components/Well/preview.html +14 -14
  332. package/design-system/components/Well/style.css +22 -0
  333. package/design-system/components/_house.css +324 -0
  334. package/design-system/components/bundle.css +4091 -744
  335. package/design-system/tokens.json +1314 -124
  336. package/dist/fello-core.css +2 -2
  337. package/dist/fello.css +6 -1369
  338. package/dist/fello.scoped.css +7 -0
  339. package/dist/index.d.ts +110 -11
  340. package/dist/index.js +781 -96
  341. package/dist/palettes.d.ts +464 -0
  342. package/dist/palettes.js +497 -0
  343. package/dist/scoped.d.ts +3 -0
  344. package/dist/scoped.js +16 -0
  345. package/dist/toast.d.ts +14 -0
  346. package/dist/toast.js +33 -29
  347. package/dist/tokens.d.ts +1686 -62
  348. package/dist/tokens.js +1668 -61
  349. package/package.json +20 -4
  350. package/scripts/check-palette.mjs +295 -0
  351. package/scripts/token-model.mjs +552 -0
  352. package/tokens/_dark.css +174 -0
  353. package/tokens/_palettes.css +46 -0
  354. package/tokens/_product.css +266 -53
  355. package/tokens/_source.hubl.css +39 -19
  356. package/tokens/design-tokens.json +319 -0
  357. package/tokens/palettes.ts +504 -0
  358. package/tokens/shadcn-compat.css +19 -19
  359. package/tokens/shadcn-compat.hsl.css +76 -0
  360. package/tokens/tokens.css +1292 -62
  361. package/tokens/tokens.md +588 -61
  362. package/tokens/tokens.root.css +1298 -62
  363. package/tokens/tokens.ts +1677 -64
@@ -1,66 +1,122 @@
1
- A page's slim header: its one headline at 26 px, one line of what the page shows, and its acts at the right. The
2
- page-headline rule: a page names itself here, once, and its answer is the tiles and cards below, not a hero.
1
+ A page's 56 px header, Seth's thread header: the app's face, the page's name and a quiet word of context at the left;
2
+ its acts and a way back at the right. The page names itself here, once; its answer is the figures and cards below.
3
3
 
4
4
  ## Use it when
5
5
 
6
- - A page of the product or an artifact (a dashboard, a report, a list page) needs its name and one line of what it
7
- shows above its tiles and cards.
8
- - The page has a few controls that act on the whole page (a period, Share, Export) and at most one navy button.
6
+ - A page of the product or an artifact needs its name, what it belongs to ("Grow", "This month") and the few acts that
7
+ work on the whole page.
8
+ - A report opens full screen from a chat and needs Seth's "Back to the chat".
9
+ - In `AppShell`, as the bar itself: put `ws-app-shell__bar` and `ws-page-bar` on one `<header>`.
9
10
 
10
11
  ## Not for
11
12
 
12
- - A page whose top is an answer in itself, with a picture or a summary beside the words: use `PageHero`.
13
- - A card's own title and sentence: use the card's head (`.ws-head` with `.ws-title`, see `Card`).
14
- - A group of things inside a page: use `Section`.
15
- - A product area's own top bar with its links and search: use `TopBar` (in an app shell, the 56 px bar carries the
16
- page's name; the page then needs no PageBar).
13
+ - A page whose top is an answer in itself, with a picture or a big figure beside the words: use `PageHero` (or the
14
+ page's own figure) under this bar.
15
+ - A card's own title: the card's head (`.ws-head`, see `Card`).
16
+ - A group inside a page: `Section`.
17
+ - Links across a product's sections: `TopBar` or `AppShell`'s nav.
17
18
 
18
19
  ## Anatomy
19
20
 
20
- - `<header class="ws-page-bar">`: a row that wraps, the words on the left and the acts on the right, bottom-aligned,
21
- 16 apart across and 8 apart when the acts wrap under.
22
- - Words (`__words`): the title (`__title`, the page's one `h1`: 26 px `--font-size-2xl`, semibold, 32 px line,
23
- `--ws-tracking-title`, navy, balanced when it wraps); under it one line in `ws-body`; under that an optional slim
24
- status (a `ws-meta` line, a chip), 4 apart.
25
- - Acts (`__acts`): the page's controls, 8 apart, the page's one primary last.
26
- - It sits first in `.ws-page`, one gap (16) above the tiles or the board.
21
+ - `<header class="ws-page-bar">`: one row, at least 56 tall (`--ws-header-h`), words at the left and acts at the right,
22
+ centred on one line, 24 apart. No side padding of its own (the page's gutter or the shell's bar holds it); 8 above
23
+ and below, so a bar that wraps keeps clear of the edge above it (one line stays 56).
24
+ - Words (`__words`), one line that wraps only when it must:
25
+ - Face (`__face`): the app's 20 px mark (`--ws-icon-lg`), 14 before the name. Optional.
26
+ - Name (`__title`): the page's one `h1`, 16 / 22 semibold navy (Seth's thread title), one line, truncated with its
27
+ full words in `title`.
28
+ - Context (`__context`): 14 / 20 in muted, 16 after the name (Seth's 18, on the scale). It wraps under the name on a
29
+ narrow page.
30
+ - Acts (`__acts`), 8 apart:
31
+ - Fact (`__meta`): control words, 13 / 18 medium navy, its parts 6 apart ("Last audit", "Nov 2, today"), 16 before
32
+ the buttons (its own 8 and the acts' 8, Seth's gap). It also holds a working line.
33
+ - Buttons: `Button` secondary (quiet), at most one primary, last.
34
+ - Way back (`__back`): a 20 px icon, 10, then 15 / 20 regular navy words, no box (its focus ring takes the 4 px
35
+ control corners), 24 after the acts before it, at least 24 tall. Give it an `aria-label` that matches its words.
36
+ - A fact that is the last act (a working line) ends on the bar's edge, like a button would.
37
+ - On a page that is narrower than 40rem the words keep 160 before the acts drop under them, and the way back shows its
38
+ icon alone in a 40 px target (`__back-words` hides; the `aria-label` names it).
39
+
40
+ ## Variants and sizes
41
+
42
+ | Use | Shows |
43
+ | --- | --- |
44
+ | Thread header (a report from a chat) | Face, name, the app's name, a fact, quiet buttons, the way back |
45
+ | A page of its own | Name, context, the page's controls and its one primary |
46
+ | In `AppShell` | Either of those as the shell's bar, on the bar's 32 px edges |
27
47
 
28
48
  ## States
29
49
 
30
- - **Default**: title, line, acts.
31
- - **With a status**: a slim line under the line while something is being prepared or did not finish (a working dot
32
- and words, never a spinner alone).
33
- - **No acts**: the words take the whole row.
34
- - **Narrow**: the acts wrap under the words; the title wraps (balanced) rather than truncating.
50
+ - **Default**: as above.
51
+ - **Working**: the fact slot says what is happening, a working dot and words (`role="status"`), never a spinner alone.
52
+ - **No acts**: the words take the row.
53
+ - **Long name**: one line with an ellipsis, the full name in `title`; the context wraps under it.
54
+ - **Narrow**: the context goes under the name, then the acts go under the words. When the way back is the bar's only
55
+ act it keeps its icon on the name's line; with other acts it goes last on their line, under the name, on the right
56
+ rail (acts under the words take the whole line, however few they are). A fact takes a line of its own above the
57
+ buttons, so they and the way back stay on one line. So on a phone
58
+ in a shell keep the bar to the name and the way back, and move the rest into the page (K6).
59
+ - **Hover** on the way back: its words underline. **Focus**: the house's 2 px navy ring.
35
60
 
36
61
  ## Behaviour
37
62
 
38
- - The title is the page's only `h1`; the cards below use `h2` or `h3`.
39
- - No motion of its own; the cards below rise in.
63
+ - The name is the page's only `h1`; the cards below use `h2` or `h3`.
64
+ - No motion of its own; the page's parts settle in below it.
40
65
 
41
66
  ## Content
42
67
 
43
- - The title is the page's name as the navigation says it ("How you show up"), sentence case, no period.
44
- - The line says what the page shows and for when ("this month", "the last 90 days"), one sentence.
45
- - One navy button at most, the page's one primary; the others are secondary or ghost.
68
+ - The name is the page's name as the nav or the chat says it ("Audit report"), sentence case, no period.
69
+ - The context is one or two words: the app ("Grow") or the window ("This month").
70
+ - One navy button at most, the page's one primary; the rest are quiet.
46
71
 
47
72
  ## Props
48
73
 
49
74
  | Name | Type | Meaning |
50
75
  | --- | --- | --- |
51
76
  | `title` | `string` | The page's name, its one `h1` |
52
- | `line` | `ReactNode` | One line of what the page shows |
53
- | `status` | `ReactNode` | A slim status under the line |
77
+ | `face` | `ReactNode` | The app's 20 px mark |
78
+ | `context` | `ReactNode` | The quiet word beside the name |
79
+ | `meta` | `ReactNode` | A fact before the acts, or a working line |
54
80
  | `actions` | `ReactNode` | The page's controls and its one primary |
81
+ | `back` | `{ label, href }` | The way back, last |
55
82
 
56
83
  ## Rules
57
84
 
58
- - **The page-headline rule**: a page's headline is this bar's 26 px title, once; no second heading in the canvas, no
59
- hero on a page whose answer is tiles and cards.
85
+ - **One name per page**, here, once; no second heading repeats it in the body.
60
86
  - **One primary per page**, here or in a card's band, never both.
87
+ - **One line where it sticks**: as a shell's bar under 40rem it keeps one 56 px line (K6): the context goes (North's
88
+ rule: the secondary words go, the title stays), then the name gives way with its ellipsis and its `title`.
61
89
 
62
90
  ## Source
63
91
 
64
- **Derived from**: the first product's Grow pages (`PageBar`, the dashboard arrangement, 23 Oct 2026): the title, one
65
- line, a status under it, the controls and the one navy button on the right. **Precedent**: the first product built on
66
- the system.
92
+ **Derived from**: Seth's Fia thread header (Figma `301:1632`, same in `305:2282`, `308:2468`, `313:2673`,
93
+ `319:3304`): 56 tall, 32 px sides, face 20, 14, name 16 / 22 semibold, 18, app name 14 / 20; at the right a fact in
94
+ 13 / 18 medium, two quiet 32 px buttons and "Back to the chat" (20 px icon, 10, 15 / 20). It replaces 0.4's 26 px
95
+ headline bar (Seth wins, D1).
96
+
97
+ ## Markup
98
+
99
+ ```html
100
+ <header class="ws-page-bar">
101
+ <div class="ws-page-bar__words">
102
+ <svg class="ws-page-bar__face" viewBox="0 0 20 20" aria-hidden="true"><!-- the app's mark --></svg>
103
+ <h1 class="ws-page-bar__title">Audit report</h1>
104
+ <span class="ws-page-bar__context">Grow</span>
105
+ </div>
106
+ <div class="ws-page-bar__acts">
107
+ <p class="ws-page-bar__meta"><span>Last audit</span><span>Nov 2, today</span></p>
108
+ <button type="button" class="ws-btn ws-btn--secondary">Refresh</button>
109
+ <a href="/chat" class="ws-page-bar__back" aria-label="Back to the chat">
110
+ <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v5H3M12 3v5h5M8 17v-5H3M12 17v-5h5"/></svg>
111
+ <span class="ws-page-bar__back-words">Back to the chat</span>
112
+ </a>
113
+ </div>
114
+ </header>
115
+ ```
116
+
117
+ ## Styles
118
+
119
+ `PageBar/style.css`; the buttons are `Button`'s. It is a size container named `ws-page-bar`. Tokens:
120
+ `--ws-header-h`, `--font-size-md`, `--ws-leading-section`, `--ws-text-body`, `--ws-leading-row`, `--ws-text-control`,
121
+ `--ws-leading-control`, `--ws-text-section`, `--ws-icon-lg`, `--ws-touch`, `--color-text-heading`,
122
+ `--color-text-muted`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Layout" height=420 -->
1
+ <!-- @dsCard group="Layout" height=458 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -11,47 +11,88 @@
11
11
  <div class="ws-stage ws-stage--column">
12
12
 
13
13
  <div class="ws-stack">
14
- <span class="ws-muted">Default: the page's one h1, one line of what it shows, its acts at the right (the page's one primary last)</span>
14
+ <span class="ws-muted">Seth's thread header: the app's face, the page's name and the app, a fact and two quiet acts, then the way back</span>
15
15
  <header class="ws-page-bar">
16
16
  <div class="ws-page-bar__words">
17
- <h1 class="ws-page-bar__title">How you show up</h1>
18
- <p class="ws-body">Your calls, shows and follow-ups this month, against your goals.</p>
17
+ <svg class="ws-page-bar__face" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 16.5V9l6.5-5.5L16.5 9v7.5Z"/><path d="M8 16.5v-4h4v4"/></svg>
18
+ <h1 class="ws-page-bar__title">Audit report</h1>
19
+ <span class="ws-page-bar__context">Grow</span>
19
20
  </div>
20
21
  <div class="ws-page-bar__acts">
21
- <div class="ws-segmented" role="tablist" aria-label="Period">
22
- <button class="ws-segmented__item" role="tab" aria-selected="false">Week</button>
23
- <button class="ws-segmented__item" role="tab" aria-selected="true">Month</button>
24
- </div>
25
- <button class="ws-btn ws-btn--secondary">Share</button>
26
- <button class="ws-btn ws-btn--primary">Plan next week</button>
22
+ <p class="ws-page-bar__meta"><span>Last audit</span><span>Nov 2, today</span></p>
23
+ <button type="button" class="ws-btn ws-btn--secondary">
24
+ <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2.5v3h-3"/></svg>
25
+ Refresh
26
+ </button>
27
+ <button type="button" class="ws-btn ws-btn--secondary">Settings</button>
28
+ <a href="#" class="ws-page-bar__back" aria-label="Back to the chat" onclick="return false;">
29
+ <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v5H3M12 3v5h5M8 17v-5H3M12 17v-5h5"/></svg>
30
+ <span class="ws-page-bar__back-words">Back to the chat</span>
31
+ </a>
27
32
  </div>
28
33
  </header>
29
34
  </div>
30
35
 
31
36
  <div class="ws-stack">
32
- <span class="ws-muted">With a status under the line, and no acts</span>
37
+ <span class="ws-muted">A page of its own: the name and its context, a period and the page's one primary last</span>
33
38
  <header class="ws-page-bar">
34
39
  <div class="ws-page-bar__words">
35
- <h1 class="ws-page-bar__title">Fixes</h1>
36
- <p class="ws-body">What to change first, from your last ten calls.</p>
37
- <p class="ws-cluster ws-cluster--tight ws-meta"><span class="ws-dot ws-working" aria-hidden="true"></span>This week's audit is still being prepared</p>
40
+ <h1 class="ws-page-bar__title">How you show up</h1>
41
+ <span class="ws-page-bar__context">This month, against your goals</span>
42
+ </div>
43
+ <div class="ws-page-bar__acts">
44
+ <div class="ws-segmented" role="tablist" aria-label="Period">
45
+ <button type="button" class="ws-segmented__item" role="tab" aria-selected="false">Week</button>
46
+ <button type="button" class="ws-segmented__item" role="tab" aria-selected="true">Month</button>
47
+ </div>
48
+ <button type="button" class="ws-btn ws-btn--primary">Plan next week</button>
38
49
  </div>
39
50
  </header>
40
51
  </div>
41
52
 
42
- <div class="ws-stack" style="width: 300px; max-width: 100%;">
43
- <span class="ws-muted">Narrow: the acts wrap under the words, never squeezing the title</span>
53
+ <div class="ws-stack">
54
+ <span class="ws-muted">Working: the fact slot says what is happening, a working dot and words, never a spinner alone; no acts</span>
44
55
  <header class="ws-page-bar">
45
56
  <div class="ws-page-bar__words">
46
- <h1 class="ws-page-bar__title">What clients say</h1>
47
- <p class="ws-body">Reviews from the last 90 days.</p>
57
+ <h1 class="ws-page-bar__title">Fixes</h1>
58
+ <span class="ws-page-bar__context">Grow</span>
48
59
  </div>
49
60
  <div class="ws-page-bar__acts">
50
- <button class="ws-btn ws-btn--primary">Ask for a review</button>
61
+ <p class="ws-page-bar__meta" role="status"><span class="ws-cluster ws-cluster--tight"><span class="ws-dot ws-working" aria-hidden="true"></span>Preparing this week's audit</span></p>
51
62
  </div>
52
63
  </header>
53
64
  </div>
54
65
 
66
+ <div class="ws-cluster ws-cluster--start ws-cluster--component">
67
+ <div class="ws-stack" style="width: 340px; max-width: 100%;">
68
+ <span class="ws-muted">Narrow: a long name gives way with an ellipsis, the context wraps under it, the way back keeps its icon</span>
69
+ <header class="ws-page-bar">
70
+ <div class="ws-page-bar__words">
71
+ <h1 class="ws-page-bar__title" title="What buyers ask before a showing">What buyers ask before a showing</h1>
72
+ <span class="ws-page-bar__context">Coach</span>
73
+ </div>
74
+ <div class="ws-page-bar__acts">
75
+ <a href="#" class="ws-page-bar__back" aria-label="Back to the chat" onclick="return false;">
76
+ <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v5H3M12 3v5h5M8 17v-5H3M12 17v-5h5"/></svg>
77
+ <span class="ws-page-bar__back-words">Back to the chat</span>
78
+ </a>
79
+ </div>
80
+ </header>
81
+ </div>
82
+ <div class="ws-stack" style="width: 340px; max-width: 100%;">
83
+ <span class="ws-muted">Narrow with a primary: the context wraps under the name and the act keeps its place; it drops under the words only when they would go under 160</span>
84
+ <header class="ws-page-bar">
85
+ <div class="ws-page-bar__words">
86
+ <h1 class="ws-page-bar__title">What clients say</h1>
87
+ <span class="ws-page-bar__context">The last 90 days</span>
88
+ </div>
89
+ <div class="ws-page-bar__acts">
90
+ <button type="button" class="ws-btn ws-btn--primary">Ask for a review</button>
91
+ </div>
92
+ </header>
93
+ </div>
94
+ </div>
95
+
55
96
  </div>
56
97
  </body>
57
98
  </html>
@@ -0,0 +1,35 @@
1
+ /* ---- PageBar: a page's 56 px header, Seth's thread header (D1). At the left the app's 20 px face, the page's name (its one
2
+ h1, 16 / 22 semibold) and a quiet word of context; at the right its acts and, last, a way back. One line; on a narrow
3
+ page the acts wrap under the words. No side padding of its own: the page's gutter (or the shell's bar) holds it; 8
4
+ above and below, so a wrapped bar keeps its edges (one line stays 56). ---- */
5
+ .ws-page-bar { container: ws-page-bar / inline-size; display: flex; flex-shrink: 0; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-xs) var(--space-lg); min-height: var(--ws-header-h); padding-block: var(--space-xs); }
6
+ .ws-page-bar__words { display: flex; flex: 1 1 0; flex-wrap: wrap; align-items: center; column-gap: var(--space-md); min-width: min(100%, var(--space-9xl)); }
7
+ .ws-page-bar__face { flex-shrink: 0; width: var(--ws-icon-lg); height: var(--ws-icon-lg); margin-inline-end: calc(var(--space-sm-plus) - var(--space-md)); }
8
+ .ws-page-bar__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--font-size-md); line-height: var(--ws-leading-section); font-weight: 600; letter-spacing: var(--ws-tracking-title); color: var(--color-text-heading); }
9
+ .ws-page-bar__context { min-width: 0; font-size: var(--ws-text-body); line-height: var(--ws-leading-row); color: var(--color-text-muted); }
10
+ .ws-page-bar__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs); min-width: 0; }
11
+ /* A fact before the acts ("Last audit Nov 2, today"): control words, 6 apart. */
12
+ .ws-page-bar__meta { display: inline-flex; flex-wrap: wrap; column-gap: var(--space-xxs-plus); padding-inline-end: var(--space-xs); font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; color: var(--color-text-heading); }
13
+ .ws-page-bar__meta:last-child { padding-inline-end: 0; }
14
+ /* The way back ("Back to the chat"): a 20 px icon and 15 px words, no box, 24 after the acts before it. */
15
+ .ws-page-bar__back { display: inline-flex; align-items: center; gap: var(--space-xs-plus); min-height: var(--space-lg); padding: 0; border: 0; border-radius: var(--ws-radius-control); background: none; font-size: var(--ws-text-section); line-height: var(--ws-leading-row); font-weight: 400; color: var(--color-text-heading); text-decoration: none; white-space: nowrap; cursor: pointer; }
16
+ .ws-page-bar__acts > * + .ws-page-bar__back { margin-inline-start: var(--space-md); }
17
+ .ws-page-bar__back > svg { flex-shrink: 0; width: var(--ws-icon-lg); height: var(--ws-icon-lg); }
18
+ @media (hover: hover) { .ws-page-bar__back:hover { text-decoration: underline; text-underline-offset: var(--space-xxs); } }
19
+ /* A narrow bar keeps its one line (K6): the words keep 160 before the acts drop under them, the way back is its icon
20
+ alone, a 40 px target, named by its aria-label. A fact takes a line of its own, so the buttons and the way back share
21
+ the next one, the way back on the right rail (never alone on a line at the left). Acts that drop under the words take
22
+ that whole line, so the way back reaches the rail even when they are narrower than the bar; beside the words they
23
+ keep their own width (the words take the line's room first, 999 to 1). */
24
+ @container ws-page-bar (max-width: 40rem) {
25
+ .ws-page-bar__words { flex-grow: 999; min-width: min(100%, var(--space-8xl)); }
26
+ .ws-page-bar__acts { flex-grow: 1; }
27
+ .ws-page-bar__meta { flex-basis: 100%; padding-inline-end: 0; }
28
+ .ws-page-bar__back { justify-content: center; min-width: var(--ws-touch); min-height: var(--ws-touch); }
29
+ .ws-page-bar__back-words { display: none; }
30
+ .ws-page-bar__acts > * + .ws-page-bar__back { margin-inline-start: auto; }
31
+ /* As a shell's bar it sticks, so it keeps its one 56 px line: the context goes (Seth's R6, the secondary words go and
32
+ the title stays), then the name gives way with its ellipsis. */
33
+ .ws-app-shell__bar > .ws-page-bar__words { flex-wrap: nowrap; }
34
+ .ws-app-shell__bar > .ws-page-bar__words > .ws-page-bar__context { display: none; }
35
+ }
@@ -1,64 +1,67 @@
1
- A page's slim hero: a small eyebrow, the page's finding as its headline, a line or two under it, its one act, and
2
- a picture beside them, all on the page's own wash rather than inside a card.
1
+ A page's slim hero: a small eyebrow, the page's finding as its headline, a line under it, its one act, and a picture
2
+ beside them, on the page's own wash rather than inside a card.
3
3
 
4
4
  ## Use it when
5
5
 
6
- - An app page's dashboard needs to open with its one finding in words, before the cards that back it up (a sales
7
- app's Team and Pipeline pages).
6
+ - An app page needs to open with its one finding in words, before the cards that back it up (a sales app's Team and
7
+ Pipeline pages).
8
8
  - The page has a picture, chart or sample worth showing beside its headline.
9
9
 
10
10
  ## Not for
11
11
 
12
- - Every page: most app pages use `PageBar`'s plain 26 px headline instead (no hero, no picture); reach for
13
- `PageHero` only when a page's opening finding earns the extra room.
14
- - A card's own head (`ws-head`, `ws-title`): `PageHero` sits on the page's wash, never inside a `ws-card`.
15
- - A chat's own greeting ("Morning, Ryan."): that is Home's own 22 px greeting line, not this component.
12
+ - Every page: most pages have only `PageBar` and go straight to their figures and cards.
13
+ - A card's own head (`ws-head`, `ws-title`): the hero sits on the page, never inside a `ws-card`.
14
+ - A big score as the page's answer: that is the score figure (`ws-figure--score`, 96 / 96) or `ScoreHero`.
16
15
 
17
16
  ## Anatomy
18
17
 
19
- - Layout: a two-column grid from the `lg` area up (`minmax(0,1fr) minmax(0,1fr)`) when it has an aside, stacked below
20
- it; `--space-2xl` (32 px) between the columns, `--space-lg` (24 px) between the stacked rows. The area is the nearest
21
- `.ws-page` or `.ws-area` (a container query, not the window).
22
- - Eyebrow: `ws-muted` (12 px, `--color-text-muted`).
23
- - Headline: `--font-size-2xl` (26 px) from the small area, growing to `--font-size-3xl` (40 px) from the `lg`
24
- area; semibold, `--ws-tracking-title`, navy.
25
- - Lines: `--font-size-md` (16 px), relaxed line height, `--color-text-body`, capped at prose width.
26
- - Action: the page's one navy button, `--space-xs` above the lines.
27
- - Aside: the page's picture, filling the second column, no fixed height of its own. Optional: without it the words take
28
- the whole width.
29
- - In fello.css: `.ws-page-hero` (+ `--cool`, `--team`), `__words`, `__title`, `__lines`, `__acts`, `__aside`.
18
+ - Layout: it measures itself (a size container named `ws-page-hero`, K3). Under 60rem of its own width, one column,
19
+ 24 between rows; from 60rem, when it has an aside, two columns 64 apart (`--space-4xl`, Seth's Tally hero): equal
20
+ halves, or the words take the rest and the aside `--ws-page-hero-aside` (Tally's status is 600:
21
+ `calc(var(--space-9xl) * 3)`).
22
+ - Eyebrow: `ws-muted` (12 / 16); on a wash it takes the body grey, its AA step there (the cool wash's corner leaves
23
+ muted at 4.49 : 1).
24
+ - Figure (`__figure`): optional, the finding as a number above the headline (Seth's Tally "$29,472"): 96 / 96 regular
25
+ navy (`--ws-text-score`), -3%, proportional figures, one line that is never cut. Under 26rem of the words it steps to
26
+ 72 (`--ws-text-display`); in a narrower column it gives way to a quarter of the column's width.
27
+ - Headline (`__title`): 26 / 32 semibold navy (`--font-size-2xl`); from 60rem 40 / 48 (`--font-size-3xl`, Seth's
28
+ Tally H1), `--ws-tracking-title`, balanced when it wraps.
29
+ - Lines (`__lines`): 14 / 22 in the body grey (Seth's hero sentence), up to 60 characters wide.
30
+ - Words (`__words`): 6 apart (Seth's headline gap).
31
+ - Act (`__acts`): the page's one navy button, 12 under the lines; a note beside it 14 after.
32
+ - Aside (`__aside`): the picture, filling its column, no fixed height, centred against the words. Optional.
33
+ `__aside--top`: a status (a `ShareBar` and its act, Tally) sits at the top, 32 down, from 60rem.
34
+ - In fello.css: `.ws-page-hero` (+ `--cool`, `--team`), `__words`, `__figure`, `__title`, `__lines`, `__acts`,
35
+ `__aside` (+ `--top`).
30
36
 
31
37
  ## Variants and sizes
32
38
 
33
- | Area width | Headline size |
34
- | --- | --- |
35
- | Below `lg` (under 60rem) | 26 px, one column, the aside stacked under the words |
36
- | `lg` and up | 40 px, two columns side by side |
39
+ | Its own width | Headline | Layout |
40
+ | --- | --- | --- |
41
+ | Under 60rem | 26 / 32 | One column, the aside under the words |
42
+ | 60rem and up | 40 / 48 | Two columns, 64 apart, when it has an aside; the aside half, or `--ws-page-hero-aside` |
37
43
 
38
44
  ## States
39
45
 
40
- - **Default**: as drawn above, on the page's plain cream.
41
- - **With a wash**: a faint radial tint behind the words, `.ws-page-hero--cool` (`--ws-cool-glow`) or
42
- `.ws-page-hero--team` (`--ws-team-glow`); the hero then takes 24 px inside (`--space-lg`) and the card's 8 px corners so
43
- the wash shows round the words. Always still, never animated.
44
- - **No aside**: the words take the whole width at every size; the hero stays one column (it only goes two-column when
45
- it has an aside).
46
- - **No lines**: the headline and action sit alone, no gap left where the lines would be.
47
- - **No action**: the lines run to the hero's edge with no button under them.
48
- - **Narrow**: the aside drops below the words instead of beside them.
46
+ - **Default**: on the page's plain cream.
47
+ - **With a wash**: `--cool` (`--ws-cool-glow`) or `--team` (`--ws-team-glow`); the hero then takes 24 inside and 8 px
48
+ corners so the wash shows round the words. Always still.
49
+ - **No aside**: the words take the whole width at every size.
50
+ - **No lines** or **no act**: nothing is left where they would be.
51
+ - **With a figure**: the number above the headline, 6 apart; on a 320 phone it is 72 and never cut.
52
+ - **Narrow**: the aside drops under the words.
53
+ - **Dark**: the washes have their own dark values; nothing else changes.
49
54
 
50
55
  ## Behaviour
51
56
 
52
- - No keyboard behaviour of its own beyond its one button and any links inside `lines`.
53
- - Motion: none; a hero is still even while the rest of the page animates in.
54
- - Hidden when expanded: when a page already says in its cards what the hero would say, the hero is left out
55
- rather than repeating it (the system's rule, "Hero blocks stay slim").
57
+ - No keyboard behaviour of its own beyond its button and any links in its lines.
58
+ - No motion: the hero is still while the page settles in.
59
+ - Left out when the cards already say what it would say ("Hero blocks stay slim").
56
60
 
57
61
  ## Content
58
62
 
59
- - The headline states the finding, not the topic ("Your team this month" says less than the real pages do;
60
- prefer an answer like "Six of eight reached out this week" where the data allows it).
61
- - One or two lines at most under the headline; longer explanation belongs in the cards below.
63
+ - The headline states the finding ("Six of eight reached out this week"), not the topic.
64
+ - One or two lines under it; the rest belongs in the cards.
62
65
  - No em dashes.
63
66
 
64
67
  ## Props
@@ -66,21 +69,54 @@ a picture beside them, all on the page's own wash rather than inside a card.
66
69
  | Name | Type | Meaning |
67
70
  | --- | --- | --- |
68
71
  | `eyebrow` | `ReactNode` | The small label above the headline |
69
- | `title` | `ReactNode` | The headline itself |
70
- | `lines` | `ReactNode` | The line or two under it (optional) |
71
- | `action` | `ReactNode` | The page's one navy button (optional) |
72
- | `aside` | `ReactNode` | The picture on the right (optional: without it the words span the width) |
72
+ | `figure` | `ReactNode` | The number above the headline |
73
+ | `title` | `ReactNode` | The headline |
74
+ | `lines` | `ReactNode` | The line or two under it |
75
+ | `action` | `ReactNode` | The page's one navy button |
76
+ | `aside` | `ReactNode` | The picture beside it |
77
+ | `asideWidth` | `string` | A token for `--ws-page-hero-aside`; default half |
78
+ | `asideTop` | `boolean` | The aside at the top, 32 down, not centred |
79
+ | `wash` | `'cool'` \| `'team'` | The faint wash behind it |
73
80
 
74
81
  ## Rules
75
82
 
76
- - **Hero blocks stay slim: one line, not a banner** (the system's rule); hide it entirely when the screen already
77
- says what it would say.
78
- - Tokens only: the washes are the page-wash tokens `--ws-cool-glow` and `--ws-team-glow` (`tokens/_product.css`,
79
- declared in `tokens.css` and `fello.css`; `tokens.json` names them in its meta note, since a gradient cannot be held
80
- there). No raw colour, size or radius.
83
+ - **Hero blocks stay slim**: one finding, not a banner; hide it when the screen already says it.
84
+ - **Size from itself, not the page** (K3): the same hero is right in a pane and a page.
85
+ - Tokens only: no raw colour, size or radius.
81
86
 
82
87
  ## Source
83
88
 
84
- - **Derived from**: the system's page-wash and slim-hero rules (`--ws-cool-glow`/`--ws-team-glow`, the plainer
85
- headline most pages use instead).
86
- - **Precedent**: the first product built on the system, 23 Oct 2026.
89
+ **Derived from**: the system's page-wash and slim-hero rules, Seth's Tally report hero (Figma `319:3317`: H1 40 / 48
90
+ semibold, sentence 14 / 22, 6 apart, two columns 64 apart, the act 12 under) and Revenue OS fault K3 (a hero that read
91
+ its size from whichever ancestor was a container). **Precedent**: the first product built on the system.
92
+
93
+ ## Markup
94
+
95
+ ```html
96
+ <section class="ws-page-hero ws-page-hero--cool" aria-labelledby="hero-title">
97
+ <div class="ws-page-hero__words">
98
+ <p class="ws-muted">Progress</p>
99
+ <h2 id="hero-title" class="ws-page-hero__title">Six of eight reached out this week</h2>
100
+ <div class="ws-page-hero__lines"><p>Cold calls carried most of the gain.</p></div>
101
+ <div class="ws-page-hero__acts"><button type="button" class="ws-btn ws-btn--primary">See the team</button></div>
102
+ </div>
103
+ <div class="ws-page-hero__aside"><!-- the picture --></div>
104
+ </section>
105
+
106
+ <!-- Tally: a figure above the headline, a 600 status at the top -->
107
+ <section class="ws-page-hero" style="--ws-page-hero-aside: calc(var(--space-9xl) * 3);" aria-labelledby="tally-title">
108
+ <div class="ws-page-hero__words">
109
+ <p class="ws-page-hero__figure">$29,472</p>
110
+ <h2 id="tally-title" class="ws-page-hero__title">a year off your tools by Q1 2027</h2>
111
+ <div class="ws-page-hero__lines"><p>Out of $77,472 a year across 5 tools.</p></div>
112
+ </div>
113
+ <div class="ws-page-hero__aside ws-page-hero__aside--top"><!-- a ShareBar and its act --></div>
114
+ </section>
115
+ ```
116
+
117
+ ## Styles
118
+
119
+ `PageHero/style.css`. The words are a size container too (for the figure). Tokens: `--ws-text-score`,
120
+ `--ws-text-display`, `--ws-tracking-display`, `--font-size-2xl`, `--font-size-3xl`, `--space-xl`, `--space-3xl`, `--space-4xl`,
121
+ `--space-lg`, `--space-xxs-plus`, `--ws-text-body`, `--ws-leading-section`, `--ws-tracking-title`, `--ws-cool-glow`,
122
+ `--ws-team-glow`, `--ws-radius-card`, `--color-text-heading`, `--color-text-body`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Desk" height=914 -->
1
+ <!-- @dsCard group="Desk" height=1074 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -10,8 +10,8 @@
10
10
  <body>
11
11
  <div class="ws-stage ws-stage--column" style="align-items: center;">
12
12
 
13
- <div class="ws-stack ws-area" style="width: 900px; max-width: 100%;">
14
- <span class="ws-muted">Below the `lg` area: the 26 px headline, the aside under the words, the cool wash</span>
13
+ <div class="ws-stack" style="width: 900px; max-width: 100%;">
14
+ <span class="ws-muted">Under 60rem of its own width (here 900 px): the 26 px headline, the aside under the words, the cool wash</span>
15
15
  <section class="ws-page-hero ws-page-hero--cool" aria-labelledby="hero-narrow">
16
16
  <div class="ws-page-hero__words">
17
17
  <p class="ws-muted">Progress</p>
@@ -25,7 +25,7 @@
25
25
  </section>
26
26
  </div>
27
27
 
28
- <div class="ws-stack ws-area" style="width: 900px; max-width: 100%;">
28
+ <div class="ws-stack" style="width: 900px; max-width: 100%;">
29
29
  <span class="ws-muted">No aside: the words take the whole width at every size, the team wash</span>
30
30
  <section class="ws-page-hero ws-page-hero--team" aria-labelledby="hero-plain">
31
31
  <div class="ws-page-hero__words">
@@ -40,8 +40,8 @@
40
40
  </div>
41
41
  <div class="ws-stage ws-stage--column ws-stage--bleed" style="padding-bottom: var(--ws-gap-component);">
42
42
 
43
- <div class="ws-stack ws-area">
44
- <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">From the `lg` area (60rem) up: the 40 px headline, words and aside side by side</span>
43
+ <div class="ws-stack">
44
+ <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">From 60rem of its own width: the 40 / 48 headline, words and aside side by side, 64 apart</span>
45
45
  <section class="ws-page-hero ws-page-hero--cool" aria-labelledby="hero-wide">
46
46
  <div class="ws-page-hero__words">
47
47
  <p class="ws-muted">Progress</p>
@@ -55,6 +55,35 @@
55
55
  </section>
56
56
  </div>
57
57
 
58
+ <div class="ws-stack">
59
+ <span class="ws-muted" style="padding: 0 var(--ws-gap-component);">Seth's Tally hero: a figure above the headline (96, 72 under 26rem of the words, never cut), a 600 status at the top (--ws-page-hero-aside, __aside--top)</span>
60
+ <div style="padding: 0 var(--ws-gap-component);">
61
+ <section class="ws-page-hero" style="--ws-page-hero-aside: calc(var(--space-9xl) * 3);" aria-labelledby="hero-tally">
62
+ <div class="ws-page-hero__words">
63
+ <p class="ws-page-hero__figure">$29,472</p>
64
+ <h2 id="hero-tally" class="ws-page-hero__title">a year off your tools by Q1 2027</h2>
65
+ <div class="ws-page-hero__lines"><p>Out of $77,472 a year across 5 tools. Email turns off today, your website and CRM in Q1 2027.</p></div>
66
+ </div>
67
+ <div class="ws-page-hero__aside ws-page-hero__aside--top">
68
+ <figure class="ws-share-bar" aria-label="Where your $77,472 goes: 38% comes off.">
69
+ <div class="ws-share-bar__head" aria-hidden="true"><span>Where your $77,472 goes</span><span>38% comes off</span></div>
70
+ <div class="ws-share-bar__bar" aria-hidden="true">
71
+ <span class="ws-share-bar__part" style="--share: 26.3%; --tone: var(--ws-chart-past-half);"></span>
72
+ <span class="ws-share-bar__part" style="--share: 9.6%; --tone: var(--ws-chart-finished);"></span>
73
+ <span class="ws-share-bar__part" style="--share: 2.1%; --tone: var(--ws-chart-under-half);"></span>
74
+ </div>
75
+ <ul class="ws-share-bar__key" aria-hidden="true">
76
+ <li class="ws-share-bar__item" style="--tone: var(--ws-chart-past-half);">Website &amp; IDX <b>$20,400</b></li>
77
+ <li class="ws-share-bar__item" style="--tone: var(--ws-chart-finished);">CRM <b>$7,452</b></li>
78
+ <li class="ws-share-bar__item" style="--tone: var(--ws-chart-under-half);">Email <b>$1,620</b></li>
79
+ <li class="ws-share-bar__item">Paid ads <b>$48,000</b> stays</li>
80
+ </ul>
81
+ </figure>
82
+ </div>
83
+ </section>
84
+ </div>
85
+ </div>
86
+
58
87
  </div>
59
88
  </body>
60
89
  </html>
@@ -0,0 +1,31 @@
1
+ /* ---- PageHero: a page's slim hero, its finding as the headline, a line, its one act and a picture beside them.
2
+ It measures itself (K3): one column with the 26 px headline; from 60rem of its own width the 40 / 48 headline (Seth's
3
+ Tally H1) and, when it has an aside, two columns 64 apart, the aside half the width or --ws-page-hero-aside (Tally's
4
+ status is 600). With no aside the words take the whole width. ---- */
5
+ .ws-page-hero { container: ws-page-hero / inline-size; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--ws-page-hero-aside, 1fr)); align-items: center; column-gap: var(--space-4xl); row-gap: var(--space-lg); }
6
+ .ws-page-hero > * { grid-column: 1 / -1; min-width: 0; }
7
+ /* A faint wash behind it (the page-wash tokens), padded so the wash shows round the words. */
8
+ .ws-page-hero--cool, .ws-page-hero--team { border-radius: var(--ws-radius-card); padding: var(--space-lg); }
9
+ .ws-page-hero--cool { background-image: var(--ws-cool-glow); }
10
+ .ws-page-hero--team { background-image: var(--ws-team-glow); }
11
+ /* Muted words on a wash take the body grey, their AA step on that ground (D2): the cool wash's corner is 4.49 : 1 under
12
+ muted in a narrow hero. */
13
+ :is(.ws-page-hero--cool, .ws-page-hero--team) .ws-muted { color: var(--color-text-body); }
14
+ /* The words measure themselves too, so the figure fits the column it is in, beside an aside or alone. */
15
+ .ws-page-hero__words { container-type: inline-size; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-xxs-plus); }
16
+ /* The figure above the headline (Seth's Tally 90 / 100, on the kit's 96 / 96 score step, D6): one line, never cut; under
17
+ 26rem of the words it steps to 72, and in a narrower column it gives way to a quarter of the column's width (72 on a
18
+ 320 phone). */
19
+ .ws-page-hero__figure { max-width: 100%; font-size: min(var(--ws-text-score), 25cqi); line-height: 1; font-weight: 400; letter-spacing: var(--ws-tracking-display); color: var(--color-text-heading); font-variant-numeric: proportional-nums; white-space: nowrap; }
20
+ @container (max-width: 26rem) { .ws-page-hero__figure { font-size: min(var(--ws-text-display), 25cqi); } }
21
+ .ws-page-hero__title { font-size: var(--font-size-2xl); line-height: var(--space-xl); font-weight: 600; letter-spacing: var(--ws-tracking-title); color: var(--color-text-heading); text-wrap: balance; overflow-wrap: break-word; max-width: 100%; }
22
+ .ws-page-hero__lines { max-width: 60ch; text-wrap: pretty; display: flex; flex-direction: column; gap: var(--space-xs); font-size: var(--ws-text-body); line-height: var(--ws-leading-section); color: var(--color-text-body); }
23
+ .ws-page-hero__acts { margin-top: var(--space-xxs-plus); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-sm-plus); }
24
+ /* Under a status in the aside (Tally's ShareBar), the act is 12 under it too: the aside has no gap of its own. */
25
+ .ws-page-hero__aside > .ws-page-hero__acts { margin-top: var(--space-sm); }
26
+ @container ws-page-hero (min-width: 60rem) {
27
+ .ws-page-hero > :is(.ws-page-hero__words, .ws-page-hero__aside):not(:only-child) { grid-column: auto; }
28
+ .ws-page-hero__title { font-size: var(--font-size-3xl); line-height: var(--space-3xl); }
29
+ /* --top: a status beside the words sits at the top, 32 down (Seth's Tally status, pt 34 on the grid), not centred. */
30
+ .ws-page-hero__aside--top { align-self: start; padding-top: var(--space-xl); }
31
+ }