@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.
- package/AGENTS.md +198 -24
- package/CHANGELOG.md +197 -0
- package/README.md +34 -7
- package/design-system/01-how-claude-decides.md +26 -17
- package/design-system/02-principles.md +11 -6
- package/design-system/03-colour.md +134 -47
- package/design-system/04-type.md +45 -23
- package/design-system/05-space-and-layout.md +175 -52
- package/design-system/06-sizing-profiles.md +4 -4
- package/design-system/07-scrolling.md +66 -20
- package/design-system/08-choosing-components.md +50 -22
- package/design-system/09-charts.md +71 -28
- package/design-system/10-patterns.md +33 -10
- package/design-system/11-page-recipes.md +110 -23
- package/design-system/12-content.md +2 -1
- package/design-system/13-motion.md +330 -47
- package/design-system/14-accessibility.md +47 -24
- package/design-system/15-ai-experiences.md +11 -6
- package/design-system/16-creativity.md +1 -1
- package/design-system/17-decisions.md +357 -1
- package/design-system/18-checklist.md +79 -16
- package/design-system/19-public-pages.md +6 -4
- package/design-system/20-palettes.md +275 -0
- package/design-system/README.md +30 -17
- package/design-system/components/ActionList/README.md +96 -10
- package/design-system/components/ActionList/preview.html +52 -7
- package/design-system/components/ActionList/style.css +64 -0
- package/design-system/components/ActivityGrid/README.md +38 -2
- package/design-system/components/ActivityGrid/preview.html +1 -1
- package/design-system/components/ActivityGrid/style.css +35 -0
- package/design-system/components/AppShell/README.md +205 -75
- package/design-system/components/AppShell/preview.html +339 -58
- package/design-system/components/AppShell/style.css +154 -0
- package/design-system/components/Avatar/README.md +37 -10
- package/design-system/components/Avatar/preview.html +13 -4
- package/design-system/components/Avatar/style.css +14 -0
- package/design-system/components/Badge/README.md +41 -19
- package/design-system/components/Badge/preview.html +13 -10
- package/design-system/components/Badge/style.css +23 -0
- package/design-system/components/Banner/README.md +30 -9
- package/design-system/components/Banner/preview.html +1 -1
- package/design-system/components/Banner/style.css +19 -0
- package/design-system/components/Breadcrumb/README.md +58 -46
- package/design-system/components/Breadcrumb/preview.html +16 -16
- package/design-system/components/Breadcrumb/style.css +17 -0
- package/design-system/components/Button/README.md +113 -55
- package/design-system/components/Button/preview.html +98 -25
- package/design-system/components/Button/style.css +86 -0
- package/design-system/components/Card/README.md +158 -49
- package/design-system/components/Card/preview.html +141 -19
- package/design-system/components/Card/style.css +115 -0
- package/design-system/components/CardBoard/README.md +58 -37
- package/design-system/components/CardBoard/preview.html +26 -29
- package/design-system/components/ChatCard/README.md +115 -29
- package/design-system/components/ChatCard/preview.html +149 -32
- package/design-system/components/ChatCard/style.css +49 -0
- package/design-system/components/ChatShell/README.md +116 -0
- package/design-system/components/ChatShell/preview.html +201 -0
- package/design-system/components/ChatShell/style.css +86 -0
- package/design-system/components/ChatTurn/README.md +78 -35
- package/design-system/components/ChatTurn/preview.html +60 -28
- package/design-system/components/ChatTurn/style.css +50 -0
- package/design-system/components/CheckRow/README.md +141 -0
- package/design-system/components/CheckRow/preview.html +140 -0
- package/design-system/components/CheckRow/style.css +88 -0
- package/design-system/components/Checkbox/README.md +58 -22
- package/design-system/components/Checkbox/preview.html +112 -50
- package/design-system/components/Checkbox/style.css +45 -0
- package/design-system/components/Chip/README.md +78 -47
- package/design-system/components/Chip/preview.html +29 -4
- package/design-system/components/Chip/style.css +17 -0
- package/design-system/components/Combobox/README.md +44 -11
- package/design-system/components/Combobox/preview.html +35 -12
- package/design-system/components/Combobox/style.css +54 -0
- package/design-system/components/Composer/README.md +137 -35
- package/design-system/components/Composer/preview.html +115 -40
- package/design-system/components/Composer/style.css +81 -0
- package/design-system/components/ConfirmDialog/README.md +73 -52
- package/design-system/components/ConfirmDialog/preview.html +70 -26
- package/design-system/components/ConfirmDialog/style.css +5 -0
- package/design-system/components/Cover/preview.html +3 -3
- package/design-system/components/Cover/style.css +19 -0
- package/design-system/components/DateInput/README.md +77 -12
- package/design-system/components/DateInput/preview.html +27 -12
- package/design-system/components/DateInput/style.css +38 -0
- package/design-system/components/Dialog/README.md +112 -44
- package/design-system/components/Dialog/preview.html +141 -18
- package/design-system/components/Dialog/style.css +74 -0
- package/design-system/components/EmptyState/README.md +42 -12
- package/design-system/components/EmptyState/preview.html +11 -11
- package/design-system/components/EmptyState/style.css +9 -0
- package/design-system/components/EntryShell/README.md +73 -48
- package/design-system/components/EntryShell/preview.html +60 -27
- package/design-system/components/EntryShell/style.css +19 -0
- package/design-system/components/FeatureGrid/README.md +61 -39
- package/design-system/components/FeatureGrid/preview.html +2 -2
- package/design-system/components/FeatureGrid/style.css +20 -0
- package/design-system/components/FileUpload/README.md +33 -3
- package/design-system/components/FileUpload/preview.html +18 -4
- package/design-system/components/FileUpload/style.css +23 -0
- package/design-system/components/FilterBar/README.md +114 -0
- package/design-system/components/FilterBar/preview.html +82 -0
- package/design-system/components/FilterBar/style.css +22 -0
- package/design-system/components/Fold/README.md +84 -26
- package/design-system/components/Fold/preview.html +77 -34
- package/design-system/components/Fold/style.css +48 -0
- package/design-system/components/Footer/README.md +62 -39
- package/design-system/components/Footer/preview.html +5 -5
- package/design-system/components/Footer/style.css +30 -0
- package/design-system/components/FunnelBars/README.md +24 -3
- package/design-system/components/FunnelBars/preview.html +5 -5
- package/design-system/components/FunnelBars/style.css +13 -0
- package/design-system/components/GoalBars/README.md +54 -10
- package/design-system/components/GoalBars/preview.html +69 -28
- package/design-system/components/GoalBars/style.css +51 -0
- package/design-system/components/GoalTicks/README.md +74 -58
- package/design-system/components/GoalTicks/preview.html +41 -118
- package/design-system/components/GoalTicks/style.css +37 -0
- package/design-system/components/GoalTubes/README.md +29 -3
- package/design-system/components/GoalTubes/preview.html +6 -6
- package/design-system/components/GoalTubes/style.css +23 -0
- package/design-system/components/Heatmap/README.md +133 -0
- package/design-system/components/Heatmap/preview.html +168 -0
- package/design-system/components/Heatmap/style.css +119 -0
- package/design-system/components/Hero/README.md +58 -40
- package/design-system/components/Hero/preview.html +1 -1
- package/design-system/components/Hero/style.css +19 -0
- package/design-system/components/HoverCard/README.md +114 -0
- package/design-system/components/HoverCard/preview.html +107 -0
- package/design-system/components/HoverCard/style.css +59 -0
- package/design-system/components/IconButton/README.md +69 -38
- package/design-system/components/IconButton/preview.html +77 -43
- package/design-system/components/IconButton/style.css +45 -0
- package/design-system/components/Input/README.md +36 -11
- package/design-system/components/Input/preview.html +1 -1
- package/design-system/components/Input/style.css +23 -0
- package/design-system/components/KanbanBoard/README.md +93 -45
- package/design-system/components/KanbanBoard/preview.html +159 -43
- package/design-system/components/KanbanBoard/style.css +53 -0
- package/design-system/components/Kbd/README.md +25 -9
- package/design-system/components/Kbd/preview.html +6 -2
- package/design-system/components/Kbd/style.css +9 -0
- package/design-system/components/KitButton/README.md +81 -47
- package/design-system/components/KitButton/preview.html +35 -13
- package/design-system/components/KitButton/style.css +46 -0
- package/design-system/components/KitCard/README.md +75 -44
- package/design-system/components/KitCard/preview.html +18 -10
- package/design-system/components/KitCard/style.css +15 -0
- package/design-system/components/KitInput/README.md +54 -39
- package/design-system/components/KitInput/preview.html +7 -7
- package/design-system/components/KitInput/style.css +23 -0
- package/design-system/components/Leaderboard/README.md +76 -49
- package/design-system/components/Leaderboard/preview.html +61 -26
- package/design-system/components/Leaderboard/style.css +44 -0
- package/design-system/components/ListDetail/README.md +222 -0
- package/design-system/components/ListDetail/preview.html +213 -0
- package/design-system/components/ListDetail/style.css +148 -0
- package/design-system/components/LoadBar/README.md +79 -0
- package/design-system/components/LoadBar/preview.html +40 -0
- package/design-system/components/LoadBar/style.css +17 -0
- package/design-system/components/MarketingNav/README.md +76 -42
- package/design-system/components/MarketingNav/preview.html +37 -8
- package/design-system/components/MarketingNav/style.css +45 -0
- package/design-system/components/Matrix/README.md +129 -0
- package/design-system/components/Matrix/preview.html +99 -0
- package/design-system/components/Matrix/style.css +84 -0
- package/design-system/components/Menu/README.md +117 -41
- package/design-system/components/Menu/preview.html +85 -23
- package/design-system/components/Menu/style.css +61 -0
- package/design-system/components/Meter/README.md +39 -4
- package/design-system/components/Meter/preview.html +18 -1
- package/design-system/components/Meter/style.css +23 -0
- package/design-system/components/MetricTile/README.md +237 -0
- package/design-system/components/MetricTile/preview.html +241 -0
- package/design-system/components/MetricTile/style.css +129 -0
- package/design-system/components/Morph/README.md +106 -0
- package/design-system/components/Morph/preview.html +103 -0
- package/design-system/components/Morph/style.css +31 -0
- package/design-system/components/Motion/README.md +164 -0
- package/design-system/components/Motion/preview.html +2537 -0
- package/design-system/components/NumberInput/README.md +27 -8
- package/design-system/components/NumberInput/preview.html +21 -5
- package/design-system/components/NumberInput/style.css +34 -0
- package/design-system/components/PaceBar/README.md +75 -0
- package/design-system/components/PaceBar/preview.html +67 -0
- package/design-system/components/PaceBar/style.css +25 -0
- package/design-system/components/Page/README.md +57 -18
- package/design-system/components/Page/preview.html +15 -17
- package/design-system/components/Page/style.css +7 -0
- package/design-system/components/PageBar/README.md +90 -34
- package/design-system/components/PageBar/preview.html +60 -19
- package/design-system/components/PageBar/style.css +35 -0
- package/design-system/components/PageHero/README.md +87 -51
- package/design-system/components/PageHero/preview.html +35 -6
- package/design-system/components/PageHero/style.css +31 -0
- package/design-system/components/Pagination/README.md +70 -49
- package/design-system/components/Pagination/preview.html +24 -15
- package/design-system/components/Pagination/style.css +12 -0
- package/design-system/components/Panel/README.md +109 -51
- package/design-system/components/Panel/preview.html +118 -20
- package/design-system/components/Panel/style.css +51 -0
- package/design-system/components/PasswordInput/README.md +50 -18
- package/design-system/components/PasswordInput/preview.html +71 -21
- package/design-system/components/PasswordInput/style.css +31 -0
- package/design-system/components/Plate/README.md +75 -17
- package/design-system/components/Plate/preview.html +40 -7
- package/design-system/components/Plate/style.css +37 -0
- package/design-system/components/Popover/README.md +70 -49
- package/design-system/components/Popover/preview.html +44 -22
- package/design-system/components/Popover/style.css +41 -0
- package/design-system/components/PricingTable/README.md +69 -49
- package/design-system/components/PricingTable/preview.html +21 -21
- package/design-system/components/PricingTable/style.css +21 -0
- package/design-system/components/ProgressPetals/README.md +31 -3
- package/design-system/components/ProgressPetals/preview.html +14 -15
- package/design-system/components/ProgressPetals/style.css +27 -0
- package/design-system/components/README.md +151 -0
- package/design-system/components/Radio/README.md +40 -17
- package/design-system/components/Radio/preview.html +16 -1
- package/design-system/components/Radio/style.css +21 -0
- package/design-system/components/RankBar/README.md +29 -2
- package/design-system/components/RankBar/preview.html +14 -12
- package/design-system/components/RankBar/style.css +18 -0
- package/design-system/components/Ring/README.md +61 -11
- package/design-system/components/Ring/preview.html +55 -10
- package/design-system/components/Ring/style.css +49 -0
- package/design-system/components/ScoreHero/README.md +91 -0
- package/design-system/components/ScoreHero/preview.html +104 -0
- package/design-system/components/ScoreHero/style.css +32 -0
- package/design-system/components/Section/README.md +72 -33
- package/design-system/components/Section/preview.html +46 -16
- package/design-system/components/Section/style.css +18 -0
- package/design-system/components/Segmented/README.md +100 -55
- package/design-system/components/Segmented/preview.html +107 -26
- package/design-system/components/Segmented/style.css +94 -0
- package/design-system/components/SegmentedProgress/README.md +64 -0
- package/design-system/components/SegmentedProgress/preview.html +69 -0
- package/design-system/components/SegmentedProgress/style.css +11 -0
- package/design-system/components/Select/README.md +47 -12
- package/design-system/components/Select/preview.html +28 -2
- package/design-system/components/Select/style.css +22 -0
- package/design-system/components/ShareBar/README.md +69 -0
- package/design-system/components/ShareBar/preview.html +72 -0
- package/design-system/components/ShareBar/style.css +25 -0
- package/design-system/components/SideList/README.md +147 -0
- package/design-system/components/SideList/preview.html +139 -0
- package/design-system/components/SideList/style.css +94 -0
- package/design-system/components/Skeleton/README.md +52 -16
- package/design-system/components/Skeleton/preview.html +35 -23
- package/design-system/components/Skeleton/style.css +22 -0
- package/design-system/components/Slider/README.md +95 -0
- package/design-system/components/Slider/preview.html +49 -0
- package/design-system/components/Slider/style.css +13 -0
- package/design-system/components/Split/README.md +112 -0
- package/design-system/components/Split/preview.html +105 -0
- package/design-system/components/Split/style.css +30 -0
- package/design-system/components/Starter/README.md +21 -9
- package/design-system/components/Starter/preview.html +5 -5
- package/design-system/components/Stat/README.md +64 -43
- package/design-system/components/Stat/preview.html +3 -3
- package/design-system/components/Stat/style.css +15 -0
- package/design-system/components/StatTiles/README.md +88 -44
- package/design-system/components/StatTiles/preview.html +142 -71
- package/design-system/components/StatTiles/style.css +64 -0
- package/design-system/components/StatusLine/README.md +85 -0
- package/design-system/components/StatusLine/preview.html +49 -0
- package/design-system/components/StatusLine/style.css +14 -0
- package/design-system/components/StatusScreen/README.md +49 -35
- package/design-system/components/StatusScreen/preview.html +20 -5
- package/design-system/components/StatusScreen/style.css +9 -0
- package/design-system/components/StepLine/README.md +97 -0
- package/design-system/components/StepLine/preview.html +108 -0
- package/design-system/components/StepLine/style.css +62 -0
- package/design-system/components/Stepper/README.md +35 -13
- package/design-system/components/Stepper/style.css +13 -0
- package/design-system/components/StreakCalendar/README.md +22 -1
- package/design-system/components/StreakCalendar/preview.html +10 -10
- package/design-system/components/StreakCalendar/style.css +12 -0
- package/design-system/components/SuggestionChip/README.md +87 -0
- package/design-system/components/SuggestionChip/preview.html +42 -0
- package/design-system/components/SuggestionChip/style.css +20 -0
- package/design-system/components/Switch/README.md +44 -24
- package/design-system/components/Switch/preview.html +23 -8
- package/design-system/components/Switch/style.css +31 -0
- package/design-system/components/Table/README.md +129 -58
- package/design-system/components/Table/preview.html +106 -72
- package/design-system/components/Table/style.css +104 -0
- package/design-system/components/Tabs/README.md +71 -46
- package/design-system/components/Tabs/preview.html +56 -24
- package/design-system/components/Tabs/style.css +44 -0
- package/design-system/components/Testimonial/README.md +48 -32
- package/design-system/components/Testimonial/preview.html +14 -14
- package/design-system/components/Testimonial/style.css +12 -0
- package/design-system/components/TextArea/README.md +27 -11
- package/design-system/components/TextArea/preview.html +8 -2
- package/design-system/components/TextArea/style.css +12 -0
- package/design-system/components/ThemeSwitch/README.md +116 -0
- package/design-system/components/ThemeSwitch/preview.html +57 -0
- package/design-system/components/ThemeSwitch/style.css +6 -0
- package/design-system/components/TickRow/README.md +52 -36
- package/design-system/components/TickRow/preview.html +64 -41
- package/design-system/components/TickRow/style.css +23 -0
- package/design-system/components/TickStrip/README.md +95 -0
- package/design-system/components/TickStrip/preview.html +88 -0
- package/design-system/components/TickStrip/style.css +42 -0
- package/design-system/components/Tile/README.md +79 -18
- package/design-system/components/Tile/preview.html +91 -40
- package/design-system/components/Tile/style.css +36 -0
- package/design-system/components/Timeline/README.md +68 -48
- package/design-system/components/Timeline/preview.html +27 -15
- package/design-system/components/Timeline/style.css +25 -0
- package/design-system/components/Toast/README.md +70 -38
- package/design-system/components/Toast/preview.html +43 -8
- package/design-system/components/Toast/style.css +25 -0
- package/design-system/components/Tooltip/README.md +93 -35
- package/design-system/components/Tooltip/preview.html +69 -15
- package/design-system/components/Tooltip/style.css +78 -0
- package/design-system/components/TopBar/README.md +67 -53
- package/design-system/components/TopBar/preview.html +14 -27
- package/design-system/components/TopBar/style.css +35 -0
- package/design-system/components/TopicRail/README.md +108 -0
- package/design-system/components/TopicRail/preview.html +58 -0
- package/design-system/components/TopicRail/style.css +48 -0
- package/design-system/components/TrendBars/README.md +52 -14
- package/design-system/components/TrendBars/preview.html +65 -32
- package/design-system/components/TrendBars/style.css +25 -0
- package/design-system/components/TrendLine/README.md +164 -0
- package/design-system/components/TrendLine/preview.html +373 -0
- package/design-system/components/TrendLine/style.css +155 -0
- package/design-system/components/Well/README.md +64 -22
- package/design-system/components/Well/preview.html +14 -14
- package/design-system/components/Well/style.css +22 -0
- package/design-system/components/_house.css +324 -0
- package/design-system/components/bundle.css +4091 -744
- package/design-system/tokens.json +1314 -124
- package/dist/fello-core.css +2 -2
- package/dist/fello.css +6 -1369
- package/dist/fello.scoped.css +7 -0
- package/dist/index.d.ts +110 -11
- package/dist/index.js +781 -96
- package/dist/palettes.d.ts +464 -0
- package/dist/palettes.js +497 -0
- package/dist/scoped.d.ts +3 -0
- package/dist/scoped.js +16 -0
- package/dist/toast.d.ts +14 -0
- package/dist/toast.js +33 -29
- package/dist/tokens.d.ts +1686 -62
- package/dist/tokens.js +1668 -61
- package/package.json +20 -4
- package/scripts/check-palette.mjs +295 -0
- package/scripts/token-model.mjs +552 -0
- package/tokens/_dark.css +174 -0
- package/tokens/_palettes.css +46 -0
- package/tokens/_product.css +266 -53
- package/tokens/_source.hubl.css +39 -19
- package/tokens/design-tokens.json +319 -0
- package/tokens/palettes.ts +504 -0
- package/tokens/shadcn-compat.css +19 -19
- package/tokens/shadcn-compat.hsl.css +76 -0
- package/tokens/tokens.css +1292 -62
- package/tokens/tokens.md +588 -61
- package/tokens/tokens.root.css +1298 -62
- package/tokens/tokens.ts +1677 -64
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
A
|
|
2
|
-
|
|
1
|
+
A list that ranks people against one number: a rank, a face and a name, a thin bar for the score, the score itself,
|
|
2
|
+
with the person's own row lit so they find themselves at once. Every row shares one grid, so the bars start and end on
|
|
3
|
+
the same lines and no number is ever cut.
|
|
3
4
|
|
|
4
5
|
## Use it when
|
|
5
6
|
|
|
@@ -15,80 +16,106 @@ itself, with the person's own row lit so they find themselves at once.
|
|
|
15
16
|
|
|
16
17
|
## Anatomy
|
|
17
18
|
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- Person: a 28 px `Avatar` (`ws-avatar--sm
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
of the goal, by meaning, never by rank: teal
|
|
27
|
-
(
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
- `ol.ws-leaderboard` in a `Card`: one grid (rank, face, name, bar, score) that every row takes as a subgrid, 12 between
|
|
20
|
+
columns; rows at least 48 (`--ws-row-h`, a row with a face), the card's 20 px edge at both sides, a 0.5 px line between
|
|
21
|
+
rows (`--ws-divider`).
|
|
22
|
+
- Rank: 16 / 20 semibold navy numerals, right-aligned in a column at least 20 wide, tabular.
|
|
23
|
+
- Person: a 28 px `Avatar` (`ws-avatar--sm`) then the name, 14 / 20 medium navy. The name column is as wide as the
|
|
24
|
+
longest name, up to 40 % of the list and never under 108; a longer name truncates with an ellipsis and carries a
|
|
25
|
+
`title` (K13).
|
|
26
|
+
- Score: the system's thin bar, 8 tall, 1 px corners, on the empty track (`--ws-track`), as long as the score against
|
|
27
|
+
the leader's. Its fill (`__fill`) takes the tone of the row's share of the goal, by meaning, never by rank: teal
|
|
28
|
+
(`__fill--finished`, `--ws-chart-finished`) at or over the goal, purple (`__fill--past-half`,
|
|
29
|
+
`--ws-chart-past-half`) past half, salmon (`__fill--under-half`, `--ws-chart-under-half`, also the fill's default)
|
|
30
|
+
under half. The number sits at the right, 14 / 20 semibold navy, tabular, in a column as wide
|
|
31
|
+
as the widest score: it never truncates.
|
|
32
|
+
- The person's own row: `--ws-surface-sunk`, also when the row is a link or a button.
|
|
33
|
+
- Narrow (the list under 24rem): the bar drops under the name, from the name's edge to the score's, so every bar is the
|
|
34
|
+
same length; the row grows to fit. The name has its own line there and wraps instead of truncating (a phone has no
|
|
35
|
+
hover to show a `title`); the rank, face and score centre on its line or lines.
|
|
31
36
|
|
|
32
37
|
## Variants and sizes
|
|
33
38
|
|
|
34
39
|
| Part | Choice | Why |
|
|
35
40
|
| --- | --- | --- |
|
|
36
41
|
| Score mark | `TickRow` | When the number is itself a count out of a small whole ("6 of 10 goals") |
|
|
37
|
-
| Score mark | A thin bar (this preview) | When the number is a raw count or a percentage with no natural "whole"
|
|
42
|
+
| Score mark | A thin bar (this preview) | When the number is a raw count or a percentage with no natural "whole" |
|
|
43
|
+
| Row | `li.ws-leaderboard__row` | A static row |
|
|
44
|
+
| Row | `li > a.ws-leaderboard__row` | A row that opens the person; the `li` passes the grid on |
|
|
38
45
|
|
|
39
46
|
## States
|
|
40
47
|
|
|
41
48
|
- **Default**: as above.
|
|
42
|
-
- **Your row**: `--ws-surface-sunk`, no extra border or icon
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
|
|
46
|
-
- **Hover**: the row tints `--ws-surface-sunk` like any list row, stacking visually with "your row" when they coincide
|
|
47
|
-
(a slightly heavier tone is acceptable since both already share the same token).
|
|
49
|
+
- **Your row**: `--ws-surface-sunk`, no extra border or icon.
|
|
50
|
+
- **Tie**: two rows share a rank number; no invented tie-break ("T-3").
|
|
51
|
+
- **Hover** (a row that opens): North's faint navy wash (`--ws-hover-faint`), laid over the row's ground, so your own
|
|
52
|
+
row stays lit under it; its focus ring is drawn inside the row.
|
|
48
53
|
- **Empty** (nobody has a score yet): the same card, a sentence ("Nobody has logged a call yet") and the act that starts
|
|
49
|
-
it, in the band
|
|
50
|
-
- **Long name**: truncates
|
|
51
|
-
|
|
54
|
+
it, in the band; never a leaderboard drawn with every bar at zero.
|
|
55
|
+
- **Long name**: truncates past 40 % with a `title`; under 24rem it wraps instead. A short list of short names takes
|
|
56
|
+
only the room it needs.
|
|
57
|
+
- **Narrow**: the bar under the name.
|
|
52
58
|
|
|
53
59
|
## Behaviour
|
|
54
60
|
|
|
55
|
-
- Keyboard:
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
own arrival motion; reduced motion shows every bar at its final length.
|
|
61
|
+
- Keyboard: a static list unless a row opens something; then each row is a link in document order.
|
|
62
|
+
- Pointer: hover tints a row that opens.
|
|
63
|
+
- Motion: each bar fills from the left on arrival (North's fill, 700 ms on `--ws-ease-settle`), a row's worth apart
|
|
64
|
+
(`--ws-stagger-row`, 45 ms; set `--ws-i` on each fill). Under reduced motion every bar shows at its length.
|
|
60
65
|
|
|
61
66
|
## Content
|
|
62
67
|
|
|
63
|
-
- A name is the person's own name when they have consented to be named; otherwise a role ("Team best", "Team average")
|
|
64
|
-
|
|
65
|
-
- No em dashes; the score is a bare number with its unit implied by the card's title, not repeated in every row.
|
|
68
|
+
- A name is the person's own name when they have consented to be named; otherwise a role ("Team best", "Team average").
|
|
69
|
+
- No em dashes; the score is a bare number with its unit in the card's title, not repeated in every row.
|
|
66
70
|
|
|
67
71
|
## Props
|
|
68
72
|
|
|
69
73
|
| Name | Type | Meaning |
|
|
70
74
|
| --- | --- | --- |
|
|
71
|
-
| `rows` | `{ rank, name, initials, score,
|
|
72
|
-
| `scoreOf` | `number` | The value a full-width bar represents
|
|
75
|
+
| `rows` | `{ rank, name, initials, score, isYou?, href? }[]` | Every ranked row, already sorted |
|
|
76
|
+
| `scoreOf` | `number` | The value a full-width bar represents |
|
|
73
77
|
| `goal` | `number` | The goal each row's share is measured against, for its bar's tone |
|
|
74
78
|
| `markKind` | `'bar' \| 'ticks'` | Which mark draws the score |
|
|
75
79
|
|
|
76
80
|
## Rules
|
|
77
81
|
|
|
78
|
-
- **The person's row is `--ws-surface-sunk`**,
|
|
79
|
-
|
|
80
|
-
- **A
|
|
81
|
-
|
|
82
|
-
- **A bar's tone is the row's share of the goal**: finished, past half or under half, never its rank and never an
|
|
83
|
-
arbitrary colour per row, so the same tone means the same thing here as in `GoalBars` and `TickRow`.
|
|
84
|
-
- **A new shape for rankings**: rankings are a different reading task from a record table (`Table`) or a category
|
|
85
|
-
comparison (`GoalBars`), needing a rank column and a highlighted "you" row neither already provides. Derived from
|
|
86
|
-
`Table`'s row heights and hairlines, the sunk hover used everywhere for "the current one", and the goal's tones.
|
|
82
|
+
- **The person's row is `--ws-surface-sunk`**, never a new colour invented to mean "you".
|
|
83
|
+
- **A comparison with a teammate is a role, not a name, when the name is not the person's to share.**
|
|
84
|
+
- **A bar's tone is the row's share of the goal**, never its rank.
|
|
85
|
+
- **A number never truncates** (K13), and every bar has the same length (the shared grid).
|
|
87
86
|
|
|
88
87
|
## Source
|
|
89
88
|
|
|
90
|
-
- **Derived from**: the
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- **Precedent**: an intentional addition decided from the system, 26 Oct 2026
|
|
94
|
-
|
|
89
|
+
- **Derived from**: the row heights and hairlines of `Table`, the sunk "this one is you" wash, the goal's tones
|
|
90
|
+
(`GoalBars`), North's hover wash and fill motion, and the K13 audit (names cut to 108 of 125 to 139 px in a 556 px
|
|
91
|
+
card, a fixed name box).
|
|
92
|
+
- **Precedent**: an intentional addition decided from the system, 26 Oct 2026; one shared grid in 0.5.0 (4 Nov 2026).
|
|
93
|
+
|
|
94
|
+
## Markup
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<section class="ws-card" aria-label="Cold calls this month, team ranking, goal 50">
|
|
98
|
+
<ol class="ws-leaderboard">
|
|
99
|
+
<li class="ws-leaderboard__row">
|
|
100
|
+
<span class="ws-leaderboard__rank">1</span>
|
|
101
|
+
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">PN</span>
|
|
102
|
+
<span class="ws-leaderboard__name" title="Priya Nair">Priya Nair</span>
|
|
103
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished" style="width: 100%;"></span></span>
|
|
104
|
+
<span class="ws-leaderboard__score">58</span>
|
|
105
|
+
</li>
|
|
106
|
+
<li class="ws-leaderboard__row ws-leaderboard__row--you">
|
|
107
|
+
<span class="ws-leaderboard__rank">2</span>
|
|
108
|
+
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">RY</span>
|
|
109
|
+
<span class="ws-leaderboard__name" title="You">You</span>
|
|
110
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 62%; --ws-i: 1;"></span></span>
|
|
111
|
+
<span class="ws-leaderboard__score">36</span>
|
|
112
|
+
</li>
|
|
113
|
+
</ol>
|
|
114
|
+
</section>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Styles
|
|
118
|
+
|
|
119
|
+
`design-system/components/Leaderboard/style.css`, in `bundle.css` and `fello.css`. Dark comes from the tokens
|
|
120
|
+
(`--ws-track`, `--ws-surface-sunk`, the chart tones). The list is a size container named `ws-leaderboard`, so it needs
|
|
121
|
+
its card's width (a card in a shrink-to-fit row collapses: give it a width).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Data" height=
|
|
1
|
+
<!-- @dsCard group="Data" height=640 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -10,74 +10,109 @@
|
|
|
10
10
|
<body>
|
|
11
11
|
<div class="ws-stage ws-stage--grey">
|
|
12
12
|
|
|
13
|
-
<figure class="ws-stack" style="width:
|
|
14
|
-
<span class="ws-muted">8 rows against a goal of
|
|
15
|
-
<section class="ws-card" aria-label="Cold calls this month, team ranking, goal
|
|
13
|
+
<figure class="ws-stack" style="width: 556px;">
|
|
14
|
+
<span class="ws-muted">8 rows against a goal of 900 calls: one shared grid, so every bar starts and ends on the same line; names as wide as the longest up to 40 %, the score never cut; your own row lit</span>
|
|
15
|
+
<section class="ws-card" aria-label="Cold calls this month, team ranking, goal 900">
|
|
16
16
|
<ol class="ws-leaderboard">
|
|
17
17
|
<li class="ws-leaderboard__row">
|
|
18
18
|
<span class="ws-leaderboard__rank">1</span>
|
|
19
19
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">PN</span>
|
|
20
20
|
<span class="ws-leaderboard__name" title="Priya Nair">Priya Nair</span>
|
|
21
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished
|
|
22
|
-
<span class="ws-leaderboard__score">
|
|
21
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished" style="width: 100%;"></span></span>
|
|
22
|
+
<span class="ws-leaderboard__score">1,058</span>
|
|
23
23
|
</li>
|
|
24
24
|
<li class="ws-leaderboard__row">
|
|
25
25
|
<span class="ws-leaderboard__rank">2</span>
|
|
26
26
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">DA</span>
|
|
27
|
-
<span class="ws-leaderboard__name" title="Dana Alvarez">Dana Alvarez</span>
|
|
28
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished
|
|
29
|
-
<span class="ws-leaderboard__score">
|
|
27
|
+
<span class="ws-leaderboard__name" title="Dana Alvarez-Whitcombe">Dana Alvarez-Whitcombe</span>
|
|
28
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished" style="width: 91%; --ws-i: 1;"></span></span>
|
|
29
|
+
<span class="ws-leaderboard__score">963</span>
|
|
30
30
|
</li>
|
|
31
31
|
<li class="ws-leaderboard__row">
|
|
32
32
|
<span class="ws-leaderboard__rank">3</span>
|
|
33
33
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">MD</span>
|
|
34
|
-
<span class="ws-leaderboard__name" title="Marco Diaz">Marco Diaz</span>
|
|
35
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half
|
|
36
|
-
<span class="ws-leaderboard__score">
|
|
34
|
+
<span class="ws-leaderboard__name" title="Marco Diaz-Fernandez de la Vega">Marco Diaz-Fernandez de la Vega</span>
|
|
35
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 78%; --ws-i: 2;"></span></span>
|
|
36
|
+
<span class="ws-leaderboard__score">825</span>
|
|
37
37
|
</li>
|
|
38
38
|
<li class="ws-leaderboard__row">
|
|
39
39
|
<span class="ws-leaderboard__rank">4</span>
|
|
40
40
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">SO</span>
|
|
41
41
|
<span class="ws-leaderboard__name" title="Sam Okafor">Sam Okafor</span>
|
|
42
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half
|
|
43
|
-
<span class="ws-leaderboard__score">
|
|
42
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 69%; --ws-i: 3;"></span></span>
|
|
43
|
+
<span class="ws-leaderboard__score">730</span>
|
|
44
44
|
</li>
|
|
45
45
|
<li class="ws-leaderboard__row ws-leaderboard__row--you">
|
|
46
46
|
<span class="ws-leaderboard__rank">5</span>
|
|
47
47
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">RY</span>
|
|
48
48
|
<span class="ws-leaderboard__name" title="You">You</span>
|
|
49
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half
|
|
50
|
-
<span class="ws-leaderboard__score">
|
|
49
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 62%; --ws-i: 4;"></span></span>
|
|
50
|
+
<span class="ws-leaderboard__score">656</span>
|
|
51
51
|
</li>
|
|
52
52
|
<li class="ws-leaderboard__row">
|
|
53
53
|
<span class="ws-leaderboard__rank">6</span>
|
|
54
54
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">NP</span>
|
|
55
55
|
<span class="ws-leaderboard__name" title="Nellie Park">Nellie Park</span>
|
|
56
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half
|
|
57
|
-
<span class="ws-leaderboard__score">
|
|
56
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 50%; --ws-i: 5;"></span></span>
|
|
57
|
+
<span class="ws-leaderboard__score">529</span>
|
|
58
58
|
</li>
|
|
59
59
|
<li class="ws-leaderboard__row">
|
|
60
60
|
<span class="ws-leaderboard__rank">7</span>
|
|
61
61
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">JW</span>
|
|
62
62
|
<span class="ws-leaderboard__name" title="Jo Whitfield">Jo Whitfield</span>
|
|
63
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--under-half
|
|
64
|
-
<span class="ws-leaderboard__score">
|
|
63
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--under-half" style="width: 38%; --ws-i: 6;"></span></span>
|
|
64
|
+
<span class="ws-leaderboard__score">402</span>
|
|
65
65
|
</li>
|
|
66
66
|
<li class="ws-leaderboard__row">
|
|
67
67
|
<span class="ws-leaderboard__rank">8</span>
|
|
68
68
|
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">TL</span>
|
|
69
69
|
<span class="ws-leaderboard__name" title="Theo Lang">Theo Lang</span>
|
|
70
|
-
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--under-half
|
|
71
|
-
<span class="ws-leaderboard__score">
|
|
70
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--under-half" style="width: 24%; --ws-i: 7;"></span></span>
|
|
71
|
+
<span class="ws-leaderboard__score">254</span>
|
|
72
72
|
</li>
|
|
73
73
|
</ol>
|
|
74
74
|
</section>
|
|
75
|
-
<figcaption class="ws-muted">
|
|
76
|
-
When names are not the leader's to share, a row beside "You" reads as a role, "Team best" or "Team average", never
|
|
77
|
-
a name the person did not consent to show.
|
|
78
|
-
</figcaption>
|
|
75
|
+
<figcaption class="ws-muted">When names are not the leader's to share, a row beside "You" reads as a role, "Team best" or "Team average", never a name the person did not consent to show.</figcaption>
|
|
79
76
|
</figure>
|
|
80
77
|
|
|
78
|
+
<div class="ws-stack ws-stack--component" style="width: 320px;">
|
|
79
|
+
<figure class="ws-stack">
|
|
80
|
+
<span class="ws-muted">Under 24rem the bar drops under the name; rows that open a person tint on hover</span>
|
|
81
|
+
<section class="ws-card" aria-label="Deals closed this quarter, goal 10">
|
|
82
|
+
<ol class="ws-leaderboard">
|
|
83
|
+
<li><a class="ws-leaderboard__row" href="#dana">
|
|
84
|
+
<span class="ws-leaderboard__rank">1</span>
|
|
85
|
+
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">DA</span>
|
|
86
|
+
<span class="ws-leaderboard__name" title="Dana Alvarez">Dana Alvarez</span>
|
|
87
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--finished" style="width: 100%;"></span></span>
|
|
88
|
+
<span class="ws-leaderboard__score">12</span>
|
|
89
|
+
</a></li>
|
|
90
|
+
<li><a class="ws-leaderboard__row ws-leaderboard__row--you" href="#you">
|
|
91
|
+
<span class="ws-leaderboard__rank">2</span>
|
|
92
|
+
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">RY</span>
|
|
93
|
+
<span class="ws-leaderboard__name" title="You">You</span>
|
|
94
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--past-half" style="width: 58%; --ws-i: 1;"></span></span>
|
|
95
|
+
<span class="ws-leaderboard__score">7</span>
|
|
96
|
+
</a></li>
|
|
97
|
+
<li><a class="ws-leaderboard__row" href="#team">
|
|
98
|
+
<span class="ws-leaderboard__rank">3</span>
|
|
99
|
+
<span class="ws-avatar ws-avatar--sm" aria-hidden="true">TA</span>
|
|
100
|
+
<span class="ws-leaderboard__name" title="Team average">Team average</span>
|
|
101
|
+
<span class="ws-leaderboard__bar" aria-hidden="true"><span class="ws-leaderboard__fill ws-leaderboard__fill--under-half" style="width: 33%; --ws-i: 2;"></span></span>
|
|
102
|
+
<span class="ws-leaderboard__score">4</span>
|
|
103
|
+
</a></li>
|
|
104
|
+
</ol>
|
|
105
|
+
</section>
|
|
106
|
+
</figure>
|
|
107
|
+
<figure class="ws-stack">
|
|
108
|
+
<span class="ws-muted">Empty: a sentence and the act that starts it, never bars at zero</span>
|
|
109
|
+
<section class="ws-card ws-card--compound">
|
|
110
|
+
<header class="ws-head"><div><h3 class="ws-title">Nobody has logged a call yet</h3><p class="ws-body ws-card__line">The board fills in as the team calls this month.</p></div></header>
|
|
111
|
+
<div class="ws-band"><div class="ws-band__words"><span class="ws-band__title">Start with your first call</span></div><button type="button" class="ws-btn ws-btn--primary">Log a call</button></div>
|
|
112
|
+
</section>
|
|
113
|
+
</figure>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
81
116
|
</div>
|
|
82
117
|
</body>
|
|
83
118
|
</html>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* ---- Leaderboard: a team ranked by one number, a thin bar toned by each row's share of the goal, your row lit. One grid
|
|
2
|
+
for every row (subgrid), so ranks, bars and scores sit in shared columns: the name column is as wide as the longest
|
|
3
|
+
name up to 40 % (at least 108), and a number never truncates (K13). Under 24rem the bar drops under the name. ---- */
|
|
4
|
+
.ws-leaderboard { container: ws-leaderboard / inline-size; display: grid; grid-template-columns: [rank] minmax(calc(var(--space-md) + var(--space-xxs)), auto) [face] auto [name] fit-content(40%) [bar] minmax(0, 1fr) [score] auto; column-gap: var(--space-sm); border-radius: inherit; }
|
|
5
|
+
/* Each item spans the grid and passes its columns on (an li holding a link row does too), a 0.5 px line between. */
|
|
6
|
+
.ws-leaderboard > *, .ws-leaderboard__row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; }
|
|
7
|
+
.ws-leaderboard > * + * { border-top: var(--ws-divider); }
|
|
8
|
+
.ws-leaderboard > :first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }
|
|
9
|
+
.ws-leaderboard > :last-child { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
|
|
10
|
+
.ws-leaderboard__row { align-items: center; min-height: var(--ws-row-h); padding: 0 var(--ws-card-inset); }
|
|
11
|
+
/* A link row takes its li's corners (only the first and last li have any), so a lit row or a line mid-list stays square. */
|
|
12
|
+
.ws-leaderboard > * > .ws-leaderboard__row { border-radius: inherit; }
|
|
13
|
+
/* Two classes, so the lit row stays lit when it is a link or a button (their reset is transparent). */
|
|
14
|
+
.ws-leaderboard .ws-leaderboard__row--you { background-color: var(--ws-surface-sunk); }
|
|
15
|
+
.ws-leaderboard__rank { text-align: right; font-size: var(--ws-text-value); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
|
|
16
|
+
/* The name: truncates only past 40 % of the list (its title then holds it whole); never under 108. */
|
|
17
|
+
.ws-leaderboard__name { min-width: calc(var(--space-6xl) + var(--space-sm)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 500; color: var(--color-text-heading); }
|
|
18
|
+
/* The system's thin bar: 8 tall, 1 px corners, on the empty track. */
|
|
19
|
+
.ws-leaderboard__bar { position: relative; height: var(--space-xs); border-radius: var(--ws-radius-bar); background: var(--ws-track); overflow: hidden; }
|
|
20
|
+
.ws-leaderboard__fill { position: absolute; inset: 0 auto 0 0; border-radius: var(--ws-radius-bar); background: var(--ws-chart-under-half); transform-origin: left; }
|
|
21
|
+
.ws-leaderboard__fill--finished { background: var(--ws-chart-finished); }
|
|
22
|
+
.ws-leaderboard__fill--past-half { background: var(--ws-chart-past-half); }
|
|
23
|
+
.ws-leaderboard__fill--under-half { background: var(--ws-chart-under-half); }
|
|
24
|
+
.ws-leaderboard__score { text-align: right; white-space: nowrap; font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
|
|
25
|
+
/* A row that opens the person: North's faint wash on hover, laid over the row's own ground (so your lit row stays lit),
|
|
26
|
+
nothing moves. */
|
|
27
|
+
a.ws-leaderboard__row, button.ws-leaderboard__row { width: 100%; border: 0; background-color: transparent; text-align: left; text-decoration: none; color: inherit; cursor: pointer; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
28
|
+
a.ws-leaderboard__row:focus-visible, button.ws-leaderboard__row:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
29
|
+
@media (hover: hover) { a.ws-leaderboard__row:hover, button.ws-leaderboard__row:hover { background-image: linear-gradient(var(--ws-hover-faint), var(--ws-hover-faint)); } }
|
|
30
|
+
/* Arrival: each bar fills from the left (North's fill, settling), a row's worth apart; set --ws-i on each fill. */
|
|
31
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
32
|
+
.ws-leaderboard__fill { animation: ws-grow var(--ws-duration-fill) var(--ws-ease-settle) backwards; animation-delay: calc(var(--ws-i, 0) * var(--ws-stagger-row)); }
|
|
33
|
+
}
|
|
34
|
+
/* Narrow: the bar under the name, from the name's edge to the score's, so every bar is the same length; the rank, the
|
|
35
|
+
face and the score centre on the name's line (or lines). */
|
|
36
|
+
@container ws-leaderboard (max-width: 24rem) {
|
|
37
|
+
.ws-leaderboard__row { grid-template-columns: [rank] minmax(calc(var(--space-md) + var(--space-xxs)), auto) [face] auto [name] minmax(0, 1fr) [score] auto; gap: var(--space-xs) var(--space-sm); padding-block: var(--space-sm); }
|
|
38
|
+
.ws-leaderboard__rank { grid-area: 1 / rank; }
|
|
39
|
+
.ws-leaderboard__row > .ws-avatar { grid-area: 1 / face; }
|
|
40
|
+
/* The name has its own line here, and a phone has no hover to show a title, so a long name wraps instead of cutting. */
|
|
41
|
+
.ws-leaderboard__name { grid-area: 1 / name; min-width: 0; overflow: visible; white-space: normal; overflow-wrap: anywhere; }
|
|
42
|
+
.ws-leaderboard__score { grid-area: 1 / score; }
|
|
43
|
+
.ws-leaderboard__bar { grid-area: 2 / name / 3 / -1; }
|
|
44
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
A list and the thing picked from it, side by side: the list one column wide, the open item two, on one three-column
|
|
2
|
+
grid. Seth's Review inbox (313:2671) and North's board (a chart and the list that drives it), with Tally's vendors.
|
|
3
|
+
|
|
4
|
+
## Use it when
|
|
5
|
+
|
|
6
|
+
- People go through items one at a time and act on each (reviews to reply to, leads to work, tools to cut), with the
|
|
7
|
+
list in view so they keep their place.
|
|
8
|
+
- Picking a row in a short list changes a chart or a detail beside it (North's board, Tally's "Vendor by vendor").
|
|
9
|
+
|
|
10
|
+
## Not for
|
|
11
|
+
|
|
12
|
+
- Records to compare across columns: use `Table`.
|
|
13
|
+
- A detail that opens over the page: use `Panel` (a drawer) from a list.
|
|
14
|
+
- One detail at a time with no list: a `Card`.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
- `.ws-list-detail` (a size container) holding `__grid`: three equal columns; the list (`__list`) takes one, the detail
|
|
19
|
+
(`__detail`) two. The list's right edge lines up with the first of three tiles above it on the same grid. A list that
|
|
20
|
+
needs a set width instead (Tally's vendor picker and North's board list, 362) sets `--ws-list-detail-list` on
|
|
21
|
+
`.ws-list-detail`; the detail takes the rest.
|
|
22
|
+
- Joined (default): one rim, the tray grey (`--ws-tray`), 1 px round and 1 px between the panes, so a single grey line
|
|
23
|
+
splits them; 8 px corners outside, each surface rounding only its outer corners (7), so the split stays clean.
|
|
24
|
+
- `--apart` (Seth's inbox): each pane its own rim, 8 apart.
|
|
25
|
+
- `--list-end` (North's board, Tally's vendors): the list at the end, the detail first. The list stays first in the DOM.
|
|
26
|
+
- A pane: its cream surface (`__surface`) and, under it on the rim, an optional foot (`__foot`: at least 32, 8 above and
|
|
27
|
+
below, 14 at the sides, 12 / 16 body words, a figure in 600, a needs-you figure in salmon's AA word; its stars are `--ws-chart-under-half`). Where its two
|
|
28
|
+
parts do not fit side by side (a phone) the second drops under the first, at the right, instead of both wrapping.
|
|
29
|
+
- The list's head (`__head`, Seth): 12 above and below, 16 in, 20 out, 14 apart: a select-all box (`Checkbox --quiet`,
|
|
30
|
+
Seth's status box) and a filter (`Segmented --clear --stretch`: no ground, the items sharing the width; buttons with
|
|
31
|
+
`aria-pressed`, since it filters rather than switching panes); a 0.5 px line under it.
|
|
32
|
+
- The list's scroller (`__scroll`): side by side, the list takes the detail's height and scrolls inside it. While rows
|
|
33
|
+
are hidden below, its last 24 px fade out; the fade lifts at the end (a scroll-driven fade, as `Table`'s far edge),
|
|
34
|
+
and a list that fits shows none.
|
|
35
|
+
- An inbox row (`__rows > li`): 12 above and below, 16 in, 20 out, 14 apart: a box (the skinned `Checkbox`, centred on
|
|
36
|
+
the meta line, a 24 target, 40 on touch), then the open button (`__open`, its hit area the whole row): a meta line
|
|
37
|
+
(`__meta`: 12 px stars 2 apart, the date taking the room, the source; 13 / 18 medium muted, 8 apart) and, 4 under, one
|
|
38
|
+
line of the thing (`__text`, 14 / 20 navy, an ellipsis and a `title`). A 0.5 px line between rows, drawn inside the
|
|
39
|
+
top of the row, so a row's 66 includes it as in Seth's frame.
|
|
40
|
+
- A picker list: `SideList`'s `__picks` on the list's surface.
|
|
41
|
+
- The detail's body (`__body`): 16 inside (North), `--roomy` 28 above and below and 32 at the sides (Seth); parts 24
|
|
42
|
+
apart. Its parts: a pager head (`__pager`: the item's meta, "4 of 10", and `__pager-acts`, two square steppers,
|
|
43
|
+
`IconButton --solid` at 32 with 6 px corners, up and down), a title and line (`__words`, 2 apart), a top row
|
|
44
|
+
(`__top`, Tally's vendor head: the words at the left taking the room, the controls in one row at the right on the
|
|
45
|
+
title's line, 16 between the two and 8 between controls, such as two `ws-filter-pick`s and a `Checkbox --sm`; where
|
|
46
|
+
both do not fit the controls drop under the words, 12 under), a quote (`__quote`, 22 / 30 navy), a sunk draft
|
|
47
|
+
(`Plate`), the acts (`__acts`, 8 apart, pinned to the foot of the detail: the primary first, then Seth's grey act,
|
|
48
|
+
`Button --well`, and a trailing check act at the end) and a last line (`__note`, 13 / 18 medium muted).
|
|
49
|
+
- A foot's needs-you figure (`__foot-needs`): salmon's AA word (`--ws-word-needs`), its figure in 600 (`<b>`).
|
|
50
|
+
|
|
51
|
+
## Variants and sizes
|
|
52
|
+
|
|
53
|
+
| Variant | What changes |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| Joined (default) | One rim, a 1 px split |
|
|
56
|
+
| `--apart` | Two rims, 8 apart |
|
|
57
|
+
| `--list-end` | The list at the end |
|
|
58
|
+
| `--ws-list-detail-list` | The list's width in place of its third, the detail taking the rest (Tally and North: 362, `calc(var(--space-9xl) * 1.81)`); set on `.ws-list-detail`, either end |
|
|
59
|
+
| `--fill` | The pair is the rest of a height-bound column: the list scrolls, the detail's acts sit at its foot, the detail scrolls if it must |
|
|
60
|
+
| Narrow (under 48rem) | Stacked, 12 apart, each pane its own rim, the list first and as tall as its rows; a `--fill` pair scrolls as one |
|
|
61
|
+
| A detail under 30rem | The pager head takes two lines: the stars and the meta, then "4 of 10" and the steppers at the right, 8 under (the detail is a size container named `ws-list-detail-pane`) |
|
|
62
|
+
|
|
63
|
+
## States
|
|
64
|
+
|
|
65
|
+
- **Default**: as above.
|
|
66
|
+
- **Current row** (`aria-current="true"` on the open button): the sunk cream (`--ws-surface-sunk`), the words semibold at
|
|
67
|
+
the same size, so no row moves (Seth's frame grew the row 2 px; the kit does not). No left bar.
|
|
68
|
+
- **Hover** (a row): North's faint wash (`--ws-hover-faint`), not on the current one.
|
|
69
|
+
- **Focus**: the 2 px navy ring drawn inside the row.
|
|
70
|
+
- **A row ticked**: its box only; the row stays where it is until the list is refreshed.
|
|
71
|
+
- **Empty list**: the list's surface says so in a sentence (`__empty`: 14 / 20 body words on the rows' edges, 24 above
|
|
72
|
+
and below: "No reviews need a reply"), the detail shows the next step or nothing.
|
|
73
|
+
- **Loading**: ghost lines (`__ghost ws-shimmer`) in the rows and the detail; still under reduced motion.
|
|
74
|
+
- **Long words**: a row's line truncates with a `title`; the detail's words wrap.
|
|
75
|
+
|
|
76
|
+
## Behaviour
|
|
77
|
+
|
|
78
|
+
- Keyboard: each row's box and its open button are two stops; the steppers move to the previous and next item; the
|
|
79
|
+
scroller is a focusable region.
|
|
80
|
+
- Pointer: clicking a row anywhere but its box opens it.
|
|
81
|
+
- Motion: a picked row's fill slides to it and takes its height (North's "List highlight slide", `springs.highlight`
|
|
82
|
+
.45 / .14), plain CSS with no script and no new markup: the current row is a CSS anchor and `__rows`' `::before` is
|
|
83
|
+
the travelling fill, under the rows, their lines and their words, its four edges easing on motion's own
|
|
84
|
+
`spring(.45, .14)` written out as `linear()` (800 ms; `--ws-spring-highlight-duration` and `--ws-spring-highlight`). At
|
|
85
|
+
rest the current row paints its own fill (the 0.4 look); while the list is pointed at or holds focus the travelling
|
|
86
|
+
fill takes its place, so a pick made then slides. Rows that change places (a sort, a filter, a reply that files a
|
|
87
|
+
review away) glide with `reorder()` (see `KanbanBoard`). The old detail leaves and the new one arrives on
|
|
88
|
+
`springs.swap`, details settling in after it (`ws-settle`). Without CSS anchor positioning the fill moves at once;
|
|
89
|
+
under reduced motion the fill and the detail change at once. Try it in the preview: click a row.
|
|
90
|
+
|
|
91
|
+
## Content
|
|
92
|
+
|
|
93
|
+
- A row's one line is the item's own words (the review, the lead's need), never a status alone.
|
|
94
|
+
- The detail's acts are verbs with their objects ("Copy reply", "Open your Zillow reviews"); the primary first.
|
|
95
|
+
- No em dashes.
|
|
96
|
+
|
|
97
|
+
## Rules
|
|
98
|
+
|
|
99
|
+
- **The list is one column of the page's grid**, so it lines up with tiles above it; it takes a set width
|
|
100
|
+
(`--ws-list-detail-list`) only where the design sets one (Tally's and North's 362 picker beside a chart).
|
|
101
|
+
- **The list never pushes the page**: side by side it scrolls in the detail's height.
|
|
102
|
+
- **Reading order is the DOM order** (list, then detail) at every width; `--list-end` only moves the list visually.
|
|
103
|
+
- **A current row never changes size.**
|
|
104
|
+
|
|
105
|
+
## Source
|
|
106
|
+
|
|
107
|
+
**Derived from**: Seth's Review inbox (313:2671: the 3-column grid 8 apart, the list head and rows, the open review),
|
|
108
|
+
Tally's vendor board (319:3445: two trays joined by one grey line) and North's board (style1.css 173 to 206: detail and
|
|
109
|
+
list joined, 16 inside, a 31 px foot, list first on a phone), on the kit's rim (D5) and type steps (D6). **Precedent**:
|
|
110
|
+
new in 0.5.0 (4 Nov 2026).
|
|
111
|
+
|
|
112
|
+
## Markup
|
|
113
|
+
|
|
114
|
+
The inbox (Seth's Review inbox, `--apart --fill`: the list with its head, the open review with its pager, draft, acts
|
|
115
|
+
and last line):
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<div class="ws-list-detail ws-list-detail--apart ws-list-detail--fill">
|
|
119
|
+
<div class="ws-list-detail__grid">
|
|
120
|
+
<section class="ws-list-detail__list" aria-label="Reviews">
|
|
121
|
+
<div class="ws-list-detail__surface">
|
|
122
|
+
<div class="ws-list-detail__head">
|
|
123
|
+
<label class="ws-check ws-check--quiet"><input type="checkbox" aria-label="Select every review"><span class="ws-check__box" aria-hidden="true"><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 6.25L4.75 8.5L9.5 3.75"/></svg></span></label>
|
|
124
|
+
<div class="ws-segmented ws-segmented--clear ws-segmented--stretch" role="group" aria-label="Show">
|
|
125
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Needs a reply <span class="ws-tnum">10</span></button>
|
|
126
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">All <span class="ws-tnum">100</span></button>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="ws-list-detail__scroll" role="region" aria-label="Reviews, scrolls" tabindex="0">
|
|
130
|
+
<ul class="ws-list-detail__rows">
|
|
131
|
+
<li>
|
|
132
|
+
<label class="ws-check"><input type="checkbox" aria-label="Replied to the Oct 2 review"><span class="ws-check__box" aria-hidden="true"><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 6.25L4.75 8.5L9.5 3.75"/></svg></span></label>
|
|
133
|
+
<button type="button" class="ws-list-detail__open" aria-current="true">
|
|
134
|
+
<span class="ws-list-detail__meta"><span class="ws-list-detail__stars" role="img" aria-label="5 of 5 stars"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 1.5l1.9 4.1 4.4.5-3.3 3 .9 4.4L8 11.3l-3.9 2.2.9-4.4-3.3-3 4.4-.5z"/></svg><!-- five in all --></span><span>Oct 2</span><span>Zillow</span></span>
|
|
135
|
+
<span class="ws-list-detail__text" title="Knew the market inside out and got us a great price.">Knew the market inside out and got us a great price.</span>
|
|
136
|
+
</button>
|
|
137
|
+
</li>
|
|
138
|
+
</ul>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</section>
|
|
142
|
+
<section class="ws-list-detail__detail" aria-label="Review from Oct 2">
|
|
143
|
+
<div class="ws-list-detail__surface">
|
|
144
|
+
<div class="ws-list-detail__body ws-list-detail__body--roomy">
|
|
145
|
+
<div class="ws-list-detail__pager">
|
|
146
|
+
<span class="ws-list-detail__stars ws-list-detail__stars--lg" role="img" aria-label="5 of 5 stars"><svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 1.5l1.9 4.1 4.4.5-3.3 3 .9 4.4L8 11.3l-3.9 2.2.9-4.4-3.3-3 4.4-.5z"/></svg><!-- five in all --></span>
|
|
147
|
+
<span>Zillow, Oct 2, 2026</span>
|
|
148
|
+
<span class="ws-tnum">4 of 10</span>
|
|
149
|
+
<span class="ws-list-detail__pager-acts">
|
|
150
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--solid" aria-label="Previous review"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 10l4-4 4 4"/></svg></button>
|
|
151
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--solid" aria-label="Next review"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg></button>
|
|
152
|
+
</span>
|
|
153
|
+
</div>
|
|
154
|
+
<p class="ws-list-detail__quote">“Knew the market inside out and got us a great price.”</p>
|
|
155
|
+
<div class="ws-plate ws-plate--draft">
|
|
156
|
+
<div class="ws-plate__head">
|
|
157
|
+
<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="M3.5 16.5V9l6.5-5.5L16.5 9v7.5Z"/><path d="M8 16.5v-4h4v4"/></svg>
|
|
158
|
+
<p class="ws-section">Grow drafted a reply in your voice</p>
|
|
159
|
+
<button type="button" class="ws-btn ws-btn--text">Edit</button>
|
|
160
|
+
</div>
|
|
161
|
+
<p class="ws-body">Thank you both! It was a pleasure helping you price it right.</p>
|
|
162
|
+
</div>
|
|
163
|
+
<div class="ws-list-detail__acts">
|
|
164
|
+
<button type="button" class="ws-btn ws-btn--primary ws-btn--lg">Copy reply</button>
|
|
165
|
+
<button type="button" class="ws-btn ws-btn--well ws-btn--lg">Open your Zillow reviews</button>
|
|
166
|
+
<label class="ws-check"><input type="checkbox"><span class="ws-check__box" aria-hidden="true"><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 6.25L4.75 8.5L9.5 3.75"/></svg></span><span class="ws-check__words"><span class="ws-check__label">Mark as replied</span></span></label>
|
|
167
|
+
</div>
|
|
168
|
+
<p class="ws-list-detail__note">Grow never posts for you. Copy the reply and paste it on Zillow.</p>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</section>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The vendor board (Tally, `--list-end` joined: the list a set 362, a top row in the detail, its foot on the rim; the
|
|
177
|
+
picks are `SideList`'s):
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<div class="ws-list-detail ws-list-detail--list-end" style="--ws-list-detail-list: calc(var(--space-9xl) * 1.81);">
|
|
181
|
+
<div class="ws-list-detail__grid">
|
|
182
|
+
<section class="ws-list-detail__list" aria-label="Tools">
|
|
183
|
+
<div class="ws-list-detail__surface">
|
|
184
|
+
<div class="ws-list-detail__scroll">
|
|
185
|
+
<ul class="ws-side-list__picks">
|
|
186
|
+
<li><button type="button" class="ws-side-list__pick" aria-current="true" style="--ws-dot: var(--ws-chart-past-half);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Luxury Presence</span><span class="ws-side-list__sub">Website and IDX, Q1 2027</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$20,400</span><span class="ws-side-list__sub ws-side-list__sub--needs">saves $20,400</span></span></button></li>
|
|
187
|
+
</ul>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</section>
|
|
191
|
+
<section class="ws-list-detail__detail" aria-label="Luxury Presence">
|
|
192
|
+
<div class="ws-list-detail__surface">
|
|
193
|
+
<div class="ws-list-detail__body">
|
|
194
|
+
<div class="ws-list-detail__top">
|
|
195
|
+
<div class="ws-list-detail__words">
|
|
196
|
+
<h3 class="ws-title">Luxury Presence comes off in Q1 2027</h3>
|
|
197
|
+
<p class="ws-body">Fello websites and IDX home search replace it. Estimated from list prices.</p>
|
|
198
|
+
</div>
|
|
199
|
+
<div>
|
|
200
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Kind: Website and IDX"><span class="ws-filter-pick__value">Website and IDX</span><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4.5l3 3 3-3"/></svg></button>
|
|
201
|
+
<label class="ws-check ws-check--sm"><input type="checkbox"><span class="ws-check__box" aria-hidden="true"><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 6.25L4.75 8.5L9.5 3.75"/></svg></span><span class="ws-check__words"><span class="ws-check__label">Cancelled</span></span></label>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
<p class="ws-cluster"><span class="ws-figure ws-figure--pane">$20,400</span><span class="ws-body">a year</span></p>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
<div class="ws-list-detail__foot"><span>Website and IDX, estimate</span><span class="ws-list-detail__foot-needs"><b>Saves $20,400</b> a year</span></div>
|
|
208
|
+
</section>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
An empty list keeps its surface and says so: `<div class="ws-list-detail__surface"><p class="ws-list-detail__empty">No
|
|
214
|
+
reviews need a reply.</p></div>`.
|
|
215
|
+
|
|
216
|
+
## Styles
|
|
217
|
+
|
|
218
|
+
`design-system/components/ListDetail/style.css`, in `bundle.css` and `fello.css`; a picker list also needs `SideList`'s
|
|
219
|
+
styles, a vendor head's pickers `FilterBar`'s. Dark and the navy ground come from the tokens (`--ws-tray`,
|
|
220
|
+
`--color-bg-page`, `--ws-divider`, `--ws-edge`,
|
|
221
|
+
`--ws-surface-sunk`). `.ws-list-detail` is a size container named `ws-list-detail`; with `--fill` its parent must be a
|
|
222
|
+
height-bound flex column.
|