@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
|
@@ -14,11 +14,12 @@ A number field with its figures right-aligned and tabular, an optional unit insi
|
|
|
14
14
|
|
|
15
15
|
## Anatomy
|
|
16
16
|
|
|
17
|
-
- Field: `Input`'s exact shell (32 px, `--ws-radius-control`, white `--ws-field`,
|
|
18
|
-
|
|
17
|
+
- Field: `Input`'s exact shell (32 px, `--ws-radius-control`, white `--ws-field`, the inside edge, the kit's focus
|
|
18
|
+
ring, 12 px label above, error below).
|
|
19
19
|
- Numerals: `.ws-tnum` (tabular numerals), right-aligned.
|
|
20
20
|
- Unit: a muted (`--color-text-muted`) suffix inside the field, after the number, before the steppers if both are
|
|
21
|
-
shown; the field's own right padding grows to make room, the same technique `Select`'s chevron uses.
|
|
21
|
+
shown; the field's own right padding grows to make room, the same technique `Select`'s chevron uses. It is hidden
|
|
22
|
+
from reading on its own and named through the field's `aria-describedby`, so "6" is heard as "6, %".
|
|
22
23
|
- Steppers: two 24 px `xs` ghost icon buttons (`.ws-icon-btn.ws-icon-btn--xs`), minus and plus, side by side at the
|
|
23
24
|
field's right edge. Side by side, not stacked, because a 32 px field has no room for two stacked 24 px buttons without
|
|
24
25
|
growing taller, which would break the field's fixed height.
|
|
@@ -38,8 +39,8 @@ There is one size; it grows to 40 px on a touch screen.
|
|
|
38
39
|
- **Plain:** right-aligned tabular numerals, no unit, no steppers.
|
|
39
40
|
- **With unit:** the muted suffix sits after the number.
|
|
40
41
|
- **With steppers:** minus and plus buttons step the value; ArrowUp/ArrowDown do the same from the keyboard.
|
|
41
|
-
- **Focus:** the
|
|
42
|
-
- **Error:** a min/max violation
|
|
42
|
+
- **Focus:** the kit's focus ring, 2 px navy, 2 px out, as `Input`'s (a field's edge darkens under the pointer).
|
|
43
|
+
- **Error:** a min/max violation takes the salmon's AA step as its edge and rises in a message below, exactly as `Input`'s error state
|
|
43
44
|
("Enter a number between 1 and 100").
|
|
44
45
|
- **Disabled:** the field and steppers are inert, shown at reduced emphasis.
|
|
45
46
|
|
|
@@ -48,9 +49,9 @@ There is one size; it grows to 40 px on a touch screen.
|
|
|
48
49
|
- Keyboard: a real `<input type="number">` under the hood, so ArrowUp/ArrowDown step by the field's `step` and native
|
|
49
50
|
validation works for free; the native spinner is hidden in favour of the two stepper buttons, which do the same job
|
|
50
51
|
visibly.
|
|
51
|
-
- Pointer / touch: clicking minus or plus steps the value by one press; the touch floor is 40 px.
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
- Pointer / touch: clicking minus or plus steps the value by one press; the touch floor is 40 px. On touch the two
|
|
53
|
+
marks sit 16 apart and 8 from the edge, so each 40 px hit area is whole and a tap on minus never lands on plus.
|
|
54
|
+
- Motion: as `Input`'s: the edge over the hover beat; an error message rises in.
|
|
54
55
|
- Reduced motion: nothing animates.
|
|
55
56
|
|
|
56
57
|
## Content
|
|
@@ -80,3 +81,21 @@ There is one size; it grows to 40 px on a touch screen.
|
|
|
80
81
|
|
|
81
82
|
Intentional addition, decided from the system (26 Oct 2026): the system had `Input` for free text but nothing for a
|
|
82
83
|
value meant to be stepped and read as a number. Built on `Input`'s field chrome and `IconButton`'s `xs` size.
|
|
84
|
+
|
|
85
|
+
## Markup
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<span class="ws-number-input ws-number-input--steppers ws-number-input--unit">
|
|
89
|
+
<input class="ws-input ws-tnum" id="call-length" type="number" value="30" aria-describedby="call-length-unit">
|
|
90
|
+
<span class="ws-number-input__unit" id="call-length-unit" aria-hidden="true">min</span>
|
|
91
|
+
<span class="ws-number-input__steppers">
|
|
92
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Decrease by one minute"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg></button>
|
|
93
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Increase by one minute"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M8 4v8M4 8h8"/></svg></button>
|
|
94
|
+
</span>
|
|
95
|
+
</span>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Styles
|
|
99
|
+
|
|
100
|
+
`design-system/components/NumberInput/style.css`: `ws-number-input` with `--unit`, `--steppers`; `__unit`,
|
|
101
|
+
`__steppers`. The field is `Input`'s `ws-input`.
|
|
@@ -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%, 160px), 1fr)); gap: var(--ws-gap-component); width: 100%;">
|
|
13
13
|
|
|
14
14
|
<div class="ws-field">
|
|
15
15
|
<span class="ws-muted">Plain</span>
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
<span class="ws-muted">With unit</span>
|
|
24
24
|
<label class="ws-label" for="ni-unit">Commission</label>
|
|
25
25
|
<span class="ws-number-input ws-number-input--unit">
|
|
26
|
-
<input class="ws-input ws-tnum" id="ni-unit" type="number" value="6">
|
|
27
|
-
<span class="ws-number-input__unit" aria-hidden="true">%</span>
|
|
26
|
+
<input class="ws-input ws-tnum" id="ni-unit" type="number" value="6" aria-describedby="ni-unit-u">
|
|
27
|
+
<span class="ws-number-input__unit" id="ni-unit-u" aria-hidden="true">%</span>
|
|
28
28
|
</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
<span class="ws-muted">With steppers and a unit</span>
|
|
33
33
|
<label class="ws-label" for="ni-step">Call length</label>
|
|
34
34
|
<span class="ws-number-input ws-number-input--steppers ws-number-input--unit">
|
|
35
|
-
<input class="ws-input ws-tnum" id="ni-step" type="number" value="30">
|
|
36
|
-
<span class="ws-number-input__unit" aria-hidden="true">min</span>
|
|
35
|
+
<input class="ws-input ws-tnum" id="ni-step" type="number" value="30" aria-describedby="ni-step-u">
|
|
36
|
+
<span class="ws-number-input__unit" id="ni-step-u" aria-hidden="true">min</span>
|
|
37
37
|
<span class="ws-number-input__steppers">
|
|
38
38
|
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Decrease by one minute">
|
|
39
39
|
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg>
|
|
@@ -57,6 +57,22 @@
|
|
|
57
57
|
</p>
|
|
58
58
|
</div>
|
|
59
59
|
|
|
60
|
+
<div class="ws-field">
|
|
61
|
+
<span class="ws-muted">Disabled, with steppers</span>
|
|
62
|
+
<label class="ws-label" for="ni-off">Seats</label>
|
|
63
|
+
<span class="ws-number-input ws-number-input--steppers">
|
|
64
|
+
<input class="ws-input ws-tnum" id="ni-off" type="number" value="12" disabled>
|
|
65
|
+
<span class="ws-number-input__steppers">
|
|
66
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Remove a seat" disabled>
|
|
67
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 8h8"/></svg>
|
|
68
|
+
</button>
|
|
69
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--xs" aria-label="Add a seat" disabled>
|
|
70
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M8 4v8M4 8h8"/></svg>
|
|
71
|
+
</button>
|
|
72
|
+
</span>
|
|
73
|
+
</span>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
60
76
|
</div>
|
|
61
77
|
</div>
|
|
62
78
|
</body>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* ---- NumberInput: the house field, numerals at the right, a unit inside it (named to a screen reader through the
|
|
2
|
+
field's aria-describedby) and two steppers ---- */
|
|
3
|
+
.ws-number-input { position: relative; display: flex; }
|
|
4
|
+
.ws-number-input .ws-input { text-align: right; }
|
|
5
|
+
.ws-number-input__unit { position: absolute; top: 50%; transform: translateY(-50%); right: var(--space-sm); color: var(--color-text-muted); font-size: var(--ws-text-body); pointer-events: none; }
|
|
6
|
+
.ws-number-input__steppers { position: absolute; top: 50%; right: calc(var(--space-xxs) / 2); transform: translateY(-50%); display: flex; gap: calc(var(--space-xxs) / 2); }
|
|
7
|
+
/* The steppers are field marks (--ws-field-mark, Input/style.css): navy, and the field's ink on the navy ground. */
|
|
8
|
+
.ws-number-input__steppers .ws-icon-btn { color: var(--ws-field-mark, var(--color-text-heading)); }
|
|
9
|
+
/* They sit on the field, not the ground, so their ring and wash take the mark's colour too (on the navy ground the
|
|
10
|
+
white ring and wash vanished on the white field). */
|
|
11
|
+
.ws-number-input__steppers .ws-icon-btn:focus-visible { outline-color: var(--ws-field-mark, var(--ws-focus-color)); }
|
|
12
|
+
@media (hover: hover) { .ws-number-input__steppers .ws-icon-btn:not(:disabled):hover { background-color: color-mix(in srgb, var(--ws-field-mark, var(--color-text-heading)) 6%, transparent); } }
|
|
13
|
+
/* A disabled field's marks are muted, as Select's chevron (its sunk ground is dark on the navy ground). */
|
|
14
|
+
.ws-number-input:has(> .ws-input:disabled) .ws-number-input__steppers .ws-icon-btn { color: var(--color-text-muted); }
|
|
15
|
+
/* The unit's room: 36 past its right inset (a three-letter unit and 11 before the number; the browser's spinner, now
|
|
16
|
+
hidden, used to hold this room). */
|
|
17
|
+
.ws-number-input--unit .ws-input { padding-right: var(--space-3xl); }
|
|
18
|
+
/* Steppers alone: the numbers end 12 before the minus (on the scale; 56 was not). */
|
|
19
|
+
.ws-number-input--steppers .ws-input { padding-right: var(--space-4xl); }
|
|
20
|
+
.ws-number-input--steppers.ws-number-input--unit .ws-input { padding-right: var(--space-6xl); }
|
|
21
|
+
.ws-number-input--steppers .ws-number-input__unit { right: calc(var(--space-4xl) - var(--space-xxs)); }
|
|
22
|
+
|
|
23
|
+
/* The browser's own spinner is hidden: the kit's steppers do its job, and on hover it sat over the unit. The arrow keys
|
|
24
|
+
still step the value. */
|
|
25
|
+
.ws-number-input .ws-input { appearance: textfield; }
|
|
26
|
+
.ws-number-input .ws-input::-webkit-inner-spin-button, .ws-number-input .ws-input::-webkit-outer-spin-button { margin: 0; appearance: none; }
|
|
27
|
+
/* Touch: each stepper's 40 px hit area (the house's touch block) sits whole, side by side, inside the field, so a tap on
|
|
28
|
+
the minus never lands on the plus: 8 from the edge, 16 between the two 24 px marks. */
|
|
29
|
+
@media (pointer: coarse) {
|
|
30
|
+
.ws-number-input__steppers { right: var(--space-xs); gap: var(--space-md); }
|
|
31
|
+
.ws-number-input--steppers .ws-input { padding-right: var(--space-5xl); }
|
|
32
|
+
.ws-number-input--steppers .ws-number-input__unit { right: var(--space-5xl); }
|
|
33
|
+
.ws-number-input--steppers.ws-number-input--unit .ws-input { padding-right: var(--space-7xl); }
|
|
34
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Progress toward a goal on a 14 px track, with a dot where it should be by now. North's bar, used in tiles, lanes and lists.
|
|
2
|
+
|
|
3
|
+
**Use it when**
|
|
4
|
+
|
|
5
|
+
- A number runs against a goal over a period and the question is "are we on pace?" (revenue this month, calls this week).
|
|
6
|
+
- The same bar repeats down a list or across tiles, so each one reads at a glance against its own pace.
|
|
7
|
+
|
|
8
|
+
**Not for**
|
|
9
|
+
|
|
10
|
+
- A share with no time in it: use `TickStrip` or `Meter`.
|
|
11
|
+
- A running job's progress: use `Meter` or `LoadBar`.
|
|
12
|
+
- Comparing many rows by length: use `GoalBars`.
|
|
13
|
+
|
|
14
|
+
**Anatomy**
|
|
15
|
+
|
|
16
|
+
- Slot 24 tall, the track centred in it: 14 tall (`--space-sm-plus`), 2 px corners, `--ws-track`.
|
|
17
|
+
- Fill from the left to `--value`, in `--tone`, square at its end (2 px at its start).
|
|
18
|
+
- Cuts: 1 px lines in the ground's colour at quarters or targets (`__cut`, `style="--at: 25%"`).
|
|
19
|
+
- Gap (`__gap`, behind pace only): the shortfall as an open box in the ground's colour with a 0.5 px edge in the tone, no
|
|
20
|
+
left edge, from the fill to the dot.
|
|
21
|
+
- Dot (`__dot`): 14 px, in the tone, a 1.5 px ring in the ground's colour, centred on `--pace`.
|
|
22
|
+
- Data on the bar: `style="--value: 48%; --pace: 70%; --tone: var(--ws-chart-past-half)"`.
|
|
23
|
+
|
|
24
|
+
| Modifier | What changes |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `--done` | the fill reaches the end and takes the track's corners on both sides |
|
|
27
|
+
| `--thin` | 5 px, no slot, 1 px corners, no dot: the bar under a heatmap lane's name |
|
|
28
|
+
| `--draw` | the fill grows in over 700 ms on `--ws-ease-settle`, the gap after it, then the dot pops |
|
|
29
|
+
|
|
30
|
+
**Tones (North's pace bands, on kit tokens)**
|
|
31
|
+
|
|
32
|
+
| Band | Tone |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| on or ahead of pace | `--ws-chart-finished` (teal) |
|
|
35
|
+
| behind | `--ws-chart-past-half` (purple) |
|
|
36
|
+
| off pace | `--ws-chart-needs-work` (pink) |
|
|
37
|
+
| no tone yet | `--color-text-heading` (navy) |
|
|
38
|
+
|
|
39
|
+
**States**
|
|
40
|
+
|
|
41
|
+
- Ahead: the fill runs past the dot; no gap.
|
|
42
|
+
- Behind: the gap shows how far.
|
|
43
|
+
- Zero: leave out `__fill`; the gap runs from 0 to the dot as a closed box with the track's start corners.
|
|
44
|
+
- Done: `--done`.
|
|
45
|
+
- Draw: as above; reduced motion shows the final state.
|
|
46
|
+
- Hover, focus: the bar is a picture; the row or tile around it takes the pointer.
|
|
47
|
+
|
|
48
|
+
**Behaviour**
|
|
49
|
+
|
|
50
|
+
- Give the bar `role="img"` and an `aria-label` with both numbers ("48% of the goal, pace is 70%"), or `aria-hidden` when
|
|
51
|
+
the words beside it already say them.
|
|
52
|
+
|
|
53
|
+
**Rules**
|
|
54
|
+
|
|
55
|
+
- One goal a bar. The words next to it say the number; the bar never carries a figure inside it.
|
|
56
|
+
- Marks keep the chart tones; any word in a tone takes its AA step.
|
|
57
|
+
|
|
58
|
+
**Source**
|
|
59
|
+
|
|
60
|
+
**Derived from**: North's five bars (`.pbar`, `.mc-bar`, `.ho-bar`, `.talk-bar`, `.mp-bar`), built from the base values
|
|
61
|
+
(14 track, 14 dot, 24 slot) rather than the tile's 1.09 scaled ones; the fill and dot timing from North's motion config.
|
|
62
|
+
North's own pace colours (#257985 teal, #744ccb purple, #9b1b5a plum) are mapped to the kit's chart tokens.
|
|
63
|
+
|
|
64
|
+
**Markup**
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<div class="ws-pace-bar" style="--value: 48%; --pace: 70%; --tone: var(--ws-chart-past-half);" role="img" aria-label="48% of the goal, pace is 70%">
|
|
68
|
+
<span class="ws-pace-bar__fill"></span>
|
|
69
|
+
<span class="ws-pace-bar__gap"></span>
|
|
70
|
+
<span class="ws-pace-bar__cut" style="--at: 50%;"></span>
|
|
71
|
+
<span class="ws-pace-bar__dot"></span>
|
|
72
|
+
</div>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Styles**: `PaceBar/style.css`, in `bundle.css` and `fello.css` as `.ws-pace-bar`. Every value is a token.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!-- @dsCard group="Progress" height=560 -->
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>PaceBar</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" style="max-width: 560px;">
|
|
14
|
+
<span class="ws-muted">Ahead of pace: the fill past the dot, quarter cuts, drawn in once</span>
|
|
15
|
+
<div class="ws-pace-bar ws-pace-bar--draw" style="--value: 72%; --pace: 64%; --tone: var(--ws-chart-finished);" role="img" aria-label="72% of the goal, pace is 64%">
|
|
16
|
+
<span class="ws-pace-bar__fill"></span>
|
|
17
|
+
<span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span>
|
|
18
|
+
<span class="ws-pace-bar__dot"></span>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="ws-stack" style="max-width: 560px;">
|
|
23
|
+
<span class="ws-muted">Behind pace: the shortfall as an open box in the tone, from the fill to the dot</span>
|
|
24
|
+
<div class="ws-pace-bar ws-pace-bar--draw" style="--value: 48%; --pace: 70%; --tone: var(--ws-chart-past-half);" role="img" aria-label="48% of the goal, pace is 70%">
|
|
25
|
+
<span class="ws-pace-bar__fill"></span>
|
|
26
|
+
<span class="ws-pace-bar__gap"></span>
|
|
27
|
+
<span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span>
|
|
28
|
+
<span class="ws-pace-bar__dot"></span>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="ws-stack" style="max-width: 560px;">
|
|
33
|
+
<span class="ws-muted">Far behind: the needs work tone</span>
|
|
34
|
+
<div class="ws-pace-bar" style="--value: 22%; --pace: 70%; --tone: var(--ws-chart-needs-work);" role="img" aria-label="22% of the goal, pace is 70%">
|
|
35
|
+
<span class="ws-pace-bar__fill"></span>
|
|
36
|
+
<span class="ws-pace-bar__gap"></span>
|
|
37
|
+
<span class="ws-pace-bar__dot"></span>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="ws-stack" style="max-width: 560px;">
|
|
42
|
+
<span class="ws-muted">Done: the goal met before the month is out</span>
|
|
43
|
+
<div class="ws-pace-bar ws-pace-bar--done" style="--value: 100%; --pace: 90%; --tone: var(--ws-chart-finished);" role="img" aria-label="100% of the goal, pace is 90%">
|
|
44
|
+
<span class="ws-pace-bar__fill"></span>
|
|
45
|
+
<span class="ws-pace-bar__dot"></span>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="ws-stack" style="max-width: 560px;">
|
|
50
|
+
<span class="ws-muted">Nothing yet: an empty track, the dot says where it should be by now</span>
|
|
51
|
+
<div class="ws-pace-bar" style="--value: 0%; --pace: 30%; --tone: var(--color-text-heading);" role="img" aria-label="0% of the goal, pace is 30%">
|
|
52
|
+
<span class="ws-pace-bar__gap"></span>
|
|
53
|
+
<span class="ws-pace-bar__dot"></span>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div class="ws-stack" style="max-width: 200px;">
|
|
58
|
+
<span class="ws-muted">Thin (5 px): under a heatmap lane's name</span>
|
|
59
|
+
<div class="ws-pace-bar ws-pace-bar--thin" style="--value: 64%; --tone: var(--ws-chart-finished);" role="img" aria-label="64% of pace">
|
|
60
|
+
<span class="ws-pace-bar__fill"></span>
|
|
61
|
+
<span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
</div>
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* ---- PaceBar: progress toward a goal on a 14 px track, with where it should be by now as a dot ---- */
|
|
2
|
+
/* Data on the bar: style="--value: 62%; --pace: 70%; --tone: ...". The fill runs from the left to --value; the dot sits
|
|
3
|
+
on --pace with a 1.5 px ring in the ground's colour; 1 px cuts in the ground's colour mark quarters or targets
|
|
4
|
+
(style="--at: 25%"); behind pace, the shortfall is an open box in the tone (__gap) from the fill to the dot.
|
|
5
|
+
The bar sits in a 24 px slot, the track centred in it. */
|
|
6
|
+
.ws-pace-bar { --value: 0%; --pace: 0%; --tone: var(--color-text-heading); --h: var(--space-sm-plus); position: relative; height: var(--space-lg); }
|
|
7
|
+
.ws-pace-bar::before, .ws-pace-bar__fill, .ws-pace-bar__gap { position: absolute; top: calc((100% - var(--h)) / 2); height: var(--h); }
|
|
8
|
+
.ws-pace-bar::before { content: ""; left: 0; right: 0; border-radius: var(--ws-radius-chip); background: var(--ws-track); }
|
|
9
|
+
.ws-pace-bar__fill { left: 0; width: var(--value); border-radius: var(--ws-radius-chip) 0 0 var(--ws-radius-chip); background: var(--tone); transform-origin: left; }
|
|
10
|
+
.ws-pace-bar__gap { left: var(--value); width: max(0%, calc(var(--pace) - var(--value))); border: var(--ws-hairline) solid var(--tone); border-left: 0; background: var(--color-bg-page); }
|
|
11
|
+
/* Nothing yet (no __fill): the shortfall starts the track, so it closes its box and takes the track's start corners. */
|
|
12
|
+
.ws-pace-bar:not(:has(> .ws-pace-bar__fill)) > .ws-pace-bar__gap { border-left: var(--ws-hairline) solid var(--tone); border-radius: var(--ws-radius-chip) 0 0 var(--ws-radius-chip); }
|
|
13
|
+
.ws-pace-bar__cut { position: absolute; top: calc((100% - var(--h)) / 2); left: var(--at); height: var(--h); border-left: var(--ws-line) solid var(--color-bg-page); }
|
|
14
|
+
.ws-pace-bar__dot { position: absolute; top: calc((100% - var(--h)) / 2); left: var(--pace); width: var(--h); height: var(--h); margin-left: calc(var(--h) / -2); border: calc(var(--ws-hairline) * 3) solid var(--color-bg-page); border-radius: var(--radius-full); background: var(--tone); }
|
|
15
|
+
/* Done: the fill reaches the end, so it takes the track's corners on both sides. */
|
|
16
|
+
.ws-pace-bar--done .ws-pace-bar__fill { width: 100%; border-radius: var(--ws-radius-chip); }
|
|
17
|
+
/* Thin: the 5 px bar under a heatmap lane's name, no slot of its own and no dot. */
|
|
18
|
+
.ws-pace-bar--thin { --h: calc(var(--space-xxs) + var(--ws-line)); height: var(--h); }
|
|
19
|
+
.ws-pace-bar--thin::before, .ws-pace-bar--thin .ws-pace-bar__fill { border-radius: var(--ws-radius-bar); }
|
|
20
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
21
|
+
/* The fill (North): 700 ms on the settle curve; the dot pops once the fill has landed. */
|
|
22
|
+
.ws-pace-bar--draw .ws-pace-bar__fill, .ws-pace-bar--draw .ws-pace-bar__gap { animation: ws-grow var(--ws-duration-fill) var(--ws-ease-settle) backwards; animation-delay: var(--ws-build-at, 0s); }
|
|
23
|
+
.ws-pace-bar--draw .ws-pace-bar__gap { transform-origin: left; animation-delay: calc(var(--ws-build-at, 0s) + var(--ws-duration-settle)); }
|
|
24
|
+
.ws-pace-bar--draw .ws-pace-bar__dot { animation: ws-bloom var(--ws-duration-settle) var(--ws-ease-pop) backwards; animation-delay: calc(var(--ws-build-at, 0s) + var(--ws-duration-fill)); }
|
|
25
|
+
}
|
|
@@ -8,29 +8,47 @@ and a cluster. All in fello.css; with these a page needs no layout CSS of its ow
|
|
|
8
8
|
|
|
9
9
|
## Not for
|
|
10
10
|
|
|
11
|
-
- A product area with a
|
|
11
|
+
- A product area with a nav and a bar: use `AppShell`. Its body is the page (it brings the same gutter, gap and size
|
|
12
|
+
container), so put the page's parts straight in it, with no `.ws-page` inside.
|
|
12
13
|
- A public, marketing page: its sections (`Hero`, `FeatureGrid`, `Footer`) size from the kit's `layout-content-max`
|
|
13
14
|
and `layout-margin`, full bleed (Public pages).
|
|
15
|
+
- A main column and its aside: `Split`.
|
|
14
16
|
- Laying out the inside of one component: the component's own classes do that.
|
|
15
17
|
|
|
16
18
|
## Anatomy
|
|
17
19
|
|
|
18
20
|
| Class | What it does | Values |
|
|
19
21
|
| --- | --- | --- |
|
|
20
|
-
| `.ws-page` | The page: a column of its parts, centred, at most two board columns wide | max `2 x --ws-chart-card-w + --ws-gap-component` (1128) plus the gutters;
|
|
21
|
-
| `.ws-page--column` | The one column: a form, a reading page
|
|
22
|
-
| `.ws-area` | Any other region
|
|
23
|
-
| `.ws-board` | A board of chart cards (`CardBoard`): two side by side once both fit at 480, each up to 556; below that one column at full width, in DOM order | grid by width, `--ws-chart-card-min`, `--ws-chart-card-w`, gap 16 |
|
|
22
|
+
| `.ws-page` | The page: a column of its parts, centred, at most two board columns wide | max `2 x --ws-chart-card-w + --ws-gap-component` (1128) plus the gutters; Seth's 32 gutter (`--space-xl`, D4), 16 on a phone (under 40rem); parts 16 apart; a size container |
|
|
23
|
+
| `.ws-page--column` | The one column: a form, a reading page | max `--ws-column-width` (656) plus the gutters |
|
|
24
|
+
| `.ws-area` | Any other region a component without its own container should size from | `container-type: inline-size` |
|
|
25
|
+
| `.ws-board` | A board of chart cards (`CardBoard`): two side by side once both fit at 480, each up to 556; below that one column at full width, in DOM order; on the content's start edge, never centred | grid by width, `--ws-chart-card-min`, `--ws-chart-card-w`, gap 16 |
|
|
24
26
|
| `.ws-board__column` | A column of cards inside the board, each card its own height | gap 16 |
|
|
25
|
-
| `.ws-board--4` | Small cards
|
|
27
|
+
| `.ws-board--4` | Small cards: one across, two from 40rem, four from 60rem **of the board's own width** (K3) | a size container named `ws-board`, four tracks, each card spans 4, 2 or 1 |
|
|
26
28
|
| `.ws-stack` | Things top to bottom | gap `--ws-gap` (8) |
|
|
27
29
|
| `.ws-cluster` | Things side by side, centred, wrapping | gap `--ws-gap` (8); `--start` aligns them to the top |
|
|
28
30
|
| `--tight`, `--loose`, `--component`, `--group` | The other named gaps, on a stack or a cluster | 4, 12, 16, 24 |
|
|
31
|
+
| `.ws-stack--block` | Seth's report blocks, top to bottom (a stack only) | `--ws-gap-block` (32) |
|
|
32
|
+
| `.ws-stack--section` | Page sections, top to bottom (a stack only) | `--ws-gap-section` (56) |
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
Which stack each Fia page (Seth's frames, `11-page-recipes.md`) uses, so a page never writes its own gap:
|
|
35
|
+
|
|
36
|
+
| Page | Its column | Inside each block |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Grow audit report (recipe 23) | `.ws-stack--block`: the tabs, the `ScoreHero`, the checks, 32 apart | `.ws-stack--component` (16): a heading and its card |
|
|
39
|
+
| Fixes checklist | `.ws-stack--block`: the areas, 32 apart (Seth's 28 snaps to it, D4) | the area heading 10 over its card (`Section`) |
|
|
40
|
+
| Tally report | `.ws-stack--section`: the hero, the bill row, the vendor board, 56 apart | `.ws-stack--loose` (12): a board's head, body and source |
|
|
41
|
+
| Review inbox (recipe 24) | no stack: one three-column grid, 8 apart (`ListDetail`) | the card's own parts |
|
|
42
|
+
| First open (recipe 22) | the thread's column (`ChatShell`) | the card's own parts |
|
|
43
|
+
|
|
44
|
+
The four app pages (Grow, Fixes, Tally, Inbox) sit in `ws-app-shell__body--wide` (Seth's 1350), under the thread header (`PageBar`).
|
|
45
|
+
|
|
46
|
+
- The page's width comes from the board: two 556 columns and the gap, so a board of two columns fills the page and
|
|
47
|
+
lines up with the bar and tiles above it.
|
|
48
|
+
- `.ws-board--4` measures itself, so the same markup is four across on a wide page, two in a 700 px pane and one in a
|
|
49
|
+
card, with no `.ws-area` round it. Give it four, two or one cards; never three or five (a 4 + 1 orphan).
|
|
50
|
+
- A column that can be height-bound (`.ws-page`, `.ws-stack`, `.ws-board__column`) never squashes its children (K1);
|
|
51
|
+
a child that should scroll inside says so (`flex: 1; min-height: 0; overflow: auto`).
|
|
34
52
|
|
|
35
53
|
## Variants and sizes
|
|
36
54
|
|
|
@@ -41,15 +59,15 @@ and a cluster. All in fello.css; with these a page needs no layout CSS of its ow
|
|
|
41
59
|
|
|
42
60
|
## States
|
|
43
61
|
|
|
44
|
-
- **Wide** (content of 976 and up): two board columns;
|
|
45
|
-
- **Middle**: one board column at the page's full width
|
|
62
|
+
- **Wide** (content of 976 and up): two board columns; small cards four across from 960 of board width.
|
|
63
|
+
- **Middle**: one board column at the page's full width; small cards two across.
|
|
46
64
|
- **Phone**: a 16 gutter, one column, the same DOM order.
|
|
47
65
|
|
|
48
66
|
## Behaviour
|
|
49
67
|
|
|
50
68
|
- The page scrolls as a whole: nothing in it sets a fixed height or hides overflow, so no part traps its content.
|
|
51
69
|
- Order is DOM order at every width, so keyboard and screen-reader order never changes with the layout.
|
|
52
|
-
- No motion of its own;
|
|
70
|
+
- No motion of its own; parts settle in (`ws-settle`, `--ws-i` for the 22 ms stagger).
|
|
53
71
|
|
|
54
72
|
## Content
|
|
55
73
|
|
|
@@ -59,12 +77,33 @@ and a cluster. All in fello.css; with these a page needs no layout CSS of its ow
|
|
|
59
77
|
## Rules
|
|
60
78
|
|
|
61
79
|
- **The gutter is the page's**: a card never adds a margin; the board's and the page's gaps separate things.
|
|
62
|
-
- **Size from the region, not the window**:
|
|
80
|
+
- **Size from the region, not the window**: adaptive pieces measure themselves (`.ws-board--4`, `PageHero`, `Split`).
|
|
63
81
|
- **Write no layout CSS**: a page made from these classes and the catalog's components needs only fello.css.
|
|
64
82
|
|
|
65
83
|
## Source
|
|
66
84
|
|
|
67
|
-
**Derived from**: Space and layout (the gaps, the
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
**Derived from**: Space and layout (the gaps, the board's 556 and 480, area-sm to area-xl at 40, 48, 60 and 76 rem),
|
|
86
|
+
the first product's Grow board, Seth's 32 gutter (D4, the Tally frame) and Revenue OS faults K1, K3 and K12 (4 Nov
|
|
87
|
+
2026). The page's maximum width is derived from the board, 27 Oct 2026, since the system had none.
|
|
88
|
+
|
|
89
|
+
## Markup
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<main class="ws-page">
|
|
93
|
+
<header class="ws-page-bar">
|
|
94
|
+
<div class="ws-page-bar__words"><h1 class="ws-page-bar__title">Team this month</h1><span class="ws-page-bar__context">Since Oct 1</span></div>
|
|
95
|
+
</header>
|
|
96
|
+
<ul class="ws-board ws-board--4" aria-label="This month">
|
|
97
|
+
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Calls</span><span class="ws-figure ws-figure--tile">142</span></li>
|
|
98
|
+
<!-- four, two or one -->
|
|
99
|
+
</ul>
|
|
100
|
+
<div class="ws-board">
|
|
101
|
+
<!-- chart cards -->
|
|
102
|
+
</div>
|
|
103
|
+
</main>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Styles
|
|
107
|
+
|
|
108
|
+
The page, the board, the stack and the cluster are in `_house.css`; `Page/style.css` holds the self-measuring
|
|
109
|
+
`.ws-board--4`. The 32 gutter is the global `--ws-gutter` (16 on a phone). Tokens: `--ws-gutter`, `--space-md`, `--ws-gap-component`, `--ws-chart-card-w`, `--ws-chart-card-min`, `--ws-column-width`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Layout" height=
|
|
1
|
+
<!-- @dsCard group="Layout" height=594 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -13,19 +13,19 @@
|
|
|
13
13
|
<header class="ws-page-bar">
|
|
14
14
|
<div class="ws-page-bar__words">
|
|
15
15
|
<h1 class="ws-page-bar__title">Team this month</h1>
|
|
16
|
-
<
|
|
16
|
+
<span class="ws-page-bar__context">Since Oct 1</span>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="ws-page-bar__acts">
|
|
19
|
-
<button class="ws-btn ws-btn--primary">Export</button>
|
|
19
|
+
<button type="button" class="ws-btn ws-btn--primary">Export</button>
|
|
20
20
|
</div>
|
|
21
21
|
</header>
|
|
22
22
|
|
|
23
|
-
<span class="ws-muted">.ws-board--4
|
|
23
|
+
<span class="ws-muted">.ws-board--4 measures itself: one across, two from 40rem of its own width, four from 60rem</span>
|
|
24
24
|
<ul class="ws-board ws-board--4" aria-label="This month">
|
|
25
|
-
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Calls</span><span class="ws-figure">142</span></li>
|
|
26
|
-
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Shows</span><span class="ws-figure">31</span></li>
|
|
27
|
-
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Follow-ups</span><span class="ws-figure">58</span></li>
|
|
28
|
-
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">New leads</span><span class="ws-figure">14</span></li>
|
|
25
|
+
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Calls</span><span class="ws-figure ws-figure--tile">142</span></li>
|
|
26
|
+
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Shows</span><span class="ws-figure ws-figure--tile">31</span></li>
|
|
27
|
+
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">Follow-ups</span><span class="ws-figure ws-figure--tile">58</span></li>
|
|
28
|
+
<li class="ws-card ws-card--inset ws-stack ws-stack--tight"><span class="ws-muted">New leads</span><span class="ws-figure ws-figure--tile">14</span></li>
|
|
29
29
|
</ul>
|
|
30
30
|
|
|
31
31
|
<span class="ws-muted">.ws-board: chart cards, two across once both fit at 480 (each up to 556), else one at full width</span>
|
|
@@ -39,18 +39,16 @@
|
|
|
39
39
|
<span class="ws-chip">Follow-up</span>
|
|
40
40
|
</div>
|
|
41
41
|
<div class="ws-cluster ws-cluster--loose">
|
|
42
|
-
<button class="ws-btn ws-btn--secondary">Share</button>
|
|
43
|
-
<button class="ws-btn ws-btn--ghost">Not now</button>
|
|
42
|
+
<button type="button" class="ws-btn ws-btn--secondary">Share</button>
|
|
43
|
+
<button type="button" class="ws-btn ws-btn--ghost">Not now</button>
|
|
44
44
|
</div>
|
|
45
45
|
</section>
|
|
46
46
|
<section class="ws-card ws-card--inset ws-stack ws-stack--loose" aria-labelledby="page-area">
|
|
47
|
-
<h2 class="ws-title" id="page-area">
|
|
48
|
-
<p class="ws-body">
|
|
49
|
-
<div class="ws-
|
|
50
|
-
<div class="ws-
|
|
51
|
-
|
|
52
|
-
<div class="ws-plate ws-stack ws-stack--tight"><span class="ws-muted">Done</span><span class="ws-section">26</span></div>
|
|
53
|
-
</div>
|
|
47
|
+
<h2 class="ws-title" id="page-area">A board in a card</h2>
|
|
48
|
+
<p class="ws-body">The small-card board sizes from its own width, not the page's: in this card it is one across, with no .ws-area round it.</p>
|
|
49
|
+
<div class="ws-board ws-board--4">
|
|
50
|
+
<div class="ws-plate ws-stack ws-stack--tight"><span class="ws-muted">Goal</span><span class="ws-section">40</span></div>
|
|
51
|
+
<div class="ws-plate ws-stack ws-stack--tight"><span class="ws-muted">Done</span><span class="ws-section">26</span></div>
|
|
54
52
|
</div>
|
|
55
53
|
</section>
|
|
56
54
|
</div>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* ---- Page: the page's own values in 0.5.0 (the page, the board and the stack live in _house.css). Seth's 32 gutter (D4) is the
|
|
2
|
+
global --ws-gutter now, 16 on a phone as before. A board of small cards measures itself (K3): one across, two from 40rem of the board's own
|
|
3
|
+
width, four from 60rem, so it is right in a pane, a column or the shell's body, with no .ws-area round it. ---- */
|
|
4
|
+
.ws-board--4 { container: ws-board / inline-size; grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
|
5
|
+
.ws-board--4 > * { grid-column: span 4; }
|
|
6
|
+
@container ws-board (min-width: 40rem) { .ws-board--4 > * { grid-column: span 2; } }
|
|
7
|
+
@container ws-board (min-width: 60rem) { .ws-board--4 > * { grid-column: span 1; } }
|