@felloinnovations/brand-kit 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +198 -24
- package/CHANGELOG.md +197 -0
- package/README.md +34 -7
- package/design-system/01-how-claude-decides.md +26 -17
- package/design-system/02-principles.md +11 -6
- package/design-system/03-colour.md +134 -47
- package/design-system/04-type.md +45 -23
- package/design-system/05-space-and-layout.md +175 -52
- package/design-system/06-sizing-profiles.md +4 -4
- package/design-system/07-scrolling.md +66 -20
- package/design-system/08-choosing-components.md +50 -22
- package/design-system/09-charts.md +71 -28
- package/design-system/10-patterns.md +33 -10
- package/design-system/11-page-recipes.md +110 -23
- package/design-system/12-content.md +2 -1
- package/design-system/13-motion.md +330 -47
- package/design-system/14-accessibility.md +47 -24
- package/design-system/15-ai-experiences.md +11 -6
- package/design-system/16-creativity.md +1 -1
- package/design-system/17-decisions.md +357 -1
- package/design-system/18-checklist.md +79 -16
- package/design-system/19-public-pages.md +6 -4
- package/design-system/20-palettes.md +275 -0
- package/design-system/README.md +30 -17
- package/design-system/components/ActionList/README.md +96 -10
- package/design-system/components/ActionList/preview.html +52 -7
- package/design-system/components/ActionList/style.css +64 -0
- package/design-system/components/ActivityGrid/README.md +38 -2
- package/design-system/components/ActivityGrid/preview.html +1 -1
- package/design-system/components/ActivityGrid/style.css +35 -0
- package/design-system/components/AppShell/README.md +205 -75
- package/design-system/components/AppShell/preview.html +339 -58
- package/design-system/components/AppShell/style.css +154 -0
- package/design-system/components/Avatar/README.md +37 -10
- package/design-system/components/Avatar/preview.html +13 -4
- package/design-system/components/Avatar/style.css +14 -0
- package/design-system/components/Badge/README.md +41 -19
- package/design-system/components/Badge/preview.html +13 -10
- package/design-system/components/Badge/style.css +23 -0
- package/design-system/components/Banner/README.md +30 -9
- package/design-system/components/Banner/preview.html +1 -1
- package/design-system/components/Banner/style.css +19 -0
- package/design-system/components/Breadcrumb/README.md +58 -46
- package/design-system/components/Breadcrumb/preview.html +16 -16
- package/design-system/components/Breadcrumb/style.css +17 -0
- package/design-system/components/Button/README.md +113 -55
- package/design-system/components/Button/preview.html +98 -25
- package/design-system/components/Button/style.css +86 -0
- package/design-system/components/Card/README.md +158 -49
- package/design-system/components/Card/preview.html +141 -19
- package/design-system/components/Card/style.css +115 -0
- package/design-system/components/CardBoard/README.md +58 -37
- package/design-system/components/CardBoard/preview.html +26 -29
- package/design-system/components/ChatCard/README.md +115 -29
- package/design-system/components/ChatCard/preview.html +149 -32
- package/design-system/components/ChatCard/style.css +49 -0
- package/design-system/components/ChatShell/README.md +116 -0
- package/design-system/components/ChatShell/preview.html +201 -0
- package/design-system/components/ChatShell/style.css +86 -0
- package/design-system/components/ChatTurn/README.md +78 -35
- package/design-system/components/ChatTurn/preview.html +60 -28
- package/design-system/components/ChatTurn/style.css +50 -0
- package/design-system/components/CheckRow/README.md +141 -0
- package/design-system/components/CheckRow/preview.html +140 -0
- package/design-system/components/CheckRow/style.css +88 -0
- package/design-system/components/Checkbox/README.md +58 -22
- package/design-system/components/Checkbox/preview.html +112 -50
- package/design-system/components/Checkbox/style.css +45 -0
- package/design-system/components/Chip/README.md +78 -47
- package/design-system/components/Chip/preview.html +29 -4
- package/design-system/components/Chip/style.css +17 -0
- package/design-system/components/Combobox/README.md +44 -11
- package/design-system/components/Combobox/preview.html +35 -12
- package/design-system/components/Combobox/style.css +54 -0
- package/design-system/components/Composer/README.md +137 -35
- package/design-system/components/Composer/preview.html +115 -40
- package/design-system/components/Composer/style.css +81 -0
- package/design-system/components/ConfirmDialog/README.md +73 -52
- package/design-system/components/ConfirmDialog/preview.html +70 -26
- package/design-system/components/ConfirmDialog/style.css +5 -0
- package/design-system/components/Cover/preview.html +3 -3
- package/design-system/components/Cover/style.css +19 -0
- package/design-system/components/DateInput/README.md +77 -12
- package/design-system/components/DateInput/preview.html +27 -12
- package/design-system/components/DateInput/style.css +38 -0
- package/design-system/components/Dialog/README.md +112 -44
- package/design-system/components/Dialog/preview.html +141 -18
- package/design-system/components/Dialog/style.css +74 -0
- package/design-system/components/EmptyState/README.md +42 -12
- package/design-system/components/EmptyState/preview.html +11 -11
- package/design-system/components/EmptyState/style.css +9 -0
- package/design-system/components/EntryShell/README.md +73 -48
- package/design-system/components/EntryShell/preview.html +60 -27
- package/design-system/components/EntryShell/style.css +19 -0
- package/design-system/components/FeatureGrid/README.md +61 -39
- package/design-system/components/FeatureGrid/preview.html +2 -2
- package/design-system/components/FeatureGrid/style.css +20 -0
- package/design-system/components/FileUpload/README.md +33 -3
- package/design-system/components/FileUpload/preview.html +18 -4
- package/design-system/components/FileUpload/style.css +23 -0
- package/design-system/components/FilterBar/README.md +114 -0
- package/design-system/components/FilterBar/preview.html +82 -0
- package/design-system/components/FilterBar/style.css +22 -0
- package/design-system/components/Fold/README.md +84 -26
- package/design-system/components/Fold/preview.html +77 -34
- package/design-system/components/Fold/style.css +48 -0
- package/design-system/components/Footer/README.md +62 -39
- package/design-system/components/Footer/preview.html +5 -5
- package/design-system/components/Footer/style.css +30 -0
- package/design-system/components/FunnelBars/README.md +24 -3
- package/design-system/components/FunnelBars/preview.html +5 -5
- package/design-system/components/FunnelBars/style.css +13 -0
- package/design-system/components/GoalBars/README.md +54 -10
- package/design-system/components/GoalBars/preview.html +69 -28
- package/design-system/components/GoalBars/style.css +51 -0
- package/design-system/components/GoalTicks/README.md +74 -58
- package/design-system/components/GoalTicks/preview.html +41 -118
- package/design-system/components/GoalTicks/style.css +37 -0
- package/design-system/components/GoalTubes/README.md +29 -3
- package/design-system/components/GoalTubes/preview.html +6 -6
- package/design-system/components/GoalTubes/style.css +23 -0
- package/design-system/components/Heatmap/README.md +133 -0
- package/design-system/components/Heatmap/preview.html +168 -0
- package/design-system/components/Heatmap/style.css +119 -0
- package/design-system/components/Hero/README.md +58 -40
- package/design-system/components/Hero/preview.html +1 -1
- package/design-system/components/Hero/style.css +19 -0
- package/design-system/components/HoverCard/README.md +114 -0
- package/design-system/components/HoverCard/preview.html +107 -0
- package/design-system/components/HoverCard/style.css +59 -0
- package/design-system/components/IconButton/README.md +69 -38
- package/design-system/components/IconButton/preview.html +77 -43
- package/design-system/components/IconButton/style.css +45 -0
- package/design-system/components/Input/README.md +36 -11
- package/design-system/components/Input/preview.html +1 -1
- package/design-system/components/Input/style.css +23 -0
- package/design-system/components/KanbanBoard/README.md +93 -45
- package/design-system/components/KanbanBoard/preview.html +159 -43
- package/design-system/components/KanbanBoard/style.css +53 -0
- package/design-system/components/Kbd/README.md +25 -9
- package/design-system/components/Kbd/preview.html +6 -2
- package/design-system/components/Kbd/style.css +9 -0
- package/design-system/components/KitButton/README.md +81 -47
- package/design-system/components/KitButton/preview.html +35 -13
- package/design-system/components/KitButton/style.css +46 -0
- package/design-system/components/KitCard/README.md +75 -44
- package/design-system/components/KitCard/preview.html +18 -10
- package/design-system/components/KitCard/style.css +15 -0
- package/design-system/components/KitInput/README.md +54 -39
- package/design-system/components/KitInput/preview.html +7 -7
- package/design-system/components/KitInput/style.css +23 -0
- package/design-system/components/Leaderboard/README.md +76 -49
- package/design-system/components/Leaderboard/preview.html +61 -26
- package/design-system/components/Leaderboard/style.css +44 -0
- package/design-system/components/ListDetail/README.md +222 -0
- package/design-system/components/ListDetail/preview.html +213 -0
- package/design-system/components/ListDetail/style.css +148 -0
- package/design-system/components/LoadBar/README.md +79 -0
- package/design-system/components/LoadBar/preview.html +40 -0
- package/design-system/components/LoadBar/style.css +17 -0
- package/design-system/components/MarketingNav/README.md +76 -42
- package/design-system/components/MarketingNav/preview.html +37 -8
- package/design-system/components/MarketingNav/style.css +45 -0
- package/design-system/components/Matrix/README.md +129 -0
- package/design-system/components/Matrix/preview.html +99 -0
- package/design-system/components/Matrix/style.css +84 -0
- package/design-system/components/Menu/README.md +117 -41
- package/design-system/components/Menu/preview.html +85 -23
- package/design-system/components/Menu/style.css +61 -0
- package/design-system/components/Meter/README.md +39 -4
- package/design-system/components/Meter/preview.html +18 -1
- package/design-system/components/Meter/style.css +23 -0
- package/design-system/components/MetricTile/README.md +237 -0
- package/design-system/components/MetricTile/preview.html +241 -0
- package/design-system/components/MetricTile/style.css +129 -0
- package/design-system/components/Morph/README.md +106 -0
- package/design-system/components/Morph/preview.html +103 -0
- package/design-system/components/Morph/style.css +31 -0
- package/design-system/components/Motion/README.md +164 -0
- package/design-system/components/Motion/preview.html +2537 -0
- package/design-system/components/NumberInput/README.md +27 -8
- package/design-system/components/NumberInput/preview.html +21 -5
- package/design-system/components/NumberInput/style.css +34 -0
- package/design-system/components/PaceBar/README.md +75 -0
- package/design-system/components/PaceBar/preview.html +67 -0
- package/design-system/components/PaceBar/style.css +25 -0
- package/design-system/components/Page/README.md +57 -18
- package/design-system/components/Page/preview.html +15 -17
- package/design-system/components/Page/style.css +7 -0
- package/design-system/components/PageBar/README.md +90 -34
- package/design-system/components/PageBar/preview.html +60 -19
- package/design-system/components/PageBar/style.css +35 -0
- package/design-system/components/PageHero/README.md +87 -51
- package/design-system/components/PageHero/preview.html +35 -6
- package/design-system/components/PageHero/style.css +31 -0
- package/design-system/components/Pagination/README.md +70 -49
- package/design-system/components/Pagination/preview.html +24 -15
- package/design-system/components/Pagination/style.css +12 -0
- package/design-system/components/Panel/README.md +109 -51
- package/design-system/components/Panel/preview.html +118 -20
- package/design-system/components/Panel/style.css +51 -0
- package/design-system/components/PasswordInput/README.md +50 -18
- package/design-system/components/PasswordInput/preview.html +71 -21
- package/design-system/components/PasswordInput/style.css +31 -0
- package/design-system/components/Plate/README.md +75 -17
- package/design-system/components/Plate/preview.html +40 -7
- package/design-system/components/Plate/style.css +37 -0
- package/design-system/components/Popover/README.md +70 -49
- package/design-system/components/Popover/preview.html +44 -22
- package/design-system/components/Popover/style.css +41 -0
- package/design-system/components/PricingTable/README.md +69 -49
- package/design-system/components/PricingTable/preview.html +21 -21
- package/design-system/components/PricingTable/style.css +21 -0
- package/design-system/components/ProgressPetals/README.md +31 -3
- package/design-system/components/ProgressPetals/preview.html +14 -15
- package/design-system/components/ProgressPetals/style.css +27 -0
- package/design-system/components/README.md +151 -0
- package/design-system/components/Radio/README.md +40 -17
- package/design-system/components/Radio/preview.html +16 -1
- package/design-system/components/Radio/style.css +21 -0
- package/design-system/components/RankBar/README.md +29 -2
- package/design-system/components/RankBar/preview.html +14 -12
- package/design-system/components/RankBar/style.css +18 -0
- package/design-system/components/Ring/README.md +61 -11
- package/design-system/components/Ring/preview.html +55 -10
- package/design-system/components/Ring/style.css +49 -0
- package/design-system/components/ScoreHero/README.md +91 -0
- package/design-system/components/ScoreHero/preview.html +104 -0
- package/design-system/components/ScoreHero/style.css +32 -0
- package/design-system/components/Section/README.md +72 -33
- package/design-system/components/Section/preview.html +46 -16
- package/design-system/components/Section/style.css +18 -0
- package/design-system/components/Segmented/README.md +100 -55
- package/design-system/components/Segmented/preview.html +107 -26
- package/design-system/components/Segmented/style.css +94 -0
- package/design-system/components/SegmentedProgress/README.md +64 -0
- package/design-system/components/SegmentedProgress/preview.html +69 -0
- package/design-system/components/SegmentedProgress/style.css +11 -0
- package/design-system/components/Select/README.md +47 -12
- package/design-system/components/Select/preview.html +28 -2
- package/design-system/components/Select/style.css +22 -0
- package/design-system/components/ShareBar/README.md +69 -0
- package/design-system/components/ShareBar/preview.html +72 -0
- package/design-system/components/ShareBar/style.css +25 -0
- package/design-system/components/SideList/README.md +147 -0
- package/design-system/components/SideList/preview.html +139 -0
- package/design-system/components/SideList/style.css +94 -0
- package/design-system/components/Skeleton/README.md +52 -16
- package/design-system/components/Skeleton/preview.html +35 -23
- package/design-system/components/Skeleton/style.css +22 -0
- package/design-system/components/Slider/README.md +95 -0
- package/design-system/components/Slider/preview.html +49 -0
- package/design-system/components/Slider/style.css +13 -0
- package/design-system/components/Split/README.md +112 -0
- package/design-system/components/Split/preview.html +105 -0
- package/design-system/components/Split/style.css +30 -0
- package/design-system/components/Starter/README.md +21 -9
- package/design-system/components/Starter/preview.html +5 -5
- package/design-system/components/Stat/README.md +64 -43
- package/design-system/components/Stat/preview.html +3 -3
- package/design-system/components/Stat/style.css +15 -0
- package/design-system/components/StatTiles/README.md +88 -44
- package/design-system/components/StatTiles/preview.html +142 -71
- package/design-system/components/StatTiles/style.css +64 -0
- package/design-system/components/StatusLine/README.md +85 -0
- package/design-system/components/StatusLine/preview.html +49 -0
- package/design-system/components/StatusLine/style.css +14 -0
- package/design-system/components/StatusScreen/README.md +49 -35
- package/design-system/components/StatusScreen/preview.html +20 -5
- package/design-system/components/StatusScreen/style.css +9 -0
- package/design-system/components/StepLine/README.md +97 -0
- package/design-system/components/StepLine/preview.html +108 -0
- package/design-system/components/StepLine/style.css +62 -0
- package/design-system/components/Stepper/README.md +35 -13
- package/design-system/components/Stepper/style.css +13 -0
- package/design-system/components/StreakCalendar/README.md +22 -1
- package/design-system/components/StreakCalendar/preview.html +10 -10
- package/design-system/components/StreakCalendar/style.css +12 -0
- package/design-system/components/SuggestionChip/README.md +87 -0
- package/design-system/components/SuggestionChip/preview.html +42 -0
- package/design-system/components/SuggestionChip/style.css +20 -0
- package/design-system/components/Switch/README.md +44 -24
- package/design-system/components/Switch/preview.html +23 -8
- package/design-system/components/Switch/style.css +31 -0
- package/design-system/components/Table/README.md +129 -58
- package/design-system/components/Table/preview.html +106 -72
- package/design-system/components/Table/style.css +104 -0
- package/design-system/components/Tabs/README.md +71 -46
- package/design-system/components/Tabs/preview.html +56 -24
- package/design-system/components/Tabs/style.css +44 -0
- package/design-system/components/Testimonial/README.md +48 -32
- package/design-system/components/Testimonial/preview.html +14 -14
- package/design-system/components/Testimonial/style.css +12 -0
- package/design-system/components/TextArea/README.md +27 -11
- package/design-system/components/TextArea/preview.html +8 -2
- package/design-system/components/TextArea/style.css +12 -0
- package/design-system/components/ThemeSwitch/README.md +116 -0
- package/design-system/components/ThemeSwitch/preview.html +57 -0
- package/design-system/components/ThemeSwitch/style.css +6 -0
- package/design-system/components/TickRow/README.md +52 -36
- package/design-system/components/TickRow/preview.html +64 -41
- package/design-system/components/TickRow/style.css +23 -0
- package/design-system/components/TickStrip/README.md +95 -0
- package/design-system/components/TickStrip/preview.html +88 -0
- package/design-system/components/TickStrip/style.css +42 -0
- package/design-system/components/Tile/README.md +79 -18
- package/design-system/components/Tile/preview.html +91 -40
- package/design-system/components/Tile/style.css +36 -0
- package/design-system/components/Timeline/README.md +68 -48
- package/design-system/components/Timeline/preview.html +27 -15
- package/design-system/components/Timeline/style.css +25 -0
- package/design-system/components/Toast/README.md +70 -38
- package/design-system/components/Toast/preview.html +43 -8
- package/design-system/components/Toast/style.css +25 -0
- package/design-system/components/Tooltip/README.md +93 -35
- package/design-system/components/Tooltip/preview.html +69 -15
- package/design-system/components/Tooltip/style.css +78 -0
- package/design-system/components/TopBar/README.md +67 -53
- package/design-system/components/TopBar/preview.html +14 -27
- package/design-system/components/TopBar/style.css +35 -0
- package/design-system/components/TopicRail/README.md +108 -0
- package/design-system/components/TopicRail/preview.html +58 -0
- package/design-system/components/TopicRail/style.css +48 -0
- package/design-system/components/TrendBars/README.md +52 -14
- package/design-system/components/TrendBars/preview.html +65 -32
- package/design-system/components/TrendBars/style.css +25 -0
- package/design-system/components/TrendLine/README.md +164 -0
- package/design-system/components/TrendLine/preview.html +373 -0
- package/design-system/components/TrendLine/style.css +155 -0
- package/design-system/components/Well/README.md +64 -22
- package/design-system/components/Well/preview.html +14 -14
- package/design-system/components/Well/style.css +22 -0
- package/design-system/components/_house.css +324 -0
- package/design-system/components/bundle.css +4091 -744
- package/design-system/tokens.json +1314 -124
- package/dist/fello-core.css +2 -2
- package/dist/fello.css +6 -1369
- package/dist/fello.scoped.css +7 -0
- package/dist/index.d.ts +110 -11
- package/dist/index.js +781 -96
- package/dist/palettes.d.ts +464 -0
- package/dist/palettes.js +497 -0
- package/dist/scoped.d.ts +3 -0
- package/dist/scoped.js +16 -0
- package/dist/toast.d.ts +14 -0
- package/dist/toast.js +33 -29
- package/dist/tokens.d.ts +1686 -62
- package/dist/tokens.js +1668 -61
- package/package.json +20 -4
- package/scripts/check-palette.mjs +295 -0
- package/scripts/token-model.mjs +552 -0
- package/tokens/_dark.css +174 -0
- package/tokens/_palettes.css +46 -0
- package/tokens/_product.css +266 -53
- package/tokens/_source.hubl.css +39 -19
- package/tokens/design-tokens.json +319 -0
- package/tokens/palettes.ts +504 -0
- package/tokens/shadcn-compat.css +19 -19
- package/tokens/shadcn-compat.hsl.css +76 -0
- package/tokens/tokens.css +1292 -62
- package/tokens/tokens.md +588 -61
- package/tokens/tokens.root.css +1298 -62
- package/tokens/tokens.ts +1677 -64
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* ---- ActionList: a card's ranked list of next acts: who or what, the reason in words, the one act at the right. --brief
|
|
2
|
+
is North's "what changed" list on a page's head: one quiet 40 px line each, the line taking the surface on hover with
|
|
3
|
+
its acts appearing on it ---- */
|
|
4
|
+
.ws-action-list { container: ws-action-list / inline-size; display: flex; flex-direction: column; }
|
|
5
|
+
/* A row: 12 above and below, the card's 20 px edge at both sides (the head above it uses the same edge), 16 between
|
|
6
|
+
parts (Seth's fix row), a 0.5 px line between rows. Every part sits on the name's first line (Seth's fix row), however
|
|
7
|
+
many lines the reason runs to: that line is 24 (a chip's height, held without one), and the lead (the 28 avatar;
|
|
8
|
+
another mark sets --ws-action-list-lead to its height) and the act are trimmed to it by their margins, so they centre on it. */
|
|
9
|
+
.ws-action-list__row { --ws-action-list-line: var(--space-lg); --ws-action-list-lead: var(--ws-control-h-sm); --ws-action-list-act: var(--ws-control-h-sm); display: flex; align-items: flex-start; gap: var(--space-md); padding: var(--space-sm) var(--ws-card-inset); }
|
|
10
|
+
.ws-action-list__row > :first-child:not(.ws-action-list__text) { flex-shrink: 0; margin-block: calc((var(--ws-action-list-line) - var(--ws-action-list-lead)) / 2); }
|
|
11
|
+
@media (pointer: coarse) { .ws-action-list__row { --ws-action-list-act: var(--ws-touch); } }
|
|
12
|
+
.ws-action-list__row + .ws-action-list__row { border-top: var(--ws-divider); }
|
|
13
|
+
.ws-action-list__text { display: flex; flex: 1; flex-direction: column; gap: var(--space-xxs); min-width: 0; }
|
|
14
|
+
/* The name: Seth's row name, 15 / 20 medium navy, an optional chip beside it; the reason a 14 / 20 description. */
|
|
15
|
+
.ws-action-list__title { display: flex; flex-wrap: wrap; align-items: center; min-height: var(--ws-action-list-line); gap: var(--space-xxs) var(--space-xs); font-size: var(--ws-text-section); line-height: var(--ws-leading-row); font-weight: 500; color: var(--color-text-heading); }
|
|
16
|
+
.ws-action-list__reason { font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); color: var(--color-text-body); }
|
|
17
|
+
.ws-action-list__act { flex-shrink: 0; margin-block: calc((var(--ws-action-list-line) - var(--ws-action-list-act)) / 2); }
|
|
18
|
+
/* Loading: a ghost line where the name and the reason go (add ws-shimmer). */
|
|
19
|
+
.ws-action-list__ghost { display: block; height: calc(var(--space-xs) + var(--space-3xs)); border-radius: var(--ws-radius-bar); background: var(--ws-track); }
|
|
20
|
+
.ws-action-list__ghost.ws-shimmer { background: var(--ws-shimmer); background-size: 300% 100%; }
|
|
21
|
+
|
|
22
|
+
/* --brief (North): rows 6 apart, 40 tall, 10 px corners, a glass ground with a 0.5 px navy edge. Hover: the line goes
|
|
23
|
+
to the surface and its edge a shade darker, nothing lifts or grows (D7; North's lifting row is not taken), its "Open"
|
|
24
|
+
act grows out and its dismiss shows; both also show on keyboard focus, and on touch they are always there. */
|
|
25
|
+
.ws-action-list--brief { gap: var(--space-xxs-plus); }
|
|
26
|
+
.ws-action-list__brief { position: relative; display: flex; align-items: center; min-height: var(--ws-row-h-dense); border-radius: var(--ws-radius-menu); background: color-mix(in srgb, var(--color-surface) 55%, transparent); box-shadow: inset 0 0 0 var(--ws-hairline) color-mix(in srgb, var(--ws-ink) 8%, transparent); transition: background-color var(--ws-duration-hover) var(--ws-ease-soft), box-shadow var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
27
|
+
.ws-action-list__main { display: flex; flex: 1; align-items: center; align-self: stretch; gap: var(--space-sm); min-width: 0; padding: 0 var(--space-xxs) 0 var(--space-md); border: 0; border-radius: inherit; background: none; font-size: var(--ws-text-body); line-height: calc(var(--space-md) + var(--space-xxs)); text-align: left; cursor: pointer; }
|
|
28
|
+
.ws-action-list__main:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
29
|
+
.ws-action-list__lead { flex: none; font-weight: 600; color: var(--color-text-heading); }
|
|
30
|
+
.ws-action-list__gist { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-text-body); }
|
|
31
|
+
/* "Open": the needs-you word (salmon's AA step), a 16 px arrow; folded to nothing until the line is hovered or focused. */
|
|
32
|
+
.ws-action-list__go { display: inline-flex; flex: none; align-items: center; gap: var(--space-xxs); max-width: 0; overflow: hidden; opacity: 0; white-space: nowrap; font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 600; color: var(--ws-word-needs); transition: opacity var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
33
|
+
.ws-action-list__go svg { width: var(--ws-icon); height: var(--ws-icon); flex-shrink: 0; }
|
|
34
|
+
.ws-action-list__dismiss { margin-right: var(--space-xs); opacity: 0; color: var(--color-text-muted); transition: opacity var(--ws-duration-hover) var(--ws-ease-soft), background-color var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
35
|
+
.ws-action-list__main:focus-visible .ws-action-list__go { max-width: var(--space-7xl); opacity: 1; }
|
|
36
|
+
.ws-action-list__dismiss:focus-visible, .ws-action-list__brief:focus-within .ws-action-list__dismiss { opacity: 1; }
|
|
37
|
+
@media (hover: hover) {
|
|
38
|
+
.ws-action-list__brief:hover { background-color: var(--color-surface); box-shadow: inset 0 0 0 var(--ws-hairline) color-mix(in srgb, var(--ws-ink) 10%, transparent); }
|
|
39
|
+
.ws-action-list__brief:hover .ws-action-list__go { max-width: var(--space-7xl); opacity: 1; }
|
|
40
|
+
.ws-action-list__brief:hover .ws-action-list__dismiss { opacity: 1; }
|
|
41
|
+
.ws-action-list__dismiss:hover { background: var(--ws-hover-strong); color: var(--color-text-heading); }
|
|
42
|
+
}
|
|
43
|
+
/* Motion, only where it is wanted: "Open" growing out, the arrow's step. */
|
|
44
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
45
|
+
.ws-action-list__go { transition: max-width var(--ws-duration-settle) var(--ws-ease-grow), opacity var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
46
|
+
.ws-action-list__go svg { transition: transform var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
47
|
+
}
|
|
48
|
+
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
|
|
49
|
+
.ws-action-list__brief:hover .ws-action-list__go svg { transform: translateX(var(--space-3xs)); }
|
|
50
|
+
}
|
|
51
|
+
@media (hover: none) { .ws-action-list__go { max-width: none; opacity: 1; } .ws-action-list__dismiss { opacity: 1; } }
|
|
52
|
+
/* On touch the dismiss's 40 px hit area reaches 8 past its box: the line keeps 8 clear after "Open" so a tap on the
|
|
53
|
+
arrow never dismisses. */
|
|
54
|
+
@media (pointer: coarse) { .ws-action-list__main { padding-right: var(--space-xs); } }
|
|
55
|
+
/* Narrow (a list under 24rem, a phone's card): the act drops under the words, on their edge, so the reason keeps the
|
|
56
|
+
row's width instead of breaking a word a line; a brief line's "Open" keeps only its arrow (its words, at no size,
|
|
57
|
+
stay in the line's name), so the gist keeps the room. */
|
|
58
|
+
@container ws-action-list (max-width: 24rem) {
|
|
59
|
+
.ws-action-list__row { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: var(--space-xs) var(--space-md); }
|
|
60
|
+
.ws-action-list__text, .ws-action-list__act { grid-column: 2; }
|
|
61
|
+
.ws-action-list__text:first-child, .ws-action-list__text:first-child ~ * { grid-column: 1 / -1; }
|
|
62
|
+
.ws-action-list__act { justify-self: start; margin-block: 0; }
|
|
63
|
+
.ws-action-list__go { gap: 0; font-size: 0; }
|
|
64
|
+
}
|
|
@@ -14,7 +14,8 @@ Who reached out, two weeks of day cells a row, a navy dot for a day done and a c
|
|
|
14
14
|
|
|
15
15
|
**Anatomy**
|
|
16
16
|
|
|
17
|
-
- Two week blocks of seven day cells, Monday to Sunday, a narrow gap between them; each cell is a square that scales with the column
|
|
17
|
+
- Two week blocks of seven day cells, Monday to Sunday, a narrow gap between them; each cell is a square that scales with the column up to 32 px (`--space-xl`), then stops; in a wider card the
|
|
18
|
+
spare room goes after the count, so the days still read as a calendar.
|
|
18
19
|
- A day with outreach: a navy dot, lighter the longer ago it was, filling the full cell as a circle.
|
|
19
20
|
- A day without: an empty cream square with the slot's fine edge, `--ws-radius-control` (4 px) corners.
|
|
20
21
|
- Today: the same empty square outlined in salmon at half strength.
|
|
@@ -29,12 +30,28 @@ Who reached out, two weeks of day cells a row, a navy dot for a day done and a c
|
|
|
29
30
|
| `tip` | A day with outreach shows its own small card (its call and outcome) while pointed at |
|
|
30
31
|
| `more` | Adds the quiet line under the grid for names outside the matrix |
|
|
31
32
|
|
|
33
|
+
**Parts and modifiers**
|
|
34
|
+
|
|
35
|
+
- `.ws-activity-grid__grid--week`: one week instead of two (seven day columns, no gap column).
|
|
36
|
+
- `.ws-activity-grid__letter`: a day's initial over its column (11 px muted); `--today` is today's, in the salmon word.
|
|
37
|
+
- `.ws-activity-grid__letter--today`: today's initial, in `--ws-word-needs`; under 18rem it is the only letter left.
|
|
38
|
+
- `.ws-activity-grid__dot--past`: a day done a week ago, a lighter navy.
|
|
39
|
+
- `.ws-activity-grid__dot--pointed`: the day under the pointer, salmon (`--ws-chart-under-half` (chart tone 3, so a palette that sets it moves it); with a `__tip`).
|
|
40
|
+
- `.ws-activity-grid__today`: today's cell while nothing is done yet: a salmon edge (`--ws-chart-under-half` at half strength).
|
|
41
|
+
- `.ws-activity-grid__empty--future`: a day not reached yet: a dashed edge.
|
|
42
|
+
- `.ws-activity-grid__count--zero`: a row with no days done: the count in regular muted grey.
|
|
43
|
+
- `.ws-activity-grid__note`: the quiet line under the grid (12 px muted) naming who has not reached out.
|
|
44
|
+
- `.ws-activity-grid__tip`: a day's own small card over its cell (use with `ws-menu`), 8 above it.
|
|
45
|
+
- `.ws-activity-grid__tip-title`: the tip's first line, medium.
|
|
46
|
+
|
|
32
47
|
**States**
|
|
33
48
|
|
|
34
49
|
- Default: the matrix simply shows; rows read top to bottom by who did the most.
|
|
35
50
|
- Hover (`tip` given): the pointed-at day's dot turns salmon and its small card appears above it.
|
|
36
51
|
- Quiet: a person with every cell empty, name and count both muted grey, never highlighted as an error.
|
|
37
|
-
- Narrow: columns shrink and stay square; the label column keeps its own width.
|
|
52
|
+
- Narrow: columns shrink and stay square; the label column keeps its own width. Under 18rem (two weeks in a phone
|
|
53
|
+
card) the gap halves to 2 and the day letters go, all but today's, so no two letters run into each other; the week
|
|
54
|
+
labels still mark each week's start.
|
|
38
55
|
- Disabled / error / focus / pressed / selected: do not apply to the grid itself; only a `tip` cell responds to a pointer.
|
|
39
56
|
- Reduced motion: cells are simply in place.
|
|
40
57
|
|
|
@@ -69,3 +86,22 @@ Who reached out, two weeks of day cells a row, a navy dot for a day done and a c
|
|
|
69
86
|
## Source
|
|
70
87
|
|
|
71
88
|
**Derived from**: the system's chart rules for a day-cell matrix, the navy "done" tone and the quiet-line pattern for naming who hasn't acted (tokens: `--ws-radius-control`, `--color-brand-navy`, `--ws-word-needs`). **Precedent**: the first product built on the system.
|
|
89
|
+
|
|
90
|
+
## Markup
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<div class="ws-dots ws-activity-grid__body">
|
|
94
|
+
<figure class="ws-activity-grid__grid" aria-label="Days with outreach, last two weeks: Priya 6 days">
|
|
95
|
+
<!-- head row: an empty cell, the week, the gap, the week, the count column -->
|
|
96
|
+
<span aria-hidden="true"></span><span class="ws-activity-grid__week" aria-hidden="true">Week of Sep 28</span><span aria-hidden="true"></span>
|
|
97
|
+
<!-- one row a person: the name, 7 day cells, the gap, 7 day cells, the count -->
|
|
98
|
+
<span class="ws-activity-grid__name ws-activity-grid__name--active" aria-hidden="true">Priya</span>
|
|
99
|
+
<span class="ws-activity-grid__cell"><span class="ws-activity-grid__dot"></span></span>
|
|
100
|
+
<span class="ws-activity-grid__cell"><span class="ws-activity-grid__empty"></span></span>
|
|
101
|
+
<span class="ws-activity-grid__count" aria-hidden="true">6</span>
|
|
102
|
+
</figure>
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Styles**: `ActivityGrid/style.css`, in `bundle.css` and `fello.css` as `.ws-activity-grid`. Every value is a token. `.ws-activity-grid` itself has no styles: it is the hook that
|
|
107
|
+
names the chart (and the root for its modifiers); its parts carry the styles.
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
|
|
120
120
|
<div class="ws-stack">
|
|
121
121
|
<span class="ws-muted">A day pointed at can show its own small card (`tip`); a quiet name stays grey</span>
|
|
122
|
-
<div style="width: 300px;">
|
|
122
|
+
<div style="width: 300px; padding-top: var(--space-xl);">
|
|
123
123
|
<div class="ws-card ws-card--inset ws-activity-grid">
|
|
124
124
|
<figure class="ws-activity-grid__grid ws-activity-grid__grid--week" aria-label="Days with outreach, this week: Priya 3 days, Dana 0 days">
|
|
125
125
|
<span aria-hidden="true"></span>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* ---- ActivityGrid: who reached out, two weeks of day cells a row and a count at the end ---- */
|
|
2
|
+
.ws-activity-grid__body { display: flex; flex-direction: column; gap: var(--space-xl); padding: var(--space-md) var(--ws-card-inset) var(--space-xxs-plus); container-type: inline-size; }
|
|
3
|
+
/* Day columns share the room up to 32 px each, then stop: in a wide card the days stay a calendar (not 64 px discs)
|
|
4
|
+
and the count stays beside them, the spare room after it. */
|
|
5
|
+
.ws-activity-grid__grid { display: grid; width: 100%; grid-template-columns: minmax(var(--space-4xl), max-content) repeat(7, minmax(0, var(--space-xl))) var(--space-xs) repeat(7, minmax(0, var(--space-xl))) calc(var(--space-md) + var(--space-xs) * 0.75); justify-content: start; gap: var(--space-xxs); align-items: center; }
|
|
6
|
+
.ws-activity-grid__grid--week { grid-template-columns: minmax(var(--space-4xl), max-content) repeat(7, minmax(0, var(--space-xl))) calc(var(--space-md) + var(--space-xs) * 0.75); }
|
|
7
|
+
.ws-activity-grid__week { grid-column: span 7; align-self: end; font-size: var(--ws-text-micro); font-weight: 500; line-height: var(--font-size-xs); color: var(--color-text-body); text-wrap: balance; }
|
|
8
|
+
.ws-activity-grid__letter { text-align: center; font-size: var(--ws-text-micro); font-weight: 500; color: var(--color-text-muted); }
|
|
9
|
+
.ws-activity-grid__letter--today { color: var(--ws-word-needs); }
|
|
10
|
+
.ws-activity-grid__name { padding-right: var(--space-xs); font-size: var(--ws-text-meta); line-height: var(--space-md); color: var(--color-text-muted); white-space: nowrap; }
|
|
11
|
+
.ws-activity-grid__name--active { font-weight: 500; color: var(--color-text-heading); }
|
|
12
|
+
.ws-activity-grid__cell { position: relative; width: 100%; aspect-ratio: 1; }
|
|
13
|
+
/* A day done: a navy dot, a week ago a lighter navy; salmon while pointed at. */
|
|
14
|
+
.ws-activity-grid__dot { display: block; width: 100%; height: 100%; border-radius: var(--radius-full); background: var(--color-text-heading); }
|
|
15
|
+
.ws-activity-grid__dot--past { background: color-mix(in srgb, var(--ws-chart-navy-light) 40%, var(--color-text-heading)); }
|
|
16
|
+
.ws-activity-grid__dot--pointed { background: var(--ws-chart-under-half); }
|
|
17
|
+
.ws-activity-grid__empty, .ws-activity-grid__today { display: block; width: 100%; height: 100%; border-radius: var(--ws-radius-control); border: var(--ws-hairline) solid var(--ws-edge-slot); background: var(--color-bg-page); }
|
|
18
|
+
.ws-activity-grid__today { border: var(--ws-line) solid color-mix(in srgb, var(--ws-chart-under-half) 50%, var(--color-bg-page)); }
|
|
19
|
+
.ws-activity-grid__empty--future { border-style: dashed; }
|
|
20
|
+
.ws-activity-grid__count { text-align: right; font-size: var(--ws-text-chart); font-weight: 600; color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
|
|
21
|
+
.ws-activity-grid__count--zero { font-weight: 400; color: var(--color-text-muted); }
|
|
22
|
+
.ws-activity-grid__note { font-size: var(--ws-text-dense); color: var(--color-text-muted); }
|
|
23
|
+
/* Narrow (a phone's card, two weeks under 18rem): the day columns fall under 9 px, where 11 px day letters would run
|
|
24
|
+
into each other. The gap halves so the cells stay as large as they can, and the letters go, all but today's; the
|
|
25
|
+
week labels still say where each week starts. */
|
|
26
|
+
@container (max-width: 18rem) {
|
|
27
|
+
.ws-activity-grid__grid { column-gap: var(--space-3xs); }
|
|
28
|
+
.ws-activity-grid__letter:not(.ws-activity-grid__letter--today) { visibility: hidden; }
|
|
29
|
+
/* today's letter is wider than its column now: centre it on the column rather than let it run off to the right */
|
|
30
|
+
.ws-activity-grid__letter--today { justify-self: center; }
|
|
31
|
+
}
|
|
32
|
+
/* A day's own small card (tip), a menu lifted over its cell. Use with ws-menu. */
|
|
33
|
+
.ws-activity-grid__tip { position: absolute; left: 50%; bottom: calc(100% + var(--space-xs)); transform: translateX(-50%); padding: var(--space-sm); }
|
|
34
|
+
.ws-activity-grid__tip-title { font-weight: 500; }
|
|
35
|
+
|
|
@@ -1,110 +1,240 @@
|
|
|
1
|
-
A
|
|
2
|
-
|
|
1
|
+
A product's frame, drawn from Seth's North app: a 232 px nav of grouped rows on the frame's wash, a glass stage beside
|
|
2
|
+
it, a 56 px bar at the stage's top and a body that owns the scroll. It folds to a 64 px rail and, on a phone, gives the
|
|
3
|
+
nav to a drawer.
|
|
3
4
|
|
|
4
5
|
## Use it when
|
|
5
6
|
|
|
6
|
-
- The product's work happens on pages a person
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- A team member needs a persistent reminder of who they are signed in as, at the foot of the nav.
|
|
7
|
+
- The product's work happens on pages a person moves between: a pipeline, a report, a list, settings.
|
|
8
|
+
- There are more destinations than fit a flat list, and they fall into a few groups (Reports, Settings).
|
|
9
|
+
- Every page needs the same place for its name, its acts and a way to fold the nav away.
|
|
10
|
+
- A team member needs to see who they are signed in as, pinned at the foot of the nav.
|
|
11
11
|
|
|
12
12
|
## Not for
|
|
13
13
|
|
|
14
|
-
- A chat-first
|
|
15
|
-
|
|
16
|
-
- A
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
- The marketing site: it keeps the kit's own `MarketingNav`.
|
|
14
|
+
- A chat-first screen where people act by talking to an agent: that is a chat (`ChatShell`, from WP-cards) with the
|
|
15
|
+
thread's own `PageBar` when a report opens full screen.
|
|
16
|
+
- A handful of destinations with no groups: a `TopBar` across the top reads better.
|
|
17
|
+
- A page's own filters or view switches: those are `Tabs` or `Segmented` in the body, never nav rows.
|
|
18
|
+
- The marketing site: it keeps `MarketingNav`.
|
|
20
19
|
|
|
21
20
|
## Anatomy
|
|
22
21
|
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
its
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(
|
|
22
|
+
- **Frame** (`.ws-app-shell`): the window's ground, `--ws-frame` (Seth's `#EBF0F5` to cream wash over 640 px). It
|
|
23
|
+
fills its parent's height: give that parent the window's (`100dvh`). It is a size container named `ws-app-shell`.
|
|
24
|
+
- **Nav** (`__nav`): 232 px (`--ws-sidebar-width`), no card of its own, on the frame. It sits on the stage's insets
|
|
25
|
+
(13 top, 12 bottom) so its top and foot line up with the stage.
|
|
26
|
+
- Head (`__head`): 56 tall (`--ws-header-h`), so the product's name sits on the bar's line. The name (`__wordmark`)
|
|
27
|
+
18 / 24 semibold navy; at its right one 32 px icon button that folds the nav. Sides 12 and 8 (the groups'), the name 10 inside them, so it starts on the row icons' edge, 22 in.
|
|
28
|
+
- Groups (`__groups`): the part that scrolls, between the head and the person. Each group (`__group`) has 12 / 8
|
|
29
|
+
sides and 4 above and below. A 1 px rule (`--ws-edge-card`) runs the nav's full width between groups, none above
|
|
30
|
+
the first.
|
|
31
|
+
- Group name (`__eyebrow`): Seth's sentence-case head, 11 / 16 medium in muted, 28 tall with 12 above the words, on
|
|
32
|
+
the icons' edge (22 from the nav's side). Seth draws it at 10 px; the kit keeps its 11 px floor.
|
|
33
|
+
- Rows (`__rows`, `__row`): 28 tall (`--ws-control-h-sm`, 40 on touch), 2 apart, 10 px sides, 6 px corners. A 20 px
|
|
34
|
+
icon box (the 16 px icon inside it), 4 px, then the name (`__name`) in 13 / 18 medium body grey, truncated with
|
|
35
|
+
its full words in `title`. Rows are real links (`<a href>`).
|
|
36
|
+
- Count (`__count`): Seth's navy pill, 18 tall, at least 18 wide, 11 px semibold figures in the act fill's word
|
|
37
|
+
colour (`--ws-on-act`).
|
|
38
|
+
- The person (`__foot`): pinned at the foot under a full-width 1 px rule, never scrolled away, 12 above and 6 below,
|
|
39
|
+
on the rows' edges (22 in at the left, 18 at the right: the groups' 12 / 8 and a row's 10). A 28 px avatar, 10 px,
|
|
40
|
+
then the name 13 / 16 medium navy (`__foot-name`) over the role in `ws-muted`.
|
|
41
|
+
- **Stage** (`__stage`): `--ws-glass` with a 4 px blur (`--ws-glass-blur`), a 1 px `--ws-edge-stage` edge, 16 px corners
|
|
42
|
+
(`--ws-radius-panel`), 13 from the window's top (`--ws-stage-inset-top`), 12 from its right and bottom
|
|
43
|
+
(`--ws-stage-inset`), no gap to the nav (the nav's own 8 px is the gap). `--wash` gives it the Fia frames' cream
|
|
44
|
+
wash (`--ws-stage-wash`) instead of glass.
|
|
45
|
+
- **Bar** (`__bar`): at least 56 tall, 8 above and below (a bar that wraps never touches the stage's edge), on the
|
|
46
|
+
content's 32 px edges, flat. It holds the page's name (`__title`, 16 / 22
|
|
47
|
+
semibold, one line), a `Breadcrumb`, or a `PageBar` (put both classes on one `<header>`), and at its right the acts
|
|
48
|
+
(`__acts`, 8 apart): a search box (`__search`: a `<label>` round an `<input type="search">`, 220 wide, giving down
|
|
49
|
+
to 160, 32 tall (40 on touch), the field's inset hairline, the focus ring on the box) and the page's one primary. Its
|
|
50
|
+
0.5 px edge (an inset hairline, so the bar stays a whole 56 and its controls sit on whole pixels) shows only once the
|
|
51
|
+
body has scrolled (`__bar--scrolled`).
|
|
52
|
+
- **Body** (`__body`): the page itself. 16 under the bar, 32 at the sides, 40 at the foot, its parts 16 apart. It
|
|
53
|
+
scrolls and never chains into the window (`overscroll-behavior: contain`), it is a size container (as `.ws-page` is),
|
|
54
|
+
and its content is capped at the board's two columns (1128, `2 x --ws-chart-card-w + --ws-gap-component`, the same
|
|
55
|
+
as `.ws-page`; Seth's North caps at 1119) on one start edge, so a section, its tiles, a board and a `Split` all end
|
|
56
|
+
on one edge. Put no `.ws-page` inside it.
|
|
57
|
+
- `__body--wide`: a Fia app page (Grow, Fixes, Inbox, Tally) runs the body's full width, Seth's 1350 in a 1416
|
|
58
|
+
stage, with no cap.
|
|
59
|
+
- A filled page (a `ws-split--fill` straight in the body, Seth's report and its drawer) ends 24 above the stage's
|
|
60
|
+
foot (`--ws-gap-group`) instead of 40.
|
|
61
|
+
- **Menu button** (`__menu`): an icon button in the bar, shown only in the phone form (never beside the open nav or
|
|
62
|
+
the folded rail).
|
|
63
|
+
- **Touch**: the search box is 40 tall and its words 16, so a phone or tablet never zooms into it on focus.
|
|
64
|
+
- In fello.css: `.ws-app-shell` (+ `--folded`, `--wash`), `__nav`, `__head`, `__wordmark`, `__groups`, `__group`,
|
|
65
|
+
`__eyebrow`, `__rows`, `__row` (+ `--current`), `__name`, `__count`, `__foot`, `__foot-words`, `__foot-name`,
|
|
66
|
+
`__stage`, `__bar` (+ `--scrolled`), `__title`, `__acts`, `__search`, `__menu`, `__body` (+ `--wide`); the 0.4
|
|
67
|
+
rail markup `__rail` and `__mark` (+ `--current`, `--wordmark`) still draws, and so does a 0.4 nav (wordmark, group
|
|
68
|
+
names, rows and person straight in `__nav`, no `__head` or `__groups`): the nav itself scrolls then, with the
|
|
69
|
+
wordmark and the person pinned to its ends.
|
|
44
70
|
|
|
45
71
|
## Variants and sizes
|
|
46
72
|
|
|
47
73
|
| Variant | Width | Shows |
|
|
48
74
|
| --- | --- | --- |
|
|
49
|
-
| Open (default) | 232 px
|
|
50
|
-
| Folded
|
|
75
|
+
| Open (default) | 232 px | The head, grouped rows with names and counts, the person |
|
|
76
|
+
| Folded (`--folded`) | 64 px | The same nav: 40 px rows of icons, the current one on its pill; names faded (still read aloud), counts gone, each row's name and count in its `title` (a pointer's tooltip, a screen reader's description), group names and rules gone, the avatar centred |
|
|
77
|
+
| Phone (under 60rem of the shell) | none | The bar's menu button opens the same nav in a drawer at the drawer's width; the stage goes edge to edge, 16 px sides |
|
|
78
|
+
|
|
79
|
+
| Body | Content width | Use |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| `__body` (default) | Up to 1128, on the start edge | A page of sections, tiles and boards (North) |
|
|
82
|
+
| `__body--wide` | The body's full width | A Fia app page drawn at 1350 (Grow, Fixes, Inbox, Tally) |
|
|
51
83
|
|
|
52
84
|
## States
|
|
53
85
|
|
|
54
|
-
- **
|
|
55
|
-
- **Hover
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
86
|
+
- **Rest**: body-grey names, muted icons, no wash.
|
|
87
|
+
- **Hover** (pointers that hover): Seth's navy wash, `--ws-hover` (5%), on the row's 6 px corners.
|
|
88
|
+
- **Press**: `--ws-hover-strong` (6%). Rows never scale.
|
|
89
|
+
- **Current** (`aria-current="page"`, or `--current`): a white pill (`--color-surface`, 4 px corners, Seth's two soft
|
|
90
|
+
navy shades, a light rim in dark), the icon in salmon (a mark keeps Seth's coral) and the name at salmon's AA word
|
|
91
|
+
step, `--color-text-brand-strong` (D2). Hovering it changes nothing.
|
|
92
|
+
- **Focus**: the 2 px navy ring drawn inside the row (D8), so rows 2 apart never cut it. A body with nothing in it to
|
|
93
|
+
focus takes the keyboard itself (so it can be scrolled by keys); its ring is drawn inside it too, since the stage
|
|
94
|
+
clips anything outside.
|
|
95
|
+
- **Needs you**: the navy count pill. A bare number, its meaning in `.ws-sr` words inside it ("7 waiting"), never
|
|
96
|
+
`aria-label` on the span (ARIA does not let a plain span carry a label).
|
|
97
|
+
- **Long name**: truncates on one line, the full name in `title`.
|
|
98
|
+
- **Folded**: only the icons show, so every row carries its name (and its count, "Pipeline, 7 waiting") in `title`;
|
|
99
|
+
in React, a `Tooltip` on hover and focus.
|
|
100
|
+
- **Many rows**: the groups scroll; the head and the person stay. In 0.4 markup (no `__groups`) the nav scrolls and the
|
|
101
|
+
wordmark and the person stick to its ends, on the frame's wash.
|
|
102
|
+
- **Scrolled**: `__bar--scrolled` shows the bar's 0.5 px edge. Set it from the body's scroll:
|
|
103
|
+
`body.onscroll = () => bar.classList.toggle('ws-app-shell__bar--scrolled', body.scrollTop > 0)`.
|
|
104
|
+
- **Loading**: the body holds `.ws-shimmer` ghosts the size of what is coming, with `aria-busy="true"` and a
|
|
105
|
+
`<span class="ws-sr" role="status">` saying what is loading (never `aria-label` on the body's `div`); the nav and
|
|
106
|
+
bar stay.
|
|
107
|
+
- **Phone**: see Variants. On a phone keep the bar to one line: the page's name, at most two icon acts. The search
|
|
108
|
+
box goes; give the bar a search icon act or put the search at the top of the drawer. With `viewport-fit=cover` the
|
|
109
|
+
bar keeps clear of the notch and the body's foot clear of the home bar (`env(safe-area-inset-*)`), as the sides do.
|
|
63
110
|
|
|
64
111
|
## Behaviour
|
|
65
112
|
|
|
66
|
-
- Keyboard:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
113
|
+
- Keyboard: rows are links in document order; the fold button carries `aria-expanded` and toggles `--folded` on the
|
|
114
|
+
shell. The phone's drawer is a `Dialog` (`ws-dialog--drawer`) holding the same `__nav` markup; the head's button
|
|
115
|
+
becomes its close.
|
|
116
|
+
- Pointer: hover only tints. Nothing opens on hover.
|
|
117
|
+
- Motion (North): the fold trades width over `--ws-duration-shift` on `--ws-ease-shift`; the rows, the current pill
|
|
118
|
+
and the fold button ride the nav's edge as it moves (nothing jumps to the middle and back), names fade over
|
|
119
|
+
`--ws-duration-hover`, washes ease in over 200 ms, the bar's edge over `--ws-duration-settle`. The current pill
|
|
120
|
+
slides to the new page's row, across groups (North's "Sidebar active row slide", `springs.nav` .4 / .1), plain CSS
|
|
121
|
+
with no script and no new markup: the current row is a CSS anchor and the rows' scroller (`__groups`, or a 0.4 nav
|
|
122
|
+
that holds its rows) draws the travelling pill in its `::before`, under the rows and the group names, its four edges
|
|
123
|
+
easing on motion's own `spring(.4, .1)` written out as `linear()` (550 ms; `--ws-spring-nav-duration` and `--ws-spring-nav`). At rest the current row paints its own pill (the 0.4 look); while the rows are pointed at
|
|
124
|
+
or hold focus the travelling pill takes its place, so a page chosen then (an app that routes without a reload)
|
|
125
|
+
slides. The fold and a resize carry the pill with its row at once. Without CSS anchor positioning the pill moves at
|
|
126
|
+
once; the 0.4 rail's marks stay put. The hover wash growing from the pointer (Seth's 18 px seed) is not drawn yet.
|
|
127
|
+
Reduced motion: everything lands at once. Try it in the preview: click a row.
|
|
128
|
+
- Touch: rows and the menu button grow to the 40 px floor (K10).
|
|
129
|
+
- Nothing inside the stage is trapped by its glass: the blur is drawn by a layer under the content (`::before`), not by
|
|
130
|
+
the stage, because an element with a `backdrop-filter` becomes the box of every `position: fixed` thing inside it. So
|
|
131
|
+
a toaster, a phone's full-screen `Panel` or anything the app fixes to the window reaches the window from inside the
|
|
132
|
+
stage; menus, popovers and dialogs sit in the top layer, a full-screen chat card is lifted there by `morph()`, and a
|
|
133
|
+
tooltip is anchored to the window. The stage still clips what is inside it to its 16 px corners.
|
|
134
|
+
- The shell owns the scroll (K1, K2): only the body and the groups scroll; nothing in them is squashed.
|
|
72
135
|
|
|
73
136
|
## Content
|
|
74
137
|
|
|
75
|
-
- A group's
|
|
76
|
-
|
|
77
|
-
-
|
|
138
|
+
- A group's name says what kind of page it holds ("Reports"), sentence case, two words at most. The first group can
|
|
139
|
+
go without one.
|
|
140
|
+
- A row's name is the page's own name, sentence case.
|
|
141
|
+
- The bar names the page once, exactly as its row does; no second heading repeats it in the body.
|
|
78
142
|
- No em dashes; a count is a bare number.
|
|
79
143
|
|
|
80
144
|
## Props
|
|
81
145
|
|
|
82
146
|
| Name | Type | Meaning |
|
|
83
147
|
| --- | --- | --- |
|
|
84
|
-
| `groups` | `{
|
|
85
|
-
| `NavRow` | `{ label, icon, href, current?, count? }` | One row: its words, its
|
|
86
|
-
| `person` | `{ name, role, initials }` | The foot
|
|
87
|
-
| `folded` | `boolean` |
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `primaryAction` | `{ label, onClick }` | The top bar's one `primary`, `large` button |
|
|
148
|
+
| `groups` | `{ name?: string; items: NavRow[] }[]` | The nav's groups, in order |
|
|
149
|
+
| `NavRow` | `{ label, icon, href, current?, count? }` | One row: its words, its 16 px icon, whether it is the current page, its count |
|
|
150
|
+
| `person` | `{ name, role, initials }` | The foot |
|
|
151
|
+
| `folded` | `boolean` | The 64 px rail |
|
|
152
|
+
| `bar` | `ReactNode` | The bar's content: a title, a `Breadcrumb` or a `PageBar`, and its acts |
|
|
153
|
+
| `wash` | `boolean` | The cream stage instead of glass |
|
|
91
154
|
|
|
92
155
|
## Rules
|
|
93
156
|
|
|
94
|
-
- **One navy button per page**: the
|
|
95
|
-
|
|
96
|
-
- **The
|
|
97
|
-
|
|
98
|
-
- **
|
|
99
|
-
together, the same proximity rule as any group of rows (space-and-layout.md, "Grouping").
|
|
100
|
-
- **One navy button per page** and the shared gutters and header height carry over unchanged from a chat-first shell
|
|
101
|
-
to a page-based one.
|
|
102
|
-
- The brand kit has no shell, nav or top bar of its own to diverge from; this piece is assembled entirely from the
|
|
103
|
-
shared sizing, colour and spacing tokens.
|
|
157
|
+
- **One navy button per page**: the bar's primary is the page's one; nothing in the body adds a second.
|
|
158
|
+
- **The body is the page**: it brings the 32 px gutter; a page inside never adds its own padding or a `.ws-page`.
|
|
159
|
+
- **The person never scrolls away** and the head never moves: only the groups scroll (K11).
|
|
160
|
+
- **Real links, `aria-current="page"`**: never a clickable `<li>`, never colour alone.
|
|
161
|
+
- **Seth's tokens only**: no raw colour, size or corner; dark comes from the tokens (D12).
|
|
104
162
|
|
|
105
163
|
## Source
|
|
106
164
|
|
|
107
|
-
**Derived from**:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
165
|
+
**Derived from**: Seth's North app (`style1.css` 22 to 112, 531 to 560; the 232 px sidebar, its 28 px rows, rules,
|
|
166
|
+
navy count, white current pill, the 64 px rail, the glass stage and the frame), the Fia frames' 56 px thread header and
|
|
167
|
+
32 px gutter (D4), and Revenue OS faults K1, K2, K3, K11 and K12. **Precedent**: kit 0.4's AppShell, upgraded in place
|
|
168
|
+
4 Nov 2026 (the 0.4 markup still draws).
|
|
169
|
+
|
|
170
|
+
## Markup
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<div class="ws-app-shell">
|
|
174
|
+
<nav class="ws-app-shell__nav" aria-label="Main">
|
|
175
|
+
<div class="ws-app-shell__head">
|
|
176
|
+
<span class="ws-app-shell__wordmark">Fello</span>
|
|
177
|
+
<button type="button" class="ws-icon-btn" aria-label="Fold the menu" aria-expanded="true">
|
|
178
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2.5" width="12" height="11" rx="2"/><path d="M6 2.5v11"/></svg>
|
|
179
|
+
</button>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="ws-app-shell__groups">
|
|
182
|
+
<div class="ws-app-shell__group">
|
|
183
|
+
<ul class="ws-app-shell__rows">
|
|
184
|
+
<li><a href="/pipeline" class="ws-app-shell__row" aria-current="page">
|
|
185
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg>
|
|
186
|
+
<span class="ws-app-shell__name">Pipeline</span>
|
|
187
|
+
<span class="ws-app-shell__count">7<span class="ws-sr"> waiting</span></span>
|
|
188
|
+
</a></li>
|
|
189
|
+
</ul>
|
|
190
|
+
</div>
|
|
191
|
+
<div class="ws-app-shell__group">
|
|
192
|
+
<h2 class="ws-app-shell__eyebrow">Reports</h2>
|
|
193
|
+
<ul class="ws-app-shell__rows">
|
|
194
|
+
<li><a href="/performance" class="ws-app-shell__row">
|
|
195
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 13V8M8 13V3M13 13V9.5"/></svg>
|
|
196
|
+
<span class="ws-app-shell__name">Performance</span>
|
|
197
|
+
</a></li>
|
|
198
|
+
</ul>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="ws-app-shell__foot">
|
|
202
|
+
<span class="ws-avatar ws-avatar--sm ws-avatar--plain">PN</span>
|
|
203
|
+
<span class="ws-app-shell__foot-words">
|
|
204
|
+
<span class="ws-app-shell__foot-name">Priya Nair</span>
|
|
205
|
+
<span class="ws-muted">Team lead</span>
|
|
206
|
+
</span>
|
|
207
|
+
</div>
|
|
208
|
+
</nav>
|
|
209
|
+
<div class="ws-app-shell__stage">
|
|
210
|
+
<header class="ws-app-shell__bar">
|
|
211
|
+
<button type="button" class="ws-icon-btn ws-app-shell__menu" aria-label="Open the menu">
|
|
212
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11"/></svg>
|
|
213
|
+
</button>
|
|
214
|
+
<h1 class="ws-app-shell__title">Pipeline</h1>
|
|
215
|
+
<div class="ws-app-shell__acts">
|
|
216
|
+
<label class="ws-app-shell__search">
|
|
217
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><circle cx="6.8" cy="6.8" r="3.8"/><path d="M9.7 9.7l3.6 3.6"/></svg>
|
|
218
|
+
<input type="search" placeholder="Search leads" aria-label="Search leads">
|
|
219
|
+
</label>
|
|
220
|
+
<button type="button" class="ws-btn ws-btn--primary">Add a lead</button>
|
|
221
|
+
</div>
|
|
222
|
+
</header>
|
|
223
|
+
<main class="ws-app-shell__body">
|
|
224
|
+
<!-- the page: sections, tiles, a board, a Split -->
|
|
225
|
+
</main>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Styles
|
|
231
|
+
|
|
232
|
+
`AppShell/style.css`, with `IconButton`, `Button` and `Avatar` for the bar's acts and the person (`ws-muted` is the
|
|
233
|
+
house's). Tokens: `--ws-frame`,
|
|
234
|
+
`--ws-glass`, `--ws-glass-blur`, `--ws-stage-wash`, `--ws-edge-stage`, `--ws-stage-inset-top`, `--ws-stage-inset`,
|
|
235
|
+
`--ws-sidebar-width`, `--ws-header-h`, `--ws-control-h-sm`, `--ws-touch`, `--ws-field`, `--ws-field-ink`,
|
|
236
|
+
`--ws-focus-width`, `--ws-focus-color`, `--ws-focus-offset`, `--ws-radius-row`, `--ws-radius-control`,
|
|
237
|
+
`--ws-radius-panel`, `--ws-hover`, `--ws-hover-strong`, `--ws-float-rim`, `--ws-shade`, `--ws-ink`,
|
|
238
|
+
`--color-surface`, `--color-text-brand-strong`, `--ws-chart-under-half`, `--ws-on-act`, `--ws-edge-card`,
|
|
239
|
+
`--ws-hairline`, `--ws-chart-card-w`, `--ws-gap-component`, `--ws-gap-group`, `--ws-text-value`, `--ws-duration-shift`, `--ws-ease-shift`. The shell sets `--ws-gutter` to `--space-xl` (32)
|
|
240
|
+
for everything inside it.
|