@felloinnovations/brand-kit 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +198 -24
- package/CHANGELOG.md +221 -0
- package/README.md +38 -9
- package/design-system/01-how-claude-decides.md +26 -17
- package/design-system/02-principles.md +11 -6
- package/design-system/03-colour.md +135 -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 +367 -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 +53 -16
- package/design-system/components/Skeleton/preview.html +35 -23
- package/design-system/components/Skeleton/style.css +17 -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 +4086 -744
- package/design-system/tokens.json +1310 -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 +109 -10
- 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 +173 -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 +1287 -62
- package/tokens/tokens.md +587 -61
- package/tokens/tokens.root.css +1293 -62
- package/tokens/tokens.ts +1677 -64
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Palettes
|
|
2
|
+
|
|
3
|
+
One kit, many apps. A palette is a set of values for a short list of the kit's own tokens (the contract), named for
|
|
4
|
+
how it looks. Every app can keep its own slightly different colours while every component follows them, every word
|
|
5
|
+
stays AA, dark works, the focus ring stays visible, and two apps with two palettes can sit on one page (D15).
|
|
6
|
+
|
|
7
|
+
## What a palette is
|
|
8
|
+
|
|
9
|
+
- **Only the contract.** A palette sets the tokens in the table below and nothing else. Everything else (hovers, the
|
|
10
|
+
sunk and press steps, menu lines, tints, fades, the shimmer, the hero glows, the act's hover) derives from them and
|
|
11
|
+
recomputes inside the element that sets the palette. A token outside the contract is an error in the check, with the
|
|
12
|
+
contract token to set instead.
|
|
13
|
+
- **The contract tokens the kit derives recompute too.** A few contract tokens default to another one: the focus ring
|
|
14
|
+
to the heading, the raised ground to the page, the alert words to the alert tone, the positive words to the finished
|
|
15
|
+
tone, the rating and the agent tones to their chart tones. Wherever a palette sits, on `<html>` or a container, each
|
|
16
|
+
of these follows that palette's inputs unless the palette sets it itself.
|
|
17
|
+
- **Named for how it looks**, never for an app: `default`, `cool`, `warm`. A new palette gets a look-based name too
|
|
18
|
+
(`sand`, `slate`), so it can serve the next app without a rename.
|
|
19
|
+
- **Colour only.** A palette never changes layout, size or spacing: the geometry check measures every catalog preview
|
|
20
|
+
in every built-in, light and dark, with no new finding.
|
|
21
|
+
- **Marks keep their tone; words keep AA** (D2). A palette that moves a tone keeps the mark exact and gives its words
|
|
22
|
+
an AA step, checked in light, night and the navy ground.
|
|
23
|
+
|
|
24
|
+
## The built-ins
|
|
25
|
+
|
|
26
|
+
| Palette | How it looks | Set |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| `default` | The kit's cream: a blue-grey sky at the top of the frame, the stage washed warm at its foot | nothing |
|
|
29
|
+
| `cool` | The same sky under a glass stage that stays cool to its foot, finer row lines, links in the heading navy | `data-palette="cool"` |
|
|
30
|
+
| `warm` | The plain warm cream with no sky over it, the stage washed from the cream to #FEF9F6 | `data-palette="warm"` |
|
|
31
|
+
|
|
32
|
+
Each built-in passes the palette check; the run is in `tokens/tokens.md` (Palettes, "The built-ins, checked").
|
|
33
|
+
|
|
34
|
+
No palette holds the first product's shipped tally navy (#093555). It differed from the default in that one tone, and
|
|
35
|
+
Seth's tally #2C4870 wins (D1), so the product adopts the default's tally.
|
|
36
|
+
|
|
37
|
+
## The contract
|
|
38
|
+
|
|
39
|
+
Generated from `tokens/design-tokens.json` ("palette") by `scripts/generate-tokens.mjs`, so it cannot drift from the
|
|
40
|
+
code. Each cell is the light value, then the dark (night) one; `=` means the default's value. The navy ground's values
|
|
41
|
+
are in `tokens/tokens.md` and the JS export.
|
|
42
|
+
|
|
43
|
+
<!-- contract -->
|
|
44
|
+
| Token | Group | Meaning | default | cool | warm |
|
|
45
|
+
| --- | --- | --- | --- | --- | --- |
|
|
46
|
+
| `--color-bg-page` | ground | The page and every card's surface: the cream most words sit on. | `#fefbf9` / `#0f1922` | = | = |
|
|
47
|
+
| `--ws-frame-top` | ground | The top of the page wash behind a glass stage, fading into the page by 640 px; in dark the frame is flat and paints it (the shell, unless a palette says). | `#ebf0f5` / `#0a1118` | = | `#fefbf9` / `#0a1118` |
|
|
48
|
+
| `--ws-stage-foot` | ground | The foot of a washed stage, whose gradient starts at the page (light only). | `#fef9f6` / `#0f1922` | `#fefbf9` / `#0f1922` | = |
|
|
49
|
+
| `--color-surface` | ground | What is white: a marketing card, a well row under the pointer, a chat bubble, the glass of the stage. | `#ffffff` / `#131e28` | = | = |
|
|
50
|
+
| `--ws-raised` | ground | What floats off the page: a menu, a popover, a tooltip, a dialog, a panel, a toast. | `#fefbf9` / `#16222d` | = | = |
|
|
51
|
+
| `--ws-tray` | ground | The rim and foot of a rimmed card, and the well behind rows. | `#ededed` / `#1e2b38` | = | = |
|
|
52
|
+
| `--ws-edge-card` | edge | A card's and an outlined control's 0.5 px edge. | `#d3d3d3` / `#273544` | = | = |
|
|
53
|
+
| `--ws-edge` | edge | A divider between rows; a quiet line. | `#e8e8e8` / `#1e2a36` | `#e2e2e2` / `#1e2a36` | = |
|
|
54
|
+
| `--ws-edge-hover` | edge | An outlined control's edge under the pointer. | `#aaa49d` / `#8494a5` | = | = |
|
|
55
|
+
| `--ws-well-hover` | edge | A rimmed card's rim under the pointer. | `#e4e2df` / `#273544` | = | = |
|
|
56
|
+
| `--color-text-heading` | word | Titles, names, figures, navy marks, and the act fill (the primary button, a thumb, a checked box). | `#093555` / `#e8edf3` | = | = |
|
|
57
|
+
| `--color-text-body` | word | Body words: a card's line, a row. | `#545454` / `#b0bbc7` | = | = |
|
|
58
|
+
| `--color-text-muted` | word | Meta, labels, captions. | `#666666` / `#8494a5` | = | = |
|
|
59
|
+
| `--color-text-interactive` | word | Links and words that go somewhere, a falling number, "working". | `#495883` / `#93a6dc` | `#093555` / `#e8edf3` | = |
|
|
60
|
+
| `--ws-on-act` | act | Words and marks on the act fill. | `#ffffff` / `#0f1922` | = | = |
|
|
61
|
+
| `--ws-act-hover` | act | The act fill under the pointer. | `#0f4a73` / `#d7dce2` | = | = |
|
|
62
|
+
| `--ws-word-needs` | accent | Needs you, in words: the current page, something to fix (the accent's AA step). | `#a84b3c` / `#ff8b78` | = | = |
|
|
63
|
+
| `--ws-focus-color` | focus | The 2 px focus ring, outside or inset. | `#093555` / `#e8edf3` | = | = |
|
|
64
|
+
| `--ws-word-positive` | status | Good news in words. | `#09717a` / `#4fc7be` | = | = |
|
|
65
|
+
| `--ws-word-alert` | status | Something wrong now, in words. | `#b1042f` / `#ff5470` | = | = |
|
|
66
|
+
| `--ws-chart-finished` | chart | Tone 1: done, passed, positive marks. | `#098486` / `#23a8a3` | = | = |
|
|
67
|
+
| `--ws-chart-past-half` | chart | Tone 2: past halfway marks. | `#6d4fc2` / `#9a84ee` | = | = |
|
|
68
|
+
| `--ws-chart-under-half` | chart | Tone 3: under halfway marks and needs-you dots. Drawn with its word: its 3:1 is reported. | `#ff725c` / `#ff725c` | = | = |
|
|
69
|
+
| `--ws-chart-navy-light` | chart | Tone 4: a second navy, for a series beside the heading navy. | `#2e6088` / `#6e9cc4` | = | = |
|
|
70
|
+
| `--ws-chart-needs-work` | chart | Tone 5: needs work marks. Drawn with its word: its 3:1 is reported. | `#f370a4` / `#f370a4` | = | = |
|
|
71
|
+
| `--ws-chart-alert` | chart | Tone 6: alert marks. | `#b1042f` / `#ff5470` | = | = |
|
|
72
|
+
| `--ws-rating-strong` | rating | Strong: its marks. | `#098486` / `#3bb8b2` | = | = |
|
|
73
|
+
| `--ws-rating-middle` | rating | Getting there (the middle band): its marks. | `#495883` / `#93a6dc` | `#495883` / `#e8edf3` | = |
|
|
74
|
+
| `--ws-rating-needs-work` | rating | Needs work: its marks. | `#f370a4` / `#f370a4` | = | = |
|
|
75
|
+
| `--ws-agent-coach` | agent | The coaching assistant's mark. | `#098486` / `#3bb8b2` | = | = |
|
|
76
|
+
| `--ws-agent-growth` | agent | The growth assistant's mark. | `#6d4fc2` / `#9a84ee` | = | = |
|
|
77
|
+
| `--ws-agent-recruit` | agent | The recruiting assistant's mark. | `#ff725c` / `#ff725c` | = | = |
|
|
78
|
+
| `--ws-agent-tally` | agent | The money assistant's mark, and a softer act (a figure tab's current cell, a seat meter, a hatch). | `#2c4870` / `#e8edf3` | = | = |
|
|
79
|
+
|
|
80
|
+
- **ground**: What everything sits on. Every word is checked AA on each.
|
|
81
|
+
- **edge**: Hairlines, and the edges under the pointer.
|
|
82
|
+
- **word**: Words, each AA on every ground it can sit on.
|
|
83
|
+
- **act**: The one primary act. Its fill is the heading colour.
|
|
84
|
+
- **accent**: Needs you: the current page, something to fix.
|
|
85
|
+
- **focus**: The keyboard ring, 3:1 on every ground.
|
|
86
|
+
- **status**: Good and bad news, in words.
|
|
87
|
+
- **chart**: The six data tones charts draw with: told apart from each other (CIEDE2000 10 or more) and 3:1 on the chart ground. A tone marked withWords (salmon, pink) is always drawn beside its word, so its ratio is reported, not required: Seth draws them at 2.6:1 and marks keep his exact tone (D2).
|
|
88
|
+
- **rating**: One rating scale on every screen (D10): its marks. Their words are the status and word tokens.
|
|
89
|
+
- **agent**: Each assistant keeps one tone and nothing else names it (03-colour).
|
|
90
|
+
<!-- /contract -->
|
|
91
|
+
|
|
92
|
+
## Apply one
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<html data-palette="cool"> <!-- the whole page -->
|
|
96
|
+
<div class="fello" data-palette="warm"> <!-- one container -->
|
|
97
|
+
<div class="fello" data-palette="warm" data-theme="dark"> <!-- one container, dark -->
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- **On `<html>`**: the whole page. No attribute is the default palette.
|
|
101
|
+
- **On a container**: everything inside it follows; the rest of the page keeps its own. Any element works, with
|
|
102
|
+
`fello.css` or the scoped build.
|
|
103
|
+
- **Nested**: the nearest wins. A palette inside another, a theme inside a palette, a palette inside a theme, light
|
|
104
|
+
inside dark and dark inside light all resolve as written, in both builds. An element that sets a palette or a theme
|
|
105
|
+
also sets its own words to the body colour, so plain text inside it never keeps the page's grey. A browser without
|
|
106
|
+
`@scope` keeps the theme on the element that carries it (the common `<html data-theme>`) and loses only the nesting.
|
|
107
|
+
- **Load order never matters**: the kit's own contract values sit at no specificity, so a palette wins wherever its
|
|
108
|
+
file loads, before the kit or after it.
|
|
109
|
+
- **The navy ground** (`data-theme="dark" data-ground="navy"`) is a brand ground: where it sets a token it wins over
|
|
110
|
+
the palette.
|
|
111
|
+
|
|
112
|
+
### Many apps in one bundle
|
|
113
|
+
|
|
114
|
+
When a host builds many apps into one bundle, each app takes the scoped build (one copy of the CSS serves them all) and
|
|
115
|
+
sets its palette, and its theme if it has one, on its own `.fello` root:
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<div class="fello" data-palette="cool">...one app...</div>
|
|
119
|
+
<div class="fello" data-palette="warm" data-theme="dark">...another app, dark...</div>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Nothing leaks between them or into the host. A portal (a menu, a tooltip, a dialog rendered outside the app's root)
|
|
123
|
+
carries the same `class="fello"`, `data-palette` and `data-theme` as the app's root, or it draws in the default.
|
|
124
|
+
|
|
125
|
+
## Light and dark
|
|
126
|
+
|
|
127
|
+
Dark is the same opt-in as everywhere (Colour, "Dark theme"): `data-theme="dark"`, `"system"` on a dark OS, and the
|
|
128
|
+
navy ground beside either. A palette states a dark value only where the kit's dark does not suit it. A dark value it
|
|
129
|
+
leaves out falls back to the kit's own dark, derived from the dark inputs (so a dark page the palette does set still
|
|
130
|
+
moves it), never to the palette's light value. The check reports each one, with the value dark paints instead. This
|
|
131
|
+
holds for a built-in and for an app's own palette once it ships as `--emit` writes it (Make your own).
|
|
132
|
+
|
|
133
|
+
The dark tints and fades follow the dark page: a chip tint, a chart fade or a done tint in dark is its tone over the
|
|
134
|
+
dark page (within CIEDE2000 3.5 of the night literals they replaced), so a palette that moves the dark page moves them.
|
|
135
|
+
|
|
136
|
+
## Make your own
|
|
137
|
+
|
|
138
|
+
1. **Try the built-ins first.** Most apps fit one; a new palette is for a look none of them has. Name it for that look.
|
|
139
|
+
2. **Write the checked form**: one file that sets only contract tokens, the light values on `[data-palette="name"]`
|
|
140
|
+
and the dark ones on `[data-palette="name"][data-theme="dark"]`. In dark, set only what the kit's dark does not
|
|
141
|
+
already give you. `--emit` writes the `system` rules and the navy ground for you:
|
|
142
|
+
|
|
143
|
+
```css
|
|
144
|
+
/* sand: a warmer sky over the cream, softer row lines, a slate link. */
|
|
145
|
+
[data-palette="sand"] {
|
|
146
|
+
--ws-frame-top: #f5eee6;
|
|
147
|
+
--ws-edge: #e6e0d8;
|
|
148
|
+
--color-text-interactive: #3d5a80;
|
|
149
|
+
}
|
|
150
|
+
[data-palette="sand"][data-theme="dark"] {
|
|
151
|
+
--color-text-interactive: #9fb4d8;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
3. **Check it**, and fix every error:
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
node node_modules/@felloinnovations/brand-kit/scripts/check-palette.mjs src/sand.css
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
It applies the palette over the kit as it paints once shipped and resolves every token in light, night and the navy
|
|
162
|
+
ground, then fails (exit 1) on a token outside the contract (naming the nearest contract token, or the one a
|
|
163
|
+
derived token comes from), a word under 4.5:1 on any ground it can sit on or on its own tint, a focus ring or an act
|
|
164
|
+
fill under 3:1, two chart tones closer than CIEDE2000 10, or a chart tone under 3:1 on the chart ground (salmon and
|
|
165
|
+
pink are drawn beside their words, so theirs is reported). It reports, without failing, each dark value left out
|
|
166
|
+
and what dark paints instead, and, on a file you wrote by hand, that it is not in the shipped form. The `sand` file
|
|
167
|
+
above passes:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
== src/sand.css
|
|
171
|
+
sand: passes (sets 3: --ws-frame-top, --ws-edge, --color-text-interactive)
|
|
172
|
+
report: dark: no --ws-frame-top, so it takes the kit's dark --ws-frame-top (#0a1118), derived from the dark inputs
|
|
173
|
+
report: dark: no --ws-edge, so it takes the kit's dark --ws-edge (#1e2a36), derived from the dark inputs
|
|
174
|
+
report: not in the shipped form: as written, its light values also paint in dark wherever the theme sits on another element than the palette; ship the output of `check-palette --emit`
|
|
175
|
+
1 palette: 0 errors, 3 reports. Checked in light, night and navy: ...
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
And a palette that sets a derived token and a pale grey fails, saying why:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
sand: 3 errors (sets 2: --ws-surface-sunk, --color-text-muted)
|
|
182
|
+
error contract: --ws-surface-sunk is not in the palette contract (a derived token); it derives from --color-bg-page: set that instead
|
|
183
|
+
error word: light: --color-text-muted #8a8a8a is under 4.5:1 on 18 grounds, lowest 2.78:1 on the press (--ws-surface-press #e9e6e4)
|
|
184
|
+
error word: light: --color-text-placeholder #909090 on --ws-field #ffffff is 3.19:1, under 4.5
|
|
185
|
+
report: dark: no --color-text-muted, so it takes the kit's dark --color-text-muted (#8494a5), derived from the dark inputs
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
4. **Ship what `--emit` writes**, never the file you wrote:
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
node node_modules/@felloinnovations/brand-kit/scripts/check-palette.mjs --emit src/sand.css > src/sand.shipped.css
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
It runs the same check (the report goes to stderr) and writes the palette in the built-ins' own form, with every
|
|
195
|
+
dark value left out filled with the kit's derived dark. Import `sand.shipped.css`: it nests anywhere (on `<html>`
|
|
196
|
+
or any container, either way round with the theme, light or dark, in `fello.css` and the scoped build, with the
|
|
197
|
+
navy ground over it), and load order no longer matters. As written by hand, a palette's light values also paint in
|
|
198
|
+
dark wherever the theme sits on another element than the palette (the theme on `<html>`, the palette on a
|
|
199
|
+
container): that is the "not in the shipped form" report. On an error `--emit` writes nothing and exits 1, so the
|
|
200
|
+
redirect leaves an empty file: fix the source and run it again. Run it again whenever the source changes; never
|
|
201
|
+
edit the shipped file by hand.
|
|
202
|
+
|
|
203
|
+
## What a palette does not move
|
|
204
|
+
|
|
205
|
+
A few colours keep the brand under any palette. The checks rule them by name, so nothing else can hide among them.
|
|
206
|
+
|
|
207
|
+
- **The navy messages in dark**: `Toast`, the note tip (`Tooltip`'s navy note) and the `Footer` keep the brand navy
|
|
208
|
+
with white words in dark (`--ws-inverse`, `--ws-on-inverse`; D12). In light they are the act fill and its words, so
|
|
209
|
+
a palette moves them there.
|
|
210
|
+
- **The marketing brand marks**: `KitButton`'s salmon act and its navy act, and the `Cover` logo.
|
|
211
|
+
- **Fields on the navy ground**: white with navy words, a brand pair (a `Combobox` chip in one).
|
|
212
|
+
- **The chart fades, tints and empty cell on `:root`**: declared there as the literal they paint in light (charts draw
|
|
213
|
+
them as SVG gradient stops, which cannot be told to blend in sRGB), and derived on every element that sets a palette
|
|
214
|
+
or a theme. So a bare `:root { --ws-chart-under-half: X }` override with no `data-palette` no longer moves them. Use
|
|
215
|
+
a palette (`data-palette`, on `<html>` or a container), never a `:root` override.
|
|
216
|
+
- **The 0.4 channels** `--ws-ink-rgb` and `--ws-shade-rgb`: kept for a `rgba(var(--ws-ink-rgb), a)` written before
|
|
217
|
+
0.5.0, they hold the default's values and do not follow a palette. Write
|
|
218
|
+
`color-mix(in srgb, var(--ws-ink) 5%, transparent)`, and `--ws-shade` for a drop.
|
|
219
|
+
|
|
220
|
+
## How the kit proves it
|
|
221
|
+
|
|
222
|
+
In the kit's repo (`scripts/` other than `check-palette.mjs` and `token-model.mjs` is not in the package):
|
|
223
|
+
|
|
224
|
+
- **No leftover**: `node scripts/check-palette.mjs` with no file also reads every component's styles and fails on a
|
|
225
|
+
colour a component reads that no contract token moves, in light or dark, with the brand colours above ruled. Its
|
|
226
|
+
self-test (`--selftest`) plants one.
|
|
227
|
+
- **The poison test** (`scripts/palette-poison.mjs`, run in CI by `check-scope`): each of the 33 contract tokens in
|
|
228
|
+
turn is set to a wild colour, on `<html>` and then on a container around every catalog preview, light and dark. It
|
|
229
|
+
fails on a colour that does not follow the token on the container (stale), a colour outside the container that moves
|
|
230
|
+
(a leak), or a colour no token moves (a constant). Its self-test plants one of each.
|
|
231
|
+
- **Nesting**: `check-scope` also sets an app's palette shipped by `--emit` every way (on `<html>` and a container,
|
|
232
|
+
inside a theme and around one, the navy ground over it) in both builds, loaded before the kit and after it.
|
|
233
|
+
|
|
234
|
+
## In JavaScript
|
|
235
|
+
|
|
236
|
+
For an app that injects its CSS or draws on a canvas, every built-in comes resolved: each contract token as the
|
|
237
|
+
literal it paints, in light, night and the navy ground. The contract rides along.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { palettes, contract, type PaletteName } from '@felloinnovations/brand-kit/palettes';
|
|
241
|
+
|
|
242
|
+
palettes.cool.light['--color-text-interactive']; // '#093555'
|
|
243
|
+
palettes.warm.dark['--color-bg-page']; // '#0f1922'
|
|
244
|
+
palettes.cool.navy['--ws-agent-tally']; // '#ffffff', the navy ground's value
|
|
245
|
+
contract.map((t) => t.name); // the 33 tokens a palette may set, each with its group and meaning
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The same names come from the package root. The CSS for every built-in is already in `fello.css`, `fello-core.css`,
|
|
249
|
+
`tokens.css` and the scoped build (`felloScopedCss`), so an app sets the attribute and needs nothing else.
|
|
250
|
+
|
|
251
|
+
## Check a screen in a palette
|
|
252
|
+
|
|
253
|
+
In the kit's repo, the geometry check takes the palette like the theme, and names each shot after both
|
|
254
|
+
(`<Name>-<width>-cool-dark.png`):
|
|
255
|
+
|
|
256
|
+
```sh
|
|
257
|
+
node scripts/check-geometry.mjs --widths 390,1440 --palette cool --theme dark
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The gallery's Components page has a theme and a palette switch (default, cool, warm): every preview draws in the pair
|
|
261
|
+
chosen there, and the choice is remembered on that device. Look at the screen in its palette, light and dark, before
|
|
262
|
+
calling it done (Checklist).
|
|
263
|
+
|
|
264
|
+
## Who uses which (an example, 4 Nov 2026)
|
|
265
|
+
|
|
266
|
+
How the first apps map. It is an example, not a rule: an app picks a palette by how it should look, and an app's name
|
|
267
|
+
never goes into a token, a class, an attribute, a file name or an export.
|
|
268
|
+
|
|
269
|
+
| App | Palette | Theme |
|
|
270
|
+
| --- | --- | --- |
|
|
271
|
+
| North | `cool` | light |
|
|
272
|
+
| Fia (Seth's frames) | `warm` | light |
|
|
273
|
+
| Ignite | `default`: it shipped its tally in the brand navy, Seth's #2C4870 wins (D1) and it adopts it | light; the navy ground on brand and event pages |
|
|
274
|
+
| Revenue OS | `default` | light |
|
|
275
|
+
| Campfire's apps | each its own, on its own `.fello` root | each its own |
|
package/design-system/README.md
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
Fello's design system for everything the company builds: product apps, dashboards and consoles, sign-in and onboarding,
|
|
2
2
|
public web pages, emails, decks and quick mockups. It is a decision system as much as a style sheet: how to choose the
|
|
3
3
|
face, screen and component for a job, how it looks, and how to check it. Lokesh wrote it from the first product built on
|
|
4
|
-
the brand kit; the team broadened it with the other products and the website
|
|
5
|
-
and
|
|
4
|
+
the brand kit; the team broadened it with the other products and the website, and 0.5.0 rebuilt its layout, surfaces,
|
|
5
|
+
type and motion on Seth's (the designer's) frames and his North app (history in Decisions). Names, sample data and assets
|
|
6
|
+
are generic. Every token is in Tokens.
|
|
6
7
|
|
|
7
8
|
## Start here
|
|
8
9
|
|
|
9
10
|
- **In Claude**, say "use the Fello brand kit". For an artifact, a mockup, a one-off deck or an internal page, take the
|
|
10
11
|
quick path at the top of How Claude decides; anything that ships follows its full steps.
|
|
11
|
-
- **Two faces, never both on one surface**: the *product* face (after sign-in, or anything used to do work: cream
|
|
12
|
-
one solid navy button, 14 px body) and the *marketing* face (before sign-in, or anything that sells: white `KitCard`s,
|
|
12
|
+
- **Two faces, never both on one surface**: the *product* face (after sign-in, or anything used to do work: rimmed cream
|
|
13
|
+
cards, one solid navy button, 14 px body) and the *marketing* face (before sign-in, or anything that sells: white `KitCard`s,
|
|
13
14
|
the salmon gradient `KitButton`, 16 px body). How Claude decides, step 0, maps every kind of job to its face.
|
|
14
|
-
- **Wiring**:
|
|
15
|
-
links the pinned
|
|
16
|
-
|
|
15
|
+
- **Wiring**: `fello.css` gives a page every token and component style. An artifact inlines `fello-core.css` and the
|
|
16
|
+
blocks of the components it uses (`Starter`); a page links the pinned `fello.css`; an app installs the package (in
|
|
17
|
+
Tailwind v4, the Instrument Sans `@import` before `@import "tailwindcss"`); an app living inside someone else's bundle,
|
|
18
|
+
or any Tailwind v3 app, takes the scoped build under a `.fello` root and links the font itself (the table is in How
|
|
19
|
+
Claude decides, step 0). The HubSpot site theme is out of scope.
|
|
20
|
+
- **Light by default, dark when asked**: a page that sets nothing is light; `data-theme="dark"` or `"system"` on `<html>`
|
|
21
|
+
turns on the dark theme (Colour).
|
|
22
|
+
- **One kit, many apps**: an app that wants its own slightly different colours picks a palette (`data-palette="cool"`
|
|
23
|
+
or `"warm"`) or writes one from the contract, runs `check-palette` and ships what its `--emit` writes (Palettes).
|
|
24
|
+
Never retune tokens on `:root`.
|
|
25
|
+
- **Measured, not eyeballed**: the geometry check (`node scripts/check-geometry.mjs`) and the senior QA list in Checklist
|
|
26
|
+
are how "done" is proven.
|
|
17
27
|
|
|
18
28
|
## Fello at a glance
|
|
19
29
|
|
|
20
|
-
Warm, calm, precise: Instrument Sans on a cream page, navy headings, body grey, flat surfaces
|
|
21
|
-
|
|
30
|
+
Warm, calm, precise: Instrument Sans on a cream page, navy headings, body grey, flat cream surfaces in a fine grey rim,
|
|
31
|
+
one content edge, numbers in their columns, colour spent on data rather than decoration, motion that grows things from
|
|
32
|
+
where they were, and no AI colours outside the Felix orb. The two faces are in How Claude decides.
|
|
22
33
|
|
|
23
34
|
## Iconography
|
|
24
35
|
|
|
25
36
|
In a product: Phosphor through one icon component in the project; a **line** icon for a control or an act, a **filled**
|
|
26
|
-
one for a mark that names a thing or a state
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
one for a mark that names a thing or a state. Seth's line icons are a 1.5 px stroke with round caps and joins. Sizes:
|
|
38
|
+
16 in a control or a row, with or without words; 12 inside small words (a meta line); 20 for a header's back act; larger
|
|
39
|
+
only in a disc or a hero. An inline icon in running text is `ws-icon`, never unsized. Icons take the words' colour;
|
|
40
|
+
a chevron is navy. One icon per meaning: `x` closes a dialog, a drawer or a panel, or removes one item; chevrons move between items or open a row; three dots open a menu. On a public page: thin
|
|
41
|
+
line art only (about 1.5 px stroke, round caps, one colour), never filled or duotone. Never emoji as icons. Charts and drawings are not icons.
|
|
30
42
|
|
|
31
43
|
## The chapters
|
|
32
44
|
|
|
@@ -34,14 +46,14 @@ caps, one colour), never filled or duotone. Never emoji as icons. Charts and dra
|
|
|
34
46
|
| --- | --- |
|
|
35
47
|
| How Claude decides | always first: the quick path, the faces, the wiring, the steps, the three levels of freedom |
|
|
36
48
|
| Principles | a tie between two good options; the anti-patterns |
|
|
37
|
-
| Colour | a colour, a state's tone, a contrast pair |
|
|
49
|
+
| Colour | a colour, a state's or a rating's tone, a contrast pair, the dark theme |
|
|
38
50
|
| Type | the size and weight of any words |
|
|
39
|
-
| Space and layout | gaps,
|
|
51
|
+
| Space and layout | gaps, edges, optical alignment, rimmed cards, dividers, number columns, corners, elevation, responsive |
|
|
40
52
|
| Sizing profiles | compact, comfortable, touch or public web |
|
|
41
53
|
| Scrolling | who scrolls and what stays |
|
|
42
54
|
| Choosing components | a need, mapped to a catalog component |
|
|
43
55
|
| Charts | any chart or figure |
|
|
44
|
-
| Patterns | forms, editing, feedback, states, search, selection, permissions |
|
|
56
|
+
| Patterns | forms, editing, feedback, interaction states, loading and empty, search, selection, permissions |
|
|
45
57
|
| Page recipes | the composition to start from |
|
|
46
58
|
| Content | any words a person reads |
|
|
47
59
|
| Motion | anything that moves |
|
|
@@ -49,8 +61,9 @@ caps, one colour), never filled or duotone. Never emoji as icons. Charts and dra
|
|
|
49
61
|
| AI experiences | an agent, its chat and its cards |
|
|
50
62
|
| Creativity | where expression is allowed, and how much |
|
|
51
63
|
| Decisions | why a rule is so, and what is open |
|
|
52
|
-
| Checklist | before anything is called done |
|
|
64
|
+
| Checklist | before anything is called done: the geometry check and the senior QA list |
|
|
53
65
|
| Public pages | the marketing face: landing, campaign, event and demo pages |
|
|
66
|
+
| Palettes | an app's own colours: the contract, applying a palette to a page or a container, many apps in one bundle, making and checking your own |
|
|
54
67
|
|
|
55
68
|
Each component's README says when to use it, its states and rules; copy its preview markup and `fello.css` styles it.
|
|
56
69
|
The kit's marketing pieces say so in their first line and never go in a product screen.
|
|
@@ -1,41 +1,127 @@
|
|
|
1
1
|
A card's ranked list of next acts: who or what, the reason in words, and the one act at the right of each row.
|
|
2
|
+
`--brief` is North's "what changed" list on a page's head: one quiet line each, its acts appearing on the line.
|
|
2
3
|
|
|
3
4
|
## Use it when
|
|
4
5
|
|
|
5
6
|
- A dashboard or report says what to do next: "who needs a nudge", "deals to call back", "fixes to make" (Page recipes,
|
|
6
7
|
a dashboard or console).
|
|
7
8
|
- Each row is one thing with its own act, ordered by what matters most first.
|
|
9
|
+
- `--brief`: a page's head says what changed since the person last looked, one line per change, each opening in chat.
|
|
8
10
|
|
|
9
11
|
## Not for
|
|
10
12
|
|
|
11
13
|
- Records to compare across many columns: use `Table`.
|
|
12
14
|
- Suggested questions or prompts to tap into a chat: use `Well`.
|
|
13
15
|
- A ranking by a number with bars: use `Leaderboard` (it can sit beside this list).
|
|
16
|
+
- Fixes to tick off and open in place: use `CheckRow`'s fix rows.
|
|
14
17
|
|
|
15
18
|
## Anatomy
|
|
16
19
|
|
|
17
20
|
- Sits in a `Card` under its head (`.ws-head`: the title that answers, "Three agents need a nudge", and one line).
|
|
18
|
-
- `ul.ws-action-list`, one `li.ws-action-list__row` per thing:
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
21
|
+
- `ul.ws-action-list`, one `li.ws-action-list__row` per thing: 12 above and below, the card's 20 px edge at both sides
|
|
22
|
+
(the head uses the same edge), parts 16 apart (Seth's fix row), a 0.5 px line between rows (`--ws-divider`):
|
|
23
|
+
- optional lead: an `Avatar` (`ws-avatar ws-avatar--plain ws-avatar--sm`, 28) or a mark;
|
|
24
|
+
- `.ws-action-list__text`: `__title` (Seth's row name, 15 / 20 medium navy, an optional `Chip` 8 beside it) and,
|
|
25
|
+
4 under, `__reason` (why, in words, 14 / 20 body grey);
|
|
26
|
+
- `.ws-action-list__act`: one `Button`, secondary, small, a verb and its object ("Text Theo"); it never shrinks.
|
|
27
|
+
- every part sits on the name's first line, however many lines the reason runs to: that line is held at 24 (a
|
|
28
|
+
chip's height), and the lead and the act centre on it (a lead other than the 28 avatar sets
|
|
29
|
+
`--ws-action-list-lead` to its height). Under 24rem the act drops under the words, on their edge.
|
|
24
30
|
- A bulk act for every row ("Nudge all 3") goes in the card's band, never as a second button on each row.
|
|
31
|
+
- `--brief` (North, style1.css 2100 to 2116): lines 6 apart (`--space-xxs-plus`), at least 40 tall, 10 px corners, a
|
|
32
|
+
glass ground (the surface at 55 %) with a 0.5 px navy edge at 8 %. Each line is one button (`__main`: 16 in, 12
|
|
33
|
+
between parts) holding the topic (`__lead`, 14 semibold navy), the gist (`__gist`, 14 body grey, one line, an ellipsis
|
|
34
|
+
and a `title`) and the "Open" act (`__go`, 13 / 18 semibold in salmon's AA word, `--ws-word-needs`, a 16 px arrow),
|
|
35
|
+
then a 24 px dismiss (`__dismiss`, an `IconButton --xs`, 40 on touch). On touch the line keeps 8 clear after "Open",
|
|
36
|
+
so the dismiss's 40 px hit area never covers the arrow.
|
|
25
37
|
|
|
26
38
|
## States
|
|
27
39
|
|
|
28
|
-
- Loading
|
|
29
|
-
|
|
30
|
-
-
|
|
40
|
+
- **Loading**: ghost lines where the name and the reason go (`__ghost ws-shimmer`), still under reduced motion.
|
|
41
|
+
- **Empty**: say the good news in the card's line ("Nobody needs a nudge this week") and drop the list.
|
|
42
|
+
- **Pending**: the pressed row's button shows its working state.
|
|
43
|
+
- **Long names and reasons**: they wrap; the act stays at the right and never shrinks.
|
|
44
|
+
- **Narrow** (the list under 24rem, a phone's card): the act drops under the words, on their edge, so a reason never
|
|
45
|
+
breaks a word a line; a brief line's "Open" keeps only its arrow (its words stay in the line's name), so the gist keeps
|
|
46
|
+
the room.
|
|
47
|
+
- **`--brief`, hover**: the line goes to the surface and its edge a shade darker, a colour change only: it never lifts,
|
|
48
|
+
scales or casts a shade (D7; North's one lifting row is not taken); "Open" grows out of nothing (0 to 120 wide over
|
|
49
|
+
320 ms on `--ws-ease-grow`, its arrow stepping 2 px forward) and the dismiss shows. Under reduced motion "Open" appears
|
|
50
|
+
at once and the arrow stays put.
|
|
51
|
+
- **`--brief`, focus**: keyboard focus on the line shows "Open" and the dismiss too, its ring drawn inside the line.
|
|
52
|
+
- **`--brief`, touch**: "Open" and the dismiss are always there (no hover to wait for).
|
|
31
53
|
|
|
32
|
-
##
|
|
54
|
+
## Behaviour
|
|
55
|
+
|
|
56
|
+
- Keyboard: a real list; each act is a real button. In `--brief` the line is one button (it opens the change in chat)
|
|
57
|
+
and the dismiss a second; both reachable by Tab.
|
|
58
|
+
- Pointer: a row of the card list is not itself a target; its act is. A brief line is.
|
|
59
|
+
- Motion: the hover colours over 200 ms (`--ws-duration-hover`); "Open" grows over 320 ms (`--ws-duration-settle`).
|
|
60
|
+
|
|
61
|
+
## Content
|
|
33
62
|
|
|
34
63
|
- The reason is a sentence with real figures and their period ("No calls since Tuesday, down from 30 last week"), never
|
|
35
64
|
a status word alone. Colour is never the only signal: a chip carries words.
|
|
65
|
+
- A brief line is a topic and one plain sentence ("Pipeline: three deals moved to offer, $1.2M in all").
|
|
66
|
+
- No em dashes.
|
|
67
|
+
|
|
68
|
+
## Props
|
|
69
|
+
|
|
70
|
+
| Name | Type | Meaning |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `items` | `{ id, lead?, title, chip?, reason, act: { label, onClick } }[]` | The rows, most important first |
|
|
73
|
+
| `variant` | `'card' \| 'brief'` | The card list or the brief lines |
|
|
74
|
+
| `onOpen`, `onDismiss` | functions | A brief line's two acts |
|
|
75
|
+
|
|
76
|
+
## Rules
|
|
77
|
+
|
|
36
78
|
- One act per row, secondary. The page's one primary is elsewhere.
|
|
79
|
+
- Rows sit on the card's 20 px edge, like its head: one content edge per card.
|
|
80
|
+
- A brief line's acts are never hover-only: focus shows them, touch always has them.
|
|
37
81
|
|
|
38
82
|
## Accessibility
|
|
39
83
|
|
|
40
84
|
- A real list (`ul`/`li`). Each act's words name the person or thing, so a screen reader hears "Text Theo", not "Text".
|
|
85
|
+
- A dismiss's label names the line ("Dismiss: Pipeline").
|
|
41
86
|
- On touch the buttons grow to 40 px; the row grows with them.
|
|
87
|
+
|
|
88
|
+
## Source
|
|
89
|
+
|
|
90
|
+
- **Derived from**: the card's 20 px edge, Seth's fix row (308:2466: row names 15 / 20, parts 16 apart, 12 above and
|
|
91
|
+
below), the 0.5 px divider (D5), North's brief rows (style1.css 2100 to 2116), and `Button`.
|
|
92
|
+
- **Precedent**: the first product's "who needs a nudge" card; `--brief` added in 0.5.0 (4 Nov 2026).
|
|
93
|
+
|
|
94
|
+
## Markup
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<section class="ws-card ws-card--compound">
|
|
98
|
+
<header class="ws-head"><div><h3 class="ws-title">Three agents need a nudge</h3><p class="ws-body ws-card__line">Each made under half of the 50-call goal this week.</p></div></header>
|
|
99
|
+
<ul class="ws-action-list">
|
|
100
|
+
<li class="ws-action-list__row">
|
|
101
|
+
<span class="ws-avatar ws-avatar--plain ws-avatar--sm" aria-hidden="true">TL</span>
|
|
102
|
+
<div class="ws-action-list__text">
|
|
103
|
+
<p class="ws-action-list__title">Theo Lane <span class="ws-chip">9 calls</span></p>
|
|
104
|
+
<p class="ws-action-list__reason">No calls since Tuesday, down from 30 last week.</p>
|
|
105
|
+
</div>
|
|
106
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--sm ws-action-list__act">Text Theo</button>
|
|
107
|
+
</li>
|
|
108
|
+
</ul>
|
|
109
|
+
</section>
|
|
110
|
+
|
|
111
|
+
<ul class="ws-action-list ws-action-list--brief" aria-label="What changed since yesterday">
|
|
112
|
+
<li class="ws-action-list__brief">
|
|
113
|
+
<button type="button" class="ws-action-list__main">
|
|
114
|
+
<span class="ws-action-list__lead">Calls</span>
|
|
115
|
+
<span class="ws-action-list__gist" title="The team made 212 calls, 40 more than last week">The team made 212 calls, 40 more than last week</span>
|
|
116
|
+
<span class="ws-action-list__go">Open in chat <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="M3 8h10M9 4l4 4-4 4"/></svg></span>
|
|
117
|
+
</button>
|
|
118
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs ws-action-list__dismiss" aria-label="Dismiss: Calls"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button>
|
|
119
|
+
</li>
|
|
120
|
+
</ul>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Styles
|
|
124
|
+
|
|
125
|
+
`design-system/components/ActionList/style.css`, in `bundle.css` and `fello.css`. Dark and the navy ground come from
|
|
126
|
+
the tokens (`--color-surface`, `--ws-ink`, `--ws-word-needs`). The brief's 10 px corner is
|
|
127
|
+
`--ws-radius-menu`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Data" height=
|
|
1
|
+
<!-- @dsCard group="Data" height=720 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
<link rel="stylesheet" href="../bundle.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
-
<div class="ws-stage">
|
|
12
|
-
|
|
11
|
+
<div class="ws-stage ws-stage--grey">
|
|
12
|
+
|
|
13
|
+
<section class="ws-card ws-card--compound" style="width: 520px;">
|
|
13
14
|
<header class="ws-head">
|
|
14
15
|
<div>
|
|
15
16
|
<h3 class="ws-title">Three agents need a nudge</h3>
|
|
@@ -28,10 +29,10 @@
|
|
|
28
29
|
<li class="ws-action-list__row">
|
|
29
30
|
<span class="ws-avatar ws-avatar--plain ws-avatar--sm" aria-hidden="true">JW</span>
|
|
30
31
|
<div class="ws-action-list__text">
|
|
31
|
-
<p class="ws-action-list__title">
|
|
32
|
-
<p class="ws-action-list__reason">Down from 41 last week. Nothing since Wednesday.</p>
|
|
32
|
+
<p class="ws-action-list__title">Josephine Whitfield-Abernathy <span class="ws-chip">18 calls</span></p>
|
|
33
|
+
<p class="ws-action-list__reason">Down from 41 last week. Nothing since Wednesday, and two of her three showings this week were moved.</p>
|
|
33
34
|
</div>
|
|
34
|
-
<button type="button" class="ws-btn ws-btn--secondary ws-btn--sm ws-action-list__act">Text
|
|
35
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--sm ws-action-list__act">Text Josephine</button>
|
|
35
36
|
</li>
|
|
36
37
|
<li class="ws-action-list__row">
|
|
37
38
|
<span class="ws-avatar ws-avatar--plain ws-avatar--sm" aria-hidden="true">NP</span>
|
|
@@ -39,10 +40,54 @@
|
|
|
39
40
|
<p class="ws-action-list__title">Nellie Park <span class="ws-chip">22 calls</span></p>
|
|
40
41
|
<p class="ws-action-list__reason">Reached 2 of 22 people, the lowest rate on the team.</p>
|
|
41
42
|
</div>
|
|
42
|
-
<button type="button" class="ws-btn ws-btn--secondary ws-btn--sm ws-action-list__act">
|
|
43
|
+
<button type="button" class="ws-btn ws-btn--secondary ws-btn--sm ws-action-list__act" aria-busy="true"><span class="ws-dot ws-working" aria-hidden="true"></span>Texting Nellie</button>
|
|
43
44
|
</li>
|
|
44
45
|
</ul>
|
|
45
46
|
</section>
|
|
47
|
+
|
|
48
|
+
<div class="ws-stack ws-stack--component" style="width: 360px;">
|
|
49
|
+
<section class="ws-card ws-card--compound" aria-busy="true" aria-label="Who needs a nudge, loading">
|
|
50
|
+
<header class="ws-head"><div><h3 class="ws-title">Who needs a nudge</h3><p class="ws-body ws-card__line">Checking this week's calls.</p></div></header>
|
|
51
|
+
<ul class="ws-action-list">
|
|
52
|
+
<li class="ws-action-list__row"><div class="ws-action-list__text"><div class="ws-action-list__ghost ws-shimmer" style="width: 40%;"></div><div class="ws-action-list__ghost ws-shimmer" style="width: 80%;"></div></div></li>
|
|
53
|
+
<li class="ws-action-list__row"><div class="ws-action-list__text"><div class="ws-action-list__ghost ws-shimmer" style="width: 50%;"></div><div class="ws-action-list__ghost ws-shimmer" style="width: 70%;"></div></div></li>
|
|
54
|
+
</ul>
|
|
55
|
+
</section>
|
|
56
|
+
<section class="ws-card ws-card--compound">
|
|
57
|
+
<header class="ws-head"><div><h3 class="ws-title">Nobody needs a nudge</h3><p class="ws-body ws-card__line">All six are past half the 50-call goal this week.</p></div></header>
|
|
58
|
+
</section>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="ws-stack" style="width: 640px;">
|
|
62
|
+
<span class="ws-muted">--brief, North's "what changed" lines on a page's head: hover turns a line to the surface (no lift) and shows Open and the dismiss; focus shows them too, touch always does</span>
|
|
63
|
+
<ul class="ws-action-list ws-action-list--brief" aria-label="What changed since yesterday">
|
|
64
|
+
<li class="ws-action-list__brief">
|
|
65
|
+
<button type="button" class="ws-action-list__main">
|
|
66
|
+
<span class="ws-action-list__lead">Pipeline</span>
|
|
67
|
+
<span class="ws-action-list__gist" title="Three deals moved to offer, $1.2M in all, the most in a week since August">Three deals moved to offer, $1.2M in all, the most in a week since August</span>
|
|
68
|
+
<span class="ws-action-list__go">Open in chat <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="M3 8h10M9 4l4 4-4 4"/></svg></span>
|
|
69
|
+
</button>
|
|
70
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs ws-action-list__dismiss" aria-label="Dismiss: Pipeline"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button>
|
|
71
|
+
</li>
|
|
72
|
+
<li class="ws-action-list__brief">
|
|
73
|
+
<button type="button" class="ws-action-list__main">
|
|
74
|
+
<span class="ws-action-list__lead">Calls</span>
|
|
75
|
+
<span class="ws-action-list__gist" title="The team made 212 calls, 40 more than last week">The team made 212 calls, 40 more than last week</span>
|
|
76
|
+
<span class="ws-action-list__go">Open in chat <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="M3 8h10M9 4l4 4-4 4"/></svg></span>
|
|
77
|
+
</button>
|
|
78
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs ws-action-list__dismiss" aria-label="Dismiss: Calls"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button>
|
|
79
|
+
</li>
|
|
80
|
+
<li class="ws-action-list__brief">
|
|
81
|
+
<button type="button" class="ws-action-list__main">
|
|
82
|
+
<span class="ws-action-list__lead">Showings</span>
|
|
83
|
+
<span class="ws-action-list__gist" title="Sam Okafor confirmed Saturday at 11">Sam Okafor confirmed Saturday at 11</span>
|
|
84
|
+
<span class="ws-action-list__go">Open in chat <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="M3 8h10M9 4l4 4-4 4"/></svg></span>
|
|
85
|
+
</button>
|
|
86
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs ws-action-list__dismiss" aria-label="Dismiss: Showings"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button>
|
|
87
|
+
</li>
|
|
88
|
+
</ul>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
46
91
|
</div>
|
|
47
92
|
</body>
|
|
48
93
|
</html>
|