@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,74 @@
|
|
|
1
|
+
/* ---- Dialog: the native <dialog>, a cream pane in a 1 px tray rim over the navy scrim; --drawer floats in from the right edge ---- */
|
|
2
|
+
/* The pane (D5, Seth's check drawer 301:2011): the tray rim, 12 px corners (11 inside), the raised ground and one
|
|
3
|
+
floating lift, since it sits over a scrim. Every part sits 28 in from the sides, the band's own inset, so the title,
|
|
4
|
+
the content and the foot share one edge. It never grows past the window (K4): the head and the foot stay, the
|
|
5
|
+
content between them scrolls. Nothing is clipped (K9), so the foot rounds its own corners.
|
|
6
|
+
A plate, a well or a hover inside sits half a step above the pane (raised to press): the house sunk exactly in light,
|
|
7
|
+
and still seen in dark, where the page's sunk is the pane's own raised. The house points --ws-surface-sunk at --ws-raised-sunk here. */
|
|
8
|
+
.ws-dialog { --ws-dialog-inset: var(--ws-band-inset); display: flex; flex-direction: column; width: calc(100% - var(--space-xl)); max-width: 42rem; /* raw: Ignite's Dialog cap (max-w-2xl); no width token */ max-height: calc(100dvh - var(--space-xl)); padding: 0; overflow: visible; border: var(--ws-rim) solid var(--ws-tray); border-radius: var(--ws-radius-drawer); background: var(--ws-raised); color: var(--color-text-body); box-shadow: var(--ws-shadow-float); }
|
|
9
|
+
dialog.ws-dialog:not([open]) { display: none; }
|
|
10
|
+
.ws-dialog::backdrop { background: var(--ws-scrim); }
|
|
11
|
+
/* The compact head (K6): one title, at most one line under it, the close and at most two icon acts. Facts, chips and
|
|
12
|
+
buttons go in the content. It never wraps (a card's head drops its aside under a short title; here the close stays
|
|
13
|
+
top right and the title wraps beside it). The close is Seth's 32 px tray square, centred on the title's first line
|
|
14
|
+
(on its letters, which sit a hairline above the 28 px line's middle). Doubled class: IconButton's transparent
|
|
15
|
+
ground comes later in the bundle and would win. */
|
|
16
|
+
.ws-dialog > .ws-head { flex-wrap: nowrap; gap: var(--space-sm); padding: var(--ws-card-inset) var(--ws-dialog-inset) var(--space-md); }
|
|
17
|
+
/* A head with no content after it (a confirm) keeps the 20 the content leaves above the foot. */
|
|
18
|
+
.ws-dialog > .ws-head:has(+ .ws-band) { padding-bottom: var(--ws-card-inset); }
|
|
19
|
+
.ws-dialog > .ws-head > div { gap: var(--space-xxs); min-width: 0; }
|
|
20
|
+
.ws-icon-btn.ws-dialog__close { --ws-dialog-close: var(--ws-control-h); margin-block: calc((var(--ws-leading-title) - var(--ws-dialog-close)) / 2 - var(--ws-hairline)) calc((var(--ws-leading-title) - var(--ws-dialog-close)) / 2 + var(--ws-hairline)); border-radius: var(--ws-radius-row); background-color: var(--ws-tray); color: var(--color-text-heading); }
|
|
21
|
+
@media (hover: hover) { .ws-icon-btn.ws-dialog__close:hover { background-color: var(--ws-well-hover); } }
|
|
22
|
+
@media (pointer: coarse) { .ws-icon-btn.ws-dialog__close { --ws-dialog-close: var(--ws-touch); } }
|
|
23
|
+
/* The content scrolls on its own (K4) and holds its parts 16 apart. 4 px on top keeps a first field's focus ring. It runs
|
|
24
|
+
the pane's full width, so its own focus ring (a keyboard scroller) is drawn inside it, never over the rim (D8). */
|
|
25
|
+
.ws-dialog__content { display: flex; flex: 1 1 auto; flex-direction: column; gap: var(--space-md); min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-xxs) var(--ws-dialog-inset) var(--ws-card-inset); }
|
|
26
|
+
.ws-dialog__content:focus-visible { outline-offset: calc(var(--ws-focus-width) * -1); }
|
|
27
|
+
.ws-dialog > .ws-band { border-bottom-left-radius: var(--ws-radius-drawer-inner); border-bottom-right-radius: var(--ws-radius-drawer-inner); }
|
|
28
|
+
/* The foot's buttons as one group, right of its note: they wrap together, the one primary last. On a phone they fill
|
|
29
|
+
the width in equal halves, and stack, the primary at the bottom, where a half would be under 160 or a label would
|
|
30
|
+
break (Seth's pane foot, 301:2099, the same rule as Button's ws-btn-split). */
|
|
31
|
+
.ws-dialog__acts { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-left: auto; }
|
|
32
|
+
@media (max-width: 40rem) { .ws-dialog__acts { flex: 1 1 100%; } .ws-dialog__acts > * { flex: 1 1 var(--space-8xl); min-width: min(100%, max-content); } }
|
|
33
|
+
/* A short window or a phone (K6): the whole pane scrolls as one, only the head stays, so the content gets the screen
|
|
34
|
+
even when a head holds more than its title. The content still grows into a drawer's height, so its foot stays at
|
|
35
|
+
the bottom instead of floating under a short content. */
|
|
36
|
+
@media (max-height: 40rem), (max-width: 40rem) {
|
|
37
|
+
.ws-dialog { overflow-y: auto; overscroll-behavior: contain; }
|
|
38
|
+
.ws-dialog__content { flex: 1 0 auto; overflow: visible; }
|
|
39
|
+
.ws-dialog > .ws-head { position: sticky; top: 0; z-index: 1; border-radius: var(--ws-radius-drawer-inner) var(--ws-radius-drawer-inner) 0 0; background: var(--ws-raised); }
|
|
40
|
+
}
|
|
41
|
+
/* The drawer (K5): 440 wide, floating 12 in from the window's edges with the stage's corners; under 40rem it is the
|
|
42
|
+
whole screen. --start comes from the left edge. */
|
|
43
|
+
.ws-dialog--drawer { width: min(calc(100% - var(--ws-stage-inset) * 2), var(--ws-thing-width)); max-width: none; height: calc(100% - var(--ws-stage-inset) * 2); max-height: calc(100dvh - var(--ws-stage-inset) * 2); margin: var(--ws-stage-inset) var(--ws-stage-inset) var(--ws-stage-inset) auto; }
|
|
44
|
+
.ws-dialog--drawer-start { margin: var(--ws-stage-inset) auto var(--ws-stage-inset) var(--ws-stage-inset); }
|
|
45
|
+
@media (max-width: 40rem) {
|
|
46
|
+
.ws-dialog--drawer { width: 100%; height: 100%; max-height: 100dvh; margin: 0; border: 0; border-radius: 0; }
|
|
47
|
+
.ws-dialog--drawer > :is(.ws-head, .ws-band) { border-radius: 0; }
|
|
48
|
+
}
|
|
49
|
+
/* Motion (D7, North's window, js@540954): it grows 14 px up out of .98 on the settle spring (.32 / .1) as the scrim fades
|
|
50
|
+
in over .2 s, then its details settle in after it ("opens grow from their slot, then details settle": the head, the
|
|
51
|
+
content and the foot rise 6 px out of a 3 px blur over .32 s soft, .08 s after it and 22 ms apart, as North's opened
|
|
52
|
+
tile's details). It leaves faster and shorter: 8 px down to .98 over .12 s. A drawer slides in from its edge on the
|
|
53
|
+
grow curve over .55 s ("Card grows open") and goes back over .4 s ("Card closes back into place"). Native <dialog>
|
|
54
|
+
only: @starting-style for the entrance, display and overlay allow-discrete so the exit plays. With reduced motion it
|
|
55
|
+
simply appears and goes. */
|
|
56
|
+
dialog.ws-dialog { --ws-dialog-after: 80ms; /* raw: North's details wait .08 s (open.content delay) */ }
|
|
57
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
58
|
+
dialog.ws-dialog, dialog.ws-dialog::backdrop { transition: opacity var(--ws-duration-exit) var(--ws-ease-exit), transform var(--ws-duration-exit) var(--ws-ease-exit), overlay var(--ws-duration-exit) var(--ws-ease-exit) allow-discrete, display var(--ws-duration-exit) var(--ws-ease-exit) allow-discrete; }
|
|
59
|
+
dialog.ws-dialog:not([open]) { opacity: 0; transform: translateY(var(--space-xs)) scale(var(--ws-open-scale-pane)); }
|
|
60
|
+
dialog.ws-dialog:not([open])::backdrop { opacity: 0; }
|
|
61
|
+
dialog.ws-dialog[open] { transition: opacity var(--ws-spring-settle-duration) var(--ws-spring-settle), transform var(--ws-spring-settle-duration) var(--ws-spring-settle), overlay 0s allow-discrete, display 0s allow-discrete; }
|
|
62
|
+
dialog.ws-dialog[open]::backdrop { transition: opacity var(--ws-duration-hover) var(--ws-ease-soft), overlay 0s allow-discrete, display 0s allow-discrete; }
|
|
63
|
+
dialog.ws-dialog--drawer[open] { transition: opacity var(--ws-duration-grow) var(--ws-ease-grow), transform var(--ws-duration-grow) var(--ws-ease-grow), overlay 0s allow-discrete, display 0s allow-discrete; }
|
|
64
|
+
dialog.ws-dialog--drawer:not([open]) { transform: translateX(calc(100% + var(--ws-stage-inset))); transition-duration: var(--ws-duration-shrink); transition-timing-function: var(--ws-ease-grow); }
|
|
65
|
+
dialog.ws-dialog--drawer-start:not([open]) { transform: translateX(calc(-100% - var(--ws-stage-inset))); }
|
|
66
|
+
dialog.ws-dialog[open] > * { animation: ws-settle var(--ws-duration-settle) var(--ws-ease-soft) var(--ws-dialog-after) backwards; }
|
|
67
|
+
@supports (animation-delay: calc(sibling-index() * 1ms)) { dialog.ws-dialog[open] > * { animation-delay: calc(var(--ws-dialog-after) + (sibling-index() - 1) * var(--ws-stagger-detail)); } }
|
|
68
|
+
@starting-style {
|
|
69
|
+
dialog.ws-dialog[open] { opacity: 0; transform: translateY(var(--space-sm-plus)) scale(var(--ws-open-scale-pane)); }
|
|
70
|
+
dialog.ws-dialog--drawer[open] { transform: translateX(calc(100% + var(--ws-stage-inset))); }
|
|
71
|
+
dialog.ws-dialog--drawer-start[open] { transform: translateX(calc(-100% - var(--ws-stage-inset))); }
|
|
72
|
+
dialog.ws-dialog[open]::backdrop { opacity: 0; }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Nothing here yet: the same card the place would show, with its mark
|
|
1
|
+
Nothing here yet: the same plain cream card the place would show, with its mark and the one act that fills it.
|
|
2
2
|
|
|
3
3
|
## Use it when
|
|
4
4
|
|
|
5
5
|
- A page or a panel has no data yet for a reason the person can act on (nothing connected, nothing created, no matches).
|
|
6
|
-
- An app's first screen should introduce itself before there is anything real to show (the app's own face, still, on the
|
|
6
|
+
- An app's first screen should introduce itself before there is anything real to show (the app's own face, still, on the plain card).
|
|
7
7
|
- A filtered list comes back with nothing: say so, and offer the one way to see something again.
|
|
8
8
|
|
|
9
9
|
## Not for
|
|
@@ -14,11 +14,14 @@ Nothing here yet: the same card the place would show, with its mark on the dots
|
|
|
14
14
|
|
|
15
15
|
## Anatomy
|
|
16
16
|
|
|
17
|
-
- The same `Card
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
17
|
+
- The same `Card` (the tray rim round the cream), plain cream with no dots (the dotted field is a chart's ground
|
|
18
|
+
only, owner's ruling of 2 Nov), centred text, 40 px above
|
|
19
|
+
(`--space-2xl`), 16 px at the sides and under, its parts 8 px apart.
|
|
20
|
+
- Its mark: an icon on a cream disc (`--radius-full`, the hairline shadow, `--color-text-heading` icon at `--space-md`, 16 px); a first-run introduction uses a smaller, plain 24 px disc on the sunk cream (`ws-empty-state__mark--intro`, a 12 px line icon, no shadow) instead, standing in for an app's own illustration.
|
|
21
|
+
- A 15 / 22 semibold navy title (`ws-section`, Seth's section title).
|
|
22
|
+
- One sentence under it, 14 / 20 in `--color-text-body`, at most 260 px wide.
|
|
23
|
+
- The act in the card's band (`ws-band`, its buttons in `ws-band__acts`); in a card under 26rem the act takes the
|
|
24
|
+
band's whole line.
|
|
22
25
|
|
|
23
26
|
## Variants and sizes
|
|
24
27
|
|
|
@@ -32,14 +35,18 @@ Nothing here yet: the same card the place would show, with its mark on the dots
|
|
|
32
35
|
- **First use**: the small intro disc, a welcoming title, the one act that starts things.
|
|
33
36
|
- **No matches**: a search or filter icon, a title naming what did not match, an act that clears the filter.
|
|
34
37
|
- **Unavailable data**: an icon naming what is missing, a title that says what is not connected, an act that connects it.
|
|
35
|
-
- **With an action**: the act sits
|
|
38
|
+
- **With an action**: the act sits in the band, at its end on a wide card, across the whole band on a narrow one.
|
|
36
39
|
- **Without an action**: the card ends after the sentence; nothing is invented to fill the space.
|
|
40
|
+
- **Long title**: it wraps, centred; nothing is cut off.
|
|
41
|
+
- **Loading**: not an empty state. Use `Skeleton` until the answer arrives.
|
|
42
|
+
- **Dark**: the card and the disc follow the theme.
|
|
37
43
|
|
|
38
44
|
## Behaviour
|
|
39
45
|
|
|
40
46
|
- Keyboard: its title is a real heading (`h2`), so the empty card is reachable like any other section; its action, if given, is a normal button or link.
|
|
41
47
|
- Pointer and touch: only the action (if any) is interactive; the rest of the card is static.
|
|
42
|
-
- Motion: the whole card
|
|
48
|
+
- Motion: the whole card settles in (`ws-settle`: 6 px, out of a 3 px blur, `--ws-duration-settle`) like any other
|
|
49
|
+
arriving card.
|
|
43
50
|
- Reduced motion: it appears in place without rising.
|
|
44
51
|
|
|
45
52
|
## Content
|
|
@@ -60,13 +67,15 @@ Nothing here yet: the same card the place would show, with its mark on the dots
|
|
|
60
67
|
|
|
61
68
|
## Rules
|
|
62
69
|
|
|
63
|
-
-
|
|
70
|
+
- An empty state is the same plain cream card with the place's mark and the act that fills it in the band; the dots
|
|
71
|
+
are a chart's ground only, never an empty state's (owner, 2 Nov; logged in 17-decisions).
|
|
64
72
|
- A card whose data does not exist is left out, never faked: `EmptyState` is for "there is an answer, and it is nothing you can act on yet", never a stand-in for data that will never come.
|
|
65
|
-
- The same
|
|
73
|
+
- The same card rim, the same cream, the same title as every other card: an empty state never looks like a different
|
|
74
|
+
kind of surface.
|
|
66
75
|
|
|
67
76
|
## Source
|
|
68
77
|
|
|
69
|
-
**Derived from**: the card system's
|
|
78
|
+
**Derived from**: the card system's empty-state pattern (once drawn on the dotted field, now a plain card), generalized so a plain 24 px disc and line icon stand in
|
|
70
79
|
for an app's own illustration rather than requiring one. **Precedent**: the first product built on the system (its
|
|
71
80
|
own first-run screen used an agent's face image in this slot).
|
|
72
81
|
|
|
@@ -74,3 +83,24 @@ own first-run screen used an agent's face image in this slot).
|
|
|
74
83
|
band" (the card's footer band, with its 28 px sides and inset shade). The reference implementation has no footer
|
|
75
84
|
band at all: its action is a plain centred slot directly under the sentence. This preview follows the documented
|
|
76
85
|
band rule; the component as built does not currently draw one.
|
|
86
|
+
|
|
87
|
+
## Markup
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<div class="ws-card">
|
|
91
|
+
<div class="ws-empty-state__body">
|
|
92
|
+
<span class="ws-empty-state__mark" aria-hidden="true"><svg viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="4.5" stroke="currentColor" stroke-width="1.5"/><path d="M13 13l-2.5-2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></span>
|
|
93
|
+
<h2 class="ws-section">No leads match</h2>
|
|
94
|
+
<p class="ws-body ws-empty-state__words">Try a different stage or clear the filter.</p>
|
|
95
|
+
</div>
|
|
96
|
+
<footer class="ws-band">
|
|
97
|
+
<div class="ws-band__words"><p class="ws-band__title">Clear the filter</p></div>
|
|
98
|
+
<div class="ws-band__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Clear</button></div>
|
|
99
|
+
</footer>
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Styles
|
|
104
|
+
|
|
105
|
+
`EmptyState/style.css` (the body and the mark); the card and the band are `Card` and the house. Tokens:
|
|
106
|
+
`--space-2xl`, `--space-md`, `--space-xl`, `--ws-shadow-hairline`, `--ws-surface-sunk`, `--color-text-heading`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Cards" height=
|
|
1
|
+
<!-- @dsCard group="Cards" height=352 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
<link rel="stylesheet" href="../bundle.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
-
<div class="ws-stage
|
|
11
|
+
<div class="ws-stage">
|
|
12
12
|
|
|
13
|
-
<div class="ws-stack" style="
|
|
13
|
+
<div class="ws-stack" style="width: 340px;">
|
|
14
14
|
<span class="ws-muted">First use: an introduction, a plain disc and icon standing in for the app's own mark</span>
|
|
15
|
-
<div class="ws-card
|
|
15
|
+
<div class="ws-card">
|
|
16
16
|
<div class="ws-empty-state__body">
|
|
17
17
|
<span class="ws-empty-state__mark ws-empty-state__mark--intro" aria-hidden="true">
|
|
18
18
|
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 4.5h10a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H7l-2.5 2v-2H3a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1z"/></svg>
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
<p class="ws-band__title">Start your first call</p>
|
|
26
26
|
<p class="ws-band__how">The assistant lines up who to call next</p>
|
|
27
27
|
</div>
|
|
28
|
-
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Start</button>
|
|
28
|
+
<div class="ws-band__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Start</button></div>
|
|
29
29
|
</footer>
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
33
|
-
<div class="ws-stack" style="
|
|
33
|
+
<div class="ws-stack" style="width: 340px;">
|
|
34
34
|
<span class="ws-muted">No matches</span>
|
|
35
|
-
<div class="ws-card
|
|
35
|
+
<div class="ws-card">
|
|
36
36
|
<div class="ws-empty-state__body">
|
|
37
37
|
<span class="ws-empty-state__mark" aria-hidden="true">
|
|
38
38
|
<svg viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="4.5" stroke="currentColor" stroke-width="1.5"/><path d="M13 13l-2.5-2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
<div class="ws-band__words">
|
|
45
45
|
<p class="ws-band__title">Clear the filter</p>
|
|
46
46
|
</div>
|
|
47
|
-
<button type="button" class="ws-btn ws-btn--secondary">Clear</button>
|
|
47
|
+
<div class="ws-band__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Clear</button></div>
|
|
48
48
|
</footer>
|
|
49
49
|
</div>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
|
-
<div class="ws-stack" style="
|
|
52
|
+
<div class="ws-stack" style="width: 340px;">
|
|
53
53
|
<span class="ws-muted">Unavailable data: left out, never faked, except where its own act still fits the band</span>
|
|
54
|
-
<div class="ws-card
|
|
54
|
+
<div class="ws-card">
|
|
55
55
|
<div class="ws-empty-state__body">
|
|
56
56
|
<span class="ws-empty-state__mark" aria-hidden="true">
|
|
57
57
|
<svg viewBox="0 0 16 16" fill="none"><path d="M8 2l6 3.5v5L8 14l-6-3.5v-5L8 2z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 8v3M8 5.5v.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
<div class="ws-band__words">
|
|
64
64
|
<p class="ws-band__title">Connect your site</p>
|
|
65
65
|
</div>
|
|
66
|
-
<button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Connect</button>
|
|
66
|
+
<div class="ws-band__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg">Connect</button></div>
|
|
67
67
|
</footer>
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* ---- EmptyState: a plain cream card with a mark, a title, one sentence and the act in the band (the dots are a chart's ground only) ---- */
|
|
2
|
+
.ws-empty-state__body { display: flex; flex-direction: column; align-items: center; gap: var(--space-xs); padding: var(--space-2xl) var(--space-md) var(--space-md); text-align: center; }
|
|
3
|
+
/* The mark: an icon on a cream disc with the hairline; a first run uses the plain 24 px ws-disc instead (--intro). */
|
|
4
|
+
.ws-empty-state__mark { display: flex; width: var(--space-xl); height: var(--space-xl); align-items: center; justify-content: center; border-radius: var(--radius-full); background: var(--color-bg-page); box-shadow: var(--ws-shadow-hairline); }
|
|
5
|
+
.ws-empty-state__mark svg { width: var(--space-md); height: var(--space-md); color: var(--color-text-heading); }
|
|
6
|
+
.ws-empty-state__mark--intro { width: var(--space-lg); height: var(--space-lg); background: var(--ws-surface-sunk); box-shadow: none; }
|
|
7
|
+
.ws-empty-state__mark--intro svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
8
|
+
.ws-empty-state__words { max-width: calc(var(--space-9xl) + var(--space-4xl) - var(--space-xxs)); }
|
|
9
|
+
|
|
@@ -1,82 +1,107 @@
|
|
|
1
|
-
The frame for every page before the product's main workspace: the wordmark top left, a centred column
|
|
2
|
-
|
|
1
|
+
The frame for every page before the product's main workspace: the wordmark top left, a centred column, and on a wide
|
|
2
|
+
frame a grey panel beside it holding a sample of the product's own cards.
|
|
3
3
|
|
|
4
4
|
## Use it when
|
|
5
5
|
|
|
6
|
-
- Sign-in, an invite, or any
|
|
7
|
-
|
|
8
|
-
- A status screen (an expired invite, a setup gate) needs the same quiet, centred frame.
|
|
6
|
+
- Sign-in, an invite, or any welcome step needs the product's frame before a person has a team or a chat to land in.
|
|
7
|
+
- A gate before the product (an expired invite, a setup step) needs the same quiet, centred frame.
|
|
9
8
|
|
|
10
9
|
## Not for
|
|
11
10
|
|
|
12
|
-
- Anything inside the
|
|
13
|
-
|
|
14
|
-
- A
|
|
15
|
-
- A page that needs the full window's width: the column is capped (`max-w-sm` by default, `max-w-xl` for a wider
|
|
16
|
-
step), never edge to edge.
|
|
11
|
+
- Anything inside the workspace: once a person is signed in, `AppShell` (or the chat) takes over.
|
|
12
|
+
- A dialog or a drawer: those float over the workspace.
|
|
13
|
+
- A whole-page failure: `StatusScreen`.
|
|
17
14
|
|
|
18
15
|
## Anatomy
|
|
19
16
|
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
(`
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
- The shell (`.ws-entry-shell`): a size container named `ws-entry-shell`. It fills its parent (K17): a parent with a
|
|
18
|
+
height (`min-height: 100%`), a flex column that has only a `min-height` (`flex: 1 0 auto`), or `--page` for the
|
|
19
|
+
window's (`100dvh`).
|
|
20
|
+
- Main (`__main`): the cream ground, 24 inside.
|
|
21
|
+
- Wordmark (`__wordmark`): "Fello" in navy, 16 / 24 semibold, top left, no link.
|
|
22
|
+
- Centre (`__center`): the column, centred both ways, 40 above and below.
|
|
23
|
+
- Form (`__form`): up to 320 wide (`--space-9xl` + `--space-7xl`), its parts 24 apart; the title (`__title`)
|
|
24
|
+
24 / 32 semibold, centred; the field the large one, 36 tall (40 on touch); the one large navy button, full width.
|
|
25
|
+
- Aside (`__aside`): from 48rem of the shell's own width only. The grey (`--ws-page`), 16 px corners, 8 in from the
|
|
26
|
+
frame, 40 inside, centred, holding an eyebrow and sample cards (`__samples`, 16 apart; `__sample`, 16 inside, a label
|
|
27
|
+
in `ws-muted` over Seth's 32 / 38 tile figure, `__sample-figure`). It is `aria-hidden`.
|
|
30
28
|
|
|
31
29
|
## Variants and sizes
|
|
32
30
|
|
|
33
|
-
|
|
|
31
|
+
| Its own width | Shows |
|
|
34
32
|
| --- | --- |
|
|
35
|
-
|
|
|
36
|
-
|
|
|
33
|
+
| Under 48rem | The main column alone, the form centred in it |
|
|
34
|
+
| 48rem and up, with an aside | The main column and the grey aside, each half, both the frame's full height |
|
|
37
35
|
|
|
38
36
|
## States
|
|
39
37
|
|
|
40
|
-
- **Default**:
|
|
41
|
-
- **
|
|
42
|
-
|
|
43
|
-
- **Submitting**: the
|
|
44
|
-
|
|
45
|
-
- **Narrow window**: the aside is hidden entirely (`hidden lg:flex`), never shrunk to fit beside the form.
|
|
38
|
+
- **Default**: the form ready for input.
|
|
39
|
+
- **Arriving**: the centre arrives (`ws-arrive`), the sample cards settle in after it (`ws-settle`, `--ws-i`).
|
|
40
|
+
- **Error**: the field's error under it (`ws-field-msg--error`, `aria-describedby`), the field's salmon edge.
|
|
41
|
+
- **Submitting**: the button's own pending state (see `Button`); nothing else moves.
|
|
42
|
+
- **Narrow**: the aside is left out, never squeezed beside the form.
|
|
46
43
|
|
|
47
44
|
## Behaviour
|
|
48
45
|
|
|
49
|
-
- Keyboard: the
|
|
50
|
-
- The frame scrolls itself on a standalone page
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
- The aside is `aria-hidden`: it is a picture of the product, nothing in it can be reached by keyboard or read by
|
|
54
|
-
a screen reader.
|
|
46
|
+
- Keyboard: the field and the button are the whole tab order.
|
|
47
|
+
- The frame scrolls itself on a standalone page; a long step is never cut off.
|
|
48
|
+
- Motion on `--ws-ease-soft`; reduced motion lands every piece in place.
|
|
49
|
+
- The aside is a picture: hidden from screen readers, nothing in it to press.
|
|
55
50
|
|
|
56
51
|
## Content
|
|
57
52
|
|
|
58
|
-
- The
|
|
59
|
-
- The button's words are the
|
|
60
|
-
- The aside's
|
|
53
|
+
- The title names the one act ("Sign in"), sentence case.
|
|
54
|
+
- The button's words are the act in full ("Continue"), never "Submit".
|
|
55
|
+
- The aside's numbers are realistic but never real.
|
|
61
56
|
|
|
62
57
|
## Props
|
|
63
58
|
|
|
64
59
|
| Name | Type | Meaning |
|
|
65
60
|
| --- | --- | --- |
|
|
66
61
|
| `children` | `ReactNode` | The page's own form or steps |
|
|
67
|
-
| `preview` | `ReactNode[]` | Sample cards for the aside;
|
|
68
|
-
| `note` | `string` | The aside's
|
|
69
|
-
| `
|
|
62
|
+
| `preview` | `ReactNode[]` | Sample cards for the aside; without it there is no aside |
|
|
63
|
+
| `note` | `string` | The aside's eyebrow |
|
|
64
|
+
| `page` | `boolean` | Fills the window (`--page`) |
|
|
70
65
|
|
|
71
66
|
## Rules
|
|
72
67
|
|
|
73
|
-
- **The preview is a picture of the product**, never real data
|
|
74
|
-
|
|
75
|
-
- No microphone test step and no consent popup appear on any entry page (the system's rule); none is drawn here
|
|
76
|
-
either.
|
|
68
|
+
- **The preview is a picture of the product**, never real data.
|
|
69
|
+
- No microphone test and no consent popup on any entry page.
|
|
77
70
|
|
|
78
71
|
## Source
|
|
79
72
|
|
|
80
|
-
**Derived from**: the product's entry frame (the wordmark, the
|
|
81
|
-
|
|
82
|
-
|
|
73
|
+
**Derived from**: the product's entry frame (the wordmark, the centred column, the grey aside of samples), Seth's 32 /
|
|
74
|
+
38 tile figure (D6) and Revenue OS fault K17 (the shell did not fill its frame: on Sign in the aside stopped at 780 in a
|
|
75
|
+
900 window). **Precedent**: the first product built on the system.
|
|
76
|
+
|
|
77
|
+
## Markup
|
|
78
|
+
|
|
79
|
+
```html
|
|
80
|
+
<div class="ws-entry-shell ws-entry-shell--page">
|
|
81
|
+
<div class="ws-entry-shell__main">
|
|
82
|
+
<span class="ws-entry-shell__wordmark">Fello</span>
|
|
83
|
+
<div class="ws-entry-shell__center ws-arrive">
|
|
84
|
+
<form class="ws-entry-shell__form">
|
|
85
|
+
<h1 class="ws-entry-shell__title">Sign in</h1>
|
|
86
|
+
<div class="ws-field">
|
|
87
|
+
<label class="ws-label" for="email">Email</label>
|
|
88
|
+
<input class="ws-input" id="email" type="email" autocomplete="email">
|
|
89
|
+
</div>
|
|
90
|
+
<div class="ws-entry-shell__acts"><button type="submit" class="ws-btn ws-btn--primary ws-btn--lg">Continue</button></div>
|
|
91
|
+
</form>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<aside class="ws-entry-shell__aside" aria-hidden="true">
|
|
95
|
+
<p class="ws-eyebrow">What’s waiting</p>
|
|
96
|
+
<div class="ws-entry-shell__samples">
|
|
97
|
+
<div class="ws-card ws-entry-shell__sample"><span class="ws-muted">Cold calls</span><span class="ws-entry-shell__sample-figure">26</span></div>
|
|
98
|
+
</div>
|
|
99
|
+
</aside>
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Styles
|
|
104
|
+
|
|
105
|
+
`EntryShell/style.css`, with `Input`, `Button` and `Card` for the field, the button and the samples. Tokens: `--ws-page`,
|
|
106
|
+
`--color-bg-page`, `--ws-radius-panel`, `--ws-control-h-md`, `--ws-text-figure`, `--ws-leading-figure`,
|
|
107
|
+
`--ws-tracking-display`, `--space-9xl`, `--space-7xl`, `--space-2xl`, `--space-lg`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- @dsCard group="Desk" height=
|
|
1
|
+
<!-- @dsCard group="Desk" height=984 -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html>
|
|
4
4
|
<head>
|
|
@@ -8,37 +8,70 @@
|
|
|
8
8
|
<link rel="stylesheet" href="../bundle.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
-
<div class="ws-stage" style="
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
11
|
+
<div class="ws-stage ws-stage--column" style="align-items: center;">
|
|
12
|
+
|
|
13
|
+
<div class="ws-stack" style="width: 900px; max-width: 100%;">
|
|
14
|
+
<span class="ws-muted">From 48rem of its own width: the form centred in its column, the grey aside of samples beside it, both the frame's full height</span>
|
|
15
|
+
<div style="display: grid; min-height: 440px; border-radius: var(--ws-radius-panel); overflow: hidden; box-shadow: var(--ws-shadow-hairline);"><div class="ws-entry-shell">
|
|
16
|
+
<div class="ws-entry-shell__main">
|
|
17
|
+
<span class="ws-entry-shell__wordmark">Fello</span>
|
|
18
|
+
<div class="ws-entry-shell__center ws-arrive">
|
|
19
|
+
<form class="ws-entry-shell__form" onsubmit="return false;">
|
|
20
|
+
<h1 class="ws-entry-shell__title">Sign in</h1>
|
|
21
|
+
<div class="ws-field">
|
|
22
|
+
<label class="ws-label" for="es-email">Email</label>
|
|
23
|
+
<input class="ws-input" id="es-email" type="email" placeholder="ryan@theyoungteam.example" autocomplete="email">
|
|
24
|
+
</div>
|
|
25
|
+
<div class="ws-entry-shell__acts">
|
|
26
|
+
<button type="submit" class="ws-btn ws-btn--primary ws-btn--lg">Continue</button>
|
|
27
|
+
</div>
|
|
28
|
+
</form>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<aside class="ws-entry-shell__aside" aria-hidden="true">
|
|
32
|
+
<p class="ws-eyebrow">What’s waiting</p>
|
|
33
|
+
<div class="ws-entry-shell__samples">
|
|
34
|
+
<div class="ws-card ws-entry-shell__sample ws-settle" style="--ws-i: 1;">
|
|
35
|
+
<span class="ws-muted">Cold calls</span>
|
|
36
|
+
<span class="ws-entry-shell__sample-figure">26</span>
|
|
21
37
|
</div>
|
|
22
|
-
<div class="ws-entry-
|
|
23
|
-
<
|
|
38
|
+
<div class="ws-card ws-entry-shell__sample ws-settle" style="--ws-i: 2;">
|
|
39
|
+
<span class="ws-muted">New leads</span>
|
|
40
|
+
<span class="ws-entry-shell__sample-figure">4</span>
|
|
24
41
|
</div>
|
|
25
|
-
</form>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
<aside class="ws-entry-shell__aside" aria-hidden="true">
|
|
29
|
-
<p class="ws-eyebrow">What’s waiting</p>
|
|
30
|
-
<div class="ws-entry-shell__samples">
|
|
31
|
-
<div class="ws-card ws-entry-shell__sample ws-rise">
|
|
32
|
-
<span class="ws-muted">Cold calls</span>
|
|
33
|
-
<span class="ws-entry-shell__sample-figure">26</span>
|
|
34
42
|
</div>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
</aside>
|
|
44
|
+
</div></div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="ws-stack" style="width: 560px; max-width: 100%;">
|
|
48
|
+
<span class="ws-muted">Under 48rem: the form alone, the aside left out rather than squeezed; an error under the field</span>
|
|
49
|
+
<div style="display: grid; min-height: 440px; border-radius: var(--ws-radius-panel); overflow: hidden; box-shadow: var(--ws-shadow-hairline);"><div class="ws-entry-shell">
|
|
50
|
+
<div class="ws-entry-shell__main">
|
|
51
|
+
<span class="ws-entry-shell__wordmark">Fello</span>
|
|
52
|
+
<div class="ws-entry-shell__center">
|
|
53
|
+
<form class="ws-entry-shell__form" onsubmit="return false;">
|
|
54
|
+
<h1 class="ws-entry-shell__title">Sign in</h1>
|
|
55
|
+
<div class="ws-field">
|
|
56
|
+
<label class="ws-label" for="es-email-2">Email</label>
|
|
57
|
+
<input class="ws-input" id="es-email-2" type="email" value="ryan@theyoungteam" aria-invalid="true" aria-describedby="es-email-2-msg" autocomplete="email">
|
|
58
|
+
<p class="ws-field-msg ws-field-msg--error" id="es-email-2-msg">
|
|
59
|
+
<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><circle cx="6" cy="6" r="4.5"/><path d="M6 3.75v2.5M6 8.25v.01"/></svg>
|
|
60
|
+
Add the part after the @, like theyoungteam.com
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="ws-entry-shell__acts">
|
|
64
|
+
<button type="submit" class="ws-btn ws-btn--primary ws-btn--lg">Continue</button>
|
|
65
|
+
</div>
|
|
66
|
+
</form>
|
|
38
67
|
</div>
|
|
39
68
|
</div>
|
|
40
|
-
|
|
41
|
-
|
|
69
|
+
<aside class="ws-entry-shell__aside" aria-hidden="true">
|
|
70
|
+
<p class="ws-eyebrow">What’s waiting</p>
|
|
71
|
+
</aside>
|
|
72
|
+
</div></div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
42
75
|
</div>
|
|
43
76
|
</body>
|
|
44
77
|
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* ---- EntryShell: the sign-in page, the form centred in its 320 column and, from 48rem of the shell's own width, the grey
|
|
2
|
+
aside of samples. It fills its parent (K17): a parent with a height, a flex column with only a min-height (flex: 1),
|
|
3
|
+
or --page for the window's. ---- */
|
|
4
|
+
.ws-entry-shell { container: ws-entry-shell / inline-size; display: flex; flex: 1 0 auto; min-height: 100%; }
|
|
5
|
+
.ws-entry-shell--page { min-height: 100dvh; }
|
|
6
|
+
.ws-entry-shell__main { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; padding: var(--space-lg) var(--space-lg); background: var(--color-bg-page); }
|
|
7
|
+
.ws-entry-shell__wordmark { align-self: flex-start; font-size: var(--font-size-md); line-height: var(--space-lg); font-weight: 600; color: var(--color-text-heading); }
|
|
8
|
+
.ws-entry-shell__center { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-lg); padding: var(--space-2xl) 0; }
|
|
9
|
+
.ws-entry-shell__form { width: 100%; max-width: calc(var(--space-9xl) + var(--space-7xl)); display: flex; flex-direction: column; gap: var(--space-lg); }
|
|
10
|
+
.ws-entry-shell__title { margin: 0; font-size: var(--font-size-xl); line-height: var(--space-xl); font-weight: 600; letter-spacing: var(--ws-tracking-title); color: var(--color-text-heading); text-align: center; }
|
|
11
|
+
/* The sign-in field is the large one, 36 px (still 40 on touch). */
|
|
12
|
+
.ws-entry-shell .ws-input { min-height: var(--ws-control-h-md); }
|
|
13
|
+
.ws-entry-shell__acts { display: flex; flex-direction: column; gap: var(--space-sm); text-align: center; }
|
|
14
|
+
.ws-entry-shell__aside { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--space-md); margin: var(--space-xs); padding: var(--space-2xl); border-radius: var(--ws-radius-panel); background: var(--ws-page); }
|
|
15
|
+
.ws-entry-shell__samples { display: flex; gap: var(--space-md); }
|
|
16
|
+
.ws-entry-shell__sample { flex: 1; min-width: 0; padding: var(--ws-card-padding-lg); display: flex; flex-direction: column; gap: var(--space-xxs); }
|
|
17
|
+
.ws-entry-shell__sample-figure { font-size: var(--ws-text-figure); line-height: var(--ws-leading-figure); font-weight: 400; letter-spacing: var(--ws-tracking-display); color: var(--color-text-heading); font-variant-numeric: tabular-nums; }
|
|
18
|
+
/* A narrow shell is the form alone: the aside is a picture, never squeezed beside it. */
|
|
19
|
+
@container ws-entry-shell (max-width: 48rem) { .ws-entry-shell__aside { display: none; } }
|