@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The kit's marketing piece: for a public page, never a product screen.
|
|
2
2
|
|
|
3
|
-
Three features in a row, each a `KitCard
|
|
3
|
+
Three features in a row, each a `KitCard`-style card with an icon, a title, a sentence and a link.
|
|
4
4
|
|
|
5
5
|
## Use it when
|
|
6
6
|
|
|
@@ -11,43 +11,45 @@ Three features in a row, each a `KitCard` with an icon, a title, a sentence and
|
|
|
11
11
|
|
|
12
12
|
- More than three or four things of unequal importance: a longer list reads better as rows, not a grid of cards.
|
|
13
13
|
- A single deep feature that needs its own section and screenshot: give it its own full-width block instead.
|
|
14
|
-
- Any product screen:
|
|
15
|
-
a pitch for the product itself.
|
|
14
|
+
- Any product screen: a page inside the workspace shows state, not a pitch for the product itself.
|
|
16
15
|
|
|
17
16
|
## Anatomy
|
|
18
17
|
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Icon: the
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
underlining on hover.
|
|
18
|
+
- Band: `--color-surface`, `--space-xl` (32px) top and bottom, `--layout-margin` (48px) sides (16px under 40rem).
|
|
19
|
+
- Row (`__grid`): a grid of columns at least 260px wide, `--layout-col-gap` (24px) apart, capped at
|
|
20
|
+
`--layout-content-max`; the cards are equal height in each row.
|
|
21
|
+
- Card (`__card`): 4px corners, a 1px `--color-border-default` edge, `--color-surface`, `--space-lg` (24px) padding;
|
|
22
|
+
a column whose link sits at the foot, so cards of uneven copy line their links up.
|
|
23
|
+
- Icon (`__icon`): the house `ws-disc`, 40px, `--ws-surface-sunk` fill, a 20px line icon in `--color-text-heading`.
|
|
24
|
+
- Title (`__title`): `--space-md` (16px) under the icon, 20/28 semibold `--color-text-heading`.
|
|
25
|
+
- Body (`__body`): `--space-xs` (8px) under the title, 16/24 `--color-text-primary`, at least `--space-md` above the link.
|
|
26
|
+
- Link (`__link`): 14/20 medium `--color-text-interactive` (mid blue), a 12px trailing arrow `--space-xxs` from the
|
|
27
|
+
words, underlining on hover.
|
|
30
28
|
|
|
31
29
|
## Variants and sizes
|
|
32
30
|
|
|
33
|
-
One layout:
|
|
34
|
-
|
|
31
|
+
One layout: as many 260px-or-wider columns as the row holds, one gap. Three fit a screen from 924px wide; on a
|
|
32
|
+
tablet two sit in a row and the third takes the first column of the next, the same width as the others; on a phone,
|
|
33
|
+
one column. A fourth card joins the row where there is room for it and otherwise starts the next row, in the same
|
|
34
|
+
columns.
|
|
35
35
|
|
|
36
36
|
## States
|
|
37
37
|
|
|
38
38
|
- **Default:** as above.
|
|
39
|
-
- **Hover:** only the link reacts (underline); the card
|
|
40
|
-
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **Long label:** a longer title wraps
|
|
44
|
-
|
|
45
|
-
- **Narrow:**
|
|
39
|
+
- **Hover:** only the link reacts (underline); the card is not interactive, since the click target is the link.
|
|
40
|
+
Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
|
|
41
|
+
- **Focus:** the link takes the house ring, 2px navy, 2px out.
|
|
42
|
+
- **Selected / pending / disabled / error / empty:** not applicable.
|
|
43
|
+
- **Long label:** a longer title wraps; the body follows it, and the link stays on the card's foot, level with its
|
|
44
|
+
neighbours.
|
|
45
|
+
- **Narrow:** two to a row on a tablet, then one column on a phone, in the same order; a card that wraps never
|
|
46
|
+
stretches wider than its column.
|
|
47
|
+
- **Touch:** the link keeps its look and takes a 44px hit area above and below its words.
|
|
46
48
|
|
|
47
49
|
## Behaviour
|
|
48
50
|
|
|
49
|
-
- Keyboard: each card's link is a real `<a>`, focusable in document order; the card
|
|
50
|
-
- Pointer / touch: the link is the only
|
|
51
|
+
- Keyboard: each card's link is a real `<a>`, focusable in document order; the card takes no focus.
|
|
52
|
+
- Pointer / touch: the link is the only target; 44px tall on touch.
|
|
51
53
|
- Motion: none of its own.
|
|
52
54
|
|
|
53
55
|
## Content
|
|
@@ -58,7 +60,7 @@ shrinking the columns further.
|
|
|
58
60
|
|
|
59
61
|
## Props
|
|
60
62
|
|
|
61
|
-
Not a kit export
|
|
63
|
+
Not a kit export. A reusable version would take:
|
|
62
64
|
|
|
63
65
|
| Prop | Type | Meaning |
|
|
64
66
|
| --- | --- | --- |
|
|
@@ -66,19 +68,39 @@ Not a kit export; composed from `KitCard` and `ws-disc`. A reusable version woul
|
|
|
66
68
|
|
|
67
69
|
## Rules
|
|
68
70
|
|
|
69
|
-
- **
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- The
|
|
77
|
-
|
|
78
|
-
method: find the existing piece before adding one).
|
|
71
|
+
- **44px for every act on a public page** (`14-accessibility.md`): the link was 20px tall on touch. Its hit area grows,
|
|
72
|
+
its words do not move.
|
|
73
|
+
- **A wrapped card keeps its column** (4 Nov 2026): the row was a wrapping flex row, so at 768px the third card ran the
|
|
74
|
+
full width under the other two. It is a grid now.
|
|
75
|
+
- **Links on one line across the row** (4 Nov 2026): the link sits on each card's foot, so a two-line title in one card
|
|
76
|
+
no longer drops its link below its neighbours'.
|
|
77
|
+
- The gap between the cards is `--layout-col-gap` (24px), the kit's own column gap.
|
|
78
|
+
- The title size, `--font-size-lg2` (20px), is the kit's "marketing small heading".
|
|
79
|
+
- The icon reuses the house `ws-disc` rather than a second disc shape.
|
|
79
80
|
|
|
80
81
|
## Source
|
|
81
82
|
|
|
82
|
-
**Derived from**: `KitCard`, the
|
|
83
|
-
|
|
84
|
-
system, 26 Oct 2026
|
|
83
|
+
**Derived from**: `KitCard`, the house `ws-disc`, the kit's layout gap and type-scale tokens (`layout-col-gap`,
|
|
84
|
+
`font-size-lg2`, `font-size-md`), the touch floors and the geometry check at 390. **Precedent**: an intentional addition
|
|
85
|
+
decided from the system, 26 Oct 2026.
|
|
86
|
+
|
|
87
|
+
## Markup
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<section class="ws-feature-grid">
|
|
91
|
+
<div class="ws-feature-grid__grid">
|
|
92
|
+
<div class="ws-feature-grid__card">
|
|
93
|
+
<span class="ws-disc ws-feature-grid__icon" aria-hidden="true">
|
|
94
|
+
<svg viewBox="0 0 16 16" fill="none"><path d="M3 12V8M8 12V4M13 12V9.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
95
|
+
</span>
|
|
96
|
+
<h3 class="ws-feature-grid__title">Live call insights</h3>
|
|
97
|
+
<p class="ws-feature-grid__body">Every outreach call logged as it happens.</p>
|
|
98
|
+
<a class="ws-feature-grid__link" href="/insights">See how it works
|
|
99
|
+
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11 11 5M5.5 5h5.5v5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
100
|
+
</a>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</section>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Styles: the `FeatureGrid` block (`components/FeatureGrid/style.css`); `ws-disc` is in `fello-core.css`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* ---- FeatureGrid: the kit's three feature cards in a row, wrapping to one column ---- */
|
|
2
|
+
.ws-feature-grid { background: var(--color-surface); width: 100%; padding: var(--space-xl) var(--layout-margin); }
|
|
3
|
+
/* A grid of columns at least 260 px wide: a card that wraps keeps its column's width instead of stretching across the row. */
|
|
4
|
+
.ws-feature-grid__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--space-9xl) + var(--space-3xl) + var(--space-sm))), 1fr)); gap: var(--layout-col-gap); max-width: var(--layout-content-max); margin: 0 auto; }
|
|
5
|
+
.ws-feature-grid__card { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; border-radius: var(--ws-radius-control); border: var(--ws-line) solid var(--color-border-default); background: var(--color-surface); padding: var(--space-lg); }
|
|
6
|
+
.ws-feature-grid__icon { width: var(--space-2xl); height: var(--space-2xl); }
|
|
7
|
+
.ws-feature-grid__icon svg { width: var(--ws-icon-lg); height: var(--ws-icon-lg); }
|
|
8
|
+
.ws-feature-grid__title { margin-top: var(--space-md); font-size: var(--font-size-lg2); font-weight: 600; line-height: var(--ws-leading-title); color: var(--color-text-heading); text-wrap: balance; overflow-wrap: break-word; }
|
|
9
|
+
.ws-feature-grid__body { margin-top: var(--space-xs); margin-bottom: var(--space-md); font-size: var(--font-size-md); line-height: var(--space-lg); color: var(--color-text-primary); }
|
|
10
|
+
/* The link sits at the card's foot, so cards of uneven copy still line their links up. */
|
|
11
|
+
.ws-feature-grid__link { position: relative; margin-top: auto; display: inline-flex; align-items: center; gap: var(--space-xxs); font-size: var(--font-size-sm); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 500; color: var(--color-text-interactive); text-decoration: none; }
|
|
12
|
+
@media (hover: hover) { .ws-feature-grid__link:hover { text-decoration: underline; } }
|
|
13
|
+
.ws-feature-grid__link svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
14
|
+
/* Touch: the public page's 44 px target, as a hit area round the words so the card keeps its rhythm. */
|
|
15
|
+
@media (pointer: coarse) {
|
|
16
|
+
.ws-feature-grid__link::after { content: ""; position: absolute; inset: min(0px, calc((100% - var(--ws-touch-public)) / 2)) 0; }
|
|
17
|
+
}
|
|
18
|
+
@media (max-width: 40rem) {
|
|
19
|
+
.ws-feature-grid { padding-inline: var(--space-md); }
|
|
20
|
+
}
|
|
@@ -42,9 +42,11 @@ There is one size for the zone; it spans the width of its container.
|
|
|
42
42
|
## States
|
|
43
43
|
|
|
44
44
|
- **Empty:** the dotted zone, its icon, words and the "Choose a file" button.
|
|
45
|
-
- **
|
|
46
|
-
|
|
47
|
-
-
|
|
45
|
+
- **Focus:** the "Choose a file" act takes the kit's ring when its file input is focused.
|
|
46
|
+
- **Dragging over:** the zone's edge turns a 1 px mid blue (`--color-text-interactive`), the kit's working colour, since
|
|
47
|
+
a drag-over is an active, not an error, state (the navy ring stays the focus mark).
|
|
48
|
+
- **Uploading:** a file row shows its `Meter` bar growing to the latest share; the bar is a `role="progressbar"` with
|
|
49
|
+
`aria-valuenow` and a label naming the file, so its share is heard, not only seen.
|
|
48
50
|
- **Done:** the bar is replaced by a `--ws-word-positive` tick.
|
|
49
51
|
- **Rejected:** the row shows its reason in `--ws-word-needs` words instead of a bar.
|
|
50
52
|
|
|
@@ -85,3 +87,31 @@ There is one size for the zone; it spans the width of its container.
|
|
|
85
87
|
|
|
86
88
|
**Derived from**: the `.ws-dots` dotted field, `.ws-disc`, `Meter`'s progress bar, and `Button`'s secondary 32 px
|
|
87
89
|
size. **Precedent**: an intentional addition decided from the system, 26 Oct 2026 (no file upload control existed).
|
|
90
|
+
|
|
91
|
+
## Markup
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<div class="ws-file-upload ws-dots">
|
|
95
|
+
<span class="ws-disc ws-file-upload__disc">...</span>
|
|
96
|
+
<p class="ws-body">Drop a file here, or</p>
|
|
97
|
+
<label class="ws-btn ws-btn--secondary">Choose a file <input type="file" accept=".png,.jpg,.jpeg,.pdf"></label>
|
|
98
|
+
<p class="ws-muted">PNG, JPG or PDF, up to 10 MB</p>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="ws-file-upload__file">
|
|
101
|
+
<span class="ws-disc ws-file-upload__file-disc">...</span>
|
|
102
|
+
<div class="ws-file-upload__file-body">
|
|
103
|
+
<span class="ws-file-upload__file-name">lead-photo.jpg</span>
|
|
104
|
+
<span class="ws-file-upload__file-meta">
|
|
105
|
+
<span class="ws-file-upload__bar" role="progressbar" aria-label="Uploading lead-photo.jpg" aria-valuenow="64" aria-valuemin="0" aria-valuemax="100"><span class="ws-file-upload__bar-fill" style="width: 64%;"></span></span>
|
|
106
|
+
<span class="ws-file-upload__file-size">2.1 MB</span>
|
|
107
|
+
</span>
|
|
108
|
+
</div>
|
|
109
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Remove lead-photo.jpg">...</button>
|
|
110
|
+
</div>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Styles
|
|
114
|
+
|
|
115
|
+
`design-system/components/FileUpload/style.css`: `ws-file-upload` and `--drag`, `__disc`, `__file`, `__file-disc`,
|
|
116
|
+
`__file-body`, `__file-name`, `__file-meta`, `__file-size`, `__bar`, `__bar-fill`, `__done`, `__error`. The file input is
|
|
117
|
+
laid over its act, unseen, so the act takes its focus ring.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div class="ws-stage">
|
|
12
|
-
<div style="display: grid; grid-template-columns: repeat(
|
|
12
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: var(--ws-gap-component); width: 100%;">
|
|
13
13
|
|
|
14
14
|
<div class="ws-stack">
|
|
15
15
|
<span class="ws-muted">Empty</span>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<p class="ws-body">Drop a file here, or</p>
|
|
21
21
|
<label class="ws-btn ws-btn--secondary">
|
|
22
22
|
Choose a file
|
|
23
|
-
<input type="file"
|
|
23
|
+
<input type="file" accept=".png,.jpg,.jpeg,.pdf">
|
|
24
24
|
</label>
|
|
25
25
|
<p class="ws-muted">PNG, JPG or PDF, up to 10 MB</p>
|
|
26
26
|
</div>
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
<p class="ws-body">Drop a file here, or</p>
|
|
36
36
|
<label class="ws-btn ws-btn--secondary">
|
|
37
37
|
Choose a file
|
|
38
|
-
<input type="file"
|
|
38
|
+
<input type="file" accept=".png,.jpg,.jpeg,.pdf">
|
|
39
39
|
</label>
|
|
40
40
|
<p class="ws-muted">PNG, JPG or PDF, up to 10 MB</p>
|
|
41
41
|
</div>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<div class="ws-file-upload__file-body">
|
|
49
49
|
<span class="ws-file-upload__file-name">lead-photo.jpg</span>
|
|
50
50
|
<span class="ws-file-upload__file-meta">
|
|
51
|
-
<span class="ws-file-upload__bar" aria-
|
|
51
|
+
<span class="ws-file-upload__bar" role="progressbar" aria-label="Uploading lead-photo.jpg" aria-valuenow="64" aria-valuemin="0" aria-valuemax="100"><span class="ws-file-upload__bar-fill" style="width: 64%;"></span></span>
|
|
52
52
|
<span class="ws-file-upload__file-size">2.1 MB</span>
|
|
53
53
|
</span>
|
|
54
54
|
</div>
|
|
@@ -85,6 +85,20 @@
|
|
|
85
85
|
</div>
|
|
86
86
|
</div>
|
|
87
87
|
|
|
88
|
+
<div class="ws-stack">
|
|
89
|
+
<span class="ws-muted">A long file name wraps beside its act</span>
|
|
90
|
+
<div class="ws-file-upload__file">
|
|
91
|
+
<span class="ws-disc ws-file-upload__file-disc"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="2" width="10" height="12" rx="1"/><path d="M6 6h4M6 9h4"/></svg></span>
|
|
92
|
+
<div class="ws-file-upload__file-body">
|
|
93
|
+
<span class="ws-file-upload__file-name">2026-10-buyer-consultation-notes-priya-nair-lakeview-estates.pdf</span>
|
|
94
|
+
<span class="ws-file-upload__done"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8.3l2.6 2.6L12 5.2"/></svg>1.4 MB, done</span>
|
|
95
|
+
</div>
|
|
96
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Remove 2026-10-buyer-consultation-notes-priya-nair-lakeview-estates.pdf">
|
|
97
|
+
<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>
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
88
102
|
</div>
|
|
89
103
|
</div>
|
|
90
104
|
</body>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* ---- FileUpload: a drop zone on the dotted field with one act, then a row a file with its progress, done or error.
|
|
2
|
+
The zone's edge is drawn inside; dragging over turns it mid blue at 1 px. The act is a label holding the file input
|
|
3
|
+
(laid over it, unseen), so it takes the focus ring when the input does. A long file name wraps, never pushes the
|
|
4
|
+
remove act out. ---- */
|
|
5
|
+
.ws-file-upload { display: flex; flex-direction: column; align-items: center; gap: var(--space-xs); padding: var(--space-lg); border-radius: var(--ws-radius-card); box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card); text-align: center; transition: box-shadow var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
6
|
+
.ws-file-upload--drag { box-shadow: inset 0 0 0 var(--ws-line) var(--color-text-interactive); }
|
|
7
|
+
.ws-file-upload .ws-btn > input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
|
|
8
|
+
.ws-file-upload .ws-btn:has(> input:focus-visible) { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
|
|
9
|
+
.ws-file-upload__disc { width: var(--space-2xl); height: var(--space-2xl); }
|
|
10
|
+
.ws-file-upload__disc svg { width: var(--ws-icon-lg); height: var(--ws-icon-lg); }
|
|
11
|
+
.ws-file-upload__file { display: flex; align-items: center; gap: var(--space-xs); padding: var(--space-xs) 0; }
|
|
12
|
+
.ws-file-upload__file-disc { width: var(--ws-control-h-sm); height: var(--ws-control-h-sm); flex-shrink: 0; }
|
|
13
|
+
.ws-file-upload__file-disc svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
14
|
+
.ws-file-upload__file-body { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: var(--space-3xs); }
|
|
15
|
+
.ws-file-upload__file-name { font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); font-weight: 600; color: var(--color-text-heading); overflow-wrap: anywhere; }
|
|
16
|
+
.ws-file-upload__file-meta { display: flex; align-items: center; gap: var(--space-xs); }
|
|
17
|
+
.ws-file-upload__file-size { flex-shrink: 0; font-size: var(--ws-text-dense); line-height: var(--space-md); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
|
|
18
|
+
.ws-file-upload__bar { flex: 1; height: var(--space-xxs); overflow: hidden; border-radius: var(--ws-radius-chip); background: var(--ws-track); }
|
|
19
|
+
.ws-file-upload__bar-fill { display: block; height: 100%; border-radius: inherit; background: var(--color-text-heading); transition: width var(--ws-duration-gentle) var(--ws-ease-soft); }
|
|
20
|
+
.ws-file-upload__done, .ws-file-upload__error { display: flex; align-items: center; gap: var(--space-xxs); font-size: var(--ws-text-dense); line-height: var(--space-md); }
|
|
21
|
+
.ws-file-upload__done { color: var(--ws-word-positive); }
|
|
22
|
+
.ws-file-upload__error { color: var(--ws-word-needs); }
|
|
23
|
+
.ws-file-upload__done svg, .ws-file-upload__error svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); flex-shrink: 0; }
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
A page's filters in one row: a period switch at the start and the pickers that scope the page at the end (North's
|
|
2
|
+
filter bar).
|
|
3
|
+
|
|
4
|
+
## Use it when
|
|
5
|
+
|
|
6
|
+
- A dashboard or a report page is read for a period and a scope (this month, one team, one source), and every card on
|
|
7
|
+
the page answers to the same choice.
|
|
8
|
+
- The filters belong to the whole page, not to one chart or one list.
|
|
9
|
+
|
|
10
|
+
## Not for
|
|
11
|
+
|
|
12
|
+
- A filter that belongs to one chart or one list: put it in that card's head (`Segmented --sm`, `Select --sm`).
|
|
13
|
+
- A search: use the search box (`Input`'s `ws-search`).
|
|
14
|
+
- A form's choices: use the fields.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
- Bar: a row at least 28 px tall, two groups at the two ends (12 apart, 10 between lines when they wrap); a group that
|
|
19
|
+
wraps starts its own line at the left. It sizes from its own width, not the window's.
|
|
20
|
+
- Start group: the period, a `Segmented --sm` (a 28 px track, 24 px items, 12 / 16 words).
|
|
21
|
+
- End group: the pickers (`ws-filter-pick`), 8 apart: 28 px tall, 4 px corners, the surface with the 0.5 px card edge
|
|
22
|
+
drawn inside, 10 / 8 inside, 12 / 16 words: the label in the muted words, 6 px, then the value in navy medium, then a
|
|
23
|
+
12 px navy chevron.
|
|
24
|
+
- Narrower than 76rem the pickers tighten (8 / 6 inside, 4 apart); narrower than 48rem their labels go and only the
|
|
25
|
+
values show (each picker's `aria-label` carries its label and value). Both steps read the bar's own width (a named
|
|
26
|
+
container), so a picker used outside a bar, in a list head or a detail, keeps North's 10 / 8 wherever it sits.
|
|
27
|
+
|
|
28
|
+
## Variants and sizes
|
|
29
|
+
|
|
30
|
+
One size. The bar holds one period switch and up to four pickers; more than that is a sign the page asks too much.
|
|
31
|
+
|
|
32
|
+
## States
|
|
33
|
+
|
|
34
|
+
- **Default:** each picker shows its label and its current value.
|
|
35
|
+
- **Hover (a mouse only):** a picker's edge darkens (#AAA49D), no fill.
|
|
36
|
+
- **Focus:** the kit's ring, 2 px navy, 2 px out, round the picker or the period item.
|
|
37
|
+
- **Pressed:** a picker gives to 0.97.
|
|
38
|
+
- **Open:** the picker's `aria-expanded="true"`, its `Menu` under it (8 below, from its corner), the chosen row showing
|
|
39
|
+
its tick (`ws-menu-item__tick` in every row; only the `aria-checked="true"` one shows).
|
|
40
|
+
- **Long value:** cut with an ellipsis, whole in the picker's `title`.
|
|
41
|
+
- **Narrow:** the groups wrap, each from the left; the labels go under 48rem.
|
|
42
|
+
- **Touch:** pickers and period items 40 tall.
|
|
43
|
+
- **Dark:** the surface, the edge and the words take their dark values.
|
|
44
|
+
- **Empty / loading / error:** not applicable; a filter always holds a value ("All teams" is a value).
|
|
45
|
+
|
|
46
|
+
## Behaviour
|
|
47
|
+
|
|
48
|
+
- A picker is a `<button aria-haspopup="menu" aria-expanded>` opening a `Menu` of `menuitemradio`s; choosing one closes
|
|
49
|
+
it and updates the page.
|
|
50
|
+
- The period is a `Segmented` (buttons with `aria-pressed`, or links when the period lives in the URL).
|
|
51
|
+
- The bar is `role="group"` with an `aria-label` ("Filters").
|
|
52
|
+
- In North the bar docks into the top bar when the page scrolls under it; that belongs to the shell (`AppShell`).
|
|
53
|
+
- Motion: colours over the hover beat; the menu opens as `Menu`'s.
|
|
54
|
+
|
|
55
|
+
## Content
|
|
56
|
+
|
|
57
|
+
- A picker's label is the dimension ("Team", "Source"), its value the choice ("All teams", "Zillow, Realtor.com").
|
|
58
|
+
- "All" values say what they cover ("All teams", not "All").
|
|
59
|
+
- No em dashes.
|
|
60
|
+
|
|
61
|
+
## Props
|
|
62
|
+
|
|
63
|
+
| Name | Type | Meaning |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `period` | `SegmentedItem[]` | the period switch |
|
|
66
|
+
| `picks` | `{ key, label, value, options, onSelect }[]` | the pickers, at the end |
|
|
67
|
+
| `label` | `string` | the bar's name, default "Filters" |
|
|
68
|
+
|
|
69
|
+
## Rules
|
|
70
|
+
|
|
71
|
+
- Page-wide filters live in one `FilterBar` at the top of the page, under its title (North; overturns 10-patterns.md's
|
|
72
|
+
"nothing page-wide looks like a filter").
|
|
73
|
+
- One period switch, at the start; pickers at the end.
|
|
74
|
+
- A picker never hides its label without an `aria-label` that carries it.
|
|
75
|
+
|
|
76
|
+
## Source
|
|
77
|
+
|
|
78
|
+
**Derived from**: Seth's North (style1.css:417, :802-812, :1056-1060, :1081-1084): the 28 px filter bar, the filter
|
|
79
|
+
segmented, the label-and-value picker with its darker edge on hover, the 10 / 12 gaps, the tighter step and the hidden
|
|
80
|
+
label on a narrow page. North's 820 and 1120 px page steps snap to the kit's 48rem and 76rem container steps; its
|
|
81
|
+
#8A8A8A label (3.35:1) takes the muted words' AA step.
|
|
82
|
+
|
|
83
|
+
## Markup
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<div class="ws-filter-bar" role="group" aria-label="Filters">
|
|
87
|
+
<div class="ws-filter-bar__group">
|
|
88
|
+
<div class="ws-segmented ws-segmented--sm" role="group" aria-label="Period">
|
|
89
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Week</button>
|
|
90
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Month</button>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="ws-filter-bar__group">
|
|
94
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Team: All teams" popovertarget="team-menu">
|
|
95
|
+
<span class="ws-filter-pick__label">Team</span><span class="ws-filter-pick__value">All teams</span>
|
|
96
|
+
<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>
|
|
97
|
+
</button>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
<!-- the picker's list: Menu's choice rows, the tick on the chosen one -->
|
|
101
|
+
<div id="team-menu" class="ws-menu" role="menu" aria-label="Team" popover>
|
|
102
|
+
<button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="true">All teams
|
|
103
|
+
<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
104
|
+
</button>
|
|
105
|
+
<button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false">North region
|
|
106
|
+
<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
107
|
+
</button>
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Styles
|
|
112
|
+
|
|
113
|
+
`design-system/components/FilterBar/style.css`: `ws-filter-bar`, `__group`, `ws-filter-pick`, `__label`, `__value`. The
|
|
114
|
+
period is `Segmented`'s `--sm`; the open picker's list is `Menu`.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<!-- @dsCard group="Navigation" height=380 -->
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>FilterBar</title>
|
|
7
|
+
<link rel="stylesheet" href="../../tokens.css">
|
|
8
|
+
<link rel="stylesheet" href="../bundle.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div class="ws-stage ws-stage--column">
|
|
12
|
+
|
|
13
|
+
<div class="ws-stack">
|
|
14
|
+
<span class="ws-muted">A page's filters: the period at the start, the pickers at the end (28 px)</span>
|
|
15
|
+
<div class="ws-filter-bar" role="group" aria-label="Filters">
|
|
16
|
+
<div class="ws-filter-bar__group">
|
|
17
|
+
<div class="ws-segmented ws-segmented--sm" role="group" aria-label="Period">
|
|
18
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Week</button>
|
|
19
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Month</button>
|
|
20
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Quarter</button>
|
|
21
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Year</button>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="ws-filter-bar__group">
|
|
25
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Team: All teams">
|
|
26
|
+
<span class="ws-filter-pick__label">Team</span><span class="ws-filter-pick__value">All teams</span>
|
|
27
|
+
<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>
|
|
28
|
+
</button>
|
|
29
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Source: Zillow, Realtor.com">
|
|
30
|
+
<span class="ws-filter-pick__label">Source</span><span class="ws-filter-pick__value">Zillow, Realtor.com</span>
|
|
31
|
+
<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>
|
|
32
|
+
</button>
|
|
33
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Agent: Anyone">
|
|
34
|
+
<span class="ws-filter-pick__label">Agent</span><span class="ws-filter-pick__value">Anyone</span>
|
|
35
|
+
<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>
|
|
36
|
+
</button>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- The open menu hangs 8 under its picker, left edges flush (it starts its line, so it flips to the side with room);
|
|
42
|
+
the stack keeps the room it covers, since a menu floats over what is below it. -->
|
|
43
|
+
<div class="ws-stack" style="width: 620px; max-width: 100%; padding-bottom: var(--space-8xl);">
|
|
44
|
+
<span class="ws-muted">In a narrower region: the groups wrap, each from the left, and the pickers show their values only; Team is open</span>
|
|
45
|
+
<div class="ws-filter-bar" role="group" aria-label="Filters, narrow">
|
|
46
|
+
<div class="ws-filter-bar__group">
|
|
47
|
+
<div class="ws-segmented ws-segmented--sm" role="group" aria-label="Period">
|
|
48
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Week</button>
|
|
49
|
+
<button type="button" class="ws-segmented__item" aria-pressed="true">Month</button>
|
|
50
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Quarter</button>
|
|
51
|
+
<button type="button" class="ws-segmented__item" aria-pressed="false">Year</button>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="ws-filter-bar__group">
|
|
55
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="false" aria-label="Source: Zillow, Realtor.com and three more lead sources" title="Zillow, Realtor.com and three more lead sources">
|
|
56
|
+
<span class="ws-filter-pick__label">Source</span><span class="ws-filter-pick__value">Zillow, Realtor.com and three more lead sources</span>
|
|
57
|
+
<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>
|
|
58
|
+
</button>
|
|
59
|
+
<span style="position: relative; display: inline-flex;">
|
|
60
|
+
<button type="button" class="ws-filter-pick" aria-haspopup="menu" aria-expanded="true" aria-controls="fb-team" aria-label="Team: All teams">
|
|
61
|
+
<span class="ws-filter-pick__label">Team</span><span class="ws-filter-pick__value">All teams</span>
|
|
62
|
+
<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>
|
|
63
|
+
</button>
|
|
64
|
+
<div class="ws-menu" role="menu" id="fb-team" aria-label="Team" style="position: absolute; top: calc(100% + var(--space-xs)); left: 0;">
|
|
65
|
+
<button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="true">All teams
|
|
66
|
+
<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
67
|
+
</button>
|
|
68
|
+
<button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false">North region
|
|
69
|
+
<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
70
|
+
</button>
|
|
71
|
+
<button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false">South region
|
|
72
|
+
<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
</span>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
</div>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* ---- FilterBar: North's page filters (0.5.0, D1; style1.css:417, :802-812): a period switch (Segmented --sm) and the
|
|
2
|
+
pickers that scope the page (FilterPick), 28 tall, the two groups at the two ends, 12 apart and 10 between lines
|
|
3
|
+
when they wrap; a wrapped group starts its own line at the left. It sizes from its own width: under 76rem the
|
|
4
|
+
pickers tighten, under 48rem their labels go and only the values show (each pick's aria-label carries its label and value). ---- */
|
|
5
|
+
.ws-filter-bar { container: ws-filter-bar / inline-size; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-xs-plus) var(--space-sm); min-height: var(--ws-control-h-sm); }
|
|
6
|
+
.ws-filter-bar__group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs); min-width: 0; max-width: 100%; }
|
|
7
|
+
/* A picker: the label in the muted words, then the value in navy medium and a 12 px chevron; it opens a Menu. */
|
|
8
|
+
.ws-filter-pick { display: inline-flex; flex-shrink: 0; align-items: center; gap: var(--space-xxs-plus); max-width: 100%; height: var(--ws-control-h-sm); padding: 0 var(--space-xs) 0 var(--space-xs-plus); border: 0; border-radius: var(--ws-radius-control); background: var(--color-surface); box-shadow: var(--ws-shadow-hairline-in); color: var(--color-text-heading); font-size: var(--ws-text-dense); line-height: var(--space-md); white-space: nowrap; cursor: pointer; transition: box-shadow var(--ws-duration-hover) var(--ws-ease-soft), transform var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
9
|
+
.ws-filter-pick__label { color: var(--color-text-muted); }
|
|
10
|
+
.ws-filter-pick__value { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 500; }
|
|
11
|
+
.ws-filter-pick svg { flex-shrink: 0; width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
12
|
+
@media (hover: hover) { .ws-filter-pick:hover { box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-hover); } }
|
|
13
|
+
@media (prefers-reduced-motion: no-preference) { .ws-filter-pick:active { transform: scale(var(--ws-press-scale)); transition-duration: var(--ws-duration-instant); } }
|
|
14
|
+
/* The bar's own width (a named container: a picker outside a bar, in a list head or a detail, keeps North's 10 / 8 whatever
|
|
15
|
+
region it sits in). */
|
|
16
|
+
@container ws-filter-bar (max-width: 76rem) {
|
|
17
|
+
.ws-filter-bar__group { gap: var(--space-xxs-plus); }
|
|
18
|
+
.ws-filter-pick { gap: var(--space-xxs); padding: 0 var(--space-xxs-plus) 0 var(--space-xs); }
|
|
19
|
+
.ws-filter-bar .ws-segmented--sm .ws-segmented__item { padding: 0 var(--space-xs); }
|
|
20
|
+
}
|
|
21
|
+
@container ws-filter-bar (max-width: 48rem) { .ws-filter-pick__label { display: none; } }
|
|
22
|
+
@media (pointer: coarse) { .ws-filter-pick { min-height: var(--ws-touch); } }
|