@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,69 +1,113 @@
1
- A page's answer at a glance: four big-number tiles in a row, each a tone's stripe, a label, a figure with its chip, and one line or a tick row.
1
+ A page's answer at a glance: a few rimmed tiles, each a label, a figure with its mark or chip, and an optional foot.
2
2
 
3
3
  **Use it when**
4
4
 
5
- - A page's whole answer is a small set of numbers, not one card's single figure (a dashboard's "How you show up" and
6
- "Fixes" tiles, or a pipeline page's "Insights" tiles).
7
- - Each number deserves its own short line or tick row, not a shared chart.
5
+ - A page's whole answer is a small set of numbers (a review inbox's rating, replies due and a connection; a pipeline's
6
+ counts), not one card's single figure.
7
+ - Each number may carry a small mark (stars, a tall tick row), a chip, a short line, or a foot with its source or its act.
8
8
 
9
9
  **Not for**
10
10
 
11
- - One card's own single share with a strip: use `GoalTicks`.
11
+ - A key metric that opens into its chart across the row: use `MetricTile`.
12
+ - One card's own share with a strip: use `GoalTicks`; a report's score: use `ScoreHero`.
12
13
  - Comparing rows of the same kind of count: use `GoalBars`.
13
- - A page that already has one dominant chart card: tiles are for a page whose answer is numbers, not a chart's companion row.
14
14
 
15
15
  **Anatomy**
16
16
 
17
- - Each tile is a plain `Card`, `--ws-card-padding-lg` (16 px) inside, a `calc(--space-xxs * 0.75)` (3 px) stripe across its top in the tile's tone, pale to solid left to right (`.ws-stat-tiles__stripe--navy`, `--salmon`, `--purple`, `--teal`).
18
- - Label: 12 px semibold muted (`--ws-text-dense`), above the number.
19
- - Figure: 40 px (`--font-size-3xl`), regular weight, `--ws-tracking-display`, tabular numerals; a unit word after it in 12 px muted (`--ws-text-dense`, the system's 11 px floor rules out the kit's 10); a `ChangeChip` beside it when the number moved.
20
- - One line under the figure: either a short muted sentence (truncates) or a `TickRow` showing the number as a share of a whole; never both.
21
- - Four tiles across from the page's `lg` container width, two below it (`@area-lg/board:grid-cols-4`, `grid-cols-2` otherwise). In fello.css: `<ul class="ws-stat-tiles">` of `<li class="ws-card ws-stat-tiles__tile">`, four across once its `.ws-page` or `.ws-area` is 60rem wide, two below; outside either it stays two across.
22
-
23
- **Variants and sizes**
24
-
25
- | Variant | What changes |
26
- | --- | --- |
27
- | `tile.unit` | A word or two after the number ("of 100", "spots") |
28
- | `tile.change` | A chip beside the number: up teal, down mid blue, `null` for a run with no arrow |
29
- | `tile.ticks` | A short tick row under the number instead of a line |
30
- | `tile.line` | A short sentence under the number instead of ticks |
17
+ - The set measures itself (K3): `<div class="ws-stat-tiles">` is a size container holding
18
+ `<ul class="ws-stat-tiles__grid">`, tiles 8 apart (`--space-xs`).
19
+
20
+ | Column width | 1 to 2 tiles | 3 | 4 | 5 | 6 |
21
+ | --- | --- | --- | --- | --- | --- |
22
+ | under 40rem | 2 across | 2 + 1 | 2 + 2 | 2 + 2 + 1 | 2 + 2 + 2 |
23
+ | 40 to 60rem | 2 | 3 | 2 + 2 | 3 + 2 | 3 + 3 |
24
+ | from 60rem | 2 | 3 | 4 | 5 | 3 + 3 |
25
+
26
+ On two across an odd last tile takes the whole row, so there is never an orphan beside an empty cell.
27
+ - Tile (Seth's Review inbox): the tray rim, 1 px of `--ws-tray` through padding, 8 outside and 7 inside
28
+ (`--ws-radius-card-inner`); the cream surface 16 inside, 8 between its parts. No outline, no shadow, no stripe.
29
+ - Label: 13/18 medium, `--color-text-body`, one line.
30
+ - Figure: 32/38 regular (`--ws-text-figure`), -3%, navy, tabular. "Not connected" in the figure's place is
31
+ `__value--none`, the same size in `--color-text-muted`.
32
+ - On the figure's line, 12 after it and centred: stars (18 px salmon, 2 apart) or a `TickRow --tall` in a tone. A
33
+ `ChangeChip` or a unit word sits on the figure's baseline instead.
34
+ - Line (optional): 13/18 muted, wraps to two lines at most (K13), its `title` holds the rest.
35
+ - Foot (optional), on the tray itself: 8 above and below, 16 at the sides, 13/18 medium. Left words in
36
+ `--color-text-body`, right words in `--color-text-muted` (AA on the tray); in a narrow tile the right words drop to
37
+ their own line, and the lines pack at the top, so feet in a row share their first line. As an `<a>` it is the
38
+ tile's one act: navy words and a 16 px chevron. A link button in the surface instead ("See the 5 quoted deals" and a
39
+ chevron) takes `ws-btn--wrap`: two across on a 390 phone a tile is about 140 inside, and a one-line button runs past it.
40
+ - Tiles take two rows of the grid each (subgrid), so in a row every surface ends and every foot starts on one line.
41
+
42
+ **Parts and modifiers**
43
+
44
+ - `.ws-stat-tiles__change`: a change chip on the figure's baseline; one line, an ellipsis in a narrow tile (give it a title).
45
+ - `.ws-stat-tiles__unit`: a word or two after the figure on its baseline ("of 20"), 12 px muted.
46
+ - `.ws-stat-tiles__stars`: a rating out of five: 18 px salmon stars (`--ws-chart-under-half` (chart tone 3, so a palette that sets it moves it)), 2 apart.
47
+ - `.ws-stat-tiles__star--off`: an unlit star, in the track grey.
48
+ - `.ws-stat-tiles__line`: one line under the figure, 13/18 muted; it wraps to two lines, then an ellipsis with a title.
49
+ - `.ws-stat-tiles__ghost`: loading: a ghost the size of the label (with `ws-shimmer`); `--value` the size of the figure.
50
+ - `.ws-stat-tiles__ghost--value`: loading: a ghost the size of the figure.
31
51
 
32
52
  **States**
33
53
 
34
- - Default: tiles rise in order (`ws-rise`, staggered 40 ms each) when the page first shows.
35
- - No change: `change` omitted; the figure stands alone with its unit.
36
- - Narrow (two columns): the same tiles, same content, simply reflowed; nothing is cut beyond a long line's own ellipsis.
37
- - Disabled / error / hover / focus / pressed / selected / empty: do not apply; a tile is a read-only figure, not a control.
38
- - Reduced motion: tiles are simply in place, no rise.
54
+ - Default: tiles settle in on first paint (`ws-settle` with `--ws-i`, 22 ms apart).
55
+ - Foot act: hover washes the foot navy 5% (`--ws-hover`, 200 ms); focus draws the 2 px navy ring inside the foot; 40 px
56
+ tall on touch.
57
+ - Not connected: the figure's words in muted, the foot is the act that connects.
58
+ - Loading: ghosts the size of the label and the figure (`ws-shimmer`), `aria-busy="true"` on the list.
59
+ - Long line: two lines, then an ellipsis and its `title`. A long label truncates; give it the full words as a `title`.
60
+ - Narrow tile: a chip that has no room beside the figure drops under it; if it still has no room it ends in an ellipsis
61
+ (give it a `title`), never wrapping and never running past the tile.
62
+ - Reduced motion: tiles in place.
63
+ - Pressed, selected, disabled: do not apply; a tile is a figure, and only its foot acts.
39
64
 
40
65
  **Behaviour**
41
66
 
42
- - Each tile is one list item inside a labelled `<ul aria-label="…">`; the figure and its chip read as plain text to a screen reader (no separate `aria-label` beyond the visible words).
43
- - Motion: `ws-rise` on arrival, staggered by index; still with reduced motion.
44
- - No pointer or keyboard behaviour; a tile never links anywhere on its own.
67
+ - The list carries `aria-label` naming the set; each figure reads as plain text. Stars carry `role="img"` and an
68
+ `aria-label` ("5 of 5 stars"); a tick row is `aria-hidden`, its figure says the count.
45
69
 
46
70
  **Content**
47
71
 
48
- - Labels are short nouns in sentence case ("Pass rate", not "PASS RATE").
49
- - One line of meaning under the number: a short sentence or a tick row, never both, never a second number.
50
- - A unit is a word or two, never a full sentence ("of 100", "spots").
51
-
52
- **Props**
53
-
54
- | Name | Type | Meaning |
55
- | --- | --- | --- |
56
- | `label` | `string` | Names the whole set, for the `<ul>`'s `aria-label` |
57
- | `tiles` | `{ key, label, value, unit?, line?, tone, change?, ticks? }[]` | One tile a figure |
72
+ - Labels are short nouns in sentence case ("Need a reply").
73
+ - One line of meaning: a mark, a chip, a line or a foot; never a second number in the surface.
74
+ - A unit is a word or two ("of 20").
58
75
 
59
76
  **Rules**
60
77
 
61
- - Only pages whose answer is numbers get tiles (a dashboard's summary tiles, a pipeline page's Insights); a page already
62
- built around one chart card does not also get a tile row beside it.
63
- - The system's exact tones stay on the stripe; the figure itself is always navy, never tone-coloured.
64
- - A falling number's chip is mid blue, never red; "same" never gets an arrow.
78
+ - Only pages whose answer is numbers get tiles; a page built around one chart card does not also get a tile row.
79
+ - The figure is always navy; marks keep their exact tone; words on the tray use body or muted grey, which pass AA there.
80
+ - A falling number's chip is mid blue, never red.
65
81
 
66
82
  **Source**
67
83
 
68
- **Derived from**: the system's figure, chip and tick-row rules, arranged into a four-tile row (23 Oct 2026, an
69
- arrangement pattern rather than a single named chart card). **Precedent**: the first product built on the system.
84
+ **Derived from**: Seth's Review inbox tiles (313:2687, 313:2706, 313:2725); the container, the count rule and the
85
+ two-line wrap from Aryan's Revenue OS audit (K3, K13); the owner's ruling that a tile's line wraps (27 Oct).
86
+
87
+ **Markup**
88
+
89
+ ```html
90
+ <div class="ws-stat-tiles">
91
+ <ul class="ws-stat-tiles__grid" aria-label="Reviews at a glance">
92
+ <li class="ws-stat-tiles__tile">
93
+ <div class="ws-stat-tiles__surface">
94
+ <span class="ws-stat-tiles__label">Need a reply</span>
95
+ <span class="ws-stat-tiles__value-row">
96
+ <span class="ws-stat-tiles__value">10</span>
97
+ <span class="ws-tick-row ws-tick-row--tall" style="--tone: var(--ws-chart-alert);" aria-hidden="true">
98
+ <span class="ws-tick-row__tick"></span><!-- one a reply due -->
99
+ </span>
100
+ </span>
101
+ </div>
102
+ <div class="ws-stat-tiles__foot"><span>0 marked replied</span><span>Zillow</span></div>
103
+ </li>
104
+ </ul>
105
+ </div>
106
+ ```
107
+
108
+ 0.4 markup (`<ul class="ws-stat-tiles">` of `li.ws-card.ws-stat-tiles__tile` with a stripe) still lays out, by its own
109
+ width: as many tiles across as fit at 14rem each (four in a 60rem column, two in a 30rem side column, one on a phone),
110
+ each tile cream with its rim drawn inside and no stripe. It never reads a `.ws-page`, `.ws-area` or app shell around
111
+ it. Move to the container form above to get the count rules, two across on a phone, and the foot.
112
+
113
+ **Styles**: `StatTiles/style.css`, in `bundle.css` and `fello.css` as `.ws-stat-tiles`. Every value is a token.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Charts" height=198 -->
1
+ <!-- @dsCard group="Charts" height=1180 -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -8,80 +8,151 @@
8
8
  <link rel="stylesheet" href="../bundle.css">
9
9
  </head>
10
10
  <body>
11
- <div class="ws-stage">
11
+ <div class="ws-stage ws-stage--column">
12
12
 
13
- <div class="ws-stack ws-area" style="width: 100%;">
14
- <span class="ws-muted">Four across once the page or area is 60rem wide (its `lg` width); two below it, as here at 960 px</span>
15
- <ul class="ws-stat-tiles" aria-label="This month at a glance">
16
- <li class="ws-card ws-stat-tiles__tile ws-rise">
17
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--navy" aria-hidden="true"></span>
18
- <span class="ws-stat-tiles__label">Calls this month</span>
19
- <span class="ws-stat-tiles__value-row">
20
- <span class="ws-stat-tiles__value">142</span>
21
- <span class="ws-change ws-change--up ws-stat-tiles__change">
22
- <svg viewBox="0 0 16 16" width="12" height="12" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
23
- 18 since last week
24
- </span>
25
- </span>
26
- </li>
27
- <li class="ws-card ws-stat-tiles__tile ws-rise" style="animation-delay: 40ms;">
28
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--teal" aria-hidden="true"></span>
29
- <span class="ws-stat-tiles__label">Show rate</span>
30
- <span class="ws-stat-tiles__value-row">
31
- <span class="ws-stat-tiles__value">72%</span>
32
- </span>
33
- <span class="ws-stat-tiles__line" title="Above the 65% goal">Above the 65% goal</span>
34
- </li>
35
- <li class="ws-card ws-stat-tiles__tile ws-rise" style="animation-delay: 80ms;">
36
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--salmon" aria-hidden="true"></span>
37
- <span class="ws-stat-tiles__label">Leads sourced</span>
38
- <span class="ws-stat-tiles__value-row">
39
- <span class="ws-stat-tiles__value">14</span>
40
- </span>
41
- <span class="ws-tick-row ws-stat-tiles__ticks" aria-hidden="true">
42
- <span class="ws-tick-row__tick" style="background: var(--ws-chart-under-half);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-under-half);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-under-half);"></span>
43
- <span class="ws-tick-row__tick" style="background: var(--ws-chart-past-half);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-past-half);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-past-half);"></span>
44
- <span class="ws-tick-row__tick" style="background: var(--ws-chart-finished);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-finished);"></span><span class="ws-tick-row__tick" style="background: var(--ws-chart-finished);"></span>
45
- <span class="ws-tick-row__tick ws-tick-row__tick--empty"></span><span class="ws-tick-row__tick ws-tick-row__tick--empty"></span><span class="ws-tick-row__tick ws-tick-row__tick--empty"></span><span class="ws-tick-row__tick ws-tick-row__tick--empty"></span><span class="ws-tick-row__tick ws-tick-row__tick--empty"></span>
46
- </span>
47
- </li>
48
- <li class="ws-card ws-stat-tiles__tile ws-rise" style="animation-delay: 120ms;">
49
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--purple" aria-hidden="true"></span>
50
- <span class="ws-stat-tiles__label">Response rate</span>
51
- <span class="ws-stat-tiles__value-row">
52
- <span class="ws-stat-tiles__value">38%</span>
53
- <span class="ws-change ws-change--down ws-stat-tiles__change">
54
- <svg viewBox="0 0 16 16" width="12" height="12" fill="none" aria-hidden="true"><path d="M5 5L11 11M11 11H6M11 11V6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
55
- 4% since Monday
56
- </span>
57
- </span>
58
- </li>
59
- </ul>
13
+ <div class="ws-stack" style="max-width: 1350px;">
14
+ <span class="ws-muted">Seth's Review inbox: three tiles, a mark on the figure's line, a foot on the tray (one of them the tile's act)</span>
15
+ <div class="ws-stat-tiles">
16
+ <ul class="ws-stat-tiles__grid" aria-label="Reviews at a glance">
17
+ <li class="ws-stat-tiles__tile ws-settle" style="--ws-i: 0;">
18
+ <div class="ws-stat-tiles__surface">
19
+ <span class="ws-stat-tiles__label">Zillow rating</span>
20
+ <span class="ws-stat-tiles__value-row">
21
+ <span class="ws-stat-tiles__value">5.0</span>
22
+ <span class="ws-stat-tiles__stars" role="img" aria-label="5 of 5 stars"><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg></span>
23
+ </span>
24
+ </div>
25
+ <div class="ws-stat-tiles__foot"><span>10 reviews</span><span>Checked Nov 2</span></div>
26
+ </li>
27
+ <li class="ws-stat-tiles__tile ws-settle" style="--ws-i: 1;">
28
+ <div class="ws-stat-tiles__surface">
29
+ <span class="ws-stat-tiles__label">Need a reply</span>
30
+ <span class="ws-stat-tiles__value-row">
31
+ <span class="ws-stat-tiles__value">10</span>
32
+ <span class="ws-tick-row ws-tick-row--tall" style="--tone: var(--ws-chart-alert);" aria-hidden="true"><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span></span>
33
+ </span>
34
+ </div>
35
+ <div class="ws-stat-tiles__foot"><span>0 marked replied</span><span>Zillow</span></div>
36
+ </li>
37
+ <li class="ws-stat-tiles__tile ws-settle" style="--ws-i: 2;">
38
+ <div class="ws-stat-tiles__surface">
39
+ <span class="ws-stat-tiles__label">Google reviews</span>
40
+ <span class="ws-stat-tiles__value-row">
41
+ <span class="ws-stat-tiles__value ws-stat-tiles__value--none">Not connected</span>
42
+ </span>
43
+ </div>
44
+ <a class="ws-stat-tiles__foot" href="#connect"><span>Connect Google</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8L6.6 10.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
45
+ </li>
46
+ </ul>
47
+ </div>
48
+ </div>
49
+
50
+ <div class="ws-stack" style="max-width: 1200px;">
51
+ <span class="ws-muted">Four across from 60rem: a chip on the figure's baseline, a unit, a line that wraps to two lines</span>
52
+ <div class="ws-stat-tiles">
53
+ <ul class="ws-stat-tiles__grid" aria-label="This month at a glance">
54
+ <li class="ws-stat-tiles__tile">
55
+ <div class="ws-stat-tiles__surface">
56
+ <span class="ws-stat-tiles__label">Calls this month</span>
57
+ <span class="ws-stat-tiles__value-row">
58
+ <span class="ws-stat-tiles__value">142</span>
59
+ <span class="ws-change ws-change--up ws-stat-tiles__change" title="18 since last week"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>18 since last week</span>
60
+ </span>
61
+ </div>
62
+ </li>
63
+ <li class="ws-stat-tiles__tile">
64
+ <div class="ws-stat-tiles__surface">
65
+ <span class="ws-stat-tiles__label">Show rate</span>
66
+ <span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">72%</span></span>
67
+ <span class="ws-stat-tiles__line" title="Above the 65% goal, median from your list to the first booked showing">Above the 65% goal, median from your list to the first booked showing</span>
68
+ </div>
69
+ </li>
70
+ <li class="ws-stat-tiles__tile">
71
+ <div class="ws-stat-tiles__surface">
72
+ <span class="ws-stat-tiles__label">Leads sourced</span>
73
+ <span class="ws-stat-tiles__value-row">
74
+ <span class="ws-stat-tiles__value">14</span>
75
+ <span class="ws-stat-tiles__unit">of 20</span>
76
+ </span>
77
+ </div>
78
+ </li>
79
+ <li class="ws-stat-tiles__tile">
80
+ <div class="ws-stat-tiles__surface">
81
+ <span class="ws-stat-tiles__label">Response rate</span>
82
+ <span class="ws-stat-tiles__value-row">
83
+ <span class="ws-stat-tiles__value">38%</span>
84
+ <span class="ws-change ws-change--down ws-stat-tiles__change" title="4% since Monday"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" aria-hidden="true"><path d="M5 5L11 11M11 11H6M11 11V6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>4% since Monday</span>
85
+ </span>
86
+ </div>
87
+ </li>
88
+ </ul>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="ws-stack" style="max-width: 1200px;">
93
+ <span class="ws-muted">Five tiles: five across from 60rem, three then two below it, never four and an orphan</span>
94
+ <div class="ws-stat-tiles">
95
+ <ul class="ws-stat-tiles__grid" aria-label="Pipeline">
96
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">New leads</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">48</span></span></div></li>
97
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Booked</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">19</span></span></div></li>
98
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Shown</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">12</span></span></div></li>
99
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Under contract</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">4</span></span></div></li>
100
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Closed this month</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">2</span></span></div></li>
101
+ </ul>
102
+ </div>
103
+ </div>
104
+
105
+ <div class="ws-stack" style="max-width: 1200px;">
106
+ <span class="ws-muted">Six tiles: three and three</span>
107
+ <div class="ws-stat-tiles">
108
+ <ul class="ws-stat-tiles__grid" aria-label="Today">
109
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Calls</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">31</span></span></div></li>
110
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Texts</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">64</span></span></div></li>
111
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Emails</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">22</span></span></div></li>
112
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Booked</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">5</span></span></div></li>
113
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Follow-ups due</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">9</span></span></div></li>
114
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-stat-tiles__label">Missed</span><span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">0</span></span></div></li>
115
+ </ul>
116
+ </div>
117
+ </div>
118
+
119
+ <div class="ws-stack" style="width: 360px; max-width: 100%;">
120
+ <span class="ws-muted">A 360 px column: two across, the odd last tile takes the row</span>
121
+ <div class="ws-stat-tiles">
122
+ <ul class="ws-stat-tiles__grid" aria-label="Reviews at a glance">
123
+ <li class="ws-stat-tiles__tile">
124
+ <div class="ws-stat-tiles__surface">
125
+ <span class="ws-stat-tiles__label">Zillow rating</span>
126
+ <span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">4.6</span><span class="ws-stat-tiles__stars" role="img" aria-label="4 of 5 stars"><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg><svg viewBox="0 0 18 18" class="ws-stat-tiles__star--off" aria-hidden="true"><path d="M9 1.5l2.3 4.7 5.2.8-3.8 3.6.9 5.1L9 13.3l-4.6 2.4.9-5.1L1.5 7l5.2-.8z" fill="currentColor"/></svg></span></span>
127
+ </div>
128
+ <div class="ws-stat-tiles__foot"><span>10 reviews</span><span>Nov 2</span></div>
129
+ </li>
130
+ <li class="ws-stat-tiles__tile">
131
+ <div class="ws-stat-tiles__surface">
132
+ <span class="ws-stat-tiles__label">Need a reply</span>
133
+ <span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value">10</span><span class="ws-tick-row ws-tick-row--tall" style="--tone: var(--ws-chart-alert);" aria-hidden="true"><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span><span class="ws-tick-row__tick"></span></span></span>
134
+ </div>
135
+ <div class="ws-stat-tiles__foot"><span>0 marked replied</span><span>Zillow</span></div>
136
+ </li>
137
+ <li class="ws-stat-tiles__tile">
138
+ <div class="ws-stat-tiles__surface">
139
+ <span class="ws-stat-tiles__label">Google reviews</span>
140
+ <span class="ws-stat-tiles__value-row"><span class="ws-stat-tiles__value ws-stat-tiles__value--none">Not connected</span></span>
141
+ </div>
142
+ <a class="ws-stat-tiles__foot" href="#connect"><span>Connect Google</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8L6.6 10.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
143
+ </li>
144
+ </ul>
145
+ </div>
60
146
  </div>
61
147
 
62
148
  <div class="ws-stack" style="width: 360px; max-width: 100%;">
63
- <span class="ws-muted">Two below `lg`: the same tiles wrap to a 2-column grid</span>
64
- <ul class="ws-stat-tiles" aria-label="This month at a glance">
65
- <li class="ws-card ws-stat-tiles__tile ws-rise">
66
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--navy" aria-hidden="true"></span>
67
- <span class="ws-stat-tiles__label">Calls this month</span>
68
- <span class="ws-stat-tiles__value-row">
69
- <span class="ws-stat-tiles__value">142</span>
70
- <span class="ws-change ws-change--up ws-stat-tiles__change">
71
- <svg viewBox="0 0 16 16" width="12" height="12" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
72
- 18<span class="ws-sr"> since last week</span>
73
- </span>
74
- </span>
75
- </li>
76
- <li class="ws-card ws-stat-tiles__tile ws-rise" style="animation-delay: 40ms;">
77
- <span class="ws-stat-tiles__stripe ws-stat-tiles__stripe--teal" aria-hidden="true"></span>
78
- <span class="ws-stat-tiles__label">Show rate</span>
79
- <span class="ws-stat-tiles__value-row">
80
- <span class="ws-stat-tiles__value">72%</span>
81
- </span>
82
- <span class="ws-stat-tiles__line" title="Above the 65% goal">Above the 65% goal</span>
83
- </li>
84
- </ul>
149
+ <span class="ws-muted">Loading: ghosts the size of the label and the figure</span>
150
+ <div class="ws-stat-tiles">
151
+ <ul class="ws-stat-tiles__grid" aria-label="This month at a glance" aria-busy="true">
152
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-shimmer ws-stat-tiles__ghost" aria-hidden="true"></span><span class="ws-shimmer ws-stat-tiles__ghost ws-stat-tiles__ghost--value" aria-hidden="true"></span></div></li>
153
+ <li class="ws-stat-tiles__tile"><div class="ws-stat-tiles__surface"><span class="ws-shimmer ws-stat-tiles__ghost" aria-hidden="true"></span><span class="ws-shimmer ws-stat-tiles__ghost ws-stat-tiles__ghost--value" aria-hidden="true"></span></div></li>
154
+ </ul>
155
+ </div>
85
156
  </div>
86
157
 
87
158
  </div>
@@ -0,0 +1,64 @@
1
+ /* ---- StatTiles: a page's few numbers as rimmed tiles that measure their own width ---- */
2
+ /* K3: the set is its own container (<div class="ws-stat-tiles"> holding <ul class="ws-stat-tiles__grid">), so it lays
3
+ out by the column it sits in, never by a .ws-page or .ws-area it may not have. Two across; from 40rem three when
4
+ there are 3, 5 or 6 tiles; from 60rem four, or five for 5. An odd last tile on two across takes the whole row. */
5
+ .ws-stat-tiles:not(ul) { container-type: inline-size; }
6
+ .ws-stat-tiles__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xs); }
7
+ /* 0.4 markup (ul.ws-stat-tiles, no wrapper to measure): a grid that measures itself, a tile at least 14rem, as many
8
+ across as fit its own column. A container query on the ul would read whatever ancestor is a container (an app
9
+ shell's body), not the column the tiles sit in (Revenue OS K3). */
10
+ ul.ws-stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--space-xs); }
11
+ .ws-stat-tiles__grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
12
+ @container (min-width: 40rem) {
13
+ .ws-stat-tiles__grid > :last-child:nth-child(odd):not(:only-child) { grid-column: auto; }
14
+ .ws-stat-tiles__grid:has(> :nth-child(3):last-child, > :nth-child(5):last-child, > :nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
15
+ }
16
+ @container (min-width: 60rem) {
17
+ .ws-stat-tiles__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
18
+ .ws-stat-tiles__grid:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
19
+ .ws-stat-tiles__grid:has(> :nth-child(3):last-child, > :nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
20
+ .ws-stat-tiles__grid:has(> :nth-child(5):last-child) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
21
+ }
22
+ /* A tile (Seth's Review inbox): the tray rim (1 px of #EDEDED through padding, 8 outside, 7 inside), the cream surface,
23
+ and an optional foot that sits on the tray itself. No outline, no shadow, no stripe. Each tile takes two rows of the
24
+ set's grid (subgrid), so in a row every surface ends and every foot starts on one line. */
25
+ .ws-stat-tiles__tile { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; min-width: 0; border-radius: var(--ws-radius-card); background: var(--ws-tray); padding: var(--ws-rim); }
26
+ .ws-stat-tiles__tile:not(:has(> .ws-stat-tiles__foot)) > .ws-stat-tiles__surface { grid-row: span 2; }
27
+ .ws-stat-tiles__surface { display: flex; min-width: 0; flex-direction: column; gap: var(--space-xs); padding: var(--space-md); border-radius: var(--ws-radius-card-inner); background: var(--color-bg-page); }
28
+ /* 0.4 markup (the tile is the surface, no __surface inside): cream, the rim drawn inside. */
29
+ .ws-stat-tiles__tile:not(:has(> .ws-stat-tiles__surface)) { display: flex; grid-row: auto; flex-direction: column; gap: var(--space-xs); padding: var(--space-md); background: var(--color-bg-page); box-shadow: inset 0 0 0 var(--ws-rim) var(--ws-tray); }
30
+ .ws-stat-tiles__label { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--ws-text-control); font-weight: 500; line-height: var(--ws-leading-control); color: var(--color-text-body); }
31
+ /* The figure and its mark (stars, a tall TickRow) 12 apart and centred; a chip or a unit on the figure's baseline. */
32
+ .ws-stat-tiles__value-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xxs) var(--space-sm); min-width: 0; }
33
+ .ws-stat-tiles__value { flex-shrink: 0; font-size: var(--ws-text-figure); font-weight: 400; line-height: var(--ws-leading-figure); letter-spacing: var(--ws-tracking-display); color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
34
+ .ws-stat-tiles__value--none { flex-shrink: 1; min-width: 0; color: var(--color-text-muted); }
35
+ .ws-stat-tiles__value-row:has(> .ws-stat-tiles__change, > .ws-stat-tiles__unit) > .ws-stat-tiles__value, .ws-stat-tiles__change, .ws-stat-tiles__unit { align-self: last baseline; }
36
+ /* A chip never runs past its tile and never wraps: in a narrow tile it ends in an ellipsis (give it a title). As a block
37
+ of one line, not a flex box, so the ellipsis works on the existing markup; the icon sits 4 before the words. */
38
+ .ws-stat-tiles__change { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
39
+ .ws-stat-tiles__change > svg { display: inline-block; margin-right: var(--space-xxs); vertical-align: calc((var(--space-md) - var(--ws-icon-sm)) / -2); }
40
+ .ws-stat-tiles__unit { font-size: var(--ws-text-dense); line-height: var(--space-md); color: var(--color-text-muted); }
41
+ .ws-stat-tiles__value-row .ws-tick-row { flex: 1 1 0; }
42
+ /* Stars (a rating out of five): 18 px salmon marks, 2 apart. */
43
+ .ws-stat-tiles__stars { display: flex; gap: var(--space-3xs); color: var(--ws-chart-under-half); }
44
+ .ws-stat-tiles__stars > svg { flex-shrink: 0; width: calc(var(--space-md) + var(--space-3xs)); height: calc(var(--space-md) + var(--space-3xs)); }
45
+ .ws-stat-tiles__stars > svg.ws-stat-tiles__star--off { color: var(--ws-track); }
46
+ /* One line under the figure: it wraps to two lines at most (K13), its title holds the rest. */
47
+ .ws-stat-tiles__line { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; font-size: var(--ws-text-control); line-height: var(--ws-leading-control); color: var(--color-text-muted); text-wrap: pretty; }
48
+ /* The foot on the tray: 8 above and below, 16 at the sides (the surface's edge), 13/18 medium; the left words first,
49
+ the right ones at the end, and in a narrow tile the right ones drop to their own line. Its lines pack at the top, so
50
+ a one-line foot beside a two-line one shares its first line. As a link it is the tile's one act, with a 16 px
51
+ chevron. */
52
+ .ws-stat-tiles__foot { display: flex; flex-wrap: wrap; align-content: flex-start; align-items: center; gap: 0 var(--space-xs); min-height: calc(var(--space-xl) + var(--space-3xs)); padding: var(--space-xs) var(--space-md); border-radius: 0 0 var(--ws-radius-card-inner) var(--ws-radius-card-inner); font-size: var(--ws-text-control); font-weight: 500; line-height: var(--ws-leading-control); color: var(--color-text-body); text-decoration: none; }
53
+ .ws-stat-tiles__foot > :first-child { flex: 1 1 auto; min-width: 0; }
54
+ .ws-stat-tiles__foot > span:last-child:not(:first-child) { flex-shrink: 0; margin-left: auto; white-space: nowrap; color: var(--color-text-muted); }
55
+ a.ws-stat-tiles__foot { flex-wrap: nowrap; }
56
+ a.ws-stat-tiles__foot { color: var(--color-text-heading); cursor: pointer; }
57
+ @media (prefers-reduced-motion: no-preference) { a.ws-stat-tiles__foot { transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); } }
58
+ a.ws-stat-tiles__foot > svg { flex-shrink: 0; width: var(--ws-icon); height: var(--ws-icon); color: var(--color-text-heading); }
59
+ a.ws-stat-tiles__foot:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
60
+ @media (hover: hover) { a.ws-stat-tiles__foot:hover { background: var(--ws-hover); } }
61
+ @media (pointer: coarse) { a.ws-stat-tiles__foot { min-height: var(--ws-touch); } }
62
+ /* Loading: ghosts the size of the label and the figure. */
63
+ .ws-stat-tiles__ghost { width: var(--space-6xl); height: var(--ws-leading-control); }
64
+ .ws-stat-tiles__ghost--value { width: var(--space-7xl); height: var(--ws-leading-figure); }
@@ -0,0 +1,85 @@
1
+ The working line at the top of an answer in progress: who is working, what it is doing in a moving shimmer, and the
2
+ step it is on, so a wait never looks like a stall.
3
+
4
+ ## Use it when
5
+
6
+ - An agent is building an answer, a chart or a card and the person waits for it.
7
+ - The work has steps a person would recognise ("Reading your calls", "Checking Google", "12 of 40").
8
+ - A card is still coming (`ChatCard` loading): the line sits on top of its ghost.
9
+
10
+ ## Not for
11
+
12
+ - A person typing in a handoff: use the typing dots (`ChatTurn`).
13
+ - A wait with a known share of the work done: add a `LoadBar` (it holds the real share).
14
+ - A page still loading: use `Skeleton`.
15
+ - An error: say what went wrong in the answer's own words, not on the working line.
16
+
17
+ ## Anatomy
18
+
19
+ - One line, 24 px tall at least, 13 / 18 (`--ws-text-control`), its parts 8 px apart on the baseline, never wrapping.
20
+ - Who (`ws-status-line__who`): the agent's name, semibold navy.
21
+ - Doing (`ws-status-line__doing`): what it is doing, medium. A shimmer passes over these words every 1.6 s
22
+ (`--ws-loop-status`, steady), from navy through the AA steps of salmon, purple and teal (`--ws-word-needs`,
23
+ `--ws-word-past-half`, `--ws-word-positive`), so no letter ever drops under AA as the band passes.
24
+ - Step (`ws-status-line__step`): where it is, in `--color-text-muted`, tabular figures.
25
+ - A long line cuts the step first, then the doing, each with an ellipsis; the line's `title` holds the whole of it.
26
+
27
+ ## Variants and sizes
28
+
29
+ | Variant | Parts |
30
+ | --- | --- |
31
+ | With a step | Who, doing, step |
32
+ | Without a step | Who, doing |
33
+
34
+ One size: it sits on the answer's own edge, at the top of the agent turn or the card.
35
+
36
+ ## States
37
+
38
+ - **Working**: the shimmer runs; the doing words and the step change as the work moves (each step at least 0.55 s on
39
+ screen, so it can be read).
40
+ - **Done**: the line goes; the answer takes its place.
41
+ - **Long words**: cut with an ellipsis, the step first; the title holds it all.
42
+ - **Reduced motion**: the words stay navy and still; the line still says what is happening.
43
+ - **Dark**: the words and the shimmer's steps are theme tokens.
44
+
45
+ ## Behaviour
46
+
47
+ - Keyboard and pointer: nothing to interact with.
48
+ - Screen reader: the line is `role="status"`, so each change is said once, politely.
49
+ - Motion: the line settles in (`ws-settle`, 6 px out of a 3 px blur); the shimmer is a background clipped to the
50
+ words, so the real text never changes.
51
+
52
+ ## Content
53
+
54
+ - The doing words are a short present participle phrase in sentence case ("Reading your calls"), never a technical
55
+ status ("Fetching").
56
+ - The step is a count or a name ("12 of 40", "Follow Up Boss"), never a percentage guess.
57
+ - No em dashes.
58
+
59
+ ## Rules
60
+
61
+ - A working answer says what it is doing; it never shows a spinner alone.
62
+ - Words on the line stay AA at every frame of the shimmer.
63
+ - One working line per answer.
64
+
65
+ ## Source
66
+
67
+ **Derived from**: North's status line (style1.css:1471-1475: "North" 600 navy, the verb shimmering navy, coral,
68
+ purple, teal over 1.6 s, the step in #8A8A8A; js@615941, each step 0.55 s). The step's grey and the shimmer's tones
69
+ take their AA steps (D2).
70
+
71
+ ## Markup
72
+
73
+ ```html
74
+ <p class="ws-status-line" role="status" title="Coach: reading your calls, 12 of 40">
75
+ <b class="ws-status-line__who">Coach</b>
76
+ <span class="ws-status-line__doing">Reading your calls</span>
77
+ <span class="ws-status-line__step">12 of 40</span>
78
+ </p>
79
+ ```
80
+
81
+ ## Styles
82
+
83
+ `StatusLine/style.css`; the keyframes are the house's `ws-shimmer` and `ws-settle`. Tokens: `--ws-text-control`,
84
+ `--ws-leading-control`, `--ws-loop-status`, `--ws-ease-steady`, `--ws-word-needs`, `--ws-word-past-half`,
85
+ `--ws-word-positive`, `--color-text-heading`, `--color-text-muted`.