@felloinnovations/brand-kit 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +198 -24
- package/CHANGELOG.md +221 -0
- package/README.md +38 -9
- package/design-system/01-how-claude-decides.md +26 -17
- package/design-system/02-principles.md +11 -6
- package/design-system/03-colour.md +135 -47
- package/design-system/04-type.md +45 -23
- package/design-system/05-space-and-layout.md +175 -52
- package/design-system/06-sizing-profiles.md +4 -4
- package/design-system/07-scrolling.md +66 -20
- package/design-system/08-choosing-components.md +50 -22
- package/design-system/09-charts.md +71 -28
- package/design-system/10-patterns.md +33 -10
- package/design-system/11-page-recipes.md +110 -23
- package/design-system/12-content.md +2 -1
- package/design-system/13-motion.md +330 -47
- package/design-system/14-accessibility.md +47 -24
- package/design-system/15-ai-experiences.md +11 -6
- package/design-system/16-creativity.md +1 -1
- package/design-system/17-decisions.md +367 -1
- package/design-system/18-checklist.md +79 -16
- package/design-system/19-public-pages.md +6 -4
- package/design-system/20-palettes.md +275 -0
- package/design-system/README.md +30 -17
- package/design-system/components/ActionList/README.md +96 -10
- package/design-system/components/ActionList/preview.html +52 -7
- package/design-system/components/ActionList/style.css +64 -0
- package/design-system/components/ActivityGrid/README.md +38 -2
- package/design-system/components/ActivityGrid/preview.html +1 -1
- package/design-system/components/ActivityGrid/style.css +35 -0
- package/design-system/components/AppShell/README.md +205 -75
- package/design-system/components/AppShell/preview.html +339 -58
- package/design-system/components/AppShell/style.css +154 -0
- package/design-system/components/Avatar/README.md +37 -10
- package/design-system/components/Avatar/preview.html +13 -4
- package/design-system/components/Avatar/style.css +14 -0
- package/design-system/components/Badge/README.md +41 -19
- package/design-system/components/Badge/preview.html +13 -10
- package/design-system/components/Badge/style.css +23 -0
- package/design-system/components/Banner/README.md +30 -9
- package/design-system/components/Banner/preview.html +1 -1
- package/design-system/components/Banner/style.css +19 -0
- package/design-system/components/Breadcrumb/README.md +58 -46
- package/design-system/components/Breadcrumb/preview.html +16 -16
- package/design-system/components/Breadcrumb/style.css +17 -0
- package/design-system/components/Button/README.md +113 -55
- package/design-system/components/Button/preview.html +98 -25
- package/design-system/components/Button/style.css +86 -0
- package/design-system/components/Card/README.md +158 -49
- package/design-system/components/Card/preview.html +141 -19
- package/design-system/components/Card/style.css +115 -0
- package/design-system/components/CardBoard/README.md +58 -37
- package/design-system/components/CardBoard/preview.html +26 -29
- package/design-system/components/ChatCard/README.md +115 -29
- package/design-system/components/ChatCard/preview.html +149 -32
- package/design-system/components/ChatCard/style.css +49 -0
- package/design-system/components/ChatShell/README.md +116 -0
- package/design-system/components/ChatShell/preview.html +201 -0
- package/design-system/components/ChatShell/style.css +86 -0
- package/design-system/components/ChatTurn/README.md +78 -35
- package/design-system/components/ChatTurn/preview.html +60 -28
- package/design-system/components/ChatTurn/style.css +50 -0
- package/design-system/components/CheckRow/README.md +141 -0
- package/design-system/components/CheckRow/preview.html +140 -0
- package/design-system/components/CheckRow/style.css +88 -0
- package/design-system/components/Checkbox/README.md +58 -22
- package/design-system/components/Checkbox/preview.html +112 -50
- package/design-system/components/Checkbox/style.css +45 -0
- package/design-system/components/Chip/README.md +78 -47
- package/design-system/components/Chip/preview.html +29 -4
- package/design-system/components/Chip/style.css +17 -0
- package/design-system/components/Combobox/README.md +44 -11
- package/design-system/components/Combobox/preview.html +35 -12
- package/design-system/components/Combobox/style.css +54 -0
- package/design-system/components/Composer/README.md +137 -35
- package/design-system/components/Composer/preview.html +115 -40
- package/design-system/components/Composer/style.css +81 -0
- package/design-system/components/ConfirmDialog/README.md +73 -52
- package/design-system/components/ConfirmDialog/preview.html +70 -26
- package/design-system/components/ConfirmDialog/style.css +5 -0
- package/design-system/components/Cover/preview.html +3 -3
- package/design-system/components/Cover/style.css +19 -0
- package/design-system/components/DateInput/README.md +77 -12
- package/design-system/components/DateInput/preview.html +27 -12
- package/design-system/components/DateInput/style.css +38 -0
- package/design-system/components/Dialog/README.md +112 -44
- package/design-system/components/Dialog/preview.html +141 -18
- package/design-system/components/Dialog/style.css +74 -0
- package/design-system/components/EmptyState/README.md +42 -12
- package/design-system/components/EmptyState/preview.html +11 -11
- package/design-system/components/EmptyState/style.css +9 -0
- package/design-system/components/EntryShell/README.md +73 -48
- package/design-system/components/EntryShell/preview.html +60 -27
- package/design-system/components/EntryShell/style.css +19 -0
- package/design-system/components/FeatureGrid/README.md +61 -39
- package/design-system/components/FeatureGrid/preview.html +2 -2
- package/design-system/components/FeatureGrid/style.css +20 -0
- package/design-system/components/FileUpload/README.md +33 -3
- package/design-system/components/FileUpload/preview.html +18 -4
- package/design-system/components/FileUpload/style.css +23 -0
- package/design-system/components/FilterBar/README.md +114 -0
- package/design-system/components/FilterBar/preview.html +82 -0
- package/design-system/components/FilterBar/style.css +22 -0
- package/design-system/components/Fold/README.md +84 -26
- package/design-system/components/Fold/preview.html +77 -34
- package/design-system/components/Fold/style.css +48 -0
- package/design-system/components/Footer/README.md +62 -39
- package/design-system/components/Footer/preview.html +5 -5
- package/design-system/components/Footer/style.css +30 -0
- package/design-system/components/FunnelBars/README.md +24 -3
- package/design-system/components/FunnelBars/preview.html +5 -5
- package/design-system/components/FunnelBars/style.css +13 -0
- package/design-system/components/GoalBars/README.md +54 -10
- package/design-system/components/GoalBars/preview.html +69 -28
- package/design-system/components/GoalBars/style.css +51 -0
- package/design-system/components/GoalTicks/README.md +74 -58
- package/design-system/components/GoalTicks/preview.html +41 -118
- package/design-system/components/GoalTicks/style.css +37 -0
- package/design-system/components/GoalTubes/README.md +29 -3
- package/design-system/components/GoalTubes/preview.html +6 -6
- package/design-system/components/GoalTubes/style.css +23 -0
- package/design-system/components/Heatmap/README.md +133 -0
- package/design-system/components/Heatmap/preview.html +168 -0
- package/design-system/components/Heatmap/style.css +119 -0
- package/design-system/components/Hero/README.md +58 -40
- package/design-system/components/Hero/preview.html +1 -1
- package/design-system/components/Hero/style.css +19 -0
- package/design-system/components/HoverCard/README.md +114 -0
- package/design-system/components/HoverCard/preview.html +107 -0
- package/design-system/components/HoverCard/style.css +59 -0
- package/design-system/components/IconButton/README.md +69 -38
- package/design-system/components/IconButton/preview.html +77 -43
- package/design-system/components/IconButton/style.css +45 -0
- package/design-system/components/Input/README.md +36 -11
- package/design-system/components/Input/preview.html +1 -1
- package/design-system/components/Input/style.css +23 -0
- package/design-system/components/KanbanBoard/README.md +93 -45
- package/design-system/components/KanbanBoard/preview.html +159 -43
- package/design-system/components/KanbanBoard/style.css +53 -0
- package/design-system/components/Kbd/README.md +25 -9
- package/design-system/components/Kbd/preview.html +6 -2
- package/design-system/components/Kbd/style.css +9 -0
- package/design-system/components/KitButton/README.md +81 -47
- package/design-system/components/KitButton/preview.html +35 -13
- package/design-system/components/KitButton/style.css +46 -0
- package/design-system/components/KitCard/README.md +75 -44
- package/design-system/components/KitCard/preview.html +18 -10
- package/design-system/components/KitCard/style.css +15 -0
- package/design-system/components/KitInput/README.md +54 -39
- package/design-system/components/KitInput/preview.html +7 -7
- package/design-system/components/KitInput/style.css +23 -0
- package/design-system/components/Leaderboard/README.md +76 -49
- package/design-system/components/Leaderboard/preview.html +61 -26
- package/design-system/components/Leaderboard/style.css +44 -0
- package/design-system/components/ListDetail/README.md +222 -0
- package/design-system/components/ListDetail/preview.html +213 -0
- package/design-system/components/ListDetail/style.css +148 -0
- package/design-system/components/LoadBar/README.md +79 -0
- package/design-system/components/LoadBar/preview.html +40 -0
- package/design-system/components/LoadBar/style.css +17 -0
- package/design-system/components/MarketingNav/README.md +76 -42
- package/design-system/components/MarketingNav/preview.html +37 -8
- package/design-system/components/MarketingNav/style.css +45 -0
- package/design-system/components/Matrix/README.md +129 -0
- package/design-system/components/Matrix/preview.html +99 -0
- package/design-system/components/Matrix/style.css +84 -0
- package/design-system/components/Menu/README.md +117 -41
- package/design-system/components/Menu/preview.html +85 -23
- package/design-system/components/Menu/style.css +61 -0
- package/design-system/components/Meter/README.md +39 -4
- package/design-system/components/Meter/preview.html +18 -1
- package/design-system/components/Meter/style.css +23 -0
- package/design-system/components/MetricTile/README.md +237 -0
- package/design-system/components/MetricTile/preview.html +241 -0
- package/design-system/components/MetricTile/style.css +129 -0
- package/design-system/components/Morph/README.md +106 -0
- package/design-system/components/Morph/preview.html +103 -0
- package/design-system/components/Morph/style.css +31 -0
- package/design-system/components/Motion/README.md +164 -0
- package/design-system/components/Motion/preview.html +2537 -0
- package/design-system/components/NumberInput/README.md +27 -8
- package/design-system/components/NumberInput/preview.html +21 -5
- package/design-system/components/NumberInput/style.css +34 -0
- package/design-system/components/PaceBar/README.md +75 -0
- package/design-system/components/PaceBar/preview.html +67 -0
- package/design-system/components/PaceBar/style.css +25 -0
- package/design-system/components/Page/README.md +57 -18
- package/design-system/components/Page/preview.html +15 -17
- package/design-system/components/Page/style.css +7 -0
- package/design-system/components/PageBar/README.md +90 -34
- package/design-system/components/PageBar/preview.html +60 -19
- package/design-system/components/PageBar/style.css +35 -0
- package/design-system/components/PageHero/README.md +87 -51
- package/design-system/components/PageHero/preview.html +35 -6
- package/design-system/components/PageHero/style.css +31 -0
- package/design-system/components/Pagination/README.md +70 -49
- package/design-system/components/Pagination/preview.html +24 -15
- package/design-system/components/Pagination/style.css +12 -0
- package/design-system/components/Panel/README.md +109 -51
- package/design-system/components/Panel/preview.html +118 -20
- package/design-system/components/Panel/style.css +51 -0
- package/design-system/components/PasswordInput/README.md +50 -18
- package/design-system/components/PasswordInput/preview.html +71 -21
- package/design-system/components/PasswordInput/style.css +31 -0
- package/design-system/components/Plate/README.md +75 -17
- package/design-system/components/Plate/preview.html +40 -7
- package/design-system/components/Plate/style.css +37 -0
- package/design-system/components/Popover/README.md +70 -49
- package/design-system/components/Popover/preview.html +44 -22
- package/design-system/components/Popover/style.css +41 -0
- package/design-system/components/PricingTable/README.md +69 -49
- package/design-system/components/PricingTable/preview.html +21 -21
- package/design-system/components/PricingTable/style.css +21 -0
- package/design-system/components/ProgressPetals/README.md +31 -3
- package/design-system/components/ProgressPetals/preview.html +14 -15
- package/design-system/components/ProgressPetals/style.css +27 -0
- package/design-system/components/README.md +151 -0
- package/design-system/components/Radio/README.md +40 -17
- package/design-system/components/Radio/preview.html +16 -1
- package/design-system/components/Radio/style.css +21 -0
- package/design-system/components/RankBar/README.md +29 -2
- package/design-system/components/RankBar/preview.html +14 -12
- package/design-system/components/RankBar/style.css +18 -0
- package/design-system/components/Ring/README.md +61 -11
- package/design-system/components/Ring/preview.html +55 -10
- package/design-system/components/Ring/style.css +49 -0
- package/design-system/components/ScoreHero/README.md +91 -0
- package/design-system/components/ScoreHero/preview.html +104 -0
- package/design-system/components/ScoreHero/style.css +32 -0
- package/design-system/components/Section/README.md +72 -33
- package/design-system/components/Section/preview.html +46 -16
- package/design-system/components/Section/style.css +18 -0
- package/design-system/components/Segmented/README.md +100 -55
- package/design-system/components/Segmented/preview.html +107 -26
- package/design-system/components/Segmented/style.css +94 -0
- package/design-system/components/SegmentedProgress/README.md +64 -0
- package/design-system/components/SegmentedProgress/preview.html +69 -0
- package/design-system/components/SegmentedProgress/style.css +11 -0
- package/design-system/components/Select/README.md +47 -12
- package/design-system/components/Select/preview.html +28 -2
- package/design-system/components/Select/style.css +22 -0
- package/design-system/components/ShareBar/README.md +69 -0
- package/design-system/components/ShareBar/preview.html +72 -0
- package/design-system/components/ShareBar/style.css +25 -0
- package/design-system/components/SideList/README.md +147 -0
- package/design-system/components/SideList/preview.html +139 -0
- package/design-system/components/SideList/style.css +94 -0
- package/design-system/components/Skeleton/README.md +53 -16
- package/design-system/components/Skeleton/preview.html +35 -23
- package/design-system/components/Skeleton/style.css +17 -0
- package/design-system/components/Slider/README.md +95 -0
- package/design-system/components/Slider/preview.html +49 -0
- package/design-system/components/Slider/style.css +13 -0
- package/design-system/components/Split/README.md +112 -0
- package/design-system/components/Split/preview.html +105 -0
- package/design-system/components/Split/style.css +30 -0
- package/design-system/components/Starter/README.md +21 -9
- package/design-system/components/Starter/preview.html +5 -5
- package/design-system/components/Stat/README.md +64 -43
- package/design-system/components/Stat/preview.html +3 -3
- package/design-system/components/Stat/style.css +15 -0
- package/design-system/components/StatTiles/README.md +88 -44
- package/design-system/components/StatTiles/preview.html +142 -71
- package/design-system/components/StatTiles/style.css +64 -0
- package/design-system/components/StatusLine/README.md +85 -0
- package/design-system/components/StatusLine/preview.html +49 -0
- package/design-system/components/StatusLine/style.css +14 -0
- package/design-system/components/StatusScreen/README.md +49 -35
- package/design-system/components/StatusScreen/preview.html +20 -5
- package/design-system/components/StatusScreen/style.css +9 -0
- package/design-system/components/StepLine/README.md +97 -0
- package/design-system/components/StepLine/preview.html +108 -0
- package/design-system/components/StepLine/style.css +62 -0
- package/design-system/components/Stepper/README.md +35 -13
- package/design-system/components/Stepper/style.css +13 -0
- package/design-system/components/StreakCalendar/README.md +22 -1
- package/design-system/components/StreakCalendar/preview.html +10 -10
- package/design-system/components/StreakCalendar/style.css +12 -0
- package/design-system/components/SuggestionChip/README.md +87 -0
- package/design-system/components/SuggestionChip/preview.html +42 -0
- package/design-system/components/SuggestionChip/style.css +20 -0
- package/design-system/components/Switch/README.md +44 -24
- package/design-system/components/Switch/preview.html +23 -8
- package/design-system/components/Switch/style.css +31 -0
- package/design-system/components/Table/README.md +129 -58
- package/design-system/components/Table/preview.html +106 -72
- package/design-system/components/Table/style.css +104 -0
- package/design-system/components/Tabs/README.md +71 -46
- package/design-system/components/Tabs/preview.html +56 -24
- package/design-system/components/Tabs/style.css +44 -0
- package/design-system/components/Testimonial/README.md +48 -32
- package/design-system/components/Testimonial/preview.html +14 -14
- package/design-system/components/Testimonial/style.css +12 -0
- package/design-system/components/TextArea/README.md +27 -11
- package/design-system/components/TextArea/preview.html +8 -2
- package/design-system/components/TextArea/style.css +12 -0
- package/design-system/components/ThemeSwitch/README.md +116 -0
- package/design-system/components/ThemeSwitch/preview.html +57 -0
- package/design-system/components/ThemeSwitch/style.css +6 -0
- package/design-system/components/TickRow/README.md +52 -36
- package/design-system/components/TickRow/preview.html +64 -41
- package/design-system/components/TickRow/style.css +23 -0
- package/design-system/components/TickStrip/README.md +95 -0
- package/design-system/components/TickStrip/preview.html +88 -0
- package/design-system/components/TickStrip/style.css +42 -0
- package/design-system/components/Tile/README.md +79 -18
- package/design-system/components/Tile/preview.html +91 -40
- package/design-system/components/Tile/style.css +36 -0
- package/design-system/components/Timeline/README.md +68 -48
- package/design-system/components/Timeline/preview.html +27 -15
- package/design-system/components/Timeline/style.css +25 -0
- package/design-system/components/Toast/README.md +70 -38
- package/design-system/components/Toast/preview.html +43 -8
- package/design-system/components/Toast/style.css +25 -0
- package/design-system/components/Tooltip/README.md +93 -35
- package/design-system/components/Tooltip/preview.html +69 -15
- package/design-system/components/Tooltip/style.css +78 -0
- package/design-system/components/TopBar/README.md +67 -53
- package/design-system/components/TopBar/preview.html +14 -27
- package/design-system/components/TopBar/style.css +35 -0
- package/design-system/components/TopicRail/README.md +108 -0
- package/design-system/components/TopicRail/preview.html +58 -0
- package/design-system/components/TopicRail/style.css +48 -0
- package/design-system/components/TrendBars/README.md +52 -14
- package/design-system/components/TrendBars/preview.html +65 -32
- package/design-system/components/TrendBars/style.css +25 -0
- package/design-system/components/TrendLine/README.md +164 -0
- package/design-system/components/TrendLine/preview.html +373 -0
- package/design-system/components/TrendLine/style.css +155 -0
- package/design-system/components/Well/README.md +64 -22
- package/design-system/components/Well/preview.html +14 -14
- package/design-system/components/Well/style.css +22 -0
- package/design-system/components/_house.css +324 -0
- package/design-system/components/bundle.css +4086 -744
- package/design-system/tokens.json +1310 -124
- package/dist/fello-core.css +2 -2
- package/dist/fello.css +6 -1369
- package/dist/fello.scoped.css +7 -0
- package/dist/index.d.ts +109 -10
- package/dist/index.js +781 -96
- package/dist/palettes.d.ts +464 -0
- package/dist/palettes.js +497 -0
- package/dist/scoped.d.ts +3 -0
- package/dist/scoped.js +16 -0
- package/dist/toast.d.ts +14 -0
- package/dist/toast.js +33 -29
- package/dist/tokens.d.ts +1686 -62
- package/dist/tokens.js +1668 -61
- package/package.json +20 -4
- package/scripts/check-palette.mjs +295 -0
- package/scripts/token-model.mjs +552 -0
- package/tokens/_dark.css +173 -0
- package/tokens/_palettes.css +46 -0
- package/tokens/_product.css +266 -53
- package/tokens/_source.hubl.css +39 -19
- package/tokens/design-tokens.json +319 -0
- package/tokens/palettes.ts +504 -0
- package/tokens/shadcn-compat.css +19 -19
- package/tokens/shadcn-compat.hsl.css +76 -0
- package/tokens/tokens.css +1287 -62
- package/tokens/tokens.md +587 -61
- package/tokens/tokens.root.css +1293 -62
- package/tokens/tokens.ts +1677 -64
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* ---- TopBar: a product's 56 px top strip, the wordmark, up to five links, search, one quiet act and the person. Under
|
|
2
|
+
60rem of window (North's step, where five links and the search stop fitting) it is the phone form: the wordmark and the
|
|
3
|
+
menu button only; --phone draws that form at any width. ---- */
|
|
4
|
+
.ws-top-bar { display: flex; align-items: center; gap: var(--space-lg); min-width: 0; height: var(--ws-header-h); padding: 0 var(--space-lg); }
|
|
5
|
+
.ws-top-bar__wordmark { flex-shrink: 0; font-size: var(--ws-text-value); line-height: var(--space-lg); font-weight: 600; color: var(--color-text-heading); }
|
|
6
|
+
/* The links keep their words (they never shrink under them or run into the search); the search gives way, down to 96. */
|
|
7
|
+
.ws-top-bar__links { display: flex; flex: 1 0 auto; align-items: center; gap: var(--space-lg); }
|
|
8
|
+
.ws-top-bar__link { position: relative; display: inline-flex; align-items: center; height: var(--ws-header-h); margin-inline: calc(var(--space-xs) * -1); padding-inline: var(--space-xs); font-size: var(--ws-text-body); font-weight: 500; color: var(--color-text-body); text-decoration: none; white-space: nowrap; }
|
|
9
|
+
@media (hover: hover) { .ws-top-bar__link:hover { color: var(--color-text-heading); } }
|
|
10
|
+
.ws-top-bar__link:is(.ws-top-bar__link--current, [aria-current="page"]) { color: var(--color-text-heading); }
|
|
11
|
+
/* A link is the bar's full height, so its ring goes inside it, on the control corners, never over the bar's edge; the
|
|
12
|
+
link's box bleeds 8 past its words (Seth's A3) so the ring clears them and the words keep their place. */
|
|
13
|
+
.ws-top-bar__link:focus-visible { border-radius: var(--ws-radius-control); outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
14
|
+
.ws-top-bar__link:is(.ws-top-bar__link--current, [aria-current="page"])::after { content: ""; position: absolute; inset-inline: var(--space-xs); bottom: 0; height: var(--ws-ring); background: var(--color-text-heading); border-radius: var(--ws-radius-bar); }
|
|
15
|
+
.ws-top-bar__search { display: flex; flex-shrink: 1; align-items: center; gap: var(--space-xxs); width: var(--space-9xl); min-width: var(--space-6xl); height: var(--ws-control-h); padding: 0 var(--space-xs); border-radius: var(--ws-radius-control); background: var(--ws-field); box-shadow: inset 0 0 0 var(--ws-hairline) var(--ws-edge-card); color: var(--color-text-muted); font-size: var(--ws-text-meta); white-space: nowrap; overflow: hidden; cursor: text; }
|
|
16
|
+
.ws-top-bar__search svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); flex-shrink: 0; }
|
|
17
|
+
/* The search is a real field: a <label> round an <input type="search">; the ring goes on the box, not the bare input. */
|
|
18
|
+
.ws-top-bar__search > input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: none; -webkit-appearance: none; appearance: none; font: inherit; color: var(--ws-field-ink); }
|
|
19
|
+
.ws-top-bar__search > input::placeholder { color: var(--color-text-muted); opacity: 1; }
|
|
20
|
+
.ws-top-bar__search > input:focus-visible { outline: none; }
|
|
21
|
+
.ws-top-bar__search:focus-within { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
|
|
22
|
+
@media (pointer: coarse) { .ws-top-bar__search { height: var(--ws-touch); font-size: var(--ws-text-value); } } /* 16 px words: a phone does not zoom into the field on focus */
|
|
23
|
+
.ws-top-bar__end { display: flex; flex-shrink: 0; align-items: center; gap: var(--space-xs); }
|
|
24
|
+
.ws-top-bar__menu { display: none; }
|
|
25
|
+
/* The phone form: the wordmark at the left, the menu button at the right; the links, the search and the quiet act move
|
|
26
|
+
into the menu it opens. */
|
|
27
|
+
.ws-top-bar--phone { justify-content: space-between; gap: var(--space-md); padding: 0 var(--space-md); }
|
|
28
|
+
.ws-top-bar--phone :is(.ws-top-bar__links, .ws-top-bar__search, .ws-top-bar__end) { display: none; }
|
|
29
|
+
.ws-top-bar--phone .ws-top-bar__menu { display: inline-flex; }
|
|
30
|
+
@media (max-width: 60rem) {
|
|
31
|
+
.ws-top-bar { justify-content: space-between; gap: var(--space-md); padding: 0 var(--space-md); }
|
|
32
|
+
.ws-top-bar :is(.ws-top-bar__links, .ws-top-bar__search, .ws-top-bar__end) { display: none; }
|
|
33
|
+
.ws-top-bar .ws-top-bar__menu { display: inline-flex; }
|
|
34
|
+
}
|
|
35
|
+
@media (prefers-reduced-motion: no-preference) { .ws-top-bar__link { transition: color var(--ws-duration-hover) var(--ws-ease-soft); } }
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
One continuous chat marked by topic: a quiet topic head in the thread where the subject changes, and a rail of small
|
|
2
|
+
squares at the thread's edge that opens the list of topics.
|
|
3
|
+
|
|
4
|
+
## Use it when
|
|
5
|
+
|
|
6
|
+
- One long chat with an agent covers several subjects over days, and a person needs to see where one starts and to
|
|
7
|
+
jump back to it.
|
|
8
|
+
- A topic gets news while the person is elsewhere (the current topic is marked).
|
|
9
|
+
|
|
10
|
+
## Not for
|
|
11
|
+
|
|
12
|
+
- Separate conversations with separate people: use a list of threads.
|
|
13
|
+
- Sections of a page: use `Section`.
|
|
14
|
+
- Steps of a flow: use `Stepper`.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
- The topic head (`ws-topic`, a `li` in the thread): a 0.5 px navy rule above it (navy at 10 %; none on the first),
|
|
19
|
+
14 px under the rule; the topic (`ws-topic__name`) 12 / 16 semibold navy, the one you are in (`aria-current`) in the
|
|
20
|
+
needs-you salmon's AA step (`--ws-word-needs`); its count (`ws-topic__count`) 11 / 13 muted; 8 px apart on the
|
|
21
|
+
baseline. It sits 28 px under the item before it and 20 px above the next.
|
|
22
|
+
- Its act (`ws-topic__act`, a summary): at the end, 24 px tall, 8 px sides, 6 px corners, 12 / 16 semibold navy, on
|
|
23
|
+
the topic's baseline (its first line, when the name wraps).
|
|
24
|
+
- The rail (`ws-topic-rail`): 20 px wide, the thread's gutter (`--ws-card-inset`), so neither it nor its focus ring
|
|
25
|
+
(drawn inside it) reaches the words; on touch it takes a 40 px hit area (12 px out into the stage's inset, 8 px over the words' edge); under a pointer its squares darken; in a chat shell it sits in that gutter, 64 px from the top and 96 px from the
|
|
26
|
+
bottom. Its marks (`ws-topic-rail__marks`, one button): 4 px squares, 4 px apart, navy at 20 %, 4 px
|
|
27
|
+
in; the topic you are in is a 10 x 4 navy dash.
|
|
28
|
+
- The list (`ws-topic-rail__panel`): 264 px wide, 4 px beside the rail, centred on it, 8 px inside, 10 px corners, the
|
|
29
|
+
raised ground with the 0.5 px card edge and the menu's shadow. A head ("Topics", 12 / 16 medium muted), then a row
|
|
30
|
+
per topic (`ws-topic-rail__item`: 8 px inside, 6 px corners, 2 px between its lines): the name 13 / 18 medium navy
|
|
31
|
+
(the current one in the AA salmon), the count 11 / 13 muted, its first question 12 / 16 in the body grey, cut with a
|
|
32
|
+
title.
|
|
33
|
+
|
|
34
|
+
## Variants and sizes
|
|
35
|
+
|
|
36
|
+
| Part | Size |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| Topic head | 24 px tall at least |
|
|
39
|
+
| Rail | 20 px wide (the thread's gutter), as tall as its marks |
|
|
40
|
+
| List | 264 px wide, at most the rail's height, scrolling inside |
|
|
41
|
+
|
|
42
|
+
## States
|
|
43
|
+
|
|
44
|
+
- **Default**: the heads in the thread, the rail at rest.
|
|
45
|
+
- **Current**: the topic you are in, its head and its row in salmon, its mark the navy dash.
|
|
46
|
+
- **Head hover or focus** (a pointer that hovers): the summary act shows; on keyboard focus too. A touch screen always
|
|
47
|
+
shows it.
|
|
48
|
+
- **Rail open**: the list shows beside the rail (`aria-expanded="true"` on the marks). It opens after a short hover
|
|
49
|
+
intent and closes 160 ms after the pointer leaves (`--ws-hover-intent`, `--ws-close-delay`), or on a click and
|
|
50
|
+
Escape.
|
|
51
|
+
- **Row hover**: the navy 5 % wash; a press takes `--ws-surface-press` at once; focus draws the ring inside the row.
|
|
52
|
+
- **Long words**: a topic name wraps in the list; its first question is cut with a title.
|
|
53
|
+
- **Dark**: every rule, mark and ground is a theme token.
|
|
54
|
+
|
|
55
|
+
## Behaviour
|
|
56
|
+
|
|
57
|
+
- Keyboard: the marks are one button that opens the list; each row is a button that scrolls the thread to its topic
|
|
58
|
+
head and moves focus there. Escape closes the list and returns focus to the marks.
|
|
59
|
+
- Screen reader: the marks say where you are ("Topics, 2 of 3"); the list is a labelled group; the current row
|
|
60
|
+
carries `aria-current`.
|
|
61
|
+
- Motion: the list slides in from 8 px left out of a 3 px blur over `--ws-duration-settle`. Reduced motion: it is
|
|
62
|
+
simply there.
|
|
63
|
+
|
|
64
|
+
## Content
|
|
65
|
+
|
|
66
|
+
- A topic is named in two to five words, sentence case ("Friday's open house on Elm Street"), never a date alone.
|
|
67
|
+
- The count says how many messages, not how old.
|
|
68
|
+
|
|
69
|
+
## Rules
|
|
70
|
+
|
|
71
|
+
- One chat, many topics: a topic head never starts a new thread.
|
|
72
|
+
- What shows on hover also shows on keyboard focus, and always on touch.
|
|
73
|
+
|
|
74
|
+
## Source
|
|
75
|
+
|
|
76
|
+
**Derived from**: North's topic heads and topics rail (style1.css:606-640, :1365-1366, :1393-1397, :1737-1742: the
|
|
77
|
+
0.5 rule at navy 10 %, 14 under it, the current topic coral, 4 px squares 4 apart with a 10 x 4 dash, the 264 panel).
|
|
78
|
+
The 11.5 px words are 12 and 11 here (D3), and the coral word takes its AA step (D2).
|
|
79
|
+
|
|
80
|
+
## Markup
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<li class="ws-topic" aria-current="true">
|
|
84
|
+
<span class="ws-topic__name">Friday's open house</span>
|
|
85
|
+
<span class="ws-topic__count">2 messages</span>
|
|
86
|
+
<button type="button" class="ws-topic__act">Summary</button>
|
|
87
|
+
</li>
|
|
88
|
+
|
|
89
|
+
<div class="ws-topic-rail">
|
|
90
|
+
<button type="button" class="ws-topic-rail__marks" aria-label="Topics, 2 of 3" aria-expanded="false" aria-controls="topics">
|
|
91
|
+
<i></i><i aria-current="true"></i><i></i>
|
|
92
|
+
</button>
|
|
93
|
+
<div class="ws-topic-rail__panel" id="topics" role="group" aria-label="Topics" hidden>
|
|
94
|
+
<span class="ws-topic-rail__head">Topics</span>
|
|
95
|
+
<button type="button" class="ws-topic-rail__item" aria-current="true">
|
|
96
|
+
<span class="ws-topic-rail__title">Friday's open house</span>
|
|
97
|
+
<span class="ws-topic-rail__sub">2 messages</span>
|
|
98
|
+
<span class="ws-topic-rail__quote" title="Who is coming on Friday?">Who is coming on Friday?</span>
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Styles
|
|
105
|
+
|
|
106
|
+
`TopicRail/style.css` (its keyframe `ws-topic-in` lives there). Tokens: `--ws-ink`, `--ws-word-needs`,
|
|
107
|
+
`--ws-text-dense`, `--ws-text-micro`, `--ws-leading-micro`, `--ws-raised`, `--ws-edge-card`, `--ws-shadow-menu`,
|
|
108
|
+
`--ws-hover`, `--ws-hover-strong`, `--ws-radius-row`, `--ws-radius-menu` (the list's 10 px corners).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!-- @dsCard group="Chat" height=592 -->
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>TopicRail</title>
|
|
7
|
+
<link rel="stylesheet" href="../../tokens.css">
|
|
8
|
+
<link rel="stylesheet" href="../bundle.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div class="ws-stage" style="background: var(--ws-frame);">
|
|
12
|
+
<div class="ws-stack" style="width: 440px;">
|
|
13
|
+
<span class="ws-muted">Topic heads in one thread: a rule above each but the first; the one you are in, in salmon</span>
|
|
14
|
+
<div class="ws-chat-shell" style="height: 520px;">
|
|
15
|
+
<ol class="ws-chat-shell__thread" aria-label="Chat">
|
|
16
|
+
<li class="ws-topic">
|
|
17
|
+
<span class="ws-topic__name">Sam’s calls</span>
|
|
18
|
+
<span class="ws-topic__count">4 messages</span>
|
|
19
|
+
<button type="button" class="ws-topic__act">Summary</button>
|
|
20
|
+
</li>
|
|
21
|
+
<li class="ws-chat-turn ws-chat-turn--person"><p class="ws-chat-turn__bubble">Why is Sam so far behind?</p></li>
|
|
22
|
+
<li class="ws-chat-turn ws-chat-turn--agent"><p class="ws-chat-turn__words">He lost two days to the Elm Street closing. His calls the other three days were on pace.</p></li>
|
|
23
|
+
<li class="ws-topic" aria-current="true">
|
|
24
|
+
<span class="ws-topic__name">Friday’s open house on Elm Street</span>
|
|
25
|
+
<span class="ws-topic__count">2 messages</span>
|
|
26
|
+
<button type="button" class="ws-topic__act">Summary</button>
|
|
27
|
+
</li>
|
|
28
|
+
<li class="ws-chat-turn ws-chat-turn--person"><p class="ws-chat-turn__bubble">Who is coming on Friday?</p></li>
|
|
29
|
+
<li class="ws-chat-turn ws-chat-turn--agent"><p class="ws-chat-turn__words">Eleven so far, three of them buyers Dana has met before.</p></li>
|
|
30
|
+
</ol>
|
|
31
|
+
<div class="ws-topic-rail">
|
|
32
|
+
<button type="button" class="ws-topic-rail__marks" aria-label="Topics, 2 of 3" aria-expanded="true" aria-controls="topics-panel">
|
|
33
|
+
<i></i><i aria-current="true"></i><i></i>
|
|
34
|
+
</button>
|
|
35
|
+
<div class="ws-topic-rail__panel" id="topics-panel" role="group" aria-label="Topics">
|
|
36
|
+
<span class="ws-topic-rail__head">Topics</span>
|
|
37
|
+
<button type="button" class="ws-topic-rail__item">
|
|
38
|
+
<span class="ws-topic-rail__title">Sam’s calls</span>
|
|
39
|
+
<span class="ws-topic-rail__sub">4 messages</span>
|
|
40
|
+
<span class="ws-topic-rail__quote" title="Why is Sam so far behind?">Why is Sam so far behind?</span>
|
|
41
|
+
</button>
|
|
42
|
+
<button type="button" class="ws-topic-rail__item" aria-current="true">
|
|
43
|
+
<span class="ws-topic-rail__title">Friday’s open house on Elm Street</span>
|
|
44
|
+
<span class="ws-topic-rail__sub">2 messages</span>
|
|
45
|
+
<span class="ws-topic-rail__quote" title="Who is coming on Friday?">Who is coming on Friday?</span>
|
|
46
|
+
</button>
|
|
47
|
+
<button type="button" class="ws-topic-rail__item">
|
|
48
|
+
<span class="ws-topic-rail__title">October goal</span>
|
|
49
|
+
<span class="ws-topic-rail__sub">6 messages</span>
|
|
50
|
+
<span class="ws-topic-rail__quote" title="Are we going to make 40 calls by the end of the month, or should we move the goal?">Are we going to make 40 calls by the end of the month, or should we move the goal?</span>
|
|
51
|
+
</button>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* ---- TopicRail: one continuous chat marked by topic (North's): a topic head in the thread, and a rail of 4 px squares that opens the list of topics ---- */
|
|
2
|
+
/* The topic head: a 0.5 px navy rule above it (none on the first), 14 under the rule; the topic 12 / 16 semibold navy
|
|
3
|
+
(the one you are in, the needs-you AA salmon), its count 11 / 13 muted, 8 apart on the baseline. It sits 28 under
|
|
4
|
+
the turn before it and 20 above the next. Its act (a summary) shows on hover and on keyboard focus; always on touch. */
|
|
5
|
+
.ws-topic { display: flex; align-items: baseline; gap: var(--space-xs); min-height: var(--space-lg); padding-top: var(--space-sm-plus); border-top: var(--ws-hairline) solid color-mix(in srgb, var(--ws-ink) 10%, transparent); }
|
|
6
|
+
* + .ws-topic { margin-top: calc(var(--space-lg) + var(--space-xxs)); }
|
|
7
|
+
.ws-topic:first-child { padding-top: 0; border-top: 0; }
|
|
8
|
+
.ws-topic + * { margin-top: calc(var(--space-md) + var(--space-xxs)); }
|
|
9
|
+
.ws-topic__name { min-width: 0; font-size: var(--ws-text-dense); line-height: var(--space-md); font-weight: 600; color: var(--color-text-heading); }
|
|
10
|
+
.ws-topic[aria-current] .ws-topic__name { color: var(--ws-word-needs); }
|
|
11
|
+
.ws-topic__count { flex-shrink: 0; font-size: var(--ws-text-micro); line-height: var(--ws-leading-micro); color: var(--color-text-muted); }
|
|
12
|
+
.ws-topic__act { display: inline-flex; flex-shrink: 0; align-items: center; gap: var(--space-xxs-plus); min-height: var(--space-lg); margin-left: auto; padding: 0 var(--space-xs); border: 0; border-radius: var(--ws-radius-row); background: none; font-size: var(--ws-text-dense); line-height: var(--space-md); font-weight: 600; color: var(--color-text-heading); cursor: pointer; transition: opacity var(--ws-duration-hover) var(--ws-ease-soft), background-color var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
13
|
+
.ws-topic__act > svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
14
|
+
@media (hover: hover) {
|
|
15
|
+
.ws-topic__act { opacity: 0; }
|
|
16
|
+
.ws-topic:hover .ws-topic__act, .ws-topic__act:focus-visible, .ws-topic__act[aria-expanded="true"] { opacity: 1; }
|
|
17
|
+
.ws-topic__act:hover { background-color: var(--ws-hover-strong); }
|
|
18
|
+
}
|
|
19
|
+
/* The rail: a column of 4 px squares 4 apart, the topic you are in a 10 x 4 navy dash; the whole column is one button
|
|
20
|
+
that opens the list. In a chat shell it sits in the thread's left gutter, between the head and the composer. */
|
|
21
|
+
/* The rail is as wide as the thread's gutter (20, North's 18 rail in a 20 gutter): at 24 its button and its focus ring
|
|
22
|
+
reached 4 px into the words. The ring is drawn inside it for the same reason. */
|
|
23
|
+
.ws-topic-rail { position: relative; display: flex; align-items: center; width: var(--ws-card-inset); }
|
|
24
|
+
.ws-chat-shell > .ws-topic-rail { position: absolute; z-index: 1; top: var(--space-4xl); bottom: var(--space-6xl); left: 0; }
|
|
25
|
+
.ws-topic-rail__marks { display: flex; flex-direction: column; gap: var(--space-xxs); width: 100%; padding: var(--space-xs-plus) 0 var(--space-xs-plus) var(--space-xxs); border: 0; border-radius: var(--ws-radius-control); background: none; cursor: pointer; }
|
|
26
|
+
.ws-topic-rail__marks:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
27
|
+
/* Touch: the 20 px rail keeps its look and takes the 40 px hit area of a control with no words (the house's touch
|
|
28
|
+
floor): 12 out into the stage's inset on the left, 8 over the words' edge on the right. */
|
|
29
|
+
@media (pointer: coarse) { .ws-topic-rail__marks { position: relative; } .ws-topic-rail__marks::after { content: ""; position: absolute; inset: 0 calc(var(--space-xs) * -1) 0 calc(var(--space-sm) * -1); } }
|
|
30
|
+
/* Under the pointer the squares darken, so the rail shows it opens something. */
|
|
31
|
+
@media (hover: hover) { .ws-topic-rail__marks:hover > i:not([aria-current]) { background: color-mix(in srgb, var(--ws-ink) 40%, transparent); } }
|
|
32
|
+
.ws-topic-rail__marks > i { display: block; width: var(--space-xxs); height: var(--space-xxs); border-radius: var(--ws-radius-bar); background: color-mix(in srgb, var(--ws-ink) 20%, transparent); transition: width var(--ws-duration-hover) var(--ws-ease-soft), background-color var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
33
|
+
.ws-topic-rail__marks > i[aria-current] { width: var(--space-xs-plus); background: var(--color-text-heading); }
|
|
34
|
+
/* The list of topics: 264 wide, 8 inside, 10 px corners, the raised ground with the menu's shadow; a row per topic
|
|
35
|
+
(its name 13 / 18 medium navy, the current one in the AA salmon; a count 11 / 13 muted; its first question 12 / 16,
|
|
36
|
+
cut with a title), 8 inside, 6 px corners, the navy wash under the pointer. */
|
|
37
|
+
.ws-topic-rail__panel { position: absolute; z-index: var(--z-dropdown); top: 50%; left: calc(100% + var(--space-xxs)); translate: 0 -50%; width: calc(var(--space-9xl) + var(--space-4xl)); max-height: 100%; overflow-y: auto; padding: var(--space-xs); border: var(--ws-hairline) solid var(--ws-edge-card); border-radius: var(--ws-radius-menu); background: var(--ws-raised); box-shadow: var(--ws-shadow-menu); }
|
|
38
|
+
.ws-topic-rail__head { display: block; padding: var(--space-xxs) var(--space-xs) var(--space-xxs-plus); font-size: var(--ws-text-dense); line-height: var(--space-md); font-weight: 500; color: var(--color-text-muted); }
|
|
39
|
+
.ws-topic-rail__item { display: flex; width: 100%; flex-direction: column; align-items: flex-start; gap: var(--space-3xs); padding: var(--space-xs); border: 0; border-radius: var(--ws-radius-row); background: none; text-align: left; cursor: pointer; transition: background-color var(--ws-duration-hover) var(--ws-ease-soft); }
|
|
40
|
+
.ws-topic-rail__item:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
41
|
+
@media (hover: hover) { .ws-topic-rail__item:hover { background-color: var(--ws-hover); } }
|
|
42
|
+
.ws-topic-rail__item:active { background-color: var(--ws-surface-press); transition-duration: var(--ws-duration-instant); }
|
|
43
|
+
.ws-topic-rail__title { font-size: var(--ws-text-control); line-height: var(--ws-leading-control); font-weight: 500; color: var(--color-text-heading); }
|
|
44
|
+
.ws-topic-rail__item[aria-current] .ws-topic-rail__title { color: var(--ws-word-needs); }
|
|
45
|
+
.ws-topic-rail__sub { font-size: var(--ws-text-micro); line-height: var(--ws-leading-micro); color: var(--color-text-muted); }
|
|
46
|
+
.ws-topic-rail__quote { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--ws-text-dense); line-height: var(--space-md); color: var(--color-text-body); }
|
|
47
|
+
@keyframes ws-topic-in { from { opacity: 0; transform: translateX(calc(var(--space-xs) * -1)); filter: blur(var(--ws-blur-arrive)); } }
|
|
48
|
+
@media (prefers-reduced-motion: no-preference) { .ws-topic-rail__panel { animation: ws-topic-in var(--ws-duration-settle) var(--ws-ease-settle); } }
|
|
@@ -10,8 +10,8 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
10
10
|
## Not for
|
|
11
11
|
|
|
12
12
|
- A share of categories or a comparison with no time axis: use `GoalBars`.
|
|
13
|
-
- A
|
|
14
|
-
|
|
13
|
+
- A bill or a rate that steps over quarters against a reference line: use `StepLine` (Seth's Tally). A value over
|
|
14
|
+
months or weeks read on an axis: use `TrendLine`. A daily trend is always thin bars, never a line.
|
|
15
15
|
- A sparkline inside a row: use a `ChangeChip` instead; this component is a card's own chart, not a row decoration.
|
|
16
16
|
|
|
17
17
|
## Anatomy
|
|
@@ -20,13 +20,20 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
20
20
|
plain words.
|
|
21
21
|
- The big number: 72 px (`ws-display`, `--ws-text-display`), regular weight, tabular numerals, at the left, with its
|
|
22
22
|
`ChangeChip` beside it on the baseline ("↗ 38% since Sep 20").
|
|
23
|
-
- The bars: 2 px wide (`--ws-radius-bar` corners),
|
|
23
|
+
- The bars (`.ws-trend-bars__chart`, one `.ws-trend-bars__bar` a day): 2 px wide (`--ws-radius-bar` corners), spread
|
|
24
|
+
across the whole plot (at least 4 px apart, so the run never stops short of the card's edge), each a vertical gradient from `--ws-chart-purple-fade` at
|
|
24
25
|
its base to `--ws-chart-past-half` (purple) at its value, so taller bars read more saturated without a second colour
|
|
25
26
|
being introduced.
|
|
26
|
-
- The moment
|
|
27
|
-
`--ws-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- The moment (`.ws-trend-bars__moment` holding `__moment-line`, `__moment-chip` and a `__bar--moment`): one bar in the
|
|
28
|
+
salmon tone (`--ws-chart-under-half` (chart tone 3, so a palette that sets it moves it)) instead of purple, with a label chip above it in `--ws-tint-needs` fill and `--ws-word-needs` words
|
|
29
|
+
("Sep 20 · 88 Pine sold"), and a faint salmon guide line from the chip down to the bar. Put the moment's `--i` (its
|
|
30
|
+
day in the run) on `.ws-trend-bars__moment` and `--n` on the chart: the chip slides along its bar by that place, its
|
|
31
|
+
left end on a first-day bar, centred mid-run, its right end on the last day, so it never runs off the plot on a
|
|
32
|
+
phone. Without `--i` it centres on the bar.
|
|
33
|
+
- Axis (`.ws-trend-bars__axis`): one span a day, on the bars' spacing; a week's first day carries its date ("Sep 7",
|
|
34
|
+
"Sep 14") in 11 px muted words (`--ws-text-micro`, the system's floor), starting on its bar. Never a date under
|
|
35
|
+
every bar: at a phone's width they run into each other.
|
|
36
|
+
- The figure row (`.ws-trend-bars__figure`): the big number and its chip, 12 apart, 24 above the chart.
|
|
30
37
|
- A footer band with one act, following from the trend (drafting a follow-up post while the moment is still recent).
|
|
31
38
|
|
|
32
39
|
## Variants and sizes
|
|
@@ -34,7 +41,7 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
34
41
|
| Part | Value |
|
|
35
42
|
| --- | --- |
|
|
36
43
|
| Bar width | 2 px |
|
|
37
|
-
| Bar gap | 4 px |
|
|
44
|
+
| Bar gap | the run spans the plot, at least 4 px |
|
|
38
45
|
| Chart height | about 92 px, with 28 px of head room above the tallest bar for the moment's label |
|
|
39
46
|
| Big number | 72 px, one per card |
|
|
40
47
|
|
|
@@ -44,8 +51,9 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
44
51
|
- **No moment this period**: the sentence and band describe the trend alone; the salmon bar and its chip simply do not
|
|
45
52
|
appear rather than being forced onto an arbitrary day.
|
|
46
53
|
- **Falling trend**: the change chip switches to mid blue with the down-right mark, never red, same as any `ChangeChip`.
|
|
47
|
-
- **Narrow (
|
|
48
|
-
|
|
54
|
+
- **Narrow (a phone or the panel)**: the bars keep their 2 px width and close up toward 4 px, so four weeks (28 bars,
|
|
55
|
+
166 px) fit any column; a longer run shows fewer days rather than compressing. A moment near either end keeps its
|
|
56
|
+
chip inside the plot (its `--i`).
|
|
49
57
|
- **Empty** (no data yet): the card is left out entirely, per the system's rule that a card whose data does not exist is
|
|
50
58
|
never drawn empty.
|
|
51
59
|
- **Reduced motion**: bars shown at their final heights, no rise.
|
|
@@ -54,8 +62,9 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
54
62
|
|
|
55
63
|
- Keyboard: the chart is read, not operated; the band's one button is the card's only interactive control besides any
|
|
56
64
|
link the figure itself might carry.
|
|
57
|
-
- Motion: bars
|
|
58
|
-
on
|
|
65
|
+
- Motion: the bars draw as one 900 ms progress (`--ws-duration-draw`): bar i starts at its share of the first 55% and
|
|
66
|
+
rises from its foot on `--ws-ease-settle` (set `--n` on the chart and `--i` on each bar), as North draws a chart. The figure is static text and
|
|
67
|
+
does not count up (North). Reduced motion shows the final state at once.
|
|
59
68
|
|
|
60
69
|
## Content
|
|
61
70
|
|
|
@@ -75,8 +84,9 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
75
84
|
|
|
76
85
|
## Rules
|
|
77
86
|
|
|
78
|
-
- **
|
|
79
|
-
|
|
87
|
+
- **Thin bars for a trend over days**: a daily count's trend is thin bars, never a line. A bill or a rate that steps
|
|
88
|
+
over quarters against a reference is Seth's `StepLine` (Tally); a value over months or weeks on an axis is a
|
|
89
|
+
`TrendLine` (North's revenue chart).
|
|
80
90
|
- **One moment, one colour**: salmon marks the one day that explains the shape; every other bar stays in the purple
|
|
81
91
|
family, so salmon keeps its meaning as "the thing to notice" rather than becoming a second decorative tone.
|
|
82
92
|
- **A falling number is mid blue, never red** (`03-colour.md`), carried straight from `ChangeChip`.
|
|
@@ -92,3 +102,31 @@ A trend over days as thin rising bars, with one day called out as the moment tha
|
|
|
92
102
|
radius decided once for every trend chart. **Precedent**: an intentional addition decided from the system, 26 Oct
|
|
93
103
|
2026; no product app yet supplies real day-by-day profile-view data, so this was built directly from the designer's
|
|
94
104
|
reference.
|
|
105
|
+
|
|
106
|
+
## Markup
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<div class="ws-trend-bars__body">
|
|
110
|
+
<div class="ws-trend-bars__figure">
|
|
111
|
+
<span class="ws-display">412</span>
|
|
112
|
+
<span class="ws-change ws-change--up"><svg viewBox="0 0 16 16" aria-hidden="true">...</svg>38% since Sep 20</span>
|
|
113
|
+
</div>
|
|
114
|
+
<div class="ws-trend-bars__chart ws-dots" role="img" aria-label="Daily profile views over four weeks" style="--n: 28;">
|
|
115
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 0; height: 22%;"></div>
|
|
116
|
+
<!-- one bar a day, --i counting up; the day that moved it carries its --i on the moment: -->
|
|
117
|
+
<div class="ws-trend-bars__moment" style="--i: 13;">
|
|
118
|
+
<span class="ws-trend-bars__moment-line" aria-hidden="true"></span>
|
|
119
|
+
<span class="ws-trend-bars__moment-chip">Sep 20 · 88 Pine sold</span>
|
|
120
|
+
<div class="ws-trend-bars__bar ws-trend-bars__bar--moment ws-grow-up" style="height: 46%;"></div>
|
|
121
|
+
</div>
|
|
122
|
+
<!-- ... to --i: 27 -->
|
|
123
|
+
</div>
|
|
124
|
+
<div class="ws-trend-bars__axis" aria-hidden="true">
|
|
125
|
+
<span>Sep 7</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
126
|
+
<span>Sep 14</span><!-- six empty spans, then each week's first day: Sep 21, Sep 28 -->
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Styles**: `TrendBars/style.css`, in `bundle.css` and `fello.css` as `.ws-trend-bars`. Every value is a token. `.ws-trend-bars` itself has no styles: it is the hook that
|
|
132
|
+
names the chart (and the root for its modifiers); its parts carry the styles.
|
|
@@ -28,44 +28,45 @@
|
|
|
28
28
|
</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
|
-
<div class="ws-trend-bars__chart ws-dots" role="img" aria-label="Daily profile views over four weeks, rising sharply after 88 Pine sold on September 20">
|
|
32
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 22%;"></div>
|
|
33
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 30%;"></div>
|
|
34
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 18%;"></div>
|
|
35
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 26%;"></div>
|
|
36
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 34%;"></div>
|
|
37
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 20%;"></div>
|
|
38
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 28%;"></div>
|
|
39
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 24%;"></div>
|
|
40
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 32%;"></div>
|
|
41
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 19%;"></div>
|
|
42
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 36%;"></div>
|
|
43
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 29%;"></div>
|
|
44
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 40%;"></div>
|
|
45
|
-
<div class="ws-trend-bars__moment">
|
|
31
|
+
<div class="ws-trend-bars__chart ws-dots" role="img" aria-label="Daily profile views over four weeks, rising sharply after 88 Pine sold on September 20" style="--n: 28;">
|
|
32
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 0; height: 22%;"></div>
|
|
33
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 1; height: 30%;"></div>
|
|
34
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 2; height: 18%;"></div>
|
|
35
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 3; height: 26%;"></div>
|
|
36
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 4; height: 34%;"></div>
|
|
37
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 5; height: 20%;"></div>
|
|
38
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 6; height: 28%;"></div>
|
|
39
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 7; height: 24%;"></div>
|
|
40
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 8; height: 32%;"></div>
|
|
41
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 9; height: 19%;"></div>
|
|
42
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 10; height: 36%;"></div>
|
|
43
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 11; height: 29%;"></div>
|
|
44
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 12; height: 40%;"></div>
|
|
45
|
+
<div class="ws-trend-bars__moment" style="--i: 13;">
|
|
46
46
|
<span class="ws-trend-bars__moment-line" aria-hidden="true"></span>
|
|
47
47
|
<span class="ws-trend-bars__moment-chip">Sep 20 · 88 Pine sold</span>
|
|
48
48
|
<div class="ws-trend-bars__bar ws-trend-bars__bar--moment ws-grow-up" style="height: 46%;"></div>
|
|
49
49
|
</div>
|
|
50
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 58%;"></div>
|
|
51
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 66%;"></div>
|
|
52
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 54%;"></div>
|
|
53
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 72%;"></div>
|
|
54
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 62%;"></div>
|
|
55
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 78%;"></div>
|
|
56
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 68%;"></div>
|
|
57
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 84%;"></div>
|
|
58
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 74%;"></div>
|
|
59
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 90%;"></div>
|
|
60
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 80%;"></div>
|
|
61
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 96%;"></div>
|
|
62
|
-
<div class="ws-trend-bars__bar ws-grow-up" style="height: 86%;"></div>
|
|
50
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 14; height: 58%;"></div>
|
|
51
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 15; height: 66%;"></div>
|
|
52
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 16; height: 54%;"></div>
|
|
53
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 17; height: 72%;"></div>
|
|
54
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 18; height: 62%;"></div>
|
|
55
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 19; height: 78%;"></div>
|
|
56
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 20; height: 68%;"></div>
|
|
57
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 21; height: 84%;"></div>
|
|
58
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 22; height: 74%;"></div>
|
|
59
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 23; height: 90%;"></div>
|
|
60
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 24; height: 80%;"></div>
|
|
61
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 25; height: 96%;"></div>
|
|
62
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 26; height: 86%;"></div>
|
|
63
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 27; height: 92%;"></div>
|
|
63
64
|
</div>
|
|
64
65
|
<div class="ws-trend-bars__axis" aria-hidden="true">
|
|
65
|
-
<span>
|
|
66
|
-
<span>
|
|
67
|
-
<span>
|
|
68
|
-
<span>
|
|
66
|
+
<span>Sep 7</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
67
|
+
<span>Sep 14</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
68
|
+
<span>Sep 21</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
69
|
+
<span>Sep 28</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
69
70
|
</div>
|
|
70
71
|
</div>
|
|
71
72
|
|
|
@@ -79,6 +80,38 @@
|
|
|
79
80
|
</section>
|
|
80
81
|
</div>
|
|
81
82
|
|
|
83
|
+
<div class="ws-stack" style="width: 288px; max-width: 100%;">
|
|
84
|
+
<span class="ws-muted">A phone's card (288 px), the moment on the second day: its chip starts on its bar and stays inside the plot</span>
|
|
85
|
+
<section class="ws-card ws-trend-bars" aria-label="Profile views, two weeks">
|
|
86
|
+
<div class="ws-trend-bars__body">
|
|
87
|
+
<div class="ws-trend-bars__chart ws-dots" role="img" aria-label="Daily profile views over two weeks, a peak on October 6, the open house" style="--n: 14;">
|
|
88
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 0; height: 30%;"></div>
|
|
89
|
+
<div class="ws-trend-bars__moment" style="--i: 1;">
|
|
90
|
+
<span class="ws-trend-bars__moment-line" aria-hidden="true"></span>
|
|
91
|
+
<span class="ws-trend-bars__moment-chip">Oct 6 · open house</span>
|
|
92
|
+
<div class="ws-trend-bars__bar ws-trend-bars__bar--moment ws-grow-up" style="height: 44%;"></div>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 2; height: 26%;"></div>
|
|
95
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 3; height: 22%;"></div>
|
|
96
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 4; height: 28%;"></div>
|
|
97
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 5; height: 34%;"></div>
|
|
98
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 6; height: 24%;"></div>
|
|
99
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 7; height: 30%;"></div>
|
|
100
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 8; height: 26%;"></div>
|
|
101
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 9; height: 36%;"></div>
|
|
102
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 10; height: 32%;"></div>
|
|
103
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 11; height: 28%;"></div>
|
|
104
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 12; height: 40%;"></div>
|
|
105
|
+
<div class="ws-trend-bars__bar ws-grow-up" style="--i: 13; height: 34%;"></div>
|
|
106
|
+
</div>
|
|
107
|
+
<div class="ws-trend-bars__axis" aria-hidden="true">
|
|
108
|
+
<span>Oct 5</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
109
|
+
<span>Oct 12</span><span></span><span></span><span></span><span></span><span></span><span></span>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</section>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
82
115
|
</div>
|
|
83
116
|
</body>
|
|
84
117
|
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* ---- TrendBars: a day a thin bar over weeks, the moment that moved it marked in salmon ---- */
|
|
2
|
+
.ws-trend-bars__body { padding: var(--space-md) var(--ws-card-inset) 0; }
|
|
3
|
+
.ws-trend-bars__figure { display: flex; align-items: baseline; gap: var(--space-sm); margin-bottom: var(--space-lg); }
|
|
4
|
+
/* The run spans the plot: the bars keep 2 px and spread (at least 4 apart), the axis below on the same spacing, so
|
|
5
|
+
each date sits on its day's bar. */
|
|
6
|
+
.ws-trend-bars__chart { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-xxs); height: calc(var(--space-5xl) + var(--space-sm)); padding-top: calc(var(--space-lg) + var(--space-xxs)); }
|
|
7
|
+
/* "in srgb": a palette's stops are derived (color-mix), and a gradient blends those in Oklab unless told; sRGB is how the kit's own stops have always blended (D15). */
|
|
8
|
+
.ws-trend-bars__bar { flex-shrink: 0; width: calc(var(--space-xxs) / 2); border-radius: var(--ws-radius-bar); background: linear-gradient(to top in srgb, var(--ws-chart-purple-fade), var(--ws-chart-past-half)); transform-origin: bottom; }
|
|
9
|
+
.ws-trend-bars__bar--moment { background: linear-gradient(to top, var(--ws-chart-under-half) 40%, var(--ws-chart-under-half)); }
|
|
10
|
+
/* The moment's wrapper takes the chart's height (a bar's percent needs one), so its chip sits in the head room above
|
|
11
|
+
the tallest bar and its line runs from the chip down to the bar. The chip slides along its bar by the moment's place
|
|
12
|
+
in the run (--i on the moment, --n on the chart): its left end on a first-day bar, centred mid-run, its right end on
|
|
13
|
+
the last day, so it never leaves the plot. Without --i it centres. */
|
|
14
|
+
.ws-trend-bars__moment { position: relative; display: flex; flex-shrink: 0; align-self: stretch; align-items: flex-end; }
|
|
15
|
+
.ws-trend-bars__moment-chip { position: absolute; bottom: calc(100% + var(--space-xxs) * 1.5); left: 50%; transform: translateX(calc(var(--i, (var(--n, 3) - 1) / 2) / max(var(--n, 3) - 1, 1) * -100%)); padding: var(--space-3xs) var(--space-xxs-plus); border-radius: var(--ws-radius-chip); background: var(--ws-tint-needs); color: var(--ws-word-needs); font-size: var(--ws-text-micro); font-weight: 500; white-space: nowrap; }
|
|
16
|
+
.ws-trend-bars__moment-line { position: absolute; top: calc((var(--space-lg) - var(--space-xxs) / 2) * -1); bottom: 0; left: 50%; width: var(--ws-line); background: var(--ws-chart-under-half); opacity: 0.5; }
|
|
17
|
+
/* One span a day: a zero-width anchor on its bar's left edge (the axis stops a bar's width short, so the anchors land
|
|
18
|
+
where the bars start); a week's first day carries its date, which starts on its bar. */
|
|
19
|
+
.ws-trend-bars__axis { display: flex; justify-content: space-between; margin-top: var(--space-xxs); padding: 0 calc(var(--space-xxs) / 2) var(--space-md) 0; }
|
|
20
|
+
.ws-trend-bars__axis > span { flex-shrink: 0; width: 0; overflow: visible; font-size: var(--ws-text-micro); line-height: var(--space-md); color: var(--color-text-muted); white-space: nowrap; }
|
|
21
|
+
/* The draw (North): one 900 ms progress; bar i starts at its share of the first 55% and rises on the settle curve.
|
|
22
|
+
Set --n (the bar count) on the chart and --i on each bar. */
|
|
23
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
24
|
+
.ws-trend-bars__bar.ws-grow-up { animation-duration: calc(var(--ws-duration-draw) * 0.45); animation-timing-function: var(--ws-ease-settle); animation-delay: calc(var(--ws-build-at, 0s) + var(--ws-duration-draw) * 0.55 * var(--i, 0) / max(var(--n, 2) - 1, 1)); }
|
|
25
|
+
}
|