@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,2537 @@
|
|
|
1
|
+
<!-- @dsCard group="Foundations" height=1200 -->
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
<title>Motion</title>
|
|
8
|
+
<link rel="stylesheet" href="../../tokens.css">
|
|
9
|
+
<link rel="stylesheet" href="../bundle.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div class="ws-stage ws-stage--column">
|
|
13
|
+
|
|
14
|
+
<header class="ws-stack">
|
|
15
|
+
<h1 class="ws-title">Motion: how the kit moves, the way Seth's North does</h1>
|
|
16
|
+
<p class="ws-body">The screen below is built only from kit components. Each navy number on it is something to do; the list says what to notice when you do it. Turn on Slow motion to see every move four times slower.</p>
|
|
17
|
+
</header>
|
|
18
|
+
|
|
19
|
+
<section class="ws-stack" aria-labelledby="mo-play" data-play>
|
|
20
|
+
<h2 class="ws-section" id="mo-play">Try it</h2>
|
|
21
|
+
<div class="ws-cluster ws-cluster--loose" style="align-items: flex-start; gap: var(--ws-gap-component);">
|
|
22
|
+
|
|
23
|
+
<div class="ws-stack" style="flex: 1 1 18rem; max-width: 22rem; min-width: 0;">
|
|
24
|
+
<label class="ws-switch"><input type="checkbox" role="switch" data-slow><span class="ws-switch__track"><span class="ws-switch__thumb"></span></span><span class="ws-switch__words"><span class="ws-switch__label">Slow motion</span><span class="ws-muted">Every move four times slower</span></span></label>
|
|
25
|
+
<ol class="ws-stack" aria-label="What to try" style="gap: var(--space-sm); margin: 0; padding: 0; list-style: none;">
|
|
26
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">1</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Hover a card</span><span class="ws-meta">Its frame darkens, its arrow steps forward and its little chart wakes from grey.</span></span></li>
|
|
27
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">2</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Click Sales in the sidebar</span><span class="ws-meta">The white pill slides to it. On a phone, open the menu first.</span></span></li>
|
|
28
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">3</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Switch Bars / Line, or a tab</span><span class="ws-meta">The pill slides to your choice with a little give, and the bars melt into the line.</span></span></li>
|
|
29
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">4</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Open the menu</span><span class="ws-meta">It grows out of its corner and leaves faster.</span></span></li>
|
|
30
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">5</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Click the chart to open it full screen, Back to close</span><span class="ws-meta">The card grows out of its own spot, then flies home.</span></span></li>
|
|
31
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">6</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Fold a sidebar section</span><span class="ws-meta">The rows fold away and the chevron turns.</span></span></li>
|
|
32
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">7</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Point at the chart</span><span class="ws-meta">A band slides to the week and a card follows you from bar to bar.</span></span></li>
|
|
33
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">8</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Save to see a toast</span><span class="ws-meta">It rises, settles, then slips away.</span></span></li>
|
|
34
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">9</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Open the drawer</span><span class="ws-meta">Click a name: it slides in from the edge.</span></span></li>
|
|
35
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">10</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Move chat: bar, docked, full</span><span class="ws-meta">Ask Coach, dock it, make it full: it travels as one piece.</span></span></li>
|
|
36
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">11</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Sort the list</span><span class="ws-meta">Pick an order: the rows glide to their new places.</span></span></li>
|
|
37
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">12</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Press any button</span><span class="ws-meta">It gives under your finger and springs back.</span></span></li>
|
|
38
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">13</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Point at a health square</span><span class="ws-meta">After a breath it grows open in place.</span></span></li>
|
|
39
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">14</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Refresh the sources</span><span class="ws-meta">A shimmer in the chart colours, then each line settles in.</span></span></li>
|
|
40
|
+
<li class="ws-cluster" style="flex-wrap: nowrap; align-items: flex-start; gap: var(--space-xs);"><span class="ws-badge ws-badge--navy" aria-hidden="true" style="flex: none; min-width: var(--space-lg);">15</span><span class="ws-stack ws-stack--tight" style="min-width: 0;"><span class="ws-row-name">Replay the arrival</span><span class="ws-meta">The cards rise in, the columns grow in one after another and the goals fill.</span></span></li>
|
|
41
|
+
</ol>
|
|
42
|
+
<p class="ws-muted" data-reduced-readout></p>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div style="flex: 999 1 40rem; min-width: 0; height: 780px; max-height: calc(100dvh - var(--space-xl)); border-radius: var(--ws-radius-panel); overflow: hidden; box-shadow: var(--ws-shadow-hairline);" data-screen>
|
|
46
|
+
<div class="ws-app-shell" style="position: relative;" data-shell>
|
|
47
|
+
<nav class="ws-app-shell__nav" aria-label="Main" data-nav-main>
|
|
48
|
+
<div class="ws-app-shell__head">
|
|
49
|
+
<span class="ws-app-shell__wordmark">Fello</span>
|
|
50
|
+
<button type="button" class="ws-icon-btn" aria-label="Fold the menu" aria-expanded="true" data-fold-nav>
|
|
51
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2.5" width="12" height="11" rx="2"/><path d="M6 2.5v11"/></svg>
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="ws-app-shell__groups">
|
|
55
|
+
<div class="ws-app-shell__group">
|
|
56
|
+
<ul class="ws-app-shell__rows">
|
|
57
|
+
<li><a href="#home" class="ws-app-shell__row" aria-current="page" title="Home"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7.5 8 3l5 4.5V13H3Z"/></svg><span class="ws-app-shell__name">Home</span></a></li>
|
|
58
|
+
<li><a href="#sales" class="ws-app-shell__row" title="Sales"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 13V8M8 13V3M13 13V9.5"/></svg><span class="ws-app-shell__name">Sales</span><span class="ws-badge ws-badge--navy" aria-hidden="true">2</span></a></li>
|
|
59
|
+
<li><a href="#leads" class="ws-app-shell__row" title="Leads"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="5.6" r="2.4"/><path d="M3 13c0-2.5 2.2-4 5-4s5 1.5 5 4"/></svg><span class="ws-app-shell__name">Leads</span></a></li>
|
|
60
|
+
</ul>
|
|
61
|
+
</div>
|
|
62
|
+
<details class="ws-app-shell__group" open>
|
|
63
|
+
<summary class="ws-app-shell__eyebrow ws-fold__summary" style="gap: var(--space-xxs);"><span style="flex: 1;">Reports</span><span class="ws-badge ws-badge--navy" aria-hidden="true">6</span><svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></summary>
|
|
64
|
+
<ul class="ws-app-shell__rows">
|
|
65
|
+
<li><a href="#health" class="ws-app-shell__row" title="Company health"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 8h3l1.5-3 3 6L11 8h3"/></svg><span class="ws-app-shell__name">Company health</span></a></li>
|
|
66
|
+
<li><a href="#calls" class="ws-app-shell__row" title="Calls"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="5.5"/><path d="M8 5v3l2 1.5"/></svg><span class="ws-app-shell__name">Calls</span></a></li>
|
|
67
|
+
</ul>
|
|
68
|
+
</details>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="ws-app-shell__foot">
|
|
71
|
+
<span class="ws-avatar ws-avatar--sm ws-avatar--plain">PN</span>
|
|
72
|
+
<span class="ws-app-shell__foot-words"><span class="ws-app-shell__foot-name">Priya Nair</span><span class="ws-muted">Team lead</span></span>
|
|
73
|
+
</div>
|
|
74
|
+
</nav>
|
|
75
|
+
|
|
76
|
+
<div class="ws-app-shell__stage" data-stage>
|
|
77
|
+
<header class="ws-app-shell__bar ws-page-bar">
|
|
78
|
+
<div class="ws-page-bar__words">
|
|
79
|
+
<button type="button" class="ws-icon-btn ws-app-shell__menu" aria-label="Open the menu" data-open-nav>
|
|
80
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11"/></svg>
|
|
81
|
+
</button>
|
|
82
|
+
<h1 class="ws-page-bar__title" title="Home">Home</h1>
|
|
83
|
+
<span class="ws-page-bar__context">This week</span>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="ws-page-bar__acts">
|
|
86
|
+
<span class="ws-badge-host"><button type="button" class="ws-btn ws-btn--secondary" data-chat-open>Ask Coach</button><span class="ws-badge ws-badge--navy" aria-hidden="true">10</span></span>
|
|
87
|
+
<span class="ws-badge-host"><button type="button" class="ws-btn ws-btn--primary" data-toast="mo-play-toasts" data-light>Save</button><span class="ws-badge ws-badge--navy" aria-hidden="true">8</span></span>
|
|
88
|
+
</div>
|
|
89
|
+
</header>
|
|
90
|
+
|
|
91
|
+
<div style="display: flex; flex: 1; min-height: 0; gap: var(--space-sm);" data-chat-row>
|
|
92
|
+
<aside class="ws-chat-shell ws-chat-shell--bar" aria-label="Chat with Coach" style="display: none;" data-play-chat>
|
|
93
|
+
<header class="ws-chat-shell__head" style="display: none;">
|
|
94
|
+
<h2 class="ws-section">Coach</h2>
|
|
95
|
+
<span class="ws-muted ws-chat-shell__where" title="On Home">On Home</span>
|
|
96
|
+
<span class="ws-chat-shell__tools">
|
|
97
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--sm" aria-label="Full screen" title="Full screen" data-chat-to="full"><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M9.5 2.5h4v4M6.5 13.5h-4v-4M13.5 2.5L9 7M2.5 13.5L7 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
98
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--sm" aria-label="Dock beside the page" title="Dock" data-chat-to="dock" style="display: none;"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2.5" width="12" height="11" rx="2"/><path d="M7 2.5v11"/></svg></button>
|
|
99
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--sm" aria-label="Close the chat" title="Close" data-chat-close><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
100
|
+
</span>
|
|
101
|
+
</header>
|
|
102
|
+
<ol class="ws-chat-shell__thread" aria-label="Messages" style="display: none;">
|
|
103
|
+
<li class="ws-chat-turn ws-chat-turn--person"><p class="ws-chat-turn__bubble">Who should I call first today?</p></li>
|
|
104
|
+
<li class="ws-chat-turn ws-chat-turn--agent"><p class="ws-chat-turn__words">Priya Nair. Her offer runs out tonight and she asked for an answer by five.</p></li>
|
|
105
|
+
</ol>
|
|
106
|
+
<div class="ws-chat-shell__compose">
|
|
107
|
+
<div class="ws-composer">
|
|
108
|
+
<label class="ws-sr" for="mo-play-ask">Ask Coach</label>
|
|
109
|
+
<textarea id="mo-play-ask" class="ws-composer__words" rows="1" placeholder="Ask Coach"></textarea>
|
|
110
|
+
<div class="ws-composer__trail">
|
|
111
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--lg" aria-label="Dock the chat beside the page" title="Dock" data-chat-to="dock" data-bar-only><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2.5" width="12" height="11" rx="2"/><path d="M7 2.5v11"/></svg></button>
|
|
112
|
+
<button type="button" class="ws-icon-btn ws-icon-btn--primary ws-icon-btn--lg" aria-label="Talk with Coach"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M3 6.5v3M5.5 4.5v7M8 2.5v11M10.5 4.5v7M13 6.5v3"/></svg></button>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="ws-suggestions" aria-label="Ask about" data-bar-only>
|
|
116
|
+
<button type="button" class="ws-suggestion-chip"><span>Why did calls drop?</span></button>
|
|
117
|
+
<button type="button" class="ws-suggestion-chip"><span>Who needs a nudge?</span></button>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</aside>
|
|
121
|
+
|
|
122
|
+
<main class="ws-app-shell__body ws-build" data-play-body>
|
|
123
|
+
<div role="tablist" aria-label="Home" class="ws-tabs" data-tabs><button type="button" role="tab" aria-selected="true" class="ws-tabs__tab">Overview</button><button type="button" role="tab" aria-selected="false" class="ws-tabs__tab" tabindex="-1">Calls</button><button type="button" role="tab" aria-selected="false" class="ws-tabs__tab" tabindex="-1">Deals</button></div>
|
|
124
|
+
|
|
125
|
+
<div class="ws-stack ws-stack--tight">
|
|
126
|
+
<span class="ws-cluster" style="gap: var(--space-xs) var(--space-sm);"><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">1</span><span class="ws-meta">Hover a card</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">15</span><button type="button" class="ws-btn ws-btn--secondary" data-replay-arrival>Replay the arrival</button></span></span>
|
|
127
|
+
<div class="ws-build ws-split" id="mo-build-home" data-arrival style="--ws-split-aside: calc(var(--space-9xl) + var(--space-4xl));">
|
|
128
|
+
<div class="ws-split__main">
|
|
129
|
+
<div class="ws-metric-tiles">
|
|
130
|
+
<div class="ws-metric-tiles__grid">
|
|
131
|
+
<button type="button" class="ws-metric-tile ws-metric-tile--draw ws-build__card" style="--ws-i: 0;" aria-label="Recurring revenue, $12.99M, up every month from $5.1M in May; 100% of pace, $12.99M of $13.06M. Open">
|
|
132
|
+
<span class="ws-metric-tile__surface">
|
|
133
|
+
<span class="ws-metric-tile__head"><span class="ws-metric-tile__label">Recurring revenue</span><svg class="ws-metric-tile__go" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
|
134
|
+
<span class="ws-metric-tile__value">$12.99M</span>
|
|
135
|
+
<span class="ws-metric-tile__cols" style="--n: 6; --step: 33.33%;" aria-hidden="true"><span class="ws-metric-tile__col" style="--v: 34%; --i: 0;"></span><span class="ws-metric-tile__col" style="--v: 42.67%; --i: 1;"></span><span class="ws-metric-tile__col" style="--v: 52.67%; --i: 2;"></span><span class="ws-metric-tile__col" style="--v: 62.8%; --i: 3;"></span><span class="ws-metric-tile__col" style="--v: 77%; --i: 4;"></span><span class="ws-metric-tile__col ws-metric-tile__col--now" style="--v: 86.6%; --i: 5;"></span></span>
|
|
136
|
+
</span>
|
|
137
|
+
<span class="ws-metric-tile__foot"><span>Pace $12.99M of $13.06M</span><b>100%</b></span>
|
|
138
|
+
</button>
|
|
139
|
+
<button type="button" class="ws-metric-tile ws-metric-tile--draw ws-build__card" style="--ws-i: 1;" aria-label="Total revenue, $35.75M, up every month from $29.5M in May; 89% of the $40.03M plan. Open">
|
|
140
|
+
<span class="ws-metric-tile__surface">
|
|
141
|
+
<span class="ws-metric-tile__head"><span class="ws-metric-tile__label">Total revenue</span><svg class="ws-metric-tile__go" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
|
142
|
+
<span class="ws-metric-tile__value">$35.75M</span>
|
|
143
|
+
<span class="ws-metric-tile__cols" style="--n: 6; --step: 41.67%;" aria-hidden="true"><span class="ws-metric-tile__col" style="--v: 37.5%; --i: 0;"></span><span class="ws-metric-tile__col" style="--v: 46.67%; --i: 1;"></span><span class="ws-metric-tile__col" style="--v: 52.5%; --i: 2;"></span><span class="ws-metric-tile__col" style="--v: 58.83%; --i: 3;"></span><span class="ws-metric-tile__col" style="--v: 76.25%; --i: 4;"></span><span class="ws-metric-tile__col ws-metric-tile__col--now" style="--v: 89.58%; --i: 5;"></span></span>
|
|
144
|
+
</span>
|
|
145
|
+
<span class="ws-metric-tile__foot"><span>Of the $40.03M plan</span><b>89%</b></span>
|
|
146
|
+
</button>
|
|
147
|
+
<button type="button" class="ws-metric-tile ws-metric-tile--draw ws-build__card" style="--ws-i: 2;" aria-label="Net revenue retention, 99.9%, between 99.1% and 100.7% since May; 100% of the 100.0% target. Open">
|
|
148
|
+
<span class="ws-metric-tile__surface">
|
|
149
|
+
<span class="ws-metric-tile__head"><span class="ws-metric-tile__label">Net revenue retention</span><svg class="ws-metric-tile__go" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
|
150
|
+
<span class="ws-metric-tile__value">99.9%</span>
|
|
151
|
+
<span class="ws-metric-tile__line" style="--n: 6; --tone: var(--ws-chart-finished);" aria-hidden="true"><svg><line pathLength="1" x1="0%" y1="76.67%" x2="20%" y2="53.33%" style="--i: 0;"/><line pathLength="1" x1="20%" y1="53.33%" x2="40%" y2="40%" style="--i: 1;"/><line pathLength="1" x1="40%" y1="40%" x2="60%" y2="66.67%" style="--i: 2;"/><line pathLength="1" x1="60%" y1="66.67%" x2="80%" y2="23.33%" style="--i: 3;"/><line pathLength="1" x1="80%" y1="23.33%" x2="100%" y2="50%" style="--i: 4;"/><circle cx="0%" cy="76.67%" style="--i: 0;"/><circle cx="20%" cy="53.33%" style="--i: 1;"/><circle cx="40%" cy="40%" style="--i: 2;"/><circle cx="60%" cy="66.67%" style="--i: 3;"/><circle cx="80%" cy="23.33%" style="--i: 4;"/><circle class="ws-metric-tile__now" cx="100%" cy="50%" style="--i: 5;"/></svg></span>
|
|
152
|
+
</span>
|
|
153
|
+
<span class="ws-metric-tile__foot"><span>Target 100.0%</span><b>100%</b></span>
|
|
154
|
+
</button>
|
|
155
|
+
<button type="button" class="ws-metric-tile ws-metric-tile--draw ws-build__card" style="--ws-i: 3;" aria-label="Net new revenue, $1.55M this month, after $2.03M in July and $1.32M in August; 87% of pace, $1.78M of $1.87M. Open">
|
|
156
|
+
<span class="ws-metric-tile__surface">
|
|
157
|
+
<span class="ws-metric-tile__head"><span class="ws-metric-tile__label">Net new revenue</span><svg class="ws-metric-tile__go" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
|
158
|
+
<span class="ws-metric-tile__value">$1.55M</span>
|
|
159
|
+
<span class="ws-metric-tile__cols" style="--n: 6; --step: 43.48%; --tone: var(--ws-chart-alert);" aria-hidden="true"><span class="ws-metric-tile__col" style="--v: 70.43%; --i: 0;"></span><span class="ws-metric-tile__col" style="--v: 81.74%; --i: 1;"></span><span class="ws-metric-tile__col" style="--v: 88.26%; --i: 2;"></span><span class="ws-metric-tile__col" style="--v: 57.39%; --i: 3;"></span><span class="ws-metric-tile__col" style="--v: 76.52%; --i: 4;"></span><span class="ws-metric-tile__col ws-metric-tile__col--now" style="--v: 67.39%; --i: 5;"></span></span>
|
|
160
|
+
</span>
|
|
161
|
+
<span class="ws-metric-tile__foot"><span>Pace $1.78M of $1.87M</span><b>87%</b></span>
|
|
162
|
+
</button>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
<aside class="ws-split__aside">
|
|
167
|
+
<div class="ws-side-list ws-side-list--draw ws-build__card" style="--ws-i: 4;">
|
|
168
|
+
<section class="ws-side-list__group" aria-labelledby="mo-build-goals-title" style="--n: 4;">
|
|
169
|
+
<div class="ws-side-list__head">
|
|
170
|
+
<h3 class="ws-side-list__title" id="mo-build-goals-title">Q4 goals</h3>
|
|
171
|
+
<button type="button" class="ws-act">Edit</button>
|
|
172
|
+
</div>
|
|
173
|
+
<ul>
|
|
174
|
+
<li><a data-inert class="ws-side-list__row ws-side-list__row--measure" href="#goal-1" style="--i: 0;"><span class="ws-side-list__line"><span class="ws-side-list__name">Close $40M ending revenue</span><span class="ws-side-list__value">27%</span></span><span class="ws-side-list__bar" aria-hidden="true"><span style="width: 27%;"></span><i style="--at: 30%;"></i></span></a></li>
|
|
175
|
+
<li><a data-inert class="ws-side-list__row ws-side-list__row--measure" href="#goal-2" style="--i: 1;"><span class="ws-side-list__line"><span class="ws-side-list__name">Live for every team</span><span class="ws-side-list__value">60%</span></span><span class="ws-side-list__bar" aria-hidden="true"><span style="width: 60%;"></span><i style="--at: 30%;"></i></span></a></li>
|
|
176
|
+
<li><a data-inert class="ws-side-list__row ws-side-list__row--measure ws-side-list__row--over" href="#goal-3" style="--i: 2;"><span class="ws-side-list__line"><span class="ws-side-list__name">Book 40 expansion deals</span><span class="ws-side-list__value">112%</span></span><span class="ws-side-list__bar" aria-hidden="true"><span style="width: 100%;"></span><i style="--at: 30%;"></i></span></a></li>
|
|
177
|
+
<li><a data-inert class="ws-side-list__row ws-side-list__row--measure ws-side-list__row--behind" href="#goal-4" style="--i: 3;"><span class="ws-side-list__line"><span class="ws-side-list__name">Time to value under 15 days</span><span class="ws-side-list__value">9%</span></span><span class="ws-side-list__bar" aria-hidden="true"><span style="width: 9%;"></span><i style="--at: 30%;"></i></span></a></li>
|
|
178
|
+
</ul>
|
|
179
|
+
</section>
|
|
180
|
+
</div>
|
|
181
|
+
</aside>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div class="ws-stack ws-stack--tight">
|
|
186
|
+
<span class="ws-cluster" style="gap: var(--space-xs) var(--space-sm);"><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">3</span><span class="ws-meta">Bars / Line</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">5</span><span class="ws-meta">Click the chart</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">7</span><span class="ws-meta">Point at it</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">12</span><span class="ws-meta">Press a button</span></span></span>
|
|
187
|
+
<section class="ws-card ws-chat-card ws-build__card" aria-labelledby="mo-play-chart-t" style="max-width: none; --ws-i: 5;" data-play-chart>
|
|
188
|
+
<div class="ws-chat-card__head">
|
|
189
|
+
<span class="ws-eyebrow">Calls by week</span>
|
|
190
|
+
<span class="ws-cluster" style="gap: var(--space-xs);">
|
|
191
|
+
<div class="ws-segmented" role="group" aria-label="Show as" data-choose data-lens><button type="button" class="ws-segmented__item" aria-pressed="true" data-lens-to="bars">Bars</button><button type="button" class="ws-segmented__item" aria-pressed="false" data-lens-to="line">Line</button></div>
|
|
192
|
+
<button type="button" class="ws-btn ws-btn--secondary" data-chart-full>Full screen</button>
|
|
193
|
+
</span>
|
|
194
|
+
</div>
|
|
195
|
+
<p class="ws-title" id="mo-play-chart-t">Calls are up nine on last week</p>
|
|
196
|
+
<p class="ws-body">The team answered more of them too: nineteen of twenty-six.</p>
|
|
197
|
+
<div class="ws-chat-card__graph ws-dots" style="cursor: zoom-in;" data-chart-area>
|
|
198
|
+
<figure class="ws-trend-line ws-trend-line--bars" style="--n: 4; --ticks: 3; --ws-trend-line-h: 180px;" aria-labelledby="mo-play-chart-t" data-arrival>
|
|
199
|
+
<div class="ws-trend-line__plot" aria-hidden="true">
|
|
200
|
+
<div class="ws-trend-line__y"><span style="--y: 0%;">30</span><span style="--y: 33.33%;">20</span><span style="--y: 66.67%;">10</span><span style="--y: 100%;">0</span></div>
|
|
201
|
+
<div class="ws-trend-line__area">
|
|
202
|
+
<span class="ws-trend-line__rule" style="--y: 0%;"></span><span class="ws-trend-line__rule" style="--y: 33.33%;"></span><span class="ws-trend-line__rule" style="--y: 66.67%;"></span>
|
|
203
|
+
<span class="ws-trend-line__draw">
|
|
204
|
+
<span class="ws-trend-line__hatch" style="clip-path: polygon(12.5% 40%, 37.5% 20%, 62.5% 50%, 87.5% 13.33%, 87.5% 100%, 12.5% 100%);"></span>
|
|
205
|
+
<svg class="ws-trend-line__lines" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true"><path d="M12.5 40 L37.5 20 L62.5 50 L87.5 13.33"/></svg>
|
|
206
|
+
</span>
|
|
207
|
+
<span class="ws-trend-line__point" style="--i: 0; --y: 40%;"></span>
|
|
208
|
+
<span class="ws-trend-line__point" style="--i: 1; --y: 20%;"></span>
|
|
209
|
+
<span class="ws-trend-line__point" style="--i: 2; --y: 50%;"></span>
|
|
210
|
+
<span class="ws-trend-line__point ws-trend-line__point--now" style="--i: 3; --y: 13.33%;"></span>
|
|
211
|
+
<span class="ws-trend-line__band"></span>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="ws-trend-line__x"><span title="Week of 29 September">29 Sep</span><span title="Week of 6 October">6 Oct</span><span title="Week of 13 October">13 Oct</span><span class="ws-trend-line__now" title="Week of 20 October">20 Oct</span></div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="ws-trend-line__table"><table>
|
|
216
|
+
<caption>Calls by week</caption>
|
|
217
|
+
<thead><tr><th scope="col">Week</th><th scope="col">Calls</th></tr></thead>
|
|
218
|
+
<tbody><tr><th scope="row">Week of 29 September</th><td>18 calls, 12 answered</td></tr><tr><th scope="row">Week of 6 October</th><td>24 calls, 17 answered</td></tr><tr><th scope="row">Week of 13 October</th><td>15 calls, 11 answered</td></tr><tr><th scope="row">Week of 20 October</th><td>26 calls, 19 answered</td></tr></tbody>
|
|
219
|
+
</table></div>
|
|
220
|
+
</figure>
|
|
221
|
+
</div>
|
|
222
|
+
<ul class="ws-chat-card__rows" aria-label="Calls this week">
|
|
223
|
+
<li class="ws-chat-card__row"><span>Dana Okafor</span><b>12</b></li>
|
|
224
|
+
<li class="ws-chat-card__row"><span>Sam Rivera</span><b>4</b></li>
|
|
225
|
+
</ul>
|
|
226
|
+
</section>
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<div class="ws-board">
|
|
230
|
+
<div class="ws-stack ws-stack--tight" style="min-width: 0;">
|
|
231
|
+
<span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">13</span><span class="ws-meta">Point at a square</span></span>
|
|
232
|
+
<section class="ws-heatmap" aria-labelledby="mo-play-heat-h"><header class="ws-heatmap__head"><h3 class="ws-section" id="mo-play-heat-h">Company health</h3></header><div class="ws-heatmap__scroll"><div class="ws-heatmap__grid" style="--cols: 2;"><div class="ws-heatmap__row"><div class="ws-heatmap__lane"><span class="ws-heatmap__lane-name"><b>Sales</b><small>91% of pace</small></span></div><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h3" aria-label="Sales: Revenue, $412K, 94% of pace"><span class="ws-heatmap__label">Revenue</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">$412K</span><span class="ws-heatmap__flag">94%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">94% of pace</span><span class="ws-pace-bar" style="--value: 62%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h1" aria-label="Sales: Calls, 312, 66% of pace"><span class="ws-heatmap__label">Calls</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">312</span><span class="ws-heatmap__flag">66%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">66% of pace</span><span class="ws-pace-bar" style="--value: 40%; --pace: 61%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button></div><div class="ws-heatmap__row"><div class="ws-heatmap__lane"><span class="ws-heatmap__lane-name"><b>Marketing</b><small>78% of pace</small></span></div><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h2" aria-label="Marketing: Leads, 486, 71% of pace"><span class="ws-heatmap__label">Leads</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">486</span><span class="ws-heatmap__flag">71%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">71% of pace</span><span class="ws-pace-bar" style="--value: 47%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h4" aria-label="Marketing: Email opens, 44%, 101% of pace"><span class="ws-heatmap__label">Email opens</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">44%</span><span class="ws-heatmap__flag">101%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">101% of pace</span><span class="ws-pace-bar" style="--value: 67%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button></div></div></div></section>
|
|
233
|
+
</div>
|
|
234
|
+
<div class="ws-stack ws-stack--tight" style="min-width: 0;">
|
|
235
|
+
<span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">14</span><span class="ws-meta">Refresh to see it load</span></span>
|
|
236
|
+
<section class="ws-card ws-card--pad-md ws-stack" aria-labelledby="mo-play-src-t" data-play-sources>
|
|
237
|
+
<div class="ws-cluster" style="justify-content: space-between; flex-wrap: nowrap;"><h3 class="ws-section" id="mo-play-src-t">Leads by source</h3><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-play-refresh>Refresh</button></div>
|
|
238
|
+
<div class="ws-stack" data-sources-view></div>
|
|
239
|
+
<template data-sources-ready><div class="ws-stack ws-stack--tight ws-settle" style="--ws-i: 0;"><span class="ws-cluster" style="justify-content: space-between;"><span class="ws-body">Zillow</span><b class="ws-row-name">7</b></span><span class="ws-pace-bar ws-pace-bar--draw" style="--value: 58%; --tone: var(--ws-chart-finished);" aria-hidden="true"><span class="ws-pace-bar__fill"></span></span></div><div class="ws-stack ws-stack--tight ws-settle" style="--ws-i: 2;"><span class="ws-cluster" style="justify-content: space-between;"><span class="ws-body">Referrals</span><b class="ws-row-name">4</b></span><span class="ws-pace-bar ws-pace-bar--draw" style="--value: 33%; --tone: var(--ws-chart-past-half);" aria-hidden="true"><span class="ws-pace-bar__fill"></span></span></div><div class="ws-stack ws-stack--tight ws-settle" style="--ws-i: 4;"><span class="ws-cluster" style="justify-content: space-between;"><span class="ws-body">Website</span><b class="ws-row-name">1</b></span><span class="ws-pace-bar ws-pace-bar--draw" style="--value: 9%; --tone: var(--ws-chart-under-half);" aria-hidden="true"><span class="ws-pace-bar__fill"></span></span></div></template>
|
|
240
|
+
<template data-sources-loading><span class="ws-sr" role="status">Loading the sources</span><div class="ws-stack" aria-hidden="true"><span class="ws-skeleton ws-skeleton--line" style="width: 70%;"></span><span class="ws-skeleton ws-skeleton--line"></span><span class="ws-skeleton ws-skeleton--line" style="width: 55%;"></span><span class="ws-skeleton ws-skeleton--line"></span><span class="ws-skeleton ws-skeleton--line" style="width: 40%;"></span></div></template>
|
|
241
|
+
</section>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<div class="ws-stack ws-stack--tight">
|
|
246
|
+
<span class="ws-cluster" style="gap: var(--space-xs) var(--space-sm);"><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">4</span><span class="ws-meta">Open the menu</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">11</span><span class="ws-meta">Sort the list</span></span><span class="ws-cluster" style="gap: var(--space-xxs);"><span class="ws-badge ws-badge--navy" aria-hidden="true">9</span><span class="ws-meta">Click a name</span></span></span>
|
|
247
|
+
<section class="ws-card" aria-labelledby="mo-play-list-t">
|
|
248
|
+
<div class="ws-cluster" style="justify-content: space-between; flex-wrap: nowrap; padding: var(--space-sm) var(--space-sm) var(--space-xs) var(--ws-card-inset);"><h3 class="ws-section" id="mo-play-list-t">Leads to call</h3><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" popovertarget="mo-play-sort" aria-haspopup="menu" data-sort-label>Biggest first</button><div id="mo-play-sort" class="ws-menu" popover role="menu" aria-label="Sort the leads" style="width: 220px;"><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="true" popovertarget="mo-play-sort" popovertargetaction="hide" data-sort-by="big">Biggest first<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false" popovertarget="mo-play-sort" popovertargetaction="hide" data-sort-by="small">Smallest first<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false" popovertarget="mo-play-sort" popovertargetaction="hide" data-sort-by="name">By name<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button></div></div>
|
|
249
|
+
<ul class="ws-side-list__picks" id="mo-play-list" data-pick><li data-key="priya" data-figure="61000" data-name="Priya Nair"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-chart-under-half);" data-drawer-lead><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Priya Nair</span><span class="ws-side-list__sub">Offer runs out tonight</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$61,000</span></span></button></li><li data-key="dana" data-figure="24000" data-name="Dana Okafor"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-chart-past-half);" data-drawer-lead><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Dana Okafor</span><span class="ws-side-list__sub">Asked for a second showing</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$24,000</span></span></button></li><li data-key="sam" data-figure="9600" data-name="Sam Rivera"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-chart-finished);" data-drawer-lead><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Sam Rivera</span><span class="ws-side-list__sub">New from Zillow</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$9,600</span></span></button></li><li data-key="alex" data-figure="1200" data-name="Alex Chen"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);" data-drawer-lead><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Alex Chen</span><span class="ws-side-list__sub">Wants a call next week</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$1,200</span></span></button></li></ul>
|
|
250
|
+
</section>
|
|
251
|
+
</div>
|
|
252
|
+
</main>
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
<div class="ws-chat-veil" aria-hidden="true" hidden data-chat-veil></div>
|
|
256
|
+
<div aria-live="polite" style="position: absolute; right: var(--space-md); bottom: var(--space-md); left: var(--space-md); display: flex; justify-content: flex-end; pointer-events: none;" id="mo-play-toasts"></div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
|
|
262
|
+
<dialog class="ws-dialog ws-dialog--drawer" aria-labelledby="mo-play-lead-t" closedby="any" data-lead-drawer><header class="ws-head"><div><h2 id="mo-play-lead-t" class="ws-title">Priya Nair</h2><p class="ws-body" data-lead-sub>Offer runs out tonight.</p></div><button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" data-close-dialog><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button></header><div class="ws-dialog__content"><p class="ws-body">Twelve years in the neighbourhood, referred by two agents on the team.</p></div><footer class="ws-band"><div class="ws-dialog__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" data-close-dialog>Not now</button><button type="button" class="ws-btn ws-btn--primary ws-btn--lg" data-close-dialog>Start the call</button></div></footer></dialog>
|
|
263
|
+
<dialog class="ws-dialog ws-dialog--drawer ws-dialog--drawer-start" aria-label="Menu" closedby="any" data-nav-drawer style="width: min(calc(100% - var(--ws-stage-inset) * 2), var(--ws-sidebar-width)); background: var(--ws-frame);"></dialog>
|
|
264
|
+
</section>
|
|
265
|
+
|
|
266
|
+
<section class="ws-stack" aria-labelledby="mo-reference">
|
|
267
|
+
<h2 class="ws-section" id="mo-reference">Reference for developers</h2>
|
|
268
|
+
<details data-reference>
|
|
269
|
+
<summary class="ws-fold__summary ws-fold__summary--quiet"><span>Show all 206 behaviours: North's values, a live demo and the kit token for each</span><svg class="ws-fold__chevron ws-fold__chevron--down" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5.2 6.6L8 9.4l2.8-2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></summary>
|
|
270
|
+
<div class="ws-stack" style="gap: var(--ws-gap-group); padding-top: var(--ws-gap-component);">
|
|
271
|
+
<div class="ws-stack">
|
|
272
|
+
<p class="ws-body">Each row is one of North's behaviours by Seth's own label (north-motion.md), North's values, a live kit demo to hover, press or play, the kit token or class to build with, and how close the kit is. 206 behaviours: 115 exact, 45 close, 5 through a small JS helper, 41 not in the kit yet.</p>
|
|
273
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact 115</span><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close 45</span><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper 5</span><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet 41</span></span>
|
|
274
|
+
<p class="ws-muted">Slow motion (in Try it) is this page's own: it multiplies every duration, delay and stagger token by --ws-motion-slow (4), so a spring's shape shows. Reduced motion: with prefers-reduced-motion set, every row here is still (instant state changes, no springs, no view transitions, shimmers stop on their ghost), and Slow motion has nothing to slow. A browser without a feature (linear(), anchor positioning, @starting-style, interpolate-size, view transitions) shows the change at once, never a broken layout.</p>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<section class="ws-stack" aria-labelledby="mo-durations">
|
|
278
|
+
<h2 class="ws-section" id="mo-durations">1. Durations</h2>
|
|
279
|
+
<p class="ws-muted">How long each kind of move takes in North, and the kit token that carries it. Play sends the dot across on that duration (on the soft curve unless the band names its own).</p>
|
|
280
|
+
<div class="ws-board">
|
|
281
|
+
<article class="ws-card" aria-label="Exit / quick out"><div class="ws-head">
|
|
282
|
+
<div class="ws-stack ws-stack--tight">
|
|
283
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Exit / quick out</span></span>
|
|
284
|
+
<span class="ws-meta">North: 100 to 160 ms, always shorter than the way in: tooltips and menus .12, chat exit .16, picker .1</span>
|
|
285
|
+
<span class="ws-meta">Kit: --ws-duration-exit (120 ms) on --ws-ease-exit; the .16 s chat and panel exits and the .1 s morph fade are component-local raws</span>
|
|
286
|
+
</div>
|
|
287
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-exit); --mo-e: var(--ws-ease-exit);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
288
|
+
</div></article>
|
|
289
|
+
<article class="ws-card" aria-label="Tooltip fade"><div class="ws-head">
|
|
290
|
+
<div class="ws-stack ws-stack--tight">
|
|
291
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Tooltip fade</span></span>
|
|
292
|
+
<span class="ws-meta">North: 180 ms: .seg-tip and .mark-tip opacity (css:388); the aim ring out</span>
|
|
293
|
+
<span class="ws-meta">Kit: --ws-tooltip-out (180 ms) in Tooltip only; no global token yet</span>
|
|
294
|
+
</div>
|
|
295
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-tooltip-10" data-jump>Play it in Hover intent: wait before a tile opens</a></div>
|
|
296
|
+
</div></article>
|
|
297
|
+
<article class="ws-card" aria-label="Hover colour"><div class="ws-head">
|
|
298
|
+
<div class="ws-stack ws-stack--tight">
|
|
299
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Hover colour</span></span>
|
|
300
|
+
<span class="ws-meta">North: 200 ms: almost every hover tint, edge, colour and opacity (css:28, 80, 197)</span>
|
|
301
|
+
<span class="ws-meta">Kit: --ws-duration-hover</span>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="ws-cluster"><span class="ws-row ws-hover-tint">Point at this row</span></div>
|
|
304
|
+
</div></article>
|
|
305
|
+
<article class="ws-card" aria-label="Text colour, small fades"><div class="ws-head">
|
|
306
|
+
<div class="ws-stack ws-stack--tight">
|
|
307
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Text colour, small fades</span></span>
|
|
308
|
+
<span class="ws-meta">North: 250 ms: a segment's words, a nav label, a card ground (css:150, 58, 268)</span>
|
|
309
|
+
<span class="ws-meta">Kit: --ws-duration-text</span>
|
|
310
|
+
</div>
|
|
311
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-text); --mo-e: var(--ws-ease-soft);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
312
|
+
</div></article>
|
|
313
|
+
<article class="ws-card" aria-label="Content settle"><div class="ws-head">
|
|
314
|
+
<div class="ws-stack ws-stack--tight">
|
|
315
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Content settle</span></span>
|
|
316
|
+
<span class="ws-meta">North: 300 to 320 ms soft: "Details settle in" .3, "Tile details settle in" .32, tooltip rows .32, "Page behind fades" .32</span>
|
|
317
|
+
<span class="ws-meta">Kit: --ws-duration-settle (320 ms); the .3 s uses run 20 ms long</span>
|
|
318
|
+
</div>
|
|
319
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-settle); --mo-e: var(--ws-ease-soft);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
320
|
+
</div></article>
|
|
321
|
+
<article class="ws-card" aria-label="Reveal"><div class="ws-head">
|
|
322
|
+
<div class="ws-stack ws-stack--tight">
|
|
323
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Reveal</span></span>
|
|
324
|
+
<span class="ws-meta">North: 350 ms soft: link underline, top bar ground; North mark and chevron .35 on pop</span>
|
|
325
|
+
<span class="ws-meta">Kit: --ws-duration-reveal (no component uses it yet)</span>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-reveal); --mo-e: var(--ws-ease-soft);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
328
|
+
</div></article>
|
|
329
|
+
<article class="ws-card" aria-label="Indicator / spring"><div class="ws-head">
|
|
330
|
+
<div class="ws-stack ws-stack--tight">
|
|
331
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Indicator / spring</span></span>
|
|
332
|
+
<span class="ws-meta">North: 380 to 460 ms visual: toggle pill .38, sidebar row .4, list highlight .45, lens .45, lane .46, chat .42</span>
|
|
333
|
+
<span class="ws-meta">Kit: the --ws-spring-* tokens (group 3), each over its settle time</span>
|
|
334
|
+
</div>
|
|
335
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-indicator-duration); --mo-e: var(--ws-spring-indicator);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
336
|
+
</div></article>
|
|
337
|
+
<article class="ws-card" aria-label="Morph / fold"><div class="ws-head">
|
|
338
|
+
<div class="ws-stack ws-stack--tight">
|
|
339
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Morph / fold</span></span>
|
|
340
|
+
<span class="ws-meta">North: 450 ms: "Full screen: open / close" .45 on morph; home ask folds and header band .45 soft</span>
|
|
341
|
+
<span class="ws-meta">Kit: --ws-duration-morph</span>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-morph); --mo-e: var(--ws-ease-morph);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
344
|
+
</div></article>
|
|
345
|
+
<article class="ws-card" aria-label="Grow open"><div class="ws-head">
|
|
346
|
+
<div class="ws-stack ws-stack--tight">
|
|
347
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Grow open</span></span>
|
|
348
|
+
<span class="ws-meta">North: 550 ms: "Card grows open" .55 grow; "Chat moves between full screen, dock and pop-out" .55 shift</span>
|
|
349
|
+
<span class="ws-meta">Kit: --ws-duration-grow, --ws-duration-shift</span>
|
|
350
|
+
</div>
|
|
351
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-grow); --mo-e: var(--ws-ease-grow);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
352
|
+
</div></article>
|
|
353
|
+
<article class="ws-card" aria-label="Close back"><div class="ws-head">
|
|
354
|
+
<div class="ws-stack ws-stack--tight">
|
|
355
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Close back</span></span>
|
|
356
|
+
<span class="ws-meta">North: 400 ms: "Card closes back into place" .4 grow</span>
|
|
357
|
+
<span class="ws-meta">Kit: --ws-duration-shrink</span>
|
|
358
|
+
</div>
|
|
359
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-shrink); --mo-e: var(--ws-ease-grow);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
360
|
+
</div></article>
|
|
361
|
+
<article class="ws-card" aria-label="Fill"><div class="ws-head">
|
|
362
|
+
<div class="ws-stack ws-stack--tight">
|
|
363
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Fill</span></span>
|
|
364
|
+
<span class="ws-meta">North: 700 ms: "Tile pace bar fill" .7 settle</span>
|
|
365
|
+
<span class="ws-meta">Kit: --ws-duration-fill</span>
|
|
366
|
+
</div>
|
|
367
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-fill); --mo-e: var(--ws-ease-settle);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
368
|
+
</div></article>
|
|
369
|
+
<article class="ws-card" aria-label="Draw in a card"><div class="ws-head">
|
|
370
|
+
<div class="ws-stack ws-stack--tight">
|
|
371
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Draw in a card</span></span>
|
|
372
|
+
<span class="ws-meta">North: 900 ms: "Chart draw duration", "Score ring fill", "Heatmap squares: each one fades in"</span>
|
|
373
|
+
<span class="ws-meta">Kit: --ws-duration-draw</span>
|
|
374
|
+
</div>
|
|
375
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-draw); --mo-e: var(--ws-ease-steady);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
376
|
+
</div></article>
|
|
377
|
+
<article class="ws-card" aria-label="Chat chart sweep"><div class="ws-head">
|
|
378
|
+
<div class="ws-stack ws-stack--tight">
|
|
379
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Chat chart sweep</span></span>
|
|
380
|
+
<span class="ws-meta">North: 1500 ms on sweep: "Chart draws in (the sweep; each tick eases on its own)"</span>
|
|
381
|
+
<span class="ws-meta">Kit: --ws-duration-draw-chat</span>
|
|
382
|
+
</div>
|
|
383
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-draw-chat); --mo-e: var(--ws-ease-sweep);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
384
|
+
</div></article>
|
|
385
|
+
<article class="ws-card" aria-label="Page draws"><div class="ws-head">
|
|
386
|
+
<div class="ws-stack ws-stack--tight">
|
|
387
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Page draws</span></span>
|
|
388
|
+
<span class="ws-meta">North: 1.7 to 2.3 s: intro bars 1.7, revenue bars 1.9, board chart 2.3, new chart draw 2.1</span>
|
|
389
|
+
<span class="ws-meta">Kit: --ws-duration-fill-page (1700 ms) for a tile's chart and the goal bars in a .ws-build; a chart card draws over --ws-duration-draw (900 ms) as its card lands, not North's 1.9 and 2.3 s</span>
|
|
390
|
+
</div>
|
|
391
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-fill-page); --mo-e: var(--ws-ease-settle);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span><a class="ws-link" href="#mo-build-home" data-jump>Play it in Try it: Replay the arrival</a></div>
|
|
392
|
+
</div></article>
|
|
393
|
+
<article class="ws-card" aria-label="Page build-in"><div class="ws-head">
|
|
394
|
+
<div class="ws-stack ws-stack--tight">
|
|
395
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Page build-in</span></span>
|
|
396
|
+
<span class="ws-meta">North: 2.4 s linear: "Page build-in length" (Company health)</span>
|
|
397
|
+
<span class="ws-meta">Kit: --ws-duration-build</span>
|
|
398
|
+
</div>
|
|
399
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-build); --mo-e: var(--ws-ease-steady);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
400
|
+
</div></article>
|
|
401
|
+
<article class="ws-card" aria-label="Loops"><div class="ws-head">
|
|
402
|
+
<div class="ws-stack ws-stack--tight">
|
|
403
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Loops</span></span>
|
|
404
|
+
<span class="ws-meta">North: 1, 1.2, 1.4, 1.5, 1.6, 1.8, 2.4, 5.5, 6 and 26 s</span>
|
|
405
|
+
<span class="ws-meta">Kit: --ws-loop 1 s, --ws-loop-status 1.6 s, --ws-loop-shimmer 1.8 s, --ws-loop-slow 2.4 s, --ws-loop-ambient 6 s; the 1.2, 1.4, 1.5, 5.5 and 26 s loops have no token (their owners are not in the kit)</span>
|
|
406
|
+
</div>
|
|
407
|
+
<div class="ws-cluster"><span class="ws-cluster" aria-hidden="true"><span class="ws-dot ws-working" style="color: var(--color-text-heading);"></span><span class="ws-shimmer" style="width: var(--space-4xl); height: var(--space-sm);"></span></span></div>
|
|
408
|
+
</div></article>
|
|
409
|
+
</div>
|
|
410
|
+
</section>
|
|
411
|
+
|
|
412
|
+
<section class="ws-stack" aria-labelledby="mo-easings">
|
|
413
|
+
<h2 class="ws-section" id="mo-easings">2. Curves</h2>
|
|
414
|
+
<p class="ws-muted">North names a curve by its role. Play runs the dot on the curve over the duration that role uses.</p>
|
|
415
|
+
<div class="ws-board">
|
|
416
|
+
<article class="ws-card" aria-label="soft"><div class="ws-head">
|
|
417
|
+
<div class="ws-stack ws-stack--tight">
|
|
418
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">soft</span></span>
|
|
419
|
+
<span class="ws-meta">North: (.22, 1, .36, 1): the default; content arriving, details settling, hover reveals, folds (33 uses, the ie() default)</span>
|
|
420
|
+
<span class="ws-meta">Kit: --ws-ease-soft</span>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-settle); --mo-e: var(--ws-ease-soft);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
423
|
+
</div></article>
|
|
424
|
+
<article class="ws-card" aria-label="settle"><div class="ws-head">
|
|
425
|
+
<div class="ws-stack ws-stack--tight">
|
|
426
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">settle</span></span>
|
|
427
|
+
<span class="ws-meta">North: (.16, 1, .3, 1): things that land and rest; notes, each chart mark, bar fills</span>
|
|
428
|
+
<span class="ws-meta">Kit: --ws-ease-settle</span>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-fill); --mo-e: var(--ws-ease-settle);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
431
|
+
</div></article>
|
|
432
|
+
<article class="ws-card" aria-label="grow"><div class="ws-head">
|
|
433
|
+
<div class="ws-stack ws-stack--tight">
|
|
434
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">grow</span></span>
|
|
435
|
+
<span class="ws-meta">North: (.32, .72, 0, 1): a shape changing size; tile open and close, label push-out, switch thumb</span>
|
|
436
|
+
<span class="ws-meta">Kit: --ws-ease-grow</span>
|
|
437
|
+
</div>
|
|
438
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-grow); --mo-e: var(--ws-ease-grow);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
439
|
+
</div></article>
|
|
440
|
+
<article class="ws-card" aria-label="shift"><div class="ws-head">
|
|
441
|
+
<div class="ws-stack ws-stack--tight">
|
|
442
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">shift</span></span>
|
|
443
|
+
<span class="ws-meta">North: (.25, 1, .5, 1): layout moving; the chat docking, columns trading width</span>
|
|
444
|
+
<span class="ws-meta">Kit: --ws-ease-shift</span>
|
|
445
|
+
</div>
|
|
446
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-shift); --mo-e: var(--ws-ease-shift);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
447
|
+
</div></article>
|
|
448
|
+
<article class="ws-card" aria-label="morph"><div class="ws-head">
|
|
449
|
+
<div class="ws-stack ws-stack--tight">
|
|
450
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">morph</span></span>
|
|
451
|
+
<span class="ws-meta">North: (.5, 0, .15, 1): a shared element in flight</span>
|
|
452
|
+
<span class="ws-meta">Kit: --ws-ease-morph</span>
|
|
453
|
+
</div>
|
|
454
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-morph); --mo-e: var(--ws-ease-morph);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
455
|
+
</div></article>
|
|
456
|
+
<article class="ws-card" aria-label="sweep"><div class="ws-head">
|
|
457
|
+
<div class="ws-stack ws-stack--tight">
|
|
458
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">sweep</span></span>
|
|
459
|
+
<span class="ws-meta">North: (.45, 0, .55, 1): a chart drawing left to right in chat</span>
|
|
460
|
+
<span class="ws-meta">Kit: --ws-ease-sweep</span>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-draw-chat); --mo-e: var(--ws-ease-sweep);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
463
|
+
</div></article>
|
|
464
|
+
<article class="ws-card" aria-label="commit"><div class="ws-head">
|
|
465
|
+
<div class="ws-stack ws-stack--tight">
|
|
466
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">commit</span></span>
|
|
467
|
+
<span class="ws-meta">North: (.65, 0, .35, 1): a decisive one-shot; the sending bar, a check mark drawing</span>
|
|
468
|
+
<span class="ws-meta">Kit: --ws-ease-commit (no component uses it yet)</span>
|
|
469
|
+
</div>
|
|
470
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-fill); --mo-e: var(--ws-ease-commit);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
471
|
+
</div></article>
|
|
472
|
+
<article class="ws-card" aria-label="shimmer"><div class="ws-head">
|
|
473
|
+
<div class="ws-stack ws-stack--tight">
|
|
474
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">shimmer</span></span>
|
|
475
|
+
<span class="ws-meta">North: (.4, 0, .2, 1): loading sweeps, the self-pressing keycap</span>
|
|
476
|
+
<span class="ws-meta">Kit: --ws-ease-shimmer</span>
|
|
477
|
+
</div>
|
|
478
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-loop-shimmer); --mo-e: var(--ws-ease-shimmer);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
479
|
+
</div></article>
|
|
480
|
+
<article class="ws-card" aria-label="exit"><div class="ws-head">
|
|
481
|
+
<div class="ws-stack ws-stack--tight">
|
|
482
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">exit</span></span>
|
|
483
|
+
<span class="ws-meta">North: (.4, 0, 1, 1): leaving; hover shape fading, a tile unmounting, aim ring out</span>
|
|
484
|
+
<span class="ws-meta">Kit: --ws-ease-exit</span>
|
|
485
|
+
</div>
|
|
486
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-exit); --mo-e: var(--ws-ease-exit);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
487
|
+
</div></article>
|
|
488
|
+
<article class="ws-card" aria-label="pop"><div class="ws-head">
|
|
489
|
+
<div class="ws-stack ws-stack--tight">
|
|
490
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">pop</span></span>
|
|
491
|
+
<span class="ws-meta">North: (.34, 1.4, .64, 1): overshoot for small marks; North mark sun, chevron, needle</span>
|
|
492
|
+
<span class="ws-meta">Kit: --ws-ease-pop (checks, radios, badges, the pace dot)</span>
|
|
493
|
+
</div>
|
|
494
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-reveal); --mo-e: var(--ws-ease-pop);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
495
|
+
</div></article>
|
|
496
|
+
<article class="ws-card" aria-label="pop-glass"><div class="ws-head">
|
|
497
|
+
<div class="ws-stack ws-stack--tight">
|
|
498
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">pop-glass</span></span>
|
|
499
|
+
<span class="ws-meta">North: (.34, 1.45, .64, 1): the target glass growing on (.38 s)</span>
|
|
500
|
+
<span class="ws-meta">Kit: not yet: the kit has no target glass; --ws-ease-pop is its nearest</span>
|
|
501
|
+
</div>
|
|
502
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
503
|
+
</div></article>
|
|
504
|
+
<article class="ws-card" aria-label="lift"><div class="ws-head">
|
|
505
|
+
<div class="ws-stack ws-stack--tight">
|
|
506
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">lift</span></span>
|
|
507
|
+
<span class="ws-meta">North: (.22, 1.25, .36, 1): ticks and ring wedges growing on hover</span>
|
|
508
|
+
<span class="ws-meta">Kit: --ws-ease-lift (TickStrip --hover)</span>
|
|
509
|
+
</div>
|
|
510
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-settle); --mo-e: var(--ws-ease-lift);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
511
|
+
</div></article>
|
|
512
|
+
<article class="ws-card" aria-label="dot"><div class="ws-head">
|
|
513
|
+
<div class="ws-stack ws-stack--tight">
|
|
514
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">dot</span></span>
|
|
515
|
+
<span class="ws-meta">North: (.22, 1.4, .36, 1): the unread dot popping in (.4 s)</span>
|
|
516
|
+
<span class="ws-meta">Kit: not yet: the kit has no unread dot</span>
|
|
517
|
+
</div>
|
|
518
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
519
|
+
</div></article>
|
|
520
|
+
<article class="ws-card" aria-label="ambient"><div class="ws-head">
|
|
521
|
+
<div class="ws-stack ws-stack--tight">
|
|
522
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">ambient</span></span>
|
|
523
|
+
<span class="ws-meta">North: (.45, 0, .3, 1): the 6 s brand shimmer through "Ask North"</span>
|
|
524
|
+
<span class="ws-meta">Kit: --ws-ease-ambient (no component uses it yet)</span>
|
|
525
|
+
</div>
|
|
526
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-loop-ambient); --mo-e: var(--ws-ease-ambient);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
527
|
+
</div></article>
|
|
528
|
+
<article class="ws-card" aria-label="spoke"><div class="ws-head">
|
|
529
|
+
<div class="ws-stack ws-stack--tight">
|
|
530
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">spoke</span></span>
|
|
531
|
+
<span class="ws-meta">North: (.3, 0, .2, 1): North mark spokes pushing out one after another</span>
|
|
532
|
+
<span class="ws-meta">Kit: not yet: local to the North mark, which is not in the kit</span>
|
|
533
|
+
</div>
|
|
534
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
535
|
+
</div></article>
|
|
536
|
+
<article class="ws-card" aria-label="ripple"><div class="ws-head">
|
|
537
|
+
<div class="ws-stack ws-stack--tight">
|
|
538
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">ripple</span></span>
|
|
539
|
+
<span class="ws-meta">North: (.2, .7, .3, 1): the agent ring ripple (.9 s)</span>
|
|
540
|
+
<span class="ws-meta">Kit: not yet: the kit has no agent ring</span>
|
|
541
|
+
</div>
|
|
542
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
543
|
+
</div></article>
|
|
544
|
+
<article class="ws-card" aria-label="build-fade"><div class="ws-head">
|
|
545
|
+
<div class="ws-stack ws-stack--tight">
|
|
546
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">build-fade</span></span>
|
|
547
|
+
<span class="ws-meta">North: (.26, .22, .86, .85): each heatmap square fading in during the build, near linear so the wave reads</span>
|
|
548
|
+
<span class="ws-meta">Kit: not yet as a token: Heatmap --build runs its squares on --ws-ease-steady</span>
|
|
549
|
+
</div>
|
|
550
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-draw); --mo-e: var(--ws-ease-steady);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
551
|
+
</div></article>
|
|
552
|
+
<article class="ws-card" aria-label="steady"><div class="ws-head">
|
|
553
|
+
<div class="ws-stack ws-stack--tight">
|
|
554
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">steady</span></span>
|
|
555
|
+
<span class="ws-meta">North: linear: shimmers, sheen laps, undo drain, draw progress</span>
|
|
556
|
+
<span class="ws-meta">Kit: --ws-ease-steady</span>
|
|
557
|
+
</div>
|
|
558
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-draw); --mo-e: var(--ws-ease-steady);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
559
|
+
</div></article>
|
|
560
|
+
<article class="ws-card" aria-label="ease, ease-in-out"><div class="ws-head">
|
|
561
|
+
<div class="ws-stack ws-stack--tight">
|
|
562
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">ease, ease-in-out</span></span>
|
|
563
|
+
<span class="ws-meta">North: "ease" on many .2 s colour changes; "ease-in-out" on loops (orb, typing dots, load dot)</span>
|
|
564
|
+
<span class="ws-meta">Kit: --ws-ease-loop is ease-in-out (every kit loop); "ease" stays a keyword in two places (MetricTile preview, Heatmap arrow)</span>
|
|
565
|
+
</div>
|
|
566
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-loop); --mo-e: var(--ws-ease-loop);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
567
|
+
</div></article>
|
|
568
|
+
</div>
|
|
569
|
+
</section>
|
|
570
|
+
|
|
571
|
+
<section class="ws-stack" aria-labelledby="mo-springs">
|
|
572
|
+
<h2 class="ws-section" id="mo-springs">3. Springs</h2>
|
|
573
|
+
<p class="ws-muted">Every spring Seth tuned, by his label. In CSS each is a linear() curve sampled from the motion library's own solver (overshoot kept), over its settle time: transition: transform var(--ws-spring-press-duration) var(--ws-spring-press).</p>
|
|
574
|
+
<div class="ws-board">
|
|
575
|
+
<article class="ws-card" aria-label="Button press (mic, add)"><div class="ws-head">
|
|
576
|
+
<div class="ws-stack ws-stack--tight">
|
|
577
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Button press (mic, add)</span></span>
|
|
578
|
+
<span class="ws-meta">North: hover.press: spring visualDuration / bounce .2 / .3</span>
|
|
579
|
+
<span class="ws-meta">Kit: --ws-spring-press over --ws-spring-press-duration (450ms); buttons, icon buttons, chips (group 5)</span>
|
|
580
|
+
</div>
|
|
581
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-press-duration); --mo-e: var(--ws-spring-press);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
582
|
+
</div></article>
|
|
583
|
+
<article class="ws-card" aria-label="Tooltip follows cursor"><div class="ws-head">
|
|
584
|
+
<div class="ws-stack ws-stack--tight">
|
|
585
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tooltip follows cursor</span></span>
|
|
586
|
+
<span class="ws-meta">North: tipFollow: spring visualDuration / bounce .22 / 0</span>
|
|
587
|
+
<span class="ws-meta">Kit: --ws-spring-follow over --ws-spring-follow-duration (450ms); HoverCard --follow</span>
|
|
588
|
+
</div>
|
|
589
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-follow-duration); --mo-e: var(--ws-spring-follow);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
590
|
+
</div></article>
|
|
591
|
+
<article class="ws-card" aria-label="Tooltip pop-in"><div class="ws-head">
|
|
592
|
+
<div class="ws-stack ws-stack--tight">
|
|
593
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tooltip pop-in</span></span>
|
|
594
|
+
<span class="ws-meta">North: tip: spring visualDuration / bounce .35 / .1</span>
|
|
595
|
+
<span class="ws-meta">Kit: --ws-spring-pop over --ws-spring-pop-duration (500ms); Tooltip, HoverCard</span>
|
|
596
|
+
</div>
|
|
597
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-pop-duration); --mo-e: var(--ws-spring-pop);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
598
|
+
</div></article>
|
|
599
|
+
<article class="ws-card" aria-label="Messages and steps settle"><div class="ws-head">
|
|
600
|
+
<div class="ws-stack ws-stack--tight">
|
|
601
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Messages and steps settle</span></span>
|
|
602
|
+
<span class="ws-meta">North: chat.swap: spring visualDuration / bounce .32 / .1</span>
|
|
603
|
+
<span class="ws-meta">Kit: --ws-spring-settle over --ws-spring-settle-duration (450ms); Menu, Popover, Dialog, Toast</span>
|
|
604
|
+
</div>
|
|
605
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-settle-duration); --mo-e: var(--ws-spring-settle);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
606
|
+
</div></article>
|
|
607
|
+
<article class="ws-card" aria-label="Sidebar sections open / close"><div class="ws-head">
|
|
608
|
+
<div class="ws-stack ws-stack--tight">
|
|
609
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Sidebar sections open / close</span></span>
|
|
610
|
+
<span class="ws-meta">North: collapse: spring visualDuration / bounce .32 / 0</span>
|
|
611
|
+
<span class="ws-meta">Kit: --ws-spring-fold over --ws-spring-fold-duration (600ms); every kit details, .ws-unfold, CheckRow</span>
|
|
612
|
+
</div>
|
|
613
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-fold-duration); --mo-e: var(--ws-spring-fold);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
614
|
+
</div></article>
|
|
615
|
+
<article class="ws-card" aria-label="Toggle pill slide (bars / line, lanes)"><div class="ws-head">
|
|
616
|
+
<div class="ws-stack ws-stack--tight">
|
|
617
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Toggle pill slide (bars / line, lanes)</span></span>
|
|
618
|
+
<span class="ws-meta">North: select.pill: spring visualDuration / bounce .38 / .16</span>
|
|
619
|
+
<span class="ws-meta">Kit: --ws-spring-indicator over --ws-spring-indicator-duration (700ms); Segmented</span>
|
|
620
|
+
</div>
|
|
621
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-indicator-duration); --mo-e: var(--ws-spring-indicator);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
622
|
+
</div></article>
|
|
623
|
+
<article class="ws-card" aria-label="List highlight slide"><div class="ws-head">
|
|
624
|
+
<div class="ws-stack ws-stack--tight">
|
|
625
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">List highlight slide</span></span>
|
|
626
|
+
<span class="ws-meta">North: select.glide: spring visualDuration / bounce .45 / .14</span>
|
|
627
|
+
<span class="ws-meta">Kit: --ws-spring-highlight over --ws-spring-highlight-duration (800ms); SideList, ListDetail</span>
|
|
628
|
+
</div>
|
|
629
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-highlight-duration); --mo-e: var(--ws-spring-highlight);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
630
|
+
</div></article>
|
|
631
|
+
<article class="ws-card" aria-label="Sidebar active row slide"><div class="ws-head">
|
|
632
|
+
<div class="ws-stack ws-stack--tight">
|
|
633
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Sidebar active row slide</span></span>
|
|
634
|
+
<span class="ws-meta">North: health.navSlide: spring visualDuration / bounce .4 / .1</span>
|
|
635
|
+
<span class="ws-meta">Kit: --ws-spring-nav over --ws-spring-nav-duration (550ms); AppShell</span>
|
|
636
|
+
</div>
|
|
637
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-nav-duration); --mo-e: var(--ws-spring-nav);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
638
|
+
</div></article>
|
|
639
|
+
<article class="ws-card" aria-label="Department card underline (no label, js@754407)"><div class="ws-head">
|
|
640
|
+
<div class="ws-stack ws-stack--tight">
|
|
641
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Department card underline (no label, js@754407)</span></span>
|
|
642
|
+
<span class="ws-meta">North: dcard layoutId: spring visualDuration / bounce .4 / .12</span>
|
|
643
|
+
<span class="ws-meta">Kit: --ws-spring-tab over --ws-spring-tab-duration (500ms); Tabs</span>
|
|
644
|
+
</div>
|
|
645
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-tab-duration); --mo-e: var(--ws-spring-tab);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
646
|
+
</div></article>
|
|
647
|
+
<article class="ws-card" aria-label="List rows reorder"><div class="ws-head">
|
|
648
|
+
<div class="ws-stack ws-stack--tight">
|
|
649
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">List rows reorder</span></span>
|
|
650
|
+
<span class="ws-meta">North: select.list: spring visualDuration / bounce .4 / 0</span>
|
|
651
|
+
<span class="ws-meta">Kit: --ws-spring-reorder over --ws-spring-reorder-duration (750ms); reorder()</span>
|
|
652
|
+
</div>
|
|
653
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-reorder-duration); --mo-e: var(--ws-spring-reorder);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
654
|
+
</div></article>
|
|
655
|
+
<article class="ws-card" aria-label="Attention chip to card"><div class="ws-head">
|
|
656
|
+
<div class="ws-stack ws-stack--tight">
|
|
657
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Attention chip to card</span></span>
|
|
658
|
+
<span class="ws-meta">North: chips.pop: spring visualDuration / bounce .25 / .1</span>
|
|
659
|
+
<span class="ws-meta">Kit: --ws-spring-chip over --ws-spring-chip-duration (350ms); token only: no attention chip in the kit</span>
|
|
660
|
+
</div>
|
|
661
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-chip-duration); --mo-e: var(--ws-spring-chip);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
662
|
+
</div></article>
|
|
663
|
+
<article class="ws-card" aria-label="Placeholder roll"><div class="ws-head">
|
|
664
|
+
<div class="ws-stack ws-stack--tight">
|
|
665
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Placeholder roll</span></span>
|
|
666
|
+
<span class="ws-meta">North: composer.cycleSpring: spring visualDuration / bounce .45 / .05</span>
|
|
667
|
+
<span class="ws-meta">Kit: --ws-spring-roll over --ws-spring-roll-duration (700ms); Composer</span>
|
|
668
|
+
</div>
|
|
669
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-roll-duration); --mo-e: var(--ws-spring-roll);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
670
|
+
</div></article>
|
|
671
|
+
<article class="ws-card" aria-label="Focus glow"><div class="ws-head">
|
|
672
|
+
<div class="ws-stack ws-stack--tight">
|
|
673
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Focus glow</span></span>
|
|
674
|
+
<span class="ws-meta">North: composer.focus: spring visualDuration / bounce .3 / 0</span>
|
|
675
|
+
<span class="ws-meta">Kit: --ws-spring-glow over --ws-spring-glow-duration (600ms); Composer</span>
|
|
676
|
+
</div>
|
|
677
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-glow-duration); --mo-e: var(--ws-spring-glow);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
678
|
+
</div></article>
|
|
679
|
+
<article class="ws-card" aria-label="Tile grows open / closes"><div class="ws-head">
|
|
680
|
+
<div class="ws-stack ws-stack--tight">
|
|
681
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tile grows open / closes</span></span>
|
|
682
|
+
<span class="ws-meta">North: health.tileOpen: spring visualDuration / bounce .26 / .06</span>
|
|
683
|
+
<span class="ws-meta">Kit: --ws-spring-tile over --ws-spring-tile-duration (450ms); Heatmap</span>
|
|
684
|
+
</div>
|
|
685
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-tile-duration); --mo-e: var(--ws-spring-tile);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
686
|
+
</div></article>
|
|
687
|
+
<article class="ws-card" aria-label="Department: lane detail opens / closes"><div class="ws-head">
|
|
688
|
+
<div class="ws-stack ws-stack--tight">
|
|
689
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Department: lane detail opens / closes</span></span>
|
|
690
|
+
<span class="ws-meta">North: health.laneOpen: spring visualDuration / bounce .46 / .04</span>
|
|
691
|
+
<span class="ws-meta">Kit: --ws-spring-lane over --ws-spring-lane-duration (750ms); token only: no lane detail in the kit</span>
|
|
692
|
+
</div>
|
|
693
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-lane-duration); --mo-e: var(--ws-spring-lane);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
694
|
+
</div></article>
|
|
695
|
+
<article class="ws-card" aria-label="Lens switch (chart swap)"><div class="ws-head">
|
|
696
|
+
<div class="ws-stack ws-stack--tight">
|
|
697
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Lens switch (chart swap)</span></span>
|
|
698
|
+
<span class="ws-meta">North: open.lens: spring visualDuration / bounce .45 / .04</span>
|
|
699
|
+
<span class="ws-meta">Kit: --ws-spring-lens over --ws-spring-lens-duration (750ms); token only: no lens switch in the kit</span>
|
|
700
|
+
</div>
|
|
701
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-lens-duration); --mo-e: var(--ws-spring-lens);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
702
|
+
</div></article>
|
|
703
|
+
<article class="ws-card" aria-label="Old chart out / new chart in"><div class="ws-head">
|
|
704
|
+
<div class="ws-stack ws-stack--tight">
|
|
705
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Old chart out / new chart in</span></span>
|
|
706
|
+
<span class="ws-meta">North: detail.swap: spring visualDuration / bounce .6 / .06</span>
|
|
707
|
+
<span class="ws-meta">Kit: --ws-spring-swap over --ws-spring-swap-duration (900ms); token only: no chart swap in the kit</span>
|
|
708
|
+
</div>
|
|
709
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-swap-duration); --mo-e: var(--ws-spring-swap);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
710
|
+
</div></article>
|
|
711
|
+
<article class="ws-card" aria-label="Bars to line morph"><div class="ws-head">
|
|
712
|
+
<div class="ws-stack ws-stack--tight">
|
|
713
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Bars to line morph</span></span>
|
|
714
|
+
<span class="ws-meta">North: chart.morph: spring visualDuration / bounce .85 / .06</span>
|
|
715
|
+
<span class="ws-meta">Kit: --ws-spring-morph-chart over --ws-spring-morph-chart-duration (1250ms); TrendLine --bars: the columns collapse into their tops on it while the line draws over --ws-duration-draw</span>
|
|
716
|
+
</div>
|
|
717
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-morph-chart-duration); --mo-e: var(--ws-spring-morph-chart);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span><a class="ws-link" href="#mo-play-chart-t" data-jump>Play it in Try it: the chart card</a></div>
|
|
718
|
+
</div></article>
|
|
719
|
+
<article class="ws-card" aria-label="Opens / moves / docks (spring)"><div class="ws-head">
|
|
720
|
+
<div class="ws-stack ws-stack--tight">
|
|
721
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Opens / moves / docks (spring)</span></span>
|
|
722
|
+
<span class="ws-meta">North: chat.open: spring visualDuration / bounce .42 / .12</span>
|
|
723
|
+
<span class="ws-meta">Kit: --ws-spring-panel over --ws-spring-panel-duration (550ms); Panel, ChatShell</span>
|
|
724
|
+
</div>
|
|
725
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-panel-duration); --mo-e: var(--ws-spring-panel);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
726
|
+
</div></article>
|
|
727
|
+
<article class="ws-card" aria-label="Chart card arrives"><div class="ws-head">
|
|
728
|
+
<div class="ws-stack ws-stack--tight">
|
|
729
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Chart card arrives</span></span>
|
|
730
|
+
<span class="ws-meta">North: chat.card: spring visualDuration / bounce .5 / .08</span>
|
|
731
|
+
<span class="ws-meta">Kit: --ws-spring-card over --ws-spring-card-duration (700ms); ChatCard</span>
|
|
732
|
+
</div>
|
|
733
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-card-duration); --mo-e: var(--ws-spring-card);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
734
|
+
</div></article>
|
|
735
|
+
<article class="ws-card" aria-label="Trend flag follows the pointer (spring)"><div class="ws-head">
|
|
736
|
+
<div class="ws-stack ws-stack--tight">
|
|
737
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Trend flag follows the pointer (spring)</span></span>
|
|
738
|
+
<span class="ws-meta">North: chat.flag: spring visualDuration / bounce .26 / .06</span>
|
|
739
|
+
<span class="ws-meta">Kit: --ws-spring-flag over --ws-spring-flag-duration (450ms); token only: no trend flag in the kit</span>
|
|
740
|
+
</div>
|
|
741
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-flag-duration); --mo-e: var(--ws-spring-flag);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
742
|
+
</div></article>
|
|
743
|
+
<article class="ws-card" aria-label="Metric card text swap"><div class="ws-head">
|
|
744
|
+
<div class="ws-stack ws-stack--tight">
|
|
745
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Metric card text swap</span></span>
|
|
746
|
+
<span class="ws-meta">North: hover.spring: spring visualDuration / bounce .7 / .2</span>
|
|
747
|
+
<span class="ws-meta">Kit: --ws-spring-text over --ws-spring-text-duration (1200ms); token only: no text swap in the kit</span>
|
|
748
|
+
</div>
|
|
749
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-text-duration); --mo-e: var(--ws-spring-text);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
750
|
+
</div></article>
|
|
751
|
+
<article class="ws-card" aria-label="Nav count badge pop (no label, js@778124)"><div class="ws-head">
|
|
752
|
+
<div class="ws-stack ws-stack--tight">
|
|
753
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Nav count badge pop (no label, js@778124)</span></span>
|
|
754
|
+
<span class="ws-meta">North: badge: spring visualDuration / bounce .3 / .4</span>
|
|
755
|
+
<span class="ws-meta">Kit: --ws-spring-badge over --ws-spring-badge-duration (650ms); token only: no badge pops on change yet</span>
|
|
756
|
+
</div>
|
|
757
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-badge-duration); --mo-e: var(--ws-spring-badge);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
758
|
+
</div></article>
|
|
759
|
+
<article class="ws-card" aria-label="Pace dot on an opened square (no label, js@709765)"><div class="ws-head">
|
|
760
|
+
<div class="ws-stack ws-stack--tight">
|
|
761
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Pace dot on an opened square (no label, js@709765)</span></span>
|
|
762
|
+
<span class="ws-meta">North: mark: spring visualDuration / bounce .35 / .35</span>
|
|
763
|
+
<span class="ws-meta">Kit: --ws-spring-mark over --ws-spring-mark-duration (550ms); Heatmap open dot</span>
|
|
764
|
+
</div>
|
|
765
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-mark-duration); --mo-e: var(--ws-spring-mark);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
766
|
+
</div></article>
|
|
767
|
+
<article class="ws-card" aria-label="Agent orb arriving (no label, js@532276)"><div class="ws-head">
|
|
768
|
+
<div class="ws-stack ws-stack--tight">
|
|
769
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Agent orb arriving (no label, js@532276)</span></span>
|
|
770
|
+
<span class="ws-meta">North: orb: spring visualDuration / bounce .55 / .35</span>
|
|
771
|
+
<span class="ws-meta">Kit: --ws-spring-orb over --ws-spring-orb-duration (850ms); token only: no agent orb in the kit</span>
|
|
772
|
+
</div>
|
|
773
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-orb-duration); --mo-e: var(--ws-spring-orb);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
774
|
+
</div></article>
|
|
775
|
+
<article class="ws-card" aria-label="Anything not tuned (the ie() fallback)"><div class="ws-head">
|
|
776
|
+
<div class="ws-stack ws-stack--tight">
|
|
777
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Anything not tuned (the ie() fallback)</span></span>
|
|
778
|
+
<span class="ws-meta">North: ie(): spring visualDuration / bounce .4 / .15</span>
|
|
779
|
+
<span class="ws-meta">Kit: --ws-spring-default over --ws-spring-default-duration (750ms); the fallback for a new spring</span>
|
|
780
|
+
</div>
|
|
781
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-spring-default-duration); --mo-e: var(--ws-spring-default);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
782
|
+
</div></article>
|
|
783
|
+
<article class="ws-card" aria-label="Piano-key ticks"><div class="ws-head">
|
|
784
|
+
<div class="ws-stack ws-stack--tight">
|
|
785
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Piano-key ticks</span></span>
|
|
786
|
+
<span class="ws-meta">North: keys: stiffness 450, damping 22, a per-tick integrator, 23 px lift, gaussian neighbours 7 px</span>
|
|
787
|
+
<span class="ws-meta">Kit: not yet: coupled per-tick physics is not one curve; it needs a per-frame script, which the kit does not ship</span>
|
|
788
|
+
</div>
|
|
789
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
790
|
+
</div></article>
|
|
791
|
+
</div>
|
|
792
|
+
</section>
|
|
793
|
+
|
|
794
|
+
<section class="ws-stack" aria-labelledby="mo-hover">
|
|
795
|
+
<h2 class="ws-section" id="mo-hover">4. Hover</h2>
|
|
796
|
+
<p class="ws-muted">A hover is a colour change, never a lift. Point at each demo (or Tab to it: every hover reveal also opens on focus).</p>
|
|
797
|
+
<div class="ws-board">
|
|
798
|
+
<article class="ws-card" aria-label="Rows and actions tint"><div class="ws-head">
|
|
799
|
+
<div class="ws-stack ws-stack--tight">
|
|
800
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Rows and actions tint</span></span>
|
|
801
|
+
<span class="ws-meta">North: 200 ms: rows .03, popover rows .045, nav and menus .05, icon buttons and acts .06</span>
|
|
802
|
+
<span class="ws-meta">Kit: .ws-hover-tint (--faint 3%, default 5%, --strong 6%) over --ws-duration-hover; North's .045 rides on the default 5%</span>
|
|
803
|
+
</div>
|
|
804
|
+
<div class="ws-cluster"><span class="ws-stack ws-stack--tight"><span class="ws-row ws-hover-tint ws-hover-tint--faint">A list row (3%)</span><span class="ws-row ws-hover-tint">A nav or menu row (5%)</span><span class="ws-row ws-hover-tint ws-hover-tint--strong">An icon act (6%)</span></span></div>
|
|
805
|
+
</div></article>
|
|
806
|
+
<article class="ws-card" aria-label="Chips and outline buttons darken their edge"><div class="ws-head">
|
|
807
|
+
<div class="ws-stack ws-stack--tight">
|
|
808
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Chips and outline buttons darken their edge</span></span>
|
|
809
|
+
<span class="ws-meta">North: 0.5 px edge #d3d3d3 to #aaa49d over .2 s (css:80, 179)</span>
|
|
810
|
+
<span class="ws-meta">Kit: .ws-btn--secondary edge to --ws-edge-hover over --ws-duration-hover</span>
|
|
811
|
+
</div>
|
|
812
|
+
<div class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary">Point at me</button></div>
|
|
813
|
+
</div></article>
|
|
814
|
+
<article class="ws-card" aria-label="Cards: the frame darkens"><div class="ws-head">
|
|
815
|
+
<div class="ws-stack ws-stack--tight">
|
|
816
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Cards: the frame darkens</span></span>
|
|
817
|
+
<span class="ws-meta">North: well frame #ededed to #e4e2df over .25 s, no lift (css:268)</span>
|
|
818
|
+
<span class="ws-meta">Kit: a.ws-card / button.ws-card: the rim to --ws-well-hover over --ws-duration-hover (200 ms, not .25)</span>
|
|
819
|
+
</div>
|
|
820
|
+
<div class="ws-cluster"><button type="button" class="ws-card ws-card--pad-md" style="width: auto;"><span class="ws-row-name">Point at this card</span></button></div>
|
|
821
|
+
</div></article>
|
|
822
|
+
<article class="ws-card" aria-label="Navy buttons: a shade brighter, the light under the cursor"><div class="ws-head">
|
|
823
|
+
<div class="ws-stack ws-stack--tight">
|
|
824
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Navy buttons: a shade brighter, the light under the cursor</span></span>
|
|
825
|
+
<span class="ws-meta">North: #093555 to #0f4a73 over .2 s; a 90 px light rgba(255,255,255,.24) at the pointer, in over .25 s; no lift, no shadow (css:1430 to 1455)</span>
|
|
826
|
+
<span class="ws-meta">Kit: .ws-btn--primary hover; its ::before light sits at --mx / --my, which the page sets on pointermove (this demo does); without it the light sits in the middle. No helper is exported yet</span>
|
|
827
|
+
</div>
|
|
828
|
+
<div class="ws-cluster"><button type="button" class="ws-btn ws-btn--primary" id="mo-light-1" data-light>Point at me</button></div>
|
|
829
|
+
</div></article>
|
|
830
|
+
<article class="ws-card" aria-label="Shapes grow from the cursor"><div class="ws-head">
|
|
831
|
+
<div class="ws-stack ws-stack--tight">
|
|
832
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Shapes grow from the cursor</span></span>
|
|
833
|
+
<span class="ws-meta">North: the sidebar wash starts as an 18 px pill at the pointer's x, inset 5, and grows to the row over .5 s grow; leaves .25 s on exit (js@776115); "What to talk about" rows from 24 px, inset 8</span>
|
|
834
|
+
<span class="ws-meta">Kit: not yet: it needs the pointer's x when the hover starts (a tiny JS seed); kit rows take the tint at once (kit today, right)</span>
|
|
835
|
+
</div>
|
|
836
|
+
<div class="ws-cluster"><span class="ws-row ws-hover-tint">Pipeline</span></div>
|
|
837
|
+
</div></article>
|
|
838
|
+
<article class="ws-card" aria-label="Open arrows step forward"><div class="ws-head">
|
|
839
|
+
<div class="ws-stack ws-stack--tight">
|
|
840
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Open arrows step forward</span></span>
|
|
841
|
+
<span class="ws-meta">North: 2 px over .2 s (css:2076)</span>
|
|
842
|
+
<span class="ws-meta">Kit: ActionList --brief: the arrow 2 px over --ws-duration-hover</span>
|
|
843
|
+
</div>
|
|
844
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><ul class="ws-action-list ws-action-list--brief" id="mo-brief-2" aria-label="What changed" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><li class="ws-action-list__brief"><button type="button" class="ws-action-list__main"><span class="ws-action-list__lead">Calls</span><span class="ws-action-list__gist" title="The team made 212 calls, 40 more than last week">The team made 212 calls, 40 more than last week</span><span class="ws-action-list__go">Open in chat <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8h10M9 4l4 4-4 4"/></svg></span></button><button type="button" class="ws-icon-btn ws-icon-btn--xs ws-action-list__dismiss" aria-label="Dismiss: Calls"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg></button></li></ul></div>
|
|
845
|
+
</div></article>
|
|
846
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="A category's arrow slides in"><div class="ws-head">
|
|
847
|
+
<div class="ws-stack ws-stack--tight">
|
|
848
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">A category's arrow slides in</span></span>
|
|
849
|
+
<span class="ws-meta">North: from -4 px; opacity .2 s ease, transform .3 s soft (css:849)</span>
|
|
850
|
+
<span class="ws-meta">Kit: Heatmap lane arrow: from --ws-nudge, opacity --ws-duration-hover ease, transform --ws-duration-settle (320 ms) soft</span>
|
|
851
|
+
</div>
|
|
852
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-stack" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><section class="ws-heatmap" id="mo-lanes-3" aria-label="Company health"><div class="ws-heatmap__scroll"><div class="ws-heatmap__grid ws-heatmap__grid--lanes" style="--lanes: 1; --rows: 3;"><button type="button" class="ws-heatmap__lane-head" aria-label="Sales, 78% of pace. Open its outcome"><span class="ws-heatmap__lane-title"><span title="Sales">Sales</span><svg class="ws-heatmap__go" viewBox="0 0 12 12" fill="none" aria-hidden="true"><path d="M2.5 6h7M6.5 3l3 3-3 3" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/></svg></span><span class="ws-heatmap__lane-bar"><span class="ws-pace-bar ws-pace-bar--thin" style="--value: 78%; --tone: var(--ws-chart-past-half);" aria-hidden="true"><span class="ws-pace-bar__fill"></span></span><b>78</b></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h3" aria-label="Sales: Revenue, $412K, 94% of pace"><span class="ws-heatmap__label">Revenue</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">$412K</span><span class="ws-heatmap__flag">94%</span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h2" data-lit aria-label="Sales: Calls, 312, 78% of pace"><span class="ws-heatmap__label">Calls</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">312</span><span class="ws-heatmap__flag">78%</span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h1" aria-label="Sales: Show rate, 41%, 62% of pace"><span class="ws-heatmap__label">Show rate</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">41%</span><span class="ws-heatmap__flag">62%</span></span></button></div></div></section></span></div>
|
|
853
|
+
</div></article>
|
|
854
|
+
<article class="ws-card" aria-label="A tile's corner arrow nudges in"><div class="ws-head">
|
|
855
|
+
<div class="ws-stack ws-stack--tight">
|
|
856
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">A tile's corner arrow nudges in</span></span>
|
|
857
|
+
<span class="ws-meta">North: x -4 to 0 on the text spring (.7 / .2)</span>
|
|
858
|
+
<span class="ws-meta">Kit: MetricTile arrow: from --ws-nudge over --ws-duration-settle soft (a timed curve, not the text spring)</span>
|
|
859
|
+
</div>
|
|
860
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span style="display: block; width: min(100%, var(--space-9xl) + var(--space-4xl));"><button type="button" class="ws-metric-tile" id="mo-metric-4" aria-label="Deals closed, 9, 2 more than last month. Open"><span class="ws-metric-tile__surface"><span class="ws-metric-tile__head"><span class="ws-metric-tile__label">Deals closed</span><svg class="ws-metric-tile__go" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11L11 5M11 5H6M11 5V10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span><span class="ws-metric-tile__value">9</span><span class="ws-metric-tile__preview" aria-hidden="true"><span class="ws-tick-strip ws-tick-strip--bar" style="--n: 12; --tone: var(--ws-chart-finished);"><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span></span></span></span><span class="ws-metric-tile__foot"><span>More than last month</span><b>2</b></span></button></span></div>
|
|
861
|
+
</div></article>
|
|
862
|
+
<article class="ws-card" aria-label="Inline link arrow"><div class="ws-head">
|
|
863
|
+
<div class="ws-stack ws-stack--tight">
|
|
864
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Inline link arrow</span></span>
|
|
865
|
+
<span class="ws-meta">North: translateX 3 px over .3 s soft (css:428)</span>
|
|
866
|
+
<span class="ws-meta">Kit: not yet: the kit link has no arrow</span>
|
|
867
|
+
</div>
|
|
868
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
869
|
+
</div></article>
|
|
870
|
+
<article class="ws-card" aria-label="Labels push out of icons"><div class="ws-head">
|
|
871
|
+
<div class="ws-stack ws-stack--tight">
|
|
872
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Labels push out of icons</span></span>
|
|
873
|
+
<span class="ws-meta">North: answer actions: width 0 to auto, margin 0 to 6 over .34 s grow; opacity .2 s after .05 s, out .1 s (js@621181)</span>
|
|
874
|
+
<span class="ws-meta">Kit: ChatTurn action labels: width and margin over --ws-duration-settle (320 ms) grow, opacity --ws-duration-hover after --ws-stagger-row (45 ms), out --ws-duration-exit (120 ms); also on focus and open</span>
|
|
875
|
+
</div>
|
|
876
|
+
<div class="ws-cluster"><div class="ws-chat-turn__acts"><button type="button" class="ws-chat-turn__action" aria-label="Copy"><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.5" stroke="currentColor" stroke-width="1.5"/><path d="M10.5 3.5v-.5A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v5A1.5 1.5 0 0 0 4 9.5h.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg><span class="ws-chat-turn__action-label">Copy</span></button><button type="button" class="ws-chat-turn__action" aria-label="Send to Google Chat"><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2.5 8l11-5-4 11-2-4.5z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg><span class="ws-chat-turn__action-label">Send to Google Chat</span></button></div></div>
|
|
877
|
+
</div></article>
|
|
878
|
+
<article class="ws-card" aria-label="Brief rows: "Open in chat" grows"><div class="ws-head">
|
|
879
|
+
<div class="ws-stack ws-stack--tight">
|
|
880
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Brief rows: "Open in chat" grows</span></span>
|
|
881
|
+
<span class="ws-meta">North: max-width 0 to 120 px over .32 s grow (css:2110)</span>
|
|
882
|
+
<span class="ws-meta">Kit: ActionList --brief: max-width over --ws-duration-settle on --ws-ease-grow</span>
|
|
883
|
+
</div>
|
|
884
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-brief-2" data-jump>Play it in Open arrows step forward</a></div>
|
|
885
|
+
</div></article>
|
|
886
|
+
<article class="ws-card" aria-label="Rows lift in place (brief only)"><div class="ws-head">
|
|
887
|
+
<div class="ws-stack ws-stack--tight">
|
|
888
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Rows lift in place (brief only)</span></span>
|
|
889
|
+
<span class="ws-meta">North: a Home "what changed" row goes white, scale(1.008) over .3 s soft, gains 0 6px 16px -12px rgba(9,53,85,.35) (css:2104)</span>
|
|
890
|
+
<span class="ws-meta">Kit: ActionList --brief goes white with a hairline, and does not scale or lift: the kit's rule is that rows never lift (D7)</span>
|
|
891
|
+
</div>
|
|
892
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-brief-2" data-jump>Play it in Open arrows step forward</a></div>
|
|
893
|
+
</div></article>
|
|
894
|
+
<article class="ws-card" aria-label="The North mark"><div class="ws-head">
|
|
895
|
+
<div class="ws-stack ws-stack--tight">
|
|
896
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The North mark</span></span>
|
|
897
|
+
<span class="ws-meta">North: spokes push up 1.2 px, 40 ms apart, 520 ms each on spoke; sun 1.4 px .45 s pop; chevron and needle .35 / .4 pop (css:1096)</span>
|
|
898
|
+
<span class="ws-meta">Kit: not yet: the North mark is North's logo, not a kit part</span>
|
|
899
|
+
</div>
|
|
900
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
901
|
+
</div></article>
|
|
902
|
+
<article class="ws-card" aria-label="Ask North label shimmer"><div class="ws-head">
|
|
903
|
+
<div class="ws-stack ws-stack--tight">
|
|
904
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Ask North label shimmer</span></span>
|
|
905
|
+
<span class="ws-meta">North: an overlay copy shimmers in brand blue over 6 s ambient, passes in 45% then rests; on in .15 s, off .4 s (css:1110)</span>
|
|
906
|
+
<span class="ws-meta">Kit: not yet: open question (ambient loops in every app or only North; the no-AI-colours ruling)</span>
|
|
907
|
+
</div>
|
|
908
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
909
|
+
</div></article>
|
|
910
|
+
<article class="ws-card" aria-label="Chart: the hovered column band slides"><div class="ws-head">
|
|
911
|
+
<div class="ws-stack ws-stack--tight">
|
|
912
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Chart: the hovered column band slides</span></span>
|
|
913
|
+
<span class="ws-meta">North: .32 s soft</span>
|
|
914
|
+
<span class="ws-meta">Kit: TrendLine __band over --ws-duration-settle on --ws-ease-soft (a wash behind a column; a dashed guide under a line's dot)</span>
|
|
915
|
+
</div>
|
|
916
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-play-chart-t" data-jump>Play it in Try it: the chart card</a></div>
|
|
917
|
+
</div></article>
|
|
918
|
+
<article class="ws-card" aria-label="Chart: the rest step back"><div class="ws-head">
|
|
919
|
+
<div class="ws-stack ws-stack--tight">
|
|
920
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Chart: the rest step back</span></span>
|
|
921
|
+
<span class="ws-meta">North: the others fade to .45 over .25 s; ticks and wedges to .3</span>
|
|
922
|
+
<span class="ws-meta">Kit: TickStrip --hover, Matrix and Table dim the rest to --ws-dim (.3) over --ws-duration-hover; the .45 column fade has no kit chart</span>
|
|
923
|
+
</div>
|
|
924
|
+
<div class="ws-cluster"><span class="ws-tick-strip ws-tick-strip--hover" id="mo-ticks-5" style="--n: 30; width: var(--space-9xl);" aria-hidden="true"><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span><span class="ws-tick-strip__tick"></span></span></div>
|
|
925
|
+
</div></article>
|
|
926
|
+
<article class="ws-card" aria-label="Chart: the hovered dot grows"><div class="ws-head">
|
|
927
|
+
<div class="ws-stack ws-stack--tight">
|
|
928
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Chart: the hovered dot grows</span></span>
|
|
929
|
+
<span class="ws-meta">North: transition: r .2 s</span>
|
|
930
|
+
<span class="ws-meta">Kit: TrendLine: the dot to 1.5x in a 12% halo over --ws-duration-hover; North's r 4.5 to 6.5 is 1.44x. Switch the chart card to Line, then point</span>
|
|
931
|
+
</div>
|
|
932
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-play-chart-t" data-jump>Play it in Try it: the chart card</a></div>
|
|
933
|
+
</div></article>
|
|
934
|
+
<article class="ws-card" aria-label="Ticks and ring wedges grow from their base"><div class="ws-head">
|
|
935
|
+
<div class="ws-stack ws-stack--tight">
|
|
936
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Ticks and ring wedges grow from their base</span></span>
|
|
937
|
+
<span class="ws-meta">North: scaleY(1.16) over .34 to .36 s lift, rippling 4 ms per tick from the one under the cursor (css:1216)</span>
|
|
938
|
+
<span class="ws-meta">Kit: TickStrip --hover: --ws-grow-scale (1.16) over --ws-duration-settle (320 ms) on --ws-ease-lift; its two neighbours rise half as far after --ws-ripple, the rest of the run does not ripple</span>
|
|
939
|
+
</div>
|
|
940
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-ticks-5" data-jump>Play it in Chart: the rest step back</a></div>
|
|
941
|
+
</div></article>
|
|
942
|
+
<article class="ws-card" aria-label="Scoreboard previews wake"><div class="ws-head">
|
|
943
|
+
<div class="ws-stack ws-stack--tight">
|
|
944
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Scoreboard previews wake</span></span>
|
|
945
|
+
<span class="ws-meta">North: grey to colour, fill and stroke .4 s ease (--wake, css:826)</span>
|
|
946
|
+
<span class="ws-meta">Kit: MetricTile preview: the grey filter lifts over --ws-duration-shrink (400 ms) ease, on hover and focus</span>
|
|
947
|
+
</div>
|
|
948
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-metric-4" data-jump>Play it in A tile's corner arrow nudges in</a></div>
|
|
949
|
+
</div></article>
|
|
950
|
+
<article class="ws-card" aria-label="Closed pinned previews stay grey"><div class="ws-head">
|
|
951
|
+
<div class="ws-stack ws-stack--tight">
|
|
952
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Closed pinned previews stay grey</span></span>
|
|
953
|
+
<span class="ws-meta">North: grayscale(1) contrast(.55) brightness(1.32), filter .3 s (css:1517)</span>
|
|
954
|
+
<span class="ws-meta">Kit: MetricTile preview: the same filter at rest; it turns over 400 ms, not .3</span>
|
|
955
|
+
</div>
|
|
956
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-metric-4" data-jump>Play it in A tile's corner arrow nudges in</a></div>
|
|
957
|
+
</div></article>
|
|
958
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="Linking: an agenda row lights its square"><div class="ws-head">
|
|
959
|
+
<div class="ws-stack ws-stack--tight">
|
|
960
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Linking: an agenda row lights its square</span></span>
|
|
961
|
+
<span class="ws-meta">North: the rest drop to .28 (heat) and .4 (rows) over .25 s soft (css:431)</span>
|
|
962
|
+
<span class="ws-meta">Kit: Heatmap --linking with __cell--lit: the rest dim to --ws-dim over --ws-duration-hover; the app sets the classes from its list (this demo's button does)</span>
|
|
963
|
+
</div>
|
|
964
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-stack" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-link="mo-lanes-6" style="align-self: flex-start;">Point at the Calls row of a list</button><section class="ws-heatmap" id="mo-lanes-6" aria-label="Company health"><div class="ws-heatmap__scroll"><div class="ws-heatmap__grid ws-heatmap__grid--lanes" style="--lanes: 1; --rows: 3;"><button type="button" class="ws-heatmap__lane-head" aria-label="Sales, 78% of pace. Open its outcome"><span class="ws-heatmap__lane-title"><span title="Sales">Sales</span><svg class="ws-heatmap__go" viewBox="0 0 12 12" fill="none" aria-hidden="true"><path d="M2.5 6h7M6.5 3l3 3-3 3" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/></svg></span><span class="ws-heatmap__lane-bar"><span class="ws-pace-bar ws-pace-bar--thin" style="--value: 78%; --tone: var(--ws-chart-past-half);" aria-hidden="true"><span class="ws-pace-bar__fill"></span></span><b>78</b></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h3" aria-label="Sales: Revenue, $412K, 94% of pace"><span class="ws-heatmap__label">Revenue</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">$412K</span><span class="ws-heatmap__flag">94%</span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h2" data-lit aria-label="Sales: Calls, 312, 78% of pace"><span class="ws-heatmap__label">Calls</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">312</span><span class="ws-heatmap__flag">78%</span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h1" aria-label="Sales: Show rate, 41%, 62% of pace"><span class="ws-heatmap__label">Show rate</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">41%</span><span class="ws-heatmap__flag">62%</span></span></button></div></div></section></span></div>
|
|
965
|
+
</div></article>
|
|
966
|
+
<article class="ws-card" aria-label="Hover intent: wait before a tile opens"><div class="ws-head">
|
|
967
|
+
<div class="ws-stack ws-stack--tight">
|
|
968
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Hover intent: wait before a tile opens</span></span>
|
|
969
|
+
<span class="ws-meta">North: 40 ms ("Wait before a tile opens", hoverIntent .04)</span>
|
|
970
|
+
<span class="ws-meta">Kit: --ws-hover-intent (Heatmap, Tooltip, Matrix)</span>
|
|
971
|
+
</div>
|
|
972
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-cluster ws-cluster--loose" id="mo-tooltip-10" style="width: 100%;"><span class="ws-tooltip ws-tooltip--note"><span class="ws-tooltip__tip" role="tooltip" id="mo-note-9">Asked by people who want to buy a home here.</span><button type="button" class="ws-tooltip__term" aria-describedby="mo-note-9">A buyer</button></span><span class="ws-tooltip"><span class="ws-tooltip__tip" role="tooltip" id="mo-tip-7">Search</span><button type="button" class="ws-icon-btn ws-icon-btn--outline" aria-labelledby="mo-tip-7"><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></button></span><span class="ws-tooltip"><span class="ws-tooltip__tip" role="tooltip" id="mo-tip-8">Refresh the audit</span><button type="button" class="ws-icon-btn ws-icon-btn--outline" aria-labelledby="mo-tip-8"><svg viewBox="0 0 16 16" fill="none"><path d="M13 8a5 5 0 1 1-1.5-3.5M13 3v2.5h-2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button></span></span></div>
|
|
973
|
+
</div></article>
|
|
974
|
+
<article class="ws-card" aria-label="A hover-opened tile closes after leaving"><div class="ws-head">
|
|
975
|
+
<div class="ws-stack ws-stack--tight">
|
|
976
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A hover-opened tile closes after leaving</span></span>
|
|
977
|
+
<span class="ws-meta">North: 60 ms (js@710784)</span>
|
|
978
|
+
<span class="ws-meta">Kit: --ws-hover-leave (Heatmap)</span>
|
|
979
|
+
</div>
|
|
980
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-heat-15" data-jump>Play it in A heatmap square grows open</a></div>
|
|
981
|
+
</div></article>
|
|
982
|
+
<article class="ws-card" aria-label="Grace: a chart tooltip stays after leaving"><div class="ws-head">
|
|
983
|
+
<div class="ws-stack ws-stack--tight">
|
|
984
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Grace: a chart tooltip stays after leaving</span></span>
|
|
985
|
+
<span class="ws-meta">North: 180 ms ("grace" .18)</span>
|
|
986
|
+
<span class="ws-meta">Kit: --ws-hover-grace: the token; the app keeps the timer (HoverCard's demo does)</span>
|
|
987
|
+
</div>
|
|
988
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-hovercard-30" data-jump>Play it in Chart tooltip pop</a></div>
|
|
989
|
+
</div></article>
|
|
990
|
+
<article class="ws-card" aria-label="Flyouts close after leaving"><div class="ws-head">
|
|
991
|
+
<div class="ws-stack ws-stack--tight">
|
|
992
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Flyouts close after leaving</span></span>
|
|
993
|
+
<span class="ws-meta">North: rail flyout 160 ms, topics index 140, Watching list 180 (js@779402, 630808, 675315)</span>
|
|
994
|
+
<span class="ws-meta">Kit: --ws-close-delay (160 ms): the token; no kit flyout uses it yet</span>
|
|
995
|
+
</div>
|
|
996
|
+
<div class="ws-cluster"><span class="ws-muted">A token: no part uses it yet</span></div>
|
|
997
|
+
</div></article>
|
|
998
|
+
<article class="ws-card" aria-label="A Watching row opens after"><div class="ws-head">
|
|
999
|
+
<div class="ws-stack ws-stack--tight">
|
|
1000
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A Watching row opens after</span></span>
|
|
1001
|
+
<span class="ws-meta">North: 110 ms (js@589137)</span>
|
|
1002
|
+
<span class="ws-meta">Kit: not yet: the kit has no Watching list</span>
|
|
1003
|
+
</div>
|
|
1004
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1005
|
+
</div></article>
|
|
1006
|
+
</div>
|
|
1007
|
+
</section>
|
|
1008
|
+
|
|
1009
|
+
<section class="ws-stack" aria-labelledby="mo-press">
|
|
1010
|
+
<h2 class="ws-section" id="mo-press">5. Press</h2>
|
|
1011
|
+
<p class="ws-muted">Press and hold each one: it gives under the press and springs back on the press spring.</p>
|
|
1012
|
+
<div class="ws-board">
|
|
1013
|
+
<article class="ws-card" aria-label="whileTap on buttons and chips"><div class="ws-head">
|
|
1014
|
+
<div class="ws-stack ws-stack--tight">
|
|
1015
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">whileTap on buttons and chips</span></span>
|
|
1016
|
+
<span class="ws-meta">North: scale .97 on the press spring (.2 / .3), back on the same spring (btn-pri, btn-sec, btn-out, sug, cc-btn, sync)</span>
|
|
1017
|
+
<span class="ws-meta">Kit: .ws-btn, .ws-icon-btn, .ws-suggestion-chip, a button .ws-chip, .ws-press: scale var(--ws-press-scale) over --ws-spring-press; link and text words, disabled and busy do not move</span>
|
|
1018
|
+
</div>
|
|
1019
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--primary">Assign</button><button type="button" class="ws-btn ws-btn--secondary">Not now</button><button type="button" class="ws-suggestion-chip"><span>Who called back?</span></button></span></div>
|
|
1020
|
+
</div></article>
|
|
1021
|
+
<article class="ws-card" aria-label="The round voice button"><div class="ws-head">
|
|
1022
|
+
<div class="ws-stack ws-stack--tight">
|
|
1023
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The round voice button</span></span>
|
|
1024
|
+
<span class="ws-meta">North: whileTap scale .94</span>
|
|
1025
|
+
<span class="ws-meta">Kit: --ws-press-scale-round on .ws-icon-btn--round, the composer's round act, .ws-press--round</span>
|
|
1026
|
+
</div>
|
|
1027
|
+
<div class="ws-cluster"><button type="button" class="ws-icon-btn ws-icon-btn--primary ws-icon-btn--round ws-icon-btn--lg" aria-label="Talk with Coach"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M3 6.5v3M5.5 4.5v7M8 2.5v11M10.5 4.5v7M13 6.5v3"/></svg></button></div>
|
|
1028
|
+
</div></article>
|
|
1029
|
+
<article class="ws-card" aria-label="The send button"><div class="ws-head">
|
|
1030
|
+
<div class="ws-stack ws-stack--tight">
|
|
1031
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The send button</span></span>
|
|
1032
|
+
<span class="ws-meta">North: whileTap scale .92</span>
|
|
1033
|
+
<span class="ws-meta">Kit: --ws-press-scale-send on .ws-press--send; the Composer's send act does not wear it yet, so it presses to .94</span>
|
|
1034
|
+
</div>
|
|
1035
|
+
<div class="ws-cluster"><button type="button" class="ws-icon-btn ws-icon-btn--primary ws-icon-btn--round ws-icon-btn--lg ws-press--send" aria-label="Send"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 13V3M4 7l4-4 4 4"/></svg></button></div>
|
|
1036
|
+
</div></article>
|
|
1037
|
+
<article class="ws-card" aria-label="The voice button grows on hover"><div class="ws-head">
|
|
1038
|
+
<div class="ws-stack ws-stack--tight">
|
|
1039
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The voice button grows on hover</span></span>
|
|
1040
|
+
<span class="ws-meta">North: whileHover scale 1.06</span>
|
|
1041
|
+
<span class="ws-meta">Kit: not yet: a kit hover is a tint, never a scale (D7)</span>
|
|
1042
|
+
</div>
|
|
1043
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1044
|
+
</div></article>
|
|
1045
|
+
<article class="ws-card" aria-label="The outline button lifts on hover"><div class="ws-head">
|
|
1046
|
+
<div class="ws-stack ws-stack--tight">
|
|
1047
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The outline button lifts on hover</span></span>
|
|
1048
|
+
<span class="ws-meta">North: whileHover y -1</span>
|
|
1049
|
+
<span class="ws-meta">Kit: not yet: Seth later took lifts off buttons ("no lift, no shadow", css:1455); the kit follows that</span>
|
|
1050
|
+
</div>
|
|
1051
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1052
|
+
</div></article>
|
|
1053
|
+
<article class="ws-card" aria-label="Footer controls sink"><div class="ws-head">
|
|
1054
|
+
<div class="ws-stack ws-stack--tight">
|
|
1055
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Footer controls sink</span></span>
|
|
1056
|
+
<span class="ws-meta">North: translateY(.5 px) and the drop shadow off on :active (css:1961)</span>
|
|
1057
|
+
<span class="ws-meta">Kit: not yet: the kit has no Google Chat footer control</span>
|
|
1058
|
+
</div>
|
|
1059
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1060
|
+
</div></article>
|
|
1061
|
+
<article class="ws-card" aria-label="Rows never press-scale"><div class="ws-head">
|
|
1062
|
+
<div class="ws-stack ws-stack--tight">
|
|
1063
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Rows never press-scale</span></span>
|
|
1064
|
+
<span class="ws-meta">North: sidebar, list and table rows: a tint only</span>
|
|
1065
|
+
<span class="ws-meta">Kit: kit rows (.ws-well-row, .ws-row, list rows) take --ws-surface-press at once and never scale</span>
|
|
1066
|
+
</div>
|
|
1067
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><ul class="ws-well" id="mo-well-11" aria-label="What to ask" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-6xl));"><li><button type="button" class="ws-well-row"><span class="ws-well-row__words"><span>Who should I call first?</span></span></button></li><li><button type="button" class="ws-well-row"><span class="ws-well-row__words"><span>Why did calls drop?</span></span></button></li></ul></div>
|
|
1068
|
+
</div></article>
|
|
1069
|
+
<article class="ws-card" aria-label="A star pops when switched on"><div class="ws-head">
|
|
1070
|
+
<div class="ws-stack ws-stack--tight">
|
|
1071
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A star pops when switched on</span></span>
|
|
1072
|
+
<span class="ws-meta">North: scale [1, 1.28, 1] over .36 s soft (js@691457)</span>
|
|
1073
|
+
<span class="ws-meta">Kit: not yet: the kit has no pin or star control</span>
|
|
1074
|
+
</div>
|
|
1075
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1076
|
+
</div></article>
|
|
1077
|
+
</div>
|
|
1078
|
+
</section>
|
|
1079
|
+
|
|
1080
|
+
<section class="ws-stack" aria-labelledby="mo-focus">
|
|
1081
|
+
<h2 class="ws-section" id="mo-focus">6. Focus</h2>
|
|
1082
|
+
<p class="ws-muted">Tab through this group: the ring is the 2 px navy outline, 2 px out (D8).</p>
|
|
1083
|
+
<div class="ws-board">
|
|
1084
|
+
<article class="ws-card" aria-label="The global ring"><div class="ws-head">
|
|
1085
|
+
<div class="ws-stack ws-stack--tight">
|
|
1086
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The global ring</span></span>
|
|
1087
|
+
<span class="ws-meta">North: :focus-visible: 2 px navy outline, 2 px out, 4 px corners (css:17)</span>
|
|
1088
|
+
<span class="ws-meta">Kit: --ws-focus-width, --ws-focus-color, --ws-focus-offset on every kit element (D8)</span>
|
|
1089
|
+
</div>
|
|
1090
|
+
<div class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary">Tab to me</button></div>
|
|
1091
|
+
</div></article>
|
|
1092
|
+
<article class="ws-card" aria-label="Inside a dense row"><div class="ws-head">
|
|
1093
|
+
<div class="ws-stack ws-stack--tight">
|
|
1094
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Inside a dense row</span></span>
|
|
1095
|
+
<span class="ws-meta">North: rows draw focus inside themselves</span>
|
|
1096
|
+
<span class="ws-meta">Kit: the same ring drawn inside a menu, well or list row (outline-offset -2 px)</span>
|
|
1097
|
+
</div>
|
|
1098
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-well-11" data-jump>Play it in Rows never press-scale</a></div>
|
|
1099
|
+
</div></article>
|
|
1100
|
+
<article class="ws-card" aria-label="The heatmap square"><div class="ws-head">
|
|
1101
|
+
<div class="ws-stack ws-stack--tight">
|
|
1102
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The heatmap square</span></span>
|
|
1103
|
+
<span class="ws-meta">North: inset 3 px navy inside a 1 px paper gap (css:874)</span>
|
|
1104
|
+
<span class="ws-meta">Kit: Heatmap: a 2 px navy ring inside the 1 px paper gap (D8's width)</span>
|
|
1105
|
+
</div>
|
|
1106
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-heat-15" data-jump>Play it in A heatmap square grows open</a></div>
|
|
1107
|
+
</div></article>
|
|
1108
|
+
<article class="ws-card" aria-label="Hover reveals open on focus"><div class="ws-head">
|
|
1109
|
+
<div class="ws-stack ws-stack--tight">
|
|
1110
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Hover reveals open on focus</span></span>
|
|
1111
|
+
<span class="ws-meta">North: arrows, label push-out, section summary, flags, close marks and brief acts open on :focus-visible</span>
|
|
1112
|
+
<span class="ws-meta">Kit: ActionList brief, ChatTurn labels, Heatmap arrows and squares, MetricTile arrows all open on focus too</span>
|
|
1113
|
+
</div>
|
|
1114
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-brief-2" data-jump>Play it in Open arrows step forward</a></div>
|
|
1115
|
+
</div></article>
|
|
1116
|
+
<article class="ws-card" aria-label="Composer: the focus glow"><div class="ws-head">
|
|
1117
|
+
<div class="ws-stack ws-stack--tight">
|
|
1118
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Composer: the focus glow</span></span>
|
|
1119
|
+
<span class="ws-meta">North: spring glow (.3 / 0) to 0 4px 16px rgba(9,53,85,.07), the edge unchanged (css:2120)</span>
|
|
1120
|
+
<span class="ws-meta">Kit: Composer focus-within: a shade-7% shadow 4 / 16 on --ws-spring-glow; the placeholder rolls in it too (group 17)</span>
|
|
1121
|
+
</div>
|
|
1122
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div class="ws-composer" id="mo-composer-12" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><label class="ws-sr" for="mo-composer-12-words">Message Coach</label><span class="ws-composer__slot"><textarea id="mo-composer-12-words" class="ws-composer__words" rows="1" placeholder="Who should I call first?"></textarea><span class="ws-composer__roll" aria-hidden="true" data-roll id="mo-roll-13"><span>Who should I call first?</span><span>Why did calls drop?</span><span>Who needs a nudge?</span></span></span><div class="ws-composer__trail"><button type="button" class="ws-icon-btn ws-icon-btn--primary ws-icon-btn--lg" aria-label="Talk with Coach"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M3 6.5v3M5.5 4.5v7M8 2.5v11M10.5 4.5v7M13 6.5v3"/></svg></button></div></div></div>
|
|
1123
|
+
</div></article>
|
|
1124
|
+
<article class="ws-card" aria-label="The chat field keeps its edge"><div class="ws-head">
|
|
1125
|
+
<div class="ws-stack ws-stack--tight">
|
|
1126
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The chat field keeps its edge</span></span>
|
|
1127
|
+
<span class="ws-meta">North: "no highlight stroke on the chat field when it's active" (css:1408)</span>
|
|
1128
|
+
<span class="ws-meta">Kit: the field keeps its edge; a keyboard focus still draws the D8 ring</span>
|
|
1129
|
+
</div>
|
|
1130
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-composer-12" data-jump>Play it in Composer: the focus glow</a></div>
|
|
1131
|
+
</div></article>
|
|
1132
|
+
<article class="ws-card" aria-label="Focus shown only as a tint"><div class="ws-head">
|
|
1133
|
+
<div class="ws-stack ws-stack--tight">
|
|
1134
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Focus shown only as a tint</span></span>
|
|
1135
|
+
<span class="ws-meta">North: some actions set outline: none on :focus-visible and show a .06 tint (css:1641, 1946, 1738)</span>
|
|
1136
|
+
<span class="ws-meta">Kit: not taken: that tint is far under 3:1 on cream, so the kit keeps the ring (D8)</span>
|
|
1137
|
+
</div>
|
|
1138
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1139
|
+
</div></article>
|
|
1140
|
+
</div>
|
|
1141
|
+
</section>
|
|
1142
|
+
|
|
1143
|
+
<section class="ws-stack" aria-labelledby="mo-open">
|
|
1144
|
+
<h2 class="ws-section" id="mo-open">7. Open and close</h2>
|
|
1145
|
+
<p class="ws-muted">Things grow out of where they were and go back the same way, faster; the frame lands first, its details settle after.</p>
|
|
1146
|
+
<div class="ws-board">
|
|
1147
|
+
<article class="ws-card" aria-label="A metric tile grows out of its slot"><div class="ws-head">
|
|
1148
|
+
<div class="ws-stack ws-stack--tight">
|
|
1149
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper</span><span class="ws-row-name">A metric tile grows out of its slot</span></span>
|
|
1150
|
+
<span class="ws-meta">North: top/left/width/height to the row over .55 s grow, corners 8.75 to 12; the others fade .2 s; details .08 s later, .022 s apart; close .4 s grow (js@806504)</span>
|
|
1151
|
+
<span class="ws-meta">Kit: morph(update, { as: 'grow' | 'shrink', el }): the tile flies as itself on --ws-duration-grow / --ws-duration-shrink, the others step back; its type does not reshape in flight</span>
|
|
1152
|
+
</div>
|
|
1153
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div id="mo-tiles-14" data-morph-row style="display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-sm); width: min(100%, var(--ws-chart-card-w));"><button type="button" class="ws-card" aria-expanded="false" style="display: flex; flex-direction: column; align-items: flex-start; padding: var(--space-md); text-align: left;"><span class="ws-meta">Calls</span><span class="ws-section">42</span></button><button type="button" class="ws-card" aria-expanded="false" style="display: flex; flex-direction: column; align-items: flex-start; padding: var(--space-md); text-align: left;"><span class="ws-meta">Replies</span><span class="ws-section">17</span></button><button type="button" class="ws-card" aria-expanded="false" style="display: flex; flex-direction: column; align-items: flex-start; padding: var(--space-md); text-align: left;"><span class="ws-meta">Booked</span><span class="ws-section">5</span></button></div></div>
|
|
1154
|
+
</div></article>
|
|
1155
|
+
<article class="ws-card" aria-label="The closed tile's preview fades on open"><div class="ws-head">
|
|
1156
|
+
<div class="ws-stack ws-stack--tight">
|
|
1157
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The closed tile's preview fades on open</span></span>
|
|
1158
|
+
<span class="ws-meta">North: out .15 s on open, back .2 s after .12 s on close</span>
|
|
1159
|
+
<span class="ws-meta">Kit: not yet: MetricTile opens through the app's own view</span>
|
|
1160
|
+
</div>
|
|
1161
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1162
|
+
</div></article>
|
|
1163
|
+
<article class="ws-card" aria-label="An unmounting tile shrinks away"><div class="ws-head">
|
|
1164
|
+
<div class="ws-stack ws-stack--tight">
|
|
1165
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">An unmounting tile shrinks away</span></span>
|
|
1166
|
+
<span class="ws-meta">North: scale .94, fade .22 s on exit (js@807068)</span>
|
|
1167
|
+
<span class="ws-meta">Kit: not yet: no kit tile unmounts with an exit</span>
|
|
1168
|
+
</div>
|
|
1169
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1170
|
+
</div></article>
|
|
1171
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="A heatmap square grows open"><div class="ws-head">
|
|
1172
|
+
<div class="ws-stack ws-stack--tight">
|
|
1173
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A heatmap square grows open</span></span>
|
|
1174
|
+
<span class="ws-meta">North: one cell to two on the tile spring (.26 / .06) after the 40 ms intent; the last row grows upward; closes 60 ms after leave, opacity out .12 after .06</span>
|
|
1175
|
+
<span class="ws-meta">Kit: .ws-heatmap__open on --ws-spring-tile, --ws-hover-intent, --ws-hover-leave, --ws-duration-exit; the grid never reflows</span>
|
|
1176
|
+
</div>
|
|
1177
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div id="mo-heat-15" style="min-width: 0; width: min(100%, 760px);"><section class="ws-heatmap" aria-labelledby="mo-heat-15-h"><header class="ws-heatmap__head"><h3 class="ws-section" id="mo-heat-15-h">Company health</h3></header><div class="ws-heatmap__scroll"><div class="ws-heatmap__grid" style="--cols: 4;"><div class="ws-heatmap__row"><div class="ws-heatmap__lane"><span class="ws-heatmap__lane-name"><b>Sales</b><small>91% of pace</small></span></div><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h3" aria-label="Sales: Revenue, $412K, 94% of pace"><span class="ws-heatmap__label">Revenue</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">$412K</span><span class="ws-heatmap__flag">94%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">94% of pace</span><span class="ws-pace-bar" style="--value: 62%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h1" aria-label="Sales: Calls, 312, 66% of pace"><span class="ws-heatmap__label">Calls</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">312</span><span class="ws-heatmap__flag">66%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">66% of pace</span><span class="ws-pace-bar" style="--value: 40%; --pace: 61%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h5" aria-label="Sales: Meetings, 58, 121% of pace"><span class="ws-heatmap__label">Meetings</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">58</span><span class="ws-heatmap__flag">121%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">121% of pace</span><span class="ws-pace-bar" style="--value: 80%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button></div><div class="ws-heatmap__row"><div class="ws-heatmap__lane"><span class="ws-heatmap__lane-name"><b>Marketing</b><small>78% of pace</small></span></div><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h2" aria-label="Marketing: Leads, 486, 71% of pace"><span class="ws-heatmap__label">Leads</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">486</span><span class="ws-heatmap__flag">71%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">71% of pace</span><span class="ws-pace-bar" style="--value: 47%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__gap"></span><span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--h4" aria-label="Marketing: Email opens, 44%, 101% of pace"><span class="ws-heatmap__label">Email opens</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">44%</span><span class="ws-heatmap__flag">101%</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">101% of pace</span><span class="ws-pace-bar" style="--value: 67%; --pace: 66%;"><span class="ws-pace-bar__fill"></span><span class="ws-pace-bar__cut" style="--at: 25%;"></span><span class="ws-pace-bar__cut" style="--at: 50%;"></span><span class="ws-pace-bar__cut" style="--at: 75%;"></span><span class="ws-pace-bar__dot"></span></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button><button type="button" class="ws-heatmap__cell ws-heatmap__cell--none" aria-label="Marketing: Reviews, 31, no target"><span class="ws-heatmap__label">Reviews</span><span class="ws-heatmap__foot"><span class="ws-heatmap__value">31</span><span class="ws-heatmap__flag">No target</span></span><span class="ws-heatmap__open" aria-hidden="true"><span class="ws-heatmap__share">No target set</span><span class="ws-pace-bar"></span><span class="ws-heatmap__door"><span>Open</span><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></span></span></button></div></div></div></section></div></div>
|
|
1178
|
+
</div></article>
|
|
1179
|
+
<article class="ws-card" aria-label="Its details settle in"><div class="ws-head">
|
|
1180
|
+
<div class="ws-stack ws-stack--tight">
|
|
1181
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Its details settle in</span></span>
|
|
1182
|
+
<span class="ws-meta">North: "Tile details settle in" .32 soft after .04 s, .035 s apart, from y 6</span>
|
|
1183
|
+
<span class="ws-meta">Kit: ws-heatmap-detail over --ws-duration-settle soft, --ws-stagger-square (35 ms)</span>
|
|
1184
|
+
</div>
|
|
1185
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-heat-15" data-jump>Play it in A heatmap square grows open</a></div>
|
|
1186
|
+
</div></article>
|
|
1187
|
+
<article class="ws-card" aria-label="Its pace bar fills, the pace dot pops"><div class="ws-head">
|
|
1188
|
+
<div class="ws-stack ws-stack--tight">
|
|
1189
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Its pace bar fills, the pace dot pops</span></span>
|
|
1190
|
+
<span class="ws-meta">North: width .7 s settle; the dot scale 0 to 1 on the mark spring (.35 / .35) .25 s later</span>
|
|
1191
|
+
<span class="ws-meta">Kit: ws-grow over --ws-duration-fill on --ws-ease-settle; the dot on --ws-spring-mark after --ws-duration-text</span>
|
|
1192
|
+
</div>
|
|
1193
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-heat-15" data-jump>Play it in A heatmap square grows open</a></div>
|
|
1194
|
+
</div></article>
|
|
1195
|
+
<article class="ws-card" aria-label="The opened square's look"><div class="ws-head">
|
|
1196
|
+
<div class="ws-stack ws-stack--tight">
|
|
1197
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The opened square's look</span></span>
|
|
1198
|
+
<span class="ws-meta">North: frame 0 to 1.09 px, heat to well .3 s, body to paper .32 s; label 13 to 20, value 24 to 52; lifted shadow</span>
|
|
1199
|
+
<span class="ws-meta">Kit: the open panel on paper with --ws-shadow-pop, the leaving curve on --ws-ease-exit; the words do not grow</span>
|
|
1200
|
+
</div>
|
|
1201
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-heat-15" data-jump>Play it in A heatmap square grows open</a></div>
|
|
1202
|
+
</div></article>
|
|
1203
|
+
<article class="ws-card" aria-label="The heatmap behind dims"><div class="ws-head">
|
|
1204
|
+
<div class="ws-stack ws-stack--tight">
|
|
1205
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The heatmap behind dims</span></span>
|
|
1206
|
+
<span class="ws-meta">North: rgba(250,250,251,.78) and blur(1.5 px), fading in after .08 s (.hx-dim, css:923)</span>
|
|
1207
|
+
<span class="ws-meta">Kit: not yet: the kit opens the square over its neighbours without a veil</span>
|
|
1208
|
+
</div>
|
|
1209
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1210
|
+
</div></article>
|
|
1211
|
+
<article class="ws-card" aria-label="A section opens in place (department lane)"><div class="ws-head">
|
|
1212
|
+
<div class="ws-stack ws-stack--tight">
|
|
1213
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A section opens in place (department lane)</span></span>
|
|
1214
|
+
<span class="ws-meta">North: height 0 to auto on the lane spring (.46 / .04), contents .36 s soft; the page scrolls it into view 380 ms later</span>
|
|
1215
|
+
<span class="ws-meta">Kit: not yet as a part: --ws-spring-lane is ready; no kit component has a lane detail (a Fold can wear it)</span>
|
|
1216
|
+
</div>
|
|
1217
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1218
|
+
</div></article>
|
|
1219
|
+
<article class="ws-card" aria-label="Sidebar sections open / close"><div class="ws-head">
|
|
1220
|
+
<div class="ws-stack ws-stack--tight">
|
|
1221
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Sidebar sections open / close</span></span>
|
|
1222
|
+
<span class="ws-meta">North: height 0 to auto + opacity on the fold spring (.32 / 0); the chevron turns 180 on it</span>
|
|
1223
|
+
<span class="ws-meta">Kit: every kit <details> (::details-content, interpolate-size) and .ws-unfold for a [hidden] body; .ws-fold__chevron on --ws-spring-fold</span>
|
|
1224
|
+
</div>
|
|
1225
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><details class="ws-card" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-8xl));"><summary class="ws-fold__summary ws-fold__summary--card"><svg class="ws-fold__chevron ws-fold__chevron--right" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6.6 5.2L9.4 8l-2.8 2.8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg><span class="ws-fold__title">Why this lead</span><span class="ws-muted">2 reasons</span></summary><div class="ws-fold__body--card"><p class="ws-body">Twelve years in the neighbourhood, referred by two agents already on the team.</p></div></details></div>
|
|
1226
|
+
</div></article>
|
|
1227
|
+
<article class="ws-card" aria-label="A fix row opens in place"><div class="ws-head">
|
|
1228
|
+
<div class="ws-stack ws-stack--tight">
|
|
1229
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A fix row opens in place</span></span>
|
|
1230
|
+
<span class="ws-meta">North: the same fold, chevron 180</span>
|
|
1231
|
+
<span class="ws-meta">Kit: .ws-check-row__detail.ws-unfold; .ws-check-row__chev on --ws-spring-fold</span>
|
|
1232
|
+
</div>
|
|
1233
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><ul class="ws-check-row" aria-label="Website fixes" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><li class="ws-check-row__fix"><div class="ws-check-row__line"><label class="ws-check"><input type="checkbox" aria-label="Done: Speed up the homepage on phones"><span class="ws-check__box" aria-hidden="true"><svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 6.25L4.75 8.5L9.5 3.75"/></svg></span></label><button type="button" class="ws-check-row__open" aria-expanded="false" aria-controls="mo-fix-16"><span class="ws-check-row__title">Speed up the homepage on phones</span><span class="ws-check-row__effort">A few days</span></button><button type="button" class="ws-btn ws-btn--well ws-check-row__act">Send to my web person</button><svg class="ws-check-row__chev" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6l4 4 4-4"/></svg></div><div class="ws-check-row__detail ws-unfold" id="mo-fix-16" hidden><p class="ws-body">Your homepage takes 6.2 seconds to show on a phone.</p></div></li></ul></div>
|
|
1234
|
+
</div></article>
|
|
1235
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="A chart card flies to full screen and back"><div class="ws-head">
|
|
1236
|
+
<div class="ws-stack ws-stack--tight">
|
|
1237
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper</span><span class="ws-row-name">A chart card flies to full screen and back</span></span>
|
|
1238
|
+
<span class="ws-meta">North: one element in flight over .45 s morph after 32 ms, corners 8 to 16; the parts below fade out .1 s, snap, fade back .32 s soft from 55% (css:1259 to 1505)</span>
|
|
1239
|
+
<span class="ws-meta">Kit: morph(update, { as: 'full', el }) and .ws-chat-card--full: the card flies as itself, words never scale; type, padding and chart height do not reshape in flight</span>
|
|
1240
|
+
</div>
|
|
1241
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div style="position: relative; contain: layout; width: min(100%, var(--ws-chart-card-w)); padding: var(--space-md); border-radius: var(--ws-radius-panel); background: var(--ws-frame);"><div class="ws-card ws-chat-card" id="mo-morph-17" data-morph-card><div class="ws-chat-card__head"><span class="ws-eyebrow">Chart</span><button type="button" class="ws-btn ws-btn--secondary" aria-pressed="false" data-morph-go>Full screen</button></div><p class="ws-title">Calls this week, by agent</p><p class="ws-body">Sam is three behind the team; Dana is on pace.</p><ul class="ws-chat-card__rows" aria-label="Calls this week"><li class="ws-chat-card__row"><span>Dana Okafor</span><b>12</b></li><li class="ws-chat-card__row"><span>Sam Rivera</span><b>4</b></li></ul></div></div></div>
|
|
1242
|
+
</div></article>
|
|
1243
|
+
<article class="ws-card" aria-label="The page behind fades"><div class="ws-head">
|
|
1244
|
+
<div class="ws-stack ws-stack--tight">
|
|
1245
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The page behind fades</span></span>
|
|
1246
|
+
<span class="ws-meta">North: .32 s soft</span>
|
|
1247
|
+
<span class="ws-meta">Kit: :root[data-ws-morph] old and new root over --ws-duration-settle soft</span>
|
|
1248
|
+
</div>
|
|
1249
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-morph-17" data-jump>Play it in A chart card flies to full screen and back</a></div>
|
|
1250
|
+
</div></article>
|
|
1251
|
+
<article class="ws-card" aria-label="Menus grow from their corner"><div class="ws-head">
|
|
1252
|
+
<div class="ws-stack ws-stack--tight">
|
|
1253
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Menus grow from their corner</span></span>
|
|
1254
|
+
<span class="ws-meta">North: from y -4, scale .97, origin its corner, on the settle spring (.32 / .1); exit .12 s (js@620042)</span>
|
|
1255
|
+
<span class="ws-meta">Kit: .ws-menu[popover]: @starting-style on --ws-spring-settle; leaving over --ws-duration-exit, display and overlay allow-discrete</span>
|
|
1256
|
+
</div>
|
|
1257
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary" popovertarget="mo-menu-18" aria-haspopup="menu">Sort</button><div id="mo-menu-18" class="ws-menu" popover role="menu" aria-label="Sort the list" style="width: 240px;"><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="true" popovertarget="mo-menu-18" popovertargetaction="hide">Needs you first<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false" popovertarget="mo-menu-18" popovertargetaction="hide">Newest first<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="ws-menu-item" role="menuitemradio" aria-checked="false" popovertarget="mo-menu-18" popovertargetaction="hide">Biggest deal first<svg class="ws-menu-item__tick" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button></div></span></div>
|
|
1258
|
+
</div></article>
|
|
1259
|
+
<article class="ws-card" aria-label="A menu that opens above grows from below"><div class="ws-head">
|
|
1260
|
+
<div class="ws-stack ws-stack--tight">
|
|
1261
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">A menu that opens above grows from below</span></span>
|
|
1262
|
+
<span class="ws-meta">North: origin and nudge toward the button when it opens up</span>
|
|
1263
|
+
<span class="ws-meta">Kit: the 4 px nudge rides on margin, which a native flip swaps; transform-origin stays top (position-try cannot set it); data-side="top" turns both for a JS-placed menu</span>
|
|
1264
|
+
</div>
|
|
1265
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-menu-18" data-jump>Play it in Menus grow from their corner</a></div>
|
|
1266
|
+
</div></article>
|
|
1267
|
+
<article class="ws-card" aria-label="Pickers and popovers"><div class="ws-head">
|
|
1268
|
+
<div class="ws-stack ws-stack--tight">
|
|
1269
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Pickers and popovers</span></span>
|
|
1270
|
+
<span class="ws-meta">North: from y 4 or -4 by side, scale .97, settle spring; exit .1 to .12 s (js@556550)</span>
|
|
1271
|
+
<span class="ws-meta">Kit: .ws-popover[popover] on --ws-spring-settle; --above and data-side="top" flip it; leaving --ws-duration-exit</span>
|
|
1272
|
+
</div>
|
|
1273
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary" popovertarget="mo-pop-20" aria-haspopup="dialog">How it is scored</button><button type="button" class="ws-btn ws-btn--secondary" popovertarget="mo-pop-21" aria-haspopup="dialog">Above</button><div id="mo-pop-20" class="ws-popover" popover role="dialog" aria-labelledby="mo-pop-20-t"><p class="ws-popover__title" id="mo-pop-20-t">How the score is worked out</p><p class="ws-body">Each of the six checks counts the same.</p></div><div id="mo-pop-21" class="ws-popover ws-popover--above" popover role="dialog" aria-labelledby="mo-pop-21-t"><p class="ws-popover__title" id="mo-pop-21-t">Opened above its control</p><p class="ws-body">It grows up out of its bottom corner.</p></div></span></div>
|
|
1274
|
+
</div></article>
|
|
1275
|
+
<article class="ws-card" aria-label="Notes from their caret"><div class="ws-head">
|
|
1276
|
+
<div class="ws-stack ws-stack--tight">
|
|
1277
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Notes from their caret</span></span>
|
|
1278
|
+
<span class="ws-meta">North: ob-tip: from y 6, scale .97 over .4 s settle; exit y 4, .98, .14 s; origin at the caret (css:2020)</span>
|
|
1279
|
+
<span class="ws-meta">Kit: .ws-tooltip--note pops with its caret on --ws-spring-pop</span>
|
|
1280
|
+
</div>
|
|
1281
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-tooltip-10" data-jump>Play it in Hover intent: wait before a tile opens</a></div>
|
|
1282
|
+
</div></article>
|
|
1283
|
+
<article class="ws-card" aria-label="The Watching list"><div class="ws-head">
|
|
1284
|
+
<div class="ws-stack ws-stack--tight">
|
|
1285
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The Watching list</span></span>
|
|
1286
|
+
<span class="ws-meta">North: from y -4, scale .98, origin near its button (css:2036)</span>
|
|
1287
|
+
<span class="ws-meta">Kit: not yet: the kit has no Watching list (a Popover is its nearest)</span>
|
|
1288
|
+
</div>
|
|
1289
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1290
|
+
</div></article>
|
|
1291
|
+
<article class="ws-card" aria-label="The rail flyout"><div class="ws-head">
|
|
1292
|
+
<div class="ws-stack ws-stack--tight">
|
|
1293
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The rail flyout</span></span>
|
|
1294
|
+
<span class="ws-meta">North: from x -6, blur 3 on the text spring (js@780374)</span>
|
|
1295
|
+
<span class="ws-meta">Kit: not yet: the AppShell rail has no flyout</span>
|
|
1296
|
+
</div>
|
|
1297
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1298
|
+
</div></article>
|
|
1299
|
+
<article class="ws-card" aria-label="The topics panel"><div class="ws-head">
|
|
1300
|
+
<div class="ws-stack ws-stack--tight">
|
|
1301
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The topics panel</span></span>
|
|
1302
|
+
<span class="ws-meta">North: from x -8, blur 4 on the settle spring (js@631213)</span>
|
|
1303
|
+
<span class="ws-meta">Kit: TopicRail panel: from x -8 and a 3 px blur over --ws-duration-settle on --ws-ease-settle (a timed curve)</span>
|
|
1304
|
+
</div>
|
|
1305
|
+
<div class="ws-cluster"><span class="ws-muted">Live in the TopicRail card</span></div>
|
|
1306
|
+
</div></article>
|
|
1307
|
+
<article class="ws-card" aria-label="Dialog-like windows"><div class="ws-head">
|
|
1308
|
+
<div class="ws-stack ws-stack--tight">
|
|
1309
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Dialog-like windows</span></span>
|
|
1310
|
+
<span class="ws-meta">North: the scrim .2 s; the window from y 14, scale .98; exit y 8, .98 (js@540954)</span>
|
|
1311
|
+
<span class="ws-meta">Kit: dialog.ws-dialog: @starting-style on --ws-spring-settle; ::backdrop over --ws-duration-hover; leaving 120 ms on --ws-ease-exit</span>
|
|
1312
|
+
</div>
|
|
1313
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary" data-open-dialog="mo-dialog-22">Open the dialog</button><button type="button" class="ws-btn ws-btn--secondary" data-open-dialog="mo-drawer-23">Open the drawer</button></span><dialog id="mo-dialog-22" class="ws-dialog" aria-labelledby="mo-dialog-22-t" closedby="any" style="max-width: 420px;"><header class="ws-head"><div><h2 id="mo-dialog-22-t" class="ws-title">Assign this call</h2><p class="ws-body">Choose who calls them next.</p></div><button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" data-close-dialog><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button></header><div class="ws-dialog__content"><label class="ws-field"><span class="ws-label">Team member</span><input class="ws-input" value="Priya Nair" readonly></label></div><footer class="ws-band"><div class="ws-band__words"><p class="ws-band__how">Dana sees this in her chat.</p></div><div class="ws-dialog__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" data-close-dialog>Cancel</button><button type="button" class="ws-btn ws-btn--primary ws-btn--lg" data-close-dialog>Assign</button></div></footer></dialog><dialog id="mo-drawer-23" class="ws-dialog ws-dialog--drawer" aria-labelledby="mo-drawer-23-t" closedby="any"><header class="ws-head"><div><h2 id="mo-drawer-23-t" class="ws-title">Priya Nair</h2><p class="ws-body">A complicated sale, cold call.</p></div><button type="button" class="ws-icon-btn ws-dialog__close" aria-label="Close" data-close-dialog><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button></header><div class="ws-dialog__content"><p class="ws-body">Twelve years in the neighbourhood, referred by two agents on the team.</p></div><footer class="ws-band"><div class="ws-dialog__acts"><button type="button" class="ws-btn ws-btn--secondary ws-btn--lg" data-close-dialog>Not now</button><button type="button" class="ws-btn ws-btn--primary ws-btn--lg" data-close-dialog>Start the call</button></div></footer></dialog></div>
|
|
1314
|
+
</div></article>
|
|
1315
|
+
<article class="ws-card" aria-label="Opens grow, then details settle"><div class="ws-head">
|
|
1316
|
+
<div class="ws-stack ws-stack--tight">
|
|
1317
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Opens grow, then details settle</span></span>
|
|
1318
|
+
<span class="ws-meta">North: "Details settle in" .3 s soft after .08 s, rows from y 6 blur 3, .022 s apart</span>
|
|
1319
|
+
<span class="ws-meta">Kit: dialog.ws-dialog[open] > * on ws-settle (320 ms soft) after 80 ms, --ws-stagger-detail apart (sibling-index())</span>
|
|
1320
|
+
</div>
|
|
1321
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-dialog-22" data-jump>Play it in Dialog-like windows</a></div>
|
|
1322
|
+
</div></article>
|
|
1323
|
+
<article class="ws-card" aria-label="Card grows open / closes back (the drawer)"><div class="ws-head">
|
|
1324
|
+
<div class="ws-stack ws-stack--tight">
|
|
1325
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Card grows open / closes back (the drawer)</span></span>
|
|
1326
|
+
<span class="ws-meta">North: .55 s (.32, .72, 0, 1) / .4 s the same curve</span>
|
|
1327
|
+
<span class="ws-meta">Kit: dialog.ws-dialog--drawer in on --ws-duration-grow and out on --ws-duration-shrink, both --ws-ease-grow</span>
|
|
1328
|
+
</div>
|
|
1329
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-dialog-22" data-jump>Play it in Dialog-like windows</a></div>
|
|
1330
|
+
</div></article>
|
|
1331
|
+
</div>
|
|
1332
|
+
</section>
|
|
1333
|
+
|
|
1334
|
+
<section class="ws-stack" aria-labelledby="mo-panels">
|
|
1335
|
+
<h2 class="ws-section" id="mo-panels">8. Panels docking (the chat)</h2>
|
|
1336
|
+
<p class="ws-muted">The chat opens from the edge of its mode, moves between modes as itself and leaves faster than it came.</p>
|
|
1337
|
+
<div class="ws-board">
|
|
1338
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="The chat opens"><div class="ws-head">
|
|
1339
|
+
<div class="ws-stack ws-stack--tight">
|
|
1340
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The chat opens</span></span>
|
|
1341
|
+
<span class="ws-meta">North: opacity .2 s, scale .97 on the panel spring (.42 / .12), blur 8 to 0 over .24 s; origin by mode: bar 50% 0, dock 0 50%, float 50% 100%, full 50% 40%</span>
|
|
1342
|
+
<span class="ws-meta">Kit: .ws-chat-shell and .ws-panel: ws-*-fade (--ws-duration-hover), grow on --ws-spring-panel, unblur 240 ms (local raw); origins per mode (no float mode in the kit)</span>
|
|
1343
|
+
</div>
|
|
1344
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div id="mo-panel-24" data-panel style="position: relative; contain: layout; display: flex; width: 100%; height: 320px; padding: var(--space-lg); border-radius: var(--ws-radius-panel); background: var(--ws-page);"><button type="button" class="ws-btn ws-btn--secondary" style="align-self: flex-start;" data-panel-open>Website</button><template><aside class="ws-panel" aria-labelledby="mo-panel-24-t"><header class="ws-panel__head"><div class="ws-panel__heading"><div class="ws-panel__title-row"><h2 id="mo-panel-24-t" class="ws-title">Website</h2></div><p class="ws-body">How quickly your site answers a buyer on a phone.</p></div><button type="button" class="ws-icon-btn ws-panel__close" aria-label="Close Website" data-panel-close><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button></header><div class="ws-panel__body"><section class="ws-panel__section" aria-label="Score"><p class="ws-section">It loads in 2.1 s on a phone, quicker than most sites near you.</p></section></div></aside></template></div></div>
|
|
1345
|
+
</div></article>
|
|
1346
|
+
<article class="ws-card" aria-label="Its header fades in after it"><div class="ws-head">
|
|
1347
|
+
<div class="ws-stack ws-stack--tight">
|
|
1348
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Its header fades in after it</span></span>
|
|
1349
|
+
<span class="ws-meta">North: .25 s after .12 s</span>
|
|
1350
|
+
<span class="ws-meta">Kit: .ws-chat-shell__head over --ws-duration-text after 120 ms (local raw)</span>
|
|
1351
|
+
</div>
|
|
1352
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-chat-25" data-jump>Play it in Moves between full, dock and float</a></div>
|
|
1353
|
+
</div></article>
|
|
1354
|
+
<article class="ws-card" aria-label="The field focuses after it"><div class="ws-head">
|
|
1355
|
+
<div class="ws-stack ws-stack--tight">
|
|
1356
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The field focuses after it</span></span>
|
|
1357
|
+
<span class="ws-meta">North: 60 ms after</span>
|
|
1358
|
+
<span class="ws-meta">Kit: not yet: the app focuses the field; no helper</span>
|
|
1359
|
+
</div>
|
|
1360
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1361
|
+
</div></article>
|
|
1362
|
+
<article class="ws-card" aria-label="Change of mode (re-form)"><div class="ws-head">
|
|
1363
|
+
<div class="ws-stack ws-stack--tight">
|
|
1364
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Change of mode (re-form)</span></span>
|
|
1365
|
+
<span class="ws-meta">North: fade out .12 s (opacity 0, blur 6, scale .985); 130 ms later it re-appears at the new mode with the open</span>
|
|
1366
|
+
<span class="ws-meta">Kit: not yet: the kit moves modes by shift instead (next row)</span>
|
|
1367
|
+
</div>
|
|
1368
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1369
|
+
</div></article>
|
|
1370
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="Moves between full, dock and float"><div class="ws-head">
|
|
1371
|
+
<div class="ws-stack ws-stack--tight">
|
|
1372
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper</span><span class="ws-row-name">Moves between full, dock and float</span></span>
|
|
1373
|
+
<span class="ws-meta">North: left/top/width/height on shift .55 s, no fade (js@648700)</span>
|
|
1374
|
+
<span class="ws-meta">Kit: morph(update, { as: 'shift', el }): the shell moves as itself on --ws-duration-shift / --ws-ease-shift; the words ride at their own size; no float mode</span>
|
|
1375
|
+
</div>
|
|
1376
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div class="ws-chat-dock" id="mo-chat-25" data-chat style="width: 100%; height: 400px;"><aside class="ws-chat-shell ws-chat-shell--dock" aria-label="Chat with Coach"><header class="ws-chat-shell__head"><h2 class="ws-section">Coach</h2><span class="ws-muted ws-chat-shell__where" title="On Pipeline">On Pipeline</span><span class="ws-chat-shell__tools"><button type="button" class="ws-icon-btn ws-icon-btn--sm" aria-label="Full screen" title="Full screen" data-mode><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M9.5 2.5h4v4M6.5 13.5h-4v-4M13.5 2.5L9 7M2.5 13.5L7 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button><button type="button" class="ws-icon-btn ws-icon-btn--sm" aria-label="Close the chat" title="Close" data-close><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button></span></header><ol class="ws-chat-shell__thread" aria-label="Messages"><li class="ws-chat-turn ws-chat-turn--person"><p class="ws-chat-turn__bubble">Who should I call first today?</p></li><li class="ws-chat-turn ws-chat-turn--agent"><p class="ws-chat-turn__words">Priya Nair. Her offer runs out tonight and she asked for an answer by five.</p></li></ol><div class="ws-chat-shell__compose"><div class="ws-composer"><label class="ws-sr" for="mo-chat-25-words">Message Coach</label><textarea id="mo-chat-25-words" class="ws-composer__words" rows="1" placeholder="Message Coach"></textarea></div></div></aside><main class="ws-card ws-card--pad-md ws-stack"><h2 class="ws-title">Pipeline</h2><p class="ws-body">The page steps aside for the chat.</p><button type="button" class="ws-btn ws-btn--secondary" style="align-self: flex-start; display: none;" data-open>Open the chat</button></main></div></div>
|
|
1377
|
+
</div></article>
|
|
1378
|
+
<article class="ws-card" aria-label="Dock: the sidebar folds to its rail"><div class="ws-head">
|
|
1379
|
+
<div class="ws-stack ws-stack--tight">
|
|
1380
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Dock: the sidebar folds to its rail</span></span>
|
|
1381
|
+
<span class="ws-meta">North: width and grid columns .5 s soft then .55 s shift; labels fade .2 s (css:531, 1296)</span>
|
|
1382
|
+
<span class="ws-meta">Kit: AppShell nav width over --ws-duration-shift on --ws-ease-shift; names fade over --ws-duration-hover (shown here on the dot: the shell drops its nav under 960 px)</span>
|
|
1383
|
+
</div>
|
|
1384
|
+
<div class="ws-cluster"><span class="ws-cluster" data-curve style="--mo-d: var(--ws-duration-shift); --mo-e: var(--ws-ease-shift);"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm">Play</button><span class="ws-pace-bar" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-pace-bar__dot" style="left: calc(var(--h) / 2); transition: left var(--mo-d) var(--mo-e);"></span></span></span></div>
|
|
1385
|
+
</div></article>
|
|
1386
|
+
<article class="ws-card" aria-label="The page steps aside"><div class="ws-head">
|
|
1387
|
+
<div class="ws-stack ws-stack--tight">
|
|
1388
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The page steps aside</span></span>
|
|
1389
|
+
<span class="ws-meta">North: the docked chat takes room instead of covering the page</span>
|
|
1390
|
+
<span class="ws-meta">Kit: .ws-chat-shell--dock trades width over --ws-duration-shift on --ws-ease-shift</span>
|
|
1391
|
+
</div>
|
|
1392
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-chat-25" data-jump>Play it in Moves between full, dock and float</a></div>
|
|
1393
|
+
</div></article>
|
|
1394
|
+
<article class="ws-card" aria-label="Nothing moves while dragging the edge"><div class="ws-head">
|
|
1395
|
+
<div class="ws-stack ws-stack--tight">
|
|
1396
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Nothing moves while dragging the edge</span></span>
|
|
1397
|
+
<span class="ws-meta">North: a resize drag turns those transitions off (css:789)</span>
|
|
1398
|
+
<span class="ws-meta">Kit: .ws-chat-shell--resizing: transition none</span>
|
|
1399
|
+
</div>
|
|
1400
|
+
<div class="ws-cluster"><span class="ws-muted">Live in the ChatShell card</span></div>
|
|
1401
|
+
</div></article>
|
|
1402
|
+
<article class="ws-card" aria-label="Bar mode: the veil"><div class="ws-head">
|
|
1403
|
+
<div class="ws-stack ws-stack--tight">
|
|
1404
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Bar mode: the veil</span></span>
|
|
1405
|
+
<span class="ws-meta">North: rgba(236,240,244,.3) with blur(10 px) saturate(1.05), in .32 s soft (css:506)</span>
|
|
1406
|
+
<span class="ws-meta">Kit: .ws-chat-veil: --ws-veil with an 8 px blur (--ws-blur-panel), in over --ws-duration-settle soft</span>
|
|
1407
|
+
</div>
|
|
1408
|
+
<div class="ws-cluster"><span class="ws-muted">Live in the ChatShell card</span></div>
|
|
1409
|
+
</div></article>
|
|
1410
|
+
<article class="ws-card" aria-label="Home's ask field folds away; the band shrinks"><div class="ws-head">
|
|
1411
|
+
<div class="ws-stack ws-stack--tight">
|
|
1412
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Home's ask field folds away; the band shrinks</span></span>
|
|
1413
|
+
<span class="ws-meta">North: grid rows 1fr to 0fr .45 s soft, opacity .25, blur 4; band 232 to 118 px over .45 s soft (css:1205)</span>
|
|
1414
|
+
<span class="ws-meta">Kit: not yet: the kit has no Home band</span>
|
|
1415
|
+
</div>
|
|
1416
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1417
|
+
</div></article>
|
|
1418
|
+
<article class="ws-card" aria-label="The chat leaves"><div class="ws-head">
|
|
1419
|
+
<div class="ws-stack ws-stack--tight">
|
|
1420
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The chat leaves</span></span>
|
|
1421
|
+
<span class="ws-meta">North: opacity 0, scale .97, blur 6 over .16 s</span>
|
|
1422
|
+
<span class="ws-meta">Kit: data-leaving: ws-chat-out / ws-panel-out over 160 ms (local raw) on --ws-ease-exit</span>
|
|
1423
|
+
</div>
|
|
1424
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-panel-24" data-jump>Play it in The chat opens</a></div>
|
|
1425
|
+
</div></article>
|
|
1426
|
+
<article class="ws-card" aria-label="Docking into the top bar on scroll"><div class="ws-head">
|
|
1427
|
+
<div class="ws-stack ws-stack--tight">
|
|
1428
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Docking into the top bar on scroll</span></span>
|
|
1429
|
+
<span class="ws-meta">North: the composer and filters fade into the top bar: opacity, y 3 to 0, blur 2 (.42 s and .28 s soft); crumbs leave y -3 blur 2</span>
|
|
1430
|
+
<span class="ws-meta">Kit: not yet: no kit bar docks on scroll</span>
|
|
1431
|
+
</div>
|
|
1432
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1433
|
+
</div></article>
|
|
1434
|
+
</div>
|
|
1435
|
+
</section>
|
|
1436
|
+
|
|
1437
|
+
<section class="ws-stack" aria-labelledby="mo-loading">
|
|
1438
|
+
<h2 class="ws-section" id="mo-loading">9. Loading, working and loops</h2>
|
|
1439
|
+
<p class="ws-muted">Every working signal says in words what it is doing; the shimmer passes in the chart colours over ghost shapes.</p>
|
|
1440
|
+
<div class="ws-board">
|
|
1441
|
+
<article class="ws-card" aria-label="Shimmer in chart colours"><div class="ws-head">
|
|
1442
|
+
<div class="ws-stack ws-stack--tight">
|
|
1443
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Shimmer in chart colours</span></span>
|
|
1444
|
+
<span class="ws-meta">North: text and blocks: a 100deg band of #f6ddd8, #e4dcf3, #d6eaea over #ece8e4, 300% wide, 1.8 s shimmer, infinite (css:1458)</span>
|
|
1445
|
+
<span class="ws-meta">Kit: .ws-skeleton, .ws-shimmer: --ws-shimmer over --ws-loop-shimmer on --ws-ease-shimmer; still ghost under reduced motion</span>
|
|
1446
|
+
</div>
|
|
1447
|
+
<div class="ws-cluster"><span class="ws-stack" style="width: var(--space-9xl);" aria-hidden="true"><span class="ws-skeleton ws-skeleton--title" style="width: 60%;"></span><span class="ws-skeleton ws-skeleton--line"></span><span class="ws-skeleton ws-skeleton--line" style="width: 66%;"></span></span></div>
|
|
1448
|
+
</div></article>
|
|
1449
|
+
<article class="ws-card" aria-label="Empty chart shapes take the colour band"><div class="ws-head">
|
|
1450
|
+
<div class="ws-stack ws-stack--tight">
|
|
1451
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Empty chart shapes take the colour band</span></span>
|
|
1452
|
+
<span class="ws-meta">North: #e3dfdb shapes, a coral, purple, teal band at mix-blend color, .85, the same 1.8 s</span>
|
|
1453
|
+
<span class="ws-meta">Kit: .ws-skeleton__chart</span>
|
|
1454
|
+
</div>
|
|
1455
|
+
<div class="ws-cluster"><span class="ws-skeleton__chart" style="width: var(--space-9xl);" aria-hidden="true"><i style="height: 35%;"></i><i style="height: 60%;"></i><i style="height: 45%;"></i><i style="height: 75%;"></i><i style="height: 55%;"></i><i style="height: 90%;"></i><i style="height: 70%;"></i><i style="height: 50%;"></i></span></div>
|
|
1456
|
+
</div></article>
|
|
1457
|
+
<article class="ws-card" aria-label="The status line"><div class="ws-head">
|
|
1458
|
+
<div class="ws-stack ws-stack--tight">
|
|
1459
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The status line</span></span>
|
|
1460
|
+
<span class="ws-meta">North: "North" 600 navy, what it is doing shimmering navy to coral to purple to teal over 1.6 s linear, the step in grey (css:1471)</span>
|
|
1461
|
+
<span class="ws-meta">Kit: .ws-status-line: __doing over --ws-loop-status on --ws-ease-steady</span>
|
|
1462
|
+
</div>
|
|
1463
|
+
<div class="ws-cluster"><p class="ws-status-line" role="status" id="mo-status-26" title="Coach: reading your calls, 12 of 40"><b class="ws-status-line__who">Coach</b><span class="ws-status-line__doing">Reading your calls</span><span class="ws-status-line__step">12 of 40</span></p></div>
|
|
1464
|
+
</div></article>
|
|
1465
|
+
<article class="ws-card" aria-label="Thinking steps"><div class="ws-head">
|
|
1466
|
+
<div class="ws-stack ws-stack--tight">
|
|
1467
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Thinking steps</span></span>
|
|
1468
|
+
<span class="ws-meta">North: each step .55 s, x1.6 when pending (js@612974); the row enters by height and leaves .18 s</span>
|
|
1469
|
+
<span class="ws-meta">Kit: the app paces the steps; the line settles in (ws-settle on --ws-ease-settle) rather than growing in height</span>
|
|
1470
|
+
</div>
|
|
1471
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-status-26" data-jump>Play it in The status line</a></div>
|
|
1472
|
+
</div></article>
|
|
1473
|
+
<article class="ws-card" aria-label="The load bar"><div class="ws-head">
|
|
1474
|
+
<div class="ws-stack ws-stack--tight">
|
|
1475
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The load bar</span></span>
|
|
1476
|
+
<span class="ws-meta">North: 3 px, max 260; navy fill scaleX .04 to .9 (85%) to .97 linear, forwards (css:1451)</span>
|
|
1477
|
+
<span class="ws-meta">Kit: .ws-load-bar: ws-load-fill over --ws-load-for (default --ws-duration-build) on --ws-ease-steady; a known share eases on --ws-duration-fill settle</span>
|
|
1478
|
+
</div>
|
|
1479
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-stack" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-6xl));"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-load-27" aria-label="Replay the load bar">Replay</button><div class="ws-load-bar" id="mo-load-27"><p class="ws-load-bar__words"><span class="ws-load-bar__dot" aria-hidden="true"></span>Building the chart</p><span class="ws-load-bar__track" role="progressbar" aria-label="Building the chart"><span class="ws-load-bar__fill"></span></span></div></span></div>
|
|
1480
|
+
</div></article>
|
|
1481
|
+
<article class="ws-card" aria-label="The load dot"><div class="ws-head">
|
|
1482
|
+
<div class="ws-stack ws-stack--tight">
|
|
1483
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The load dot</span></span>
|
|
1484
|
+
<span class="ws-meta">North: coral 7 px, 1 s ease-in-out, opacity .35 to 1, scale .8 to 1</span>
|
|
1485
|
+
<span class="ws-meta">Kit: .ws-load-bar__dot over --ws-loop on --ws-ease-loop</span>
|
|
1486
|
+
</div>
|
|
1487
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-load-27" data-jump>Play it in The load bar</a></div>
|
|
1488
|
+
</div></article>
|
|
1489
|
+
<article class="ws-card" aria-label="An answer streams"><div class="ws-head">
|
|
1490
|
+
<div class="ws-stack ws-stack--tight">
|
|
1491
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">An answer streams</span></span>
|
|
1492
|
+
<span class="ws-meta">North: 2 words every 38 ms; an orb caret pulses 1 s</span>
|
|
1493
|
+
<span class="ws-meta">Kit: not yet: the app streams the words; the kit has no pacing helper or caret</span>
|
|
1494
|
+
</div>
|
|
1495
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1496
|
+
</div></article>
|
|
1497
|
+
<article class="ws-card" aria-label="Agent words arrive in colour"><div class="ws-head">
|
|
1498
|
+
<div class="ws-stack ws-stack--tight">
|
|
1499
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Agent words arrive in colour</span></span>
|
|
1500
|
+
<span class="ws-meta">North: one by one in the agent's colour with blur 4 and y 3, settling to #3d3d3d over .45 s + 650 ms (css:1927)</span>
|
|
1501
|
+
<span class="ws-meta">Kit: not yet: the kit has no agent word arrival</span>
|
|
1502
|
+
</div>
|
|
1503
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1504
|
+
</div></article>
|
|
1505
|
+
<article class="ws-card" aria-label="Typing dots"><div class="ws-head">
|
|
1506
|
+
<div class="ws-stack ws-stack--tight">
|
|
1507
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Typing dots</span></span>
|
|
1508
|
+
<span class="ws-meta">North: 5 px, 1 s ease-in-out, opacity .3 to 1 and y 0 to -2, 150 ms apart (css:1635)</span>
|
|
1509
|
+
<span class="ws-meta">Kit: .ws-chat-turn__dots: an opacity pulse over --ws-loop on --ws-ease-loop, 125 ms apart; no 2 px rise</span>
|
|
1510
|
+
</div>
|
|
1511
|
+
<div class="ws-cluster"><p class="ws-chat-turn__working" role="status" aria-label="Priya is typing"><span class="ws-chat-turn__dots" aria-hidden="true"><span></span><span></span><span></span></span><span class="ws-muted">Priya is typing</span></p></div>
|
|
1512
|
+
</div></article>
|
|
1513
|
+
<article class="ws-card" aria-label="Sending, then undo"><div class="ws-head">
|
|
1514
|
+
<div class="ws-stack ws-stack--tight">
|
|
1515
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Sending, then undo</span></span>
|
|
1516
|
+
<span class="ws-meta">North: a 2 px sweep .7 s commit, draining linear over the undo window; check draws .36 s commit after .08 s; sent dissolves .45 s</span>
|
|
1517
|
+
<span class="ws-meta">Kit: not yet: the kit has no send-and-undo part (--ws-ease-commit is ready)</span>
|
|
1518
|
+
</div>
|
|
1519
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1520
|
+
</div></article>
|
|
1521
|
+
<article class="ws-card" aria-label="Ambient loops"><div class="ws-head">
|
|
1522
|
+
<div class="ws-stack ws-stack--tight">
|
|
1523
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Ambient loops</span></span>
|
|
1524
|
+
<span class="ws-meta">North: glass sheen 6 s, aim ring 5.5 s, first-run hint edge 6 s, Ask North 6 s, orb turns 26 s and breathes 1.4 s, a keycap presses itself every 2.4 s</span>
|
|
1525
|
+
<span class="ws-meta">Kit: not yet: open question (do brand loops belong in every Fello app); --ws-loop-ambient and --ws-ease-ambient are ready</span>
|
|
1526
|
+
</div>
|
|
1527
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1528
|
+
</div></article>
|
|
1529
|
+
</div>
|
|
1530
|
+
</section>
|
|
1531
|
+
|
|
1532
|
+
<section class="ws-stack" aria-labelledby="mo-build">
|
|
1533
|
+
<h2 class="ws-section" id="mo-build">10. Number and chart build-ins</h2>
|
|
1534
|
+
<p class="ws-muted">A draw is one progress: each mark starts at its share of it and eases on its own. Replay plays a one-shot again.</p>
|
|
1535
|
+
<div class="ws-board">
|
|
1536
|
+
<article class="ws-card" aria-label="The Home intro timeline"><div class="ws-head">
|
|
1537
|
+
<div class="ws-stack ws-stack--tight">
|
|
1538
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The Home intro timeline</span></span>
|
|
1539
|
+
<span class="ws-meta">North: frame 0 to .8, greeting .12 to 1.02 (y -12, blur 8), ask bar .24, cards .4 to 1.75, bars .46 to 2.16, board chart to 3.75 s; reduced motion seeks to the end</span>
|
|
1540
|
+
<span class="ws-meta">Kit: .ws-build: the cards rise 70 ms apart (--ws-stagger-part) and each chart draws as its card lands, once, as it scrolls into view (a kit default, 5 Nov 2026); no 1.15 scale, and the greeting and the ask bar are the app's own</span>
|
|
1541
|
+
</div>
|
|
1542
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-build-home" data-jump>Play it in Try it: Replay the arrival</a></div>
|
|
1543
|
+
</div></article>
|
|
1544
|
+
<article class="ws-card" aria-label="Company health build-in"><div class="ws-head">
|
|
1545
|
+
<div class="ws-stack ws-stack--tight">
|
|
1546
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Company health build-in</span></span>
|
|
1547
|
+
<span class="ws-meta">North: squares fade from the centre to the corners (rows weighted 1.75) over 1.1 s after .15 s, each .9 s build-fade</span>
|
|
1548
|
+
<span class="ws-meta">Kit: Heatmap --build: each square over --ws-duration-draw on --ws-ease-steady after --ws-duration-hover + --i x 90 ms; the page sets --i (this demo by distance from the centre)</span>
|
|
1549
|
+
</div>
|
|
1550
|
+
<div class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-build-of="mo-heat-15">Replay the heatmap in group 7</button></div>
|
|
1551
|
+
</div></article>
|
|
1552
|
+
<article class="ws-card" aria-label="Category score bars"><div class="ws-head">
|
|
1553
|
+
<div class="ws-stack ws-stack--tight">
|
|
1554
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Category score bars</span></span>
|
|
1555
|
+
<span class="ws-meta">North: .55 s settle, .3 s after their names</span>
|
|
1556
|
+
<span class="ws-meta">Kit: not yet: Heatmap lane rings are drawn still</span>
|
|
1557
|
+
</div>
|
|
1558
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1559
|
+
</div></article>
|
|
1560
|
+
<article class="ws-card" aria-label="Squares do not ease on their own while the build runs"><div class="ws-head">
|
|
1561
|
+
<div class="ws-stack ws-stack--tight">
|
|
1562
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Squares do not ease on their own while the build runs</span></span>
|
|
1563
|
+
<span class="ws-meta">North: "a CSS lag on top makes each square ease on its own" (css:832)</span>
|
|
1564
|
+
<span class="ws-meta">Kit: not needed: the kit build is CSS keyframes, not a per-frame script, so nothing lags behind it</span>
|
|
1565
|
+
</div>
|
|
1566
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1567
|
+
</div></article>
|
|
1568
|
+
<article class="ws-card" aria-label="A chart draws as one progress"><div class="ws-head">
|
|
1569
|
+
<div class="ws-stack ws-stack--tight">
|
|
1570
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A chart draws as one progress</span></span>
|
|
1571
|
+
<span class="ws-meta">North: each bar or tick starts at its share (.55) of the draw and eases on settle; .9 s in a card</span>
|
|
1572
|
+
<span class="ws-meta">Kit: TrendBars and TickStrip --draw, and TrendLine on arrival: each mark over 45% of --ws-duration-draw on --ws-ease-settle, starting at 55% x i / (n - 1) of it</span>
|
|
1573
|
+
</div>
|
|
1574
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-draw-28" aria-label="Replay the draw">Replay</button><span id="mo-draw-28"><span class="ws-tick-strip ws-tick-strip--draw" style="--n: 40; width: var(--space-9xl);" aria-hidden="true"><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 0;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 1;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 2;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 3;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 4;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 5;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 6;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 7;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 8;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 9;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 10;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 11;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 12;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 13;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 14;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 15;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 16;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 17;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 18;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 19;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 20;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 21;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 22;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 23;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 24;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 25;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 26;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 27;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 28;"></span><span class="ws-tick-strip__tick ws-tick-strip__tick--on" style="--i: 29;"></span><span class="ws-tick-strip__tick" style="--i: 30;"></span><span class="ws-tick-strip__tick" style="--i: 31;"></span><span class="ws-tick-strip__tick" style="--i: 32;"></span><span class="ws-tick-strip__tick" style="--i: 33;"></span><span class="ws-tick-strip__tick" style="--i: 34;"></span><span class="ws-tick-strip__tick" style="--i: 35;"></span><span class="ws-tick-strip__tick" style="--i: 36;"></span><span class="ws-tick-strip__tick" style="--i: 37;"></span><span class="ws-tick-strip__tick" style="--i: 38;"></span><span class="ws-tick-strip__tick" style="--i: 39;"></span></span></span></span></div>
|
|
1575
|
+
</div></article>
|
|
1576
|
+
<article class="ws-card" aria-label="Values track the draw"><div class="ws-head">
|
|
1577
|
+
<div class="ws-stack ws-stack--tight">
|
|
1578
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Values track the draw</span></span>
|
|
1579
|
+
<span class="ws-meta">North: numbers written in the chart interpolate with the same progress (js@494911)</span>
|
|
1580
|
+
<span class="ws-meta">Kit: not yet: the kit draws its marks only; numbers in a chart land with it</span>
|
|
1581
|
+
</div>
|
|
1582
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1583
|
+
</div></article>
|
|
1584
|
+
<article class="ws-card" aria-label="Headline figures do not count up"><div class="ws-head">
|
|
1585
|
+
<div class="ws-stack ws-stack--tight">
|
|
1586
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Headline figures do not count up</span></span>
|
|
1587
|
+
<span class="ws-meta">North: static text; they reshape by font-size with their card (js@705406)</span>
|
|
1588
|
+
<span class="ws-meta">Kit: kit figures show their value and never count (13-motion)</span>
|
|
1589
|
+
</div>
|
|
1590
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1591
|
+
</div></article>
|
|
1592
|
+
<article class="ws-card" aria-label="The score gauge fills"><div class="ws-head">
|
|
1593
|
+
<div class="ws-stack ws-stack--tight">
|
|
1594
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The score gauge fills</span></span>
|
|
1595
|
+
<span class="ws-meta">North: the ring .9 s soft ("Score ring fill")</span>
|
|
1596
|
+
<span class="ws-meta">Kit: .ws-ring__value--draw over --ws-duration-draw soft</span>
|
|
1597
|
+
</div>
|
|
1598
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-ring-29" aria-label="Replay the ring">Replay</button><span id="mo-ring-29"><figure class="ws-ring" aria-label="72 percent"><span class="ws-ring__arc" aria-hidden="true"><svg width="48" height="48" viewBox="0 0 48 48"><circle class="ws-ring__track" cx="24" cy="24" r="21.5" stroke-width="5" /><circle class="ws-ring__value ws-ring__value--draw" cx="24" cy="24" r="21.5" stroke-width="5" stroke="var(--color-text-heading)" pathLength="1" stroke-dasharray="0.72 1" /></svg><span class="ws-ring__center ws-ring__center--sm">72%</span></span></figure></span></span></div>
|
|
1599
|
+
</div></article>
|
|
1600
|
+
<article class="ws-card" aria-label="Board chart swap"><div class="ws-head">
|
|
1601
|
+
<div class="ws-stack ws-stack--tight">
|
|
1602
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Board chart swap</span></span>
|
|
1603
|
+
<span class="ws-meta">North: old out y -slide x .6, .98, blur 4; new in from y +-14 by direction, ~1.09, blur 4; swap spring (.6 / .06), origin 50% 60%</span>
|
|
1604
|
+
<span class="ws-meta">Kit: not yet: --ws-spring-swap is ready; no kit chart swaps</span>
|
|
1605
|
+
</div>
|
|
1606
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1607
|
+
</div></article>
|
|
1608
|
+
<article class="ws-card" aria-label="Bars to line"><div class="ws-head">
|
|
1609
|
+
<div class="ws-stack ws-stack--tight">
|
|
1610
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Bars to line</span></span>
|
|
1611
|
+
<span class="ws-meta">North: the morph-chart spring (.85 / .06)</span>
|
|
1612
|
+
<span class="ws-meta">Kit: TrendLine --bars on --ws-spring-morph-chart; the columns collapse into their tops while the line and its area draw over --ws-duration-draw, the dots pop on what is left</span>
|
|
1613
|
+
</div>
|
|
1614
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-play-chart-t" data-jump>Play it in Try it: the chart card</a></div>
|
|
1615
|
+
</div></article>
|
|
1616
|
+
<article class="ws-card" aria-label="Lens switch"><div class="ws-head">
|
|
1617
|
+
<div class="ws-stack ws-stack--tight">
|
|
1618
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Lens switch</span></span>
|
|
1619
|
+
<span class="ws-meta">North: in from y 8, blur 4; out to y -6, blur 3; lens spring (.45 / .04)</span>
|
|
1620
|
+
<span class="ws-meta">Kit: not yet: --ws-spring-lens is ready; no kit tile has lenses</span>
|
|
1621
|
+
</div>
|
|
1622
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1623
|
+
</div></article>
|
|
1624
|
+
<article class="ws-card" aria-label="A nav count badge pops on change"><div class="ws-head">
|
|
1625
|
+
<div class="ws-stack ws-stack--tight">
|
|
1626
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A nav count badge pops on change</span></span>
|
|
1627
|
+
<span class="ws-meta">North: scale .6 to 1 on the badge spring (.3 / .4), re-keyed so it re-pops</span>
|
|
1628
|
+
<span class="ws-meta">Kit: not yet: --ws-spring-badge is ready; AppShell counts change at once</span>
|
|
1629
|
+
</div>
|
|
1630
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1631
|
+
</div></article>
|
|
1632
|
+
<article class="ws-card" aria-label="A topic header flashes when it gets news"><div class="ws-head">
|
|
1633
|
+
<div class="ws-stack ws-stack--tight">
|
|
1634
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A topic header flashes when it gets news</span></span>
|
|
1635
|
+
<span class="ws-meta">North: coral to navy over 1.2 s ease-out (css:624)</span>
|
|
1636
|
+
<span class="ws-meta">Kit: not yet: TopicRail heads do not flash</span>
|
|
1637
|
+
</div>
|
|
1638
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1639
|
+
</div></article>
|
|
1640
|
+
</div>
|
|
1641
|
+
</section>
|
|
1642
|
+
|
|
1643
|
+
<section class="ws-stack" aria-labelledby="mo-tips">
|
|
1644
|
+
<h2 class="ws-section" id="mo-tips">11. Tooltips and hover cards</h2>
|
|
1645
|
+
<p class="ws-muted">Tips pop out of their mark on the pop spring, follow without bouncing and leave over .12 s.</p>
|
|
1646
|
+
<div class="ws-board">
|
|
1647
|
+
<article class="ws-card" aria-label="Tooltip pop-in"><div class="ws-head">
|
|
1648
|
+
<div class="ws-stack ws-stack--tight">
|
|
1649
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tooltip pop-in</span></span>
|
|
1650
|
+
<span class="ws-meta">North: pop spring (.35 / .1) from scale .9 and y 4; fade off .18 s; 40 ms hover intent</span>
|
|
1651
|
+
<span class="ws-meta">Kit: .ws-tooltip__tip on --ws-spring-pop after --ws-hover-intent; out over --ws-tooltip-out on --ws-ease-exit</span>
|
|
1652
|
+
</div>
|
|
1653
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-tooltip-10" data-jump>Play it in Hover intent: wait before a tile opens</a></div>
|
|
1654
|
+
</div></article>
|
|
1655
|
+
<article class="ws-card" style="grid-column: 1 / -1;" aria-label="Chart tooltip pop"><div class="ws-head">
|
|
1656
|
+
<div class="ws-stack ws-stack--tight">
|
|
1657
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Chart tooltip pop</span></span>
|
|
1658
|
+
<span class="ws-meta">North: from .9 to .94, y 4 to 6 on pop; origin at the edge nearest its mark; exit .12 s to .94 to .96, y 4 (js@484880)</span>
|
|
1659
|
+
<span class="ws-meta">Kit: .ws-hover-card: ws-hover-card-in on --ws-spring-pop from .9 and --ws-rise; out .12 s to --ws-pop-scale and --ws-nudge; --start and --end move the origin</span>
|
|
1660
|
+
</div>
|
|
1661
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div id="mo-hovercard-30" data-hover-chart role="group" aria-label="Calls by week" style="position: relative; width: min(100%, var(--ws-chart-card-w)); height: 200px; border-bottom: var(--ws-line) solid var(--ws-edge-slot);"><span data-week="Week of 29 September" data-calls="18" data-answered="12" style="position: absolute; bottom: 0; left: 8%; width: 12%; height: 40%; border-radius: var(--ws-radius-bar) var(--ws-radius-bar) 0 0; background: var(--ws-chart-navy-fade);"></span><span data-week="Week of 6 October" data-calls="24" data-answered="17" style="position: absolute; bottom: 0; left: 30%; width: 12%; height: 54%; border-radius: var(--ws-radius-bar) var(--ws-radius-bar) 0 0; background: var(--ws-chart-navy-fade);"></span><span data-week="Week of 13 October" data-calls="15" data-answered="11" style="position: absolute; bottom: 0; left: 52%; width: 12%; height: 34%; border-radius: var(--ws-radius-bar) var(--ws-radius-bar) 0 0; background: var(--ws-chart-navy-fade);"></span><span data-week="Week of 20 October" data-calls="26" data-answered="19" style="position: absolute; bottom: 0; left: 74%; width: 12%; height: 60%; border-radius: var(--ws-radius-bar) var(--ws-radius-bar) 0 0; background: var(--color-text-heading);"></span></div></div>
|
|
1662
|
+
</div></article>
|
|
1663
|
+
<article class="ws-card" aria-label="It follows the pointer"><div class="ws-head">
|
|
1664
|
+
<div class="ws-stack ws-stack--tight">
|
|
1665
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">It follows the pointer</span></span>
|
|
1666
|
+
<span class="ws-meta">North: left/top on the follow spring (.22 / 0): it never bounces</span>
|
|
1667
|
+
<span class="ws-meta">Kit: .ws-hover-card--follow: left and top on --ws-spring-follow</span>
|
|
1668
|
+
</div>
|
|
1669
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-hovercard-30" data-jump>Play it in Chart tooltip pop</a></div>
|
|
1670
|
+
</div></article>
|
|
1671
|
+
<article class="ws-card" aria-label="Its rows settle in"><div class="ws-head">
|
|
1672
|
+
<div class="ws-stack ws-stack--tight">
|
|
1673
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Its rows settle in</span></span>
|
|
1674
|
+
<span class="ws-meta">North: 45 ms apart, each .32 s soft from y 5 and blur 2 (js@483244)</span>
|
|
1675
|
+
<span class="ws-meta">Kit: rows on ws-settle (320 ms soft), --ws-stagger-row apart, from the house settle (y 6, blur 3)</span>
|
|
1676
|
+
</div>
|
|
1677
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-hovercard-30" data-jump>Play it in Chart tooltip pop</a></div>
|
|
1678
|
+
</div></article>
|
|
1679
|
+
<article class="ws-card" aria-label="CSS hover cards on dots"><div class="ws-head">
|
|
1680
|
+
<div class="ws-stack ws-stack--tight">
|
|
1681
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">CSS hover cards on dots</span></span>
|
|
1682
|
+
<span class="ws-meta">North: .seg-tip and .mark-tip: opacity .18 s, from translateY(4 px) over .25 s soft (css:388)</span>
|
|
1683
|
+
<span class="ws-meta">Kit: kit tips pop on the pop spring instead (rows above)</span>
|
|
1684
|
+
</div>
|
|
1685
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-tooltip-10" data-jump>Play it in Hover intent: wait before a tile opens</a></div>
|
|
1686
|
+
</div></article>
|
|
1687
|
+
<article class="ws-card" aria-label="A description tip on a dotted label"><div class="ws-head">
|
|
1688
|
+
<div class="ws-stack ws-stack--tight">
|
|
1689
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">A description tip on a dotted label</span></span>
|
|
1690
|
+
<span class="ws-meta">North: from y 4 and blur 3 on pop, exit .12 s (js@813519)</span>
|
|
1691
|
+
<span class="ws-meta">Kit: .ws-tooltip--note on a .ws-tooltip__term: the pop spring, no blur</span>
|
|
1692
|
+
</div>
|
|
1693
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-tooltip-10" data-jump>Play it in Hover intent: wait before a tile opens</a></div>
|
|
1694
|
+
</div></article>
|
|
1695
|
+
</div>
|
|
1696
|
+
</section>
|
|
1697
|
+
|
|
1698
|
+
<section class="ws-stack" aria-labelledby="mo-stagger">
|
|
1699
|
+
<h2 class="ws-section" id="mo-stagger">12. Stagger</h2>
|
|
1700
|
+
<p class="ws-muted">Rows of new content arrive a few milliseconds apart, by role; marks inside a draw by their share of it. Replay runs each run again.</p>
|
|
1701
|
+
<div class="ws-board">
|
|
1702
|
+
<article class="ws-card" aria-label="Marks inside a draw: a share of it"><div class="ws-head">
|
|
1703
|
+
<div class="ws-stack ws-stack--tight">
|
|
1704
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Marks inside a draw: a share of it</span></span>
|
|
1705
|
+
<span class="ws-meta">North: item i of n starts at i / (n - 1) x share and runs over 1 - share; chart marks .55</span>
|
|
1706
|
+
<span class="ws-meta">Kit: TrendBars and TickStrip --draw (share .55 of --ws-duration-draw)</span>
|
|
1707
|
+
</div>
|
|
1708
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-draw-28" data-jump>Play it in A chart draws as one progress</a></div>
|
|
1709
|
+
</div></article>
|
|
1710
|
+
<article class="ws-card" aria-label="Metric cards and scoreboard cards"><div class="ws-head">
|
|
1711
|
+
<div class="ws-stack ws-stack--tight">
|
|
1712
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Metric cards and scoreboard cards</span></span>
|
|
1713
|
+
<span class="ws-meta">North: share .21 and .35 of the intro</span>
|
|
1714
|
+
<span class="ws-meta">Kit: .ws-build__card with --ws-i, 70 ms apart; a MetricTile --draw chart runs over 0.79 of --ws-duration-fill-page (North's .21 share); the goals and the chart card follow in reading order</span>
|
|
1715
|
+
</div>
|
|
1716
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-build-home" data-jump>Play it in Try it: Replay the arrival</a></div>
|
|
1717
|
+
</div></article>
|
|
1718
|
+
<article class="ws-card" aria-label="An opening tile's details"><div class="ws-head">
|
|
1719
|
+
<div class="ws-stack ws-stack--tight">
|
|
1720
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">An opening tile's details</span></span>
|
|
1721
|
+
<span class="ws-meta">North: 22 ms apart</span>
|
|
1722
|
+
<span class="ws-meta">Kit: --ws-stagger-detail (.ws-settle with --ws-i; Dialog)</span>
|
|
1723
|
+
</div>
|
|
1724
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-stagger-31" aria-label="Replay the run">Replay</button><span class="ws-cluster ws-cluster--tight" id="mo-stagger-31" aria-hidden="true"><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 0; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">1</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 1; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">2</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 2; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">3</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 3; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">4</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 4; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">5</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 5; animation-delay: calc(var(--ws-i) * var(--ws-stagger-detail));">6</span></span></span></div>
|
|
1725
|
+
</div></article>
|
|
1726
|
+
<article class="ws-card" aria-label="A list's first paint"><div class="ws-head">
|
|
1727
|
+
<div class="ws-stack ws-stack--tight">
|
|
1728
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A list's first paint</span></span>
|
|
1729
|
+
<span class="ws-meta">North: 30 ms apart (topics list)</span>
|
|
1730
|
+
<span class="ws-meta">Kit: --ws-stagger</span>
|
|
1731
|
+
</div>
|
|
1732
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-stagger-32" aria-label="Replay the run">Replay</button><span class="ws-cluster ws-cluster--tight" id="mo-stagger-32" aria-hidden="true"><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 0; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">1</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 1; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">2</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 2; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">3</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 3; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">4</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 4; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">5</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 5; animation-delay: calc(var(--ws-i) * var(--ws-stagger));">6</span></span></span></div>
|
|
1733
|
+
</div></article>
|
|
1734
|
+
<article class="ws-card" aria-label="A heatmap square's details"><div class="ws-head">
|
|
1735
|
+
<div class="ws-stack ws-stack--tight">
|
|
1736
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A heatmap square's details</span></span>
|
|
1737
|
+
<span class="ws-meta">North: 35 ms apart</span>
|
|
1738
|
+
<span class="ws-meta">Kit: --ws-stagger-square (Heatmap)</span>
|
|
1739
|
+
</div>
|
|
1740
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-stagger-33" aria-label="Replay the run">Replay</button><span class="ws-cluster ws-cluster--tight" id="mo-stagger-33" aria-hidden="true"><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 0; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">1</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 1; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">2</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 2; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">3</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 3; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">4</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 4; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">5</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 5; animation-delay: calc(var(--ws-i) * var(--ws-stagger-square));">6</span></span></span></div>
|
|
1741
|
+
</div></article>
|
|
1742
|
+
<article class="ws-card" aria-label="Answer actions, chat suggestions"><div class="ws-head">
|
|
1743
|
+
<div class="ws-stack ws-stack--tight">
|
|
1744
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Answer actions, chat suggestions</span></span>
|
|
1745
|
+
<span class="ws-meta">North: 40 ms apart, after .15 s and .1 s</span>
|
|
1746
|
+
<span class="ws-meta">Kit: not yet: no token for 40 ms</span>
|
|
1747
|
+
</div>
|
|
1748
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1749
|
+
</div></article>
|
|
1750
|
+
<article class="ws-card" aria-label="Tooltip rows, a full card's rows"><div class="ws-head">
|
|
1751
|
+
<div class="ws-stack ws-stack--tight">
|
|
1752
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tooltip rows, a full card's rows</span></span>
|
|
1753
|
+
<span class="ws-meta">North: 45 ms apart</span>
|
|
1754
|
+
<span class="ws-meta">Kit: --ws-stagger-row (HoverCard, GoalBars)</span>
|
|
1755
|
+
</div>
|
|
1756
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-stagger-34" aria-label="Replay the run">Replay</button><span class="ws-cluster ws-cluster--tight" id="mo-stagger-34" aria-hidden="true"><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 0; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">1</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 1; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">2</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 2; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">3</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 3; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">4</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 4; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">5</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 5; animation-delay: calc(var(--ws-i) * var(--ws-stagger-row));">6</span></span></span></div>
|
|
1757
|
+
</div></article>
|
|
1758
|
+
<article class="ws-card" aria-label="An empty chat, send tile parts"><div class="ws-head">
|
|
1759
|
+
<div class="ws-stack ws-stack--tight">
|
|
1760
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">An empty chat, send tile parts</span></span>
|
|
1761
|
+
<span class="ws-meta">North: 50 ms apart</span>
|
|
1762
|
+
<span class="ws-meta">Kit: not yet: no token for 50 ms</span>
|
|
1763
|
+
</div>
|
|
1764
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1765
|
+
</div></article>
|
|
1766
|
+
<article class="ws-card" aria-label="Blocks under a chart"><div class="ws-head">
|
|
1767
|
+
<div class="ws-stack ws-stack--tight">
|
|
1768
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Blocks under a chart</span></span>
|
|
1769
|
+
<span class="ws-meta">North: 70 ms apart</span>
|
|
1770
|
+
<span class="ws-meta">Kit: --ws-stagger-part (ShareBar)</span>
|
|
1771
|
+
</div>
|
|
1772
|
+
<div class="ws-cluster"><span class="ws-cluster"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-stagger-35" aria-label="Replay the run">Replay</button><span class="ws-cluster ws-cluster--tight" id="mo-stagger-35" aria-hidden="true"><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 0; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">1</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 1; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">2</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 2; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">3</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 3; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">4</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 4; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">5</span><span class="ws-chip ws-chip--sunk ws-settle" style="--ws-i: 5; animation-delay: calc(var(--ws-i) * var(--ws-stagger-part));">6</span></span></span></div>
|
|
1773
|
+
</div></article>
|
|
1774
|
+
<article class="ws-card" aria-label="A hover ripple"><div class="ws-head">
|
|
1775
|
+
<div class="ws-stack ws-stack--tight">
|
|
1776
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">A hover ripple</span></span>
|
|
1777
|
+
<span class="ws-meta">North: 4 ms per tick (12 ms per mini tick)</span>
|
|
1778
|
+
<span class="ws-meta">Kit: --ws-ripple (TickStrip, CheckRow); no 12 ms mini-tick token</span>
|
|
1779
|
+
</div>
|
|
1780
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-ticks-5" data-jump>Play it in Chart: the rest step back</a></div>
|
|
1781
|
+
</div></article>
|
|
1782
|
+
<article class="ws-card" aria-label="No stagger on a re-filter: rows glide"><div class="ws-head">
|
|
1783
|
+
<div class="ws-stack ws-stack--tight">
|
|
1784
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper</span><span class="ws-row-name">No stagger on a re-filter: rows glide</span></span>
|
|
1785
|
+
<span class="ws-meta">North: board rows reorder with layout: "position" on the reorder spring (.4 / 0) and plain opacity</span>
|
|
1786
|
+
<span class="ws-meta">Kit: reorder(update, within): a View Transition per row on --ws-spring-reorder; arriving and leaving rows fade (press Sort)</span>
|
|
1787
|
+
</div>
|
|
1788
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-stack" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-8xl));"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-sort="mo-reorder-36" style="align-self: flex-start;">Sort</button><section class="ws-card" aria-label="Tools"><ul class="ws-side-list__picks" id="mo-reorder-36"><li data-key="meta" data-figure="24000"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Meta Ads</span><span class="ws-side-list__sub">Paid ads</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$24,000</span></span></button></li><li data-key="zillow" data-figure="61000"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Zillow Premier Agent</span><span class="ws-side-list__sub">Referrals</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$61,000</span></span></button></li><li data-key="fub" data-figure="9600"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Follow Up Boss</span><span class="ws-side-list__sub">CRM</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$9,600</span></span></button></li><li data-key="canva" data-figure="1200"><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Canva</span><span class="ws-side-list__sub">Design</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$1,200</span></span></button></li></ul></section></span></div>
|
|
1789
|
+
</div></article>
|
|
1790
|
+
</div>
|
|
1791
|
+
</section>
|
|
1792
|
+
|
|
1793
|
+
<section class="ws-stack" aria-labelledby="mo-reduced">
|
|
1794
|
+
<h2 class="ws-section" id="mo-reduced">13. Reduced motion</h2>
|
|
1795
|
+
<p class="ws-muted">The kit closes North's gaps here: under prefers-reduced-motion everything is still (D7).</p>
|
|
1796
|
+
<div class="ws-board">
|
|
1797
|
+
<article class="ws-card" aria-label="Everything is still"><div class="ws-head">
|
|
1798
|
+
<div class="ws-stack ws-stack--tight">
|
|
1799
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Everything is still</span></span>
|
|
1800
|
+
<span class="ws-meta">North: North: transitions to .01 ms, some loops off; every motion-library spring, shimmer, typing dot and fade-in kept moving (css:250)</span>
|
|
1801
|
+
<span class="ws-meta">Kit: the house net under prefers-reduced-motion: reduce: every kit animation and transition .01 ms, no delays, one iteration; components also write their motion inside no-preference</span>
|
|
1802
|
+
</div>
|
|
1803
|
+
<div class="ws-cluster"><p class="ws-body" data-reduced-readout>This browser asks for full motion.</p></div>
|
|
1804
|
+
</div></article>
|
|
1805
|
+
<article class="ws-card" aria-label="Springs, morphs and helpers stand still"><div class="ws-head">
|
|
1806
|
+
<div class="ws-stack ws-stack--tight">
|
|
1807
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Springs, morphs and helpers stand still</span></span>
|
|
1808
|
+
<span class="ws-meta">North: no MotionConfig reducedMotion="user" in North</span>
|
|
1809
|
+
<span class="ws-meta">Kit: morph(), reorder() and rollPlaceholder() skip to the end state under reduce; the springs are CSS, so the net stills them</span>
|
|
1810
|
+
</div>
|
|
1811
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1812
|
+
</div></article>
|
|
1813
|
+
<article class="ws-card" aria-label="Draws show their final state"><div class="ws-head">
|
|
1814
|
+
<div class="ws-stack ws-stack--tight">
|
|
1815
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Draws show their final state</span></span>
|
|
1816
|
+
<span class="ws-meta">North: the intro seeks to its end; draws show final; a streamed answer shows whole; the placeholder holds</span>
|
|
1817
|
+
<span class="ws-meta">Kit: kit draws are animations, so they land at their end; rollPlaceholder holds the first line</span>
|
|
1818
|
+
</div>
|
|
1819
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1820
|
+
</div></article>
|
|
1821
|
+
<article class="ws-card" aria-label="Shimmers become still ghosts"><div class="ws-head">
|
|
1822
|
+
<div class="ws-stack ws-stack--tight">
|
|
1823
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Shimmers become still ghosts</span></span>
|
|
1824
|
+
<span class="ws-meta">North: North kept them moving</span>
|
|
1825
|
+
<span class="ws-meta">Kit: the shimmer stops on its ghost; a word says what is loading</span>
|
|
1826
|
+
</div>
|
|
1827
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1828
|
+
</div></article>
|
|
1829
|
+
</div>
|
|
1830
|
+
</section>
|
|
1831
|
+
|
|
1832
|
+
<section class="ws-stack" aria-labelledby="mo-never">
|
|
1833
|
+
<h2 class="ws-section" id="mo-never">14. What never moves</h2>
|
|
1834
|
+
<p class="ws-muted">Seth's explicit rules, each kept by the kit or not yet.</p>
|
|
1835
|
+
<div class="ws-board">
|
|
1836
|
+
<article class="ws-card" aria-label="Content below a chart never scales"><div class="ws-head">
|
|
1837
|
+
<div class="ws-stack ws-stack--tight">
|
|
1838
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Content below a chart never scales</span></span>
|
|
1839
|
+
<span class="ws-meta">North: it fades, snaps unseen, fades back (css:1485)</span>
|
|
1840
|
+
<span class="ws-meta">Kit: morph(): words ride at their own size and cross-fade at 55%</span>
|
|
1841
|
+
</div>
|
|
1842
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-morph-17" data-jump>Play it in A chart card flies to full screen and back</a></div>
|
|
1843
|
+
</div></article>
|
|
1844
|
+
<article class="ws-card" aria-label="The real label never changes colour on the Ask shimmer"><div class="ws-head">
|
|
1845
|
+
<div class="ws-stack ws-stack--tight">
|
|
1846
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">The real label never changes colour on the Ask shimmer</span></span>
|
|
1847
|
+
<span class="ws-meta">North: an overlay copy carries it (css:1110)</span>
|
|
1848
|
+
<span class="ws-meta">Kit: not yet: no Ask North shimmer in the kit</span>
|
|
1849
|
+
</div>
|
|
1850
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
1851
|
+
</div></article>
|
|
1852
|
+
<article class="ws-card" aria-label="No scrollbar while a card moves; a card in flight is not a size container"><div class="ws-head">
|
|
1853
|
+
<div class="ws-stack ws-stack--tight">
|
|
1854
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">No scrollbar while a card moves; a card in flight is not a size container</span></span>
|
|
1855
|
+
<span class="ws-meta">North: overflow: hidden while moving (css:1483), size container off (css:1272)</span>
|
|
1856
|
+
<span class="ws-meta">Kit: a morph flies a snapshot, so the live card never relayouts or scrolls in flight</span>
|
|
1857
|
+
</div>
|
|
1858
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-morph-17" data-jump>Play it in A chart card flies to full screen and back</a></div>
|
|
1859
|
+
</div></article>
|
|
1860
|
+
<article class="ws-card" aria-label="Nothing animates during a resize or a scroll reset"><div class="ws-head">
|
|
1861
|
+
<div class="ws-stack ws-stack--tight">
|
|
1862
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Nothing animates during a resize or a scroll reset</span></span>
|
|
1863
|
+
<span class="ws-meta">North: css:789, 1503</span>
|
|
1864
|
+
<span class="ws-meta">Kit: .ws-chat-shell--resizing; the kit has no scroll reset</span>
|
|
1865
|
+
</div>
|
|
1866
|
+
<div class="ws-cluster"><span class="ws-muted">A rule: nothing to play</span></div>
|
|
1867
|
+
</div></article>
|
|
1868
|
+
<article class="ws-card" aria-label="Buttons do not lift or cast a shadow on hover"><div class="ws-head">
|
|
1869
|
+
<div class="ws-stack ws-stack--tight">
|
|
1870
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Buttons do not lift or cast a shadow on hover</span></span>
|
|
1871
|
+
<span class="ws-meta">North: "no lift, no shadow, just a shade brighter and the light under the cursor" (css:1455)</span>
|
|
1872
|
+
<span class="ws-meta">Kit: every kit button: a tint only</span>
|
|
1873
|
+
</div>
|
|
1874
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-light-1" data-jump>Play it in Navy buttons: a shade brighter, the light under the cursor</a></div>
|
|
1875
|
+
</div></article>
|
|
1876
|
+
<article class="ws-card" aria-label="Rows do not scale on hover or press"><div class="ws-head">
|
|
1877
|
+
<div class="ws-stack ws-stack--tight">
|
|
1878
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Rows do not scale on hover or press</span></span>
|
|
1879
|
+
<span class="ws-meta">North: one exception: Home brief rows, 1.008</span>
|
|
1880
|
+
<span class="ws-meta">Kit: kit rows never scale, the brief rows included</span>
|
|
1881
|
+
</div>
|
|
1882
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-brief-2" data-jump>Play it in Open arrows step forward</a></div>
|
|
1883
|
+
</div></article>
|
|
1884
|
+
<article class="ws-card" aria-label="The chat field does not change its edge on focus"><div class="ws-head">
|
|
1885
|
+
<div class="ws-stack ws-stack--tight">
|
|
1886
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">The chat field does not change its edge on focus</span></span>
|
|
1887
|
+
<span class="ws-meta">North: css:1408</span>
|
|
1888
|
+
<span class="ws-meta">Kit: the edge stays; the D8 ring shows for the keyboard</span>
|
|
1889
|
+
</div>
|
|
1890
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-composer-12" data-jump>Play it in Composer: the focus glow</a></div>
|
|
1891
|
+
</div></article>
|
|
1892
|
+
<article class="ws-card" aria-label="A tooltip never bounces"><div class="ws-head">
|
|
1893
|
+
<div class="ws-stack ws-stack--tight">
|
|
1894
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A tooltip never bounces</span></span>
|
|
1895
|
+
<span class="ws-meta">North: follow bounce 0</span>
|
|
1896
|
+
<span class="ws-meta">Kit: --ws-spring-follow has no bounce</span>
|
|
1897
|
+
</div>
|
|
1898
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-hovercard-30" data-jump>Play it in Chart tooltip pop</a></div>
|
|
1899
|
+
</div></article>
|
|
1900
|
+
<article class="ws-card" aria-label="The segmented pill moves only on a real choice"><div class="ws-head">
|
|
1901
|
+
<div class="ws-stack ws-stack--tight">
|
|
1902
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">The segmented pill moves only on a real choice</span></span>
|
|
1903
|
+
<span class="ws-meta">North: not on a resize or a late font</span>
|
|
1904
|
+
<span class="ws-meta">Kit: Segmented: the thumb slides only while the track is pointed at or focused; otherwise it lands</span>
|
|
1905
|
+
</div>
|
|
1906
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-seg-37" data-jump>Play it in Segmented words</a></div>
|
|
1907
|
+
</div></article>
|
|
1908
|
+
<article class="ws-card" aria-label="Closed tile previews stay grey until opened or woken"><div class="ws-head">
|
|
1909
|
+
<div class="ws-stack ws-stack--tight">
|
|
1910
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Closed tile previews stay grey until opened or woken</span></span>
|
|
1911
|
+
<span class="ws-meta">North: css:1517</span>
|
|
1912
|
+
<span class="ws-meta">Kit: MetricTile preview</span>
|
|
1913
|
+
</div>
|
|
1914
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-metric-4" data-jump>Play it in A tile's corner arrow nudges in</a></div>
|
|
1915
|
+
</div></article>
|
|
1916
|
+
</div>
|
|
1917
|
+
</section>
|
|
1918
|
+
|
|
1919
|
+
<section class="ws-stack" aria-labelledby="mo-states">
|
|
1920
|
+
<h2 class="ws-section" id="mo-states">17. Interaction states not covered above</h2>
|
|
1921
|
+
<p class="ws-muted">The rest of North's state table (north-motion 17).</p>
|
|
1922
|
+
<div class="ws-board">
|
|
1923
|
+
<article class="ws-card" aria-label="Switch"><div class="ws-head">
|
|
1924
|
+
<div class="ws-stack ws-stack--tight">
|
|
1925
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Switch</span></span>
|
|
1926
|
+
<span class="ws-meta">North: track to navy .25 s soft; the 12 px thumb slides .3 s grow (css:2049)</span>
|
|
1927
|
+
<span class="ws-meta">Kit: .ws-switch: the track over --ws-duration-hover (200 ms) soft, the thumb over --ws-duration-settle (320 ms) grow</span>
|
|
1928
|
+
</div>
|
|
1929
|
+
<div class="ws-cluster"><label class="ws-switch"><input type="checkbox" role="switch"><span class="ws-switch__track"><span class="ws-switch__thumb"></span></span><span class="ws-switch__words"><span class="ws-switch__label">Text me a reminder</span></span></label></div>
|
|
1930
|
+
</div></article>
|
|
1931
|
+
<article class="ws-card" aria-label="Link underline grows"><div class="ws-head">
|
|
1932
|
+
<div class="ws-stack ws-stack--tight">
|
|
1933
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Link underline grows</span></span>
|
|
1934
|
+
<span class="ws-meta">North: a 1 px underline grows from the left over .35 s soft (css:132)</span>
|
|
1935
|
+
<span class="ws-meta">Kit: not yet: .ws-link underlines at once (a text-decoration cannot grow); --ws-duration-reveal is ready</span>
|
|
1936
|
+
</div>
|
|
1937
|
+
<div class="ws-cluster"><a class="ws-link" href="#" data-inert>Open the report</a></div>
|
|
1938
|
+
</div></article>
|
|
1939
|
+
<article class="ws-card" aria-label="Segmented words"><div class="ws-head">
|
|
1940
|
+
<div class="ws-stack ws-stack--tight">
|
|
1941
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Segmented words</span></span>
|
|
1942
|
+
<span class="ws-meta">North: colour .25 s (css:150)</span>
|
|
1943
|
+
<span class="ws-meta">Kit: Segmented item colour over --ws-duration-text soft</span>
|
|
1944
|
+
</div>
|
|
1945
|
+
<div class="ws-cluster"><div class="ws-segmented" role="group" aria-label="Call kind" id="mo-seg-37" data-choose><button type="button" class="ws-segmented__item" aria-pressed="true">Cold call</button><button type="button" class="ws-segmented__item" aria-pressed="false">Live transfer</button><button type="button" class="ws-segmented__item" aria-pressed="false">Follow-up</button></div></div>
|
|
1946
|
+
</div></article>
|
|
1947
|
+
<article class="ws-card" aria-label="Sidebar row: the white pill slides"><div class="ws-head">
|
|
1948
|
+
<div class="ws-stack ws-stack--tight">
|
|
1949
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Sidebar row: the white pill slides</span></span>
|
|
1950
|
+
<span class="ws-meta">North: layoutId nav-active on the nav spring (.4 / .1)</span>
|
|
1951
|
+
<span class="ws-meta">Kit: AppShell: a pill anchored to the current row (CSS anchor positioning) on --ws-spring-nav; group names stay above it</span>
|
|
1952
|
+
</div>
|
|
1953
|
+
<div class="ws-cluster"><div style="width: 232px; padding-block: var(--space-xs); border-radius: var(--ws-radius-card); background: var(--ws-frame);"><nav class="ws-app-shell__nav" aria-label="Demo nav" data-nav><div class="ws-app-shell__groups"><div class="ws-app-shell__group"><ul class="ws-app-shell__rows"><li><a href="#" class="ws-app-shell__row" data-inert><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg><span class="ws-app-shell__name">Home</span></a></li><li><a href="#" class="ws-app-shell__row" aria-current="page" data-inert><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg><span class="ws-app-shell__name">Pipeline</span></a></li><li><a href="#" class="ws-app-shell__row" data-inert><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg><span class="ws-app-shell__name">Leads</span></a></li></ul></div><div class="ws-app-shell__group"><h2 class="ws-app-shell__eyebrow">Reports</h2><ul class="ws-app-shell__rows"><li><a href="#" class="ws-app-shell__row" data-inert><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg><span class="ws-app-shell__name">Performance</span></a></li><li><a href="#" class="ws-app-shell__row" data-inert><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"/><path d="M2 6.5h12"/></svg><span class="ws-app-shell__name">Calls</span></a></li></ul></div></div></nav></div></div>
|
|
1954
|
+
</div></article>
|
|
1955
|
+
<article class="ws-card" aria-label="Tab underline slides"><div class="ws-head">
|
|
1956
|
+
<div class="ws-stack ws-stack--tight">
|
|
1957
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Tab underline slides</span></span>
|
|
1958
|
+
<span class="ws-meta">North: layoutId dcard-* on .4 / .12 (js@754407)</span>
|
|
1959
|
+
<span class="ws-meta">Kit: Tabs: an underline anchored to the selected tab on --ws-spring-tab</span>
|
|
1960
|
+
</div>
|
|
1961
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><div role="tablist" aria-label="Lead" class="ws-tabs" data-tabs style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><button type="button" role="tab" id="mo-tabs-38-0" aria-selected="true" class="ws-tabs__tab">Overview</button><button type="button" role="tab" id="mo-tabs-38-1" aria-selected="false" class="ws-tabs__tab" tabindex="-1">Activity</button><button type="button" role="tab" id="mo-tabs-38-2" aria-selected="false" class="ws-tabs__tab" tabindex="-1">Calls</button><button type="button" role="tab" id="mo-tabs-38-3" aria-selected="false" class="ws-tabs__tab" tabindex="-1">Notes</button></div></div>
|
|
1962
|
+
</div></article>
|
|
1963
|
+
<article class="ws-card" aria-label="Picker list: the fill slides"><div class="ws-head">
|
|
1964
|
+
<div class="ws-stack ws-stack--tight">
|
|
1965
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Picker list: the fill slides</span></span>
|
|
1966
|
+
<span class="ws-meta">North: layoutId board-sel on the highlight spring (.45 / .14)</span>
|
|
1967
|
+
<span class="ws-meta">Kit: SideList __picks: a tray fill anchored to the current pick on --ws-spring-highlight; the lines beside it fade 200 ms</span>
|
|
1968
|
+
</div>
|
|
1969
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><section class="ws-card" aria-label="Tools" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-8xl));"><ul class="ws-side-list__picks" data-pick><li><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);" aria-current="true"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Meta Ads</span><span class="ws-side-list__sub">Paid ads</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$24,000</span></span></button></li><li><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Zillow Premier Agent</span><span class="ws-side-list__sub">Paid ads</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$61,000</span></span></button></li><li><button type="button" class="ws-side-list__pick" style="--ws-dot: var(--ws-edge-card);"><span class="ws-side-list__dot" aria-hidden="true"></span><span class="ws-side-list__main"><span class="ws-side-list__pick-name">Follow Up Boss</span><span class="ws-side-list__sub">Paid ads</span></span><span class="ws-side-list__end"><span class="ws-side-list__figure">$9,600</span></span></button></li></ul></section></div>
|
|
1970
|
+
</div></article>
|
|
1971
|
+
<article class="ws-card" aria-label="Inbox rows: the fill slides and resizes"><div class="ws-head">
|
|
1972
|
+
<div class="ws-stack ws-stack--tight">
|
|
1973
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Inbox rows: the fill slides and resizes</span></span>
|
|
1974
|
+
<span class="ws-meta">North: the same spring; the fill grows to the new row's height</span>
|
|
1975
|
+
<span class="ws-meta">Kit: ListDetail rows: a sunk fill anchored to the current row on --ws-spring-highlight</span>
|
|
1976
|
+
</div>
|
|
1977
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><section class="ws-card" aria-label="Reviews" style="min-width: 0; width: min(100%, var(--space-9xl) + var(--space-8xl));"><ul class="ws-list-detail__rows" data-pick><li><button type="button" class="ws-list-detail__open" aria-current="true"><span class="ws-list-detail__meta"><span>Oct 29</span><span>Zillow</span></span><span class="ws-list-detail__text" title="Knew the market inside out and got us a great price.">Knew the market inside out and got us a great price.</span></button></li><li><button type="button" class="ws-list-detail__open"><span class="ws-list-detail__meta"><span>Oct 20</span><span>Zillow</span></span><span class="ws-list-detail__text" title="Quick to answer every call.">Quick to answer every call.</span></button></li><li><button type="button" class="ws-list-detail__open"><span class="ws-list-detail__meta"><span>Oct 12</span><span>Zillow</span></span><span class="ws-list-detail__text" title="Patient with a first-time buyer who asked a lot of questions, and found us the right street.">Patient with a first-time buyer who asked a lot of questions, and found us the right street.</span></button></li></ul></section></div>
|
|
1978
|
+
</div></article>
|
|
1979
|
+
<article class="ws-card" aria-label="Chart card arrives in the thread"><div class="ws-head">
|
|
1980
|
+
<div class="ws-stack ws-stack--tight">
|
|
1981
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--middle" style="min-width: var(--space-6xl); justify-content: center;">Close</span><span class="ws-row-name">Chart card arrives in the thread</span></span>
|
|
1982
|
+
<span class="ws-meta">North: the card spring (.5 / .08); its first pose is not in the files</span>
|
|
1983
|
+
<span class="ws-meta">Kit: .ws-chat-card.ws-settle on --ws-spring-card (the house settle pose: y 6, blur 3)</span>
|
|
1984
|
+
</div>
|
|
1985
|
+
<div class="ws-cluster" style="flex: 1 1 100%; min-width: 0;"><span class="ws-stack" style="min-width: 0; width: min(100%, var(--ws-chart-card-w));"><button type="button" class="ws-btn ws-btn--secondary ws-btn--sm" data-replay="mo-arrive-39" aria-label="Replay the card arriving">Replay</button><span id="mo-arrive-39"><span class="ws-card ws-chat-card ws-settle" style="display: block;"><span class="ws-title" style="display: block;">Calls this week, by agent</span><span class="ws-body" style="display: block;">Sam is three behind the team; Dana is on pace.</span></span></span></span></div>
|
|
1986
|
+
</div></article>
|
|
1987
|
+
<article class="ws-card" aria-label="Toast"><div class="ws-head">
|
|
1988
|
+
<div class="ws-stack ws-stack--tight">
|
|
1989
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">Toast</span></span>
|
|
1990
|
+
<span class="ws-meta">North: in from y 8, scale .96 on the settle spring; out opacity 0, y 4 (js@685658)</span>
|
|
1991
|
+
<span class="ws-meta">Kit: .ws-toast ws-toast-in on --ws-spring-settle; data-leaving over --ws-duration-exit</span>
|
|
1992
|
+
</div>
|
|
1993
|
+
<div class="ws-cluster"><span class="ws-stack"><button type="button" class="ws-btn ws-btn--secondary" data-toast="mo-toast-40" style="align-self: flex-start;">Save the draft</button><span class="ws-cluster" id="mo-toast-40" style="min-height: var(--space-2xl);" aria-live="polite"></span></span></div>
|
|
1994
|
+
</div></article>
|
|
1995
|
+
<article class="ws-card" aria-label="Placeholder roll"><div class="ws-head">
|
|
1996
|
+
<div class="ws-stack ws-stack--tight">
|
|
1997
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--accent" style="min-width: var(--space-6xl); justify-content: center;">JS helper</span><span class="ws-row-name">Placeholder roll</span></span>
|
|
1998
|
+
<span class="ws-meta">North: every 3.4 s: y 12 to 0 to -12, blur 3 on the roll spring (.45 / .05)</span>
|
|
1999
|
+
<span class="ws-meta">Kit: rollPlaceholder(roll, 3400) moves data-on; .ws-composer__roll on --ws-spring-roll with --ws-drop and --ws-blur-arrive</span>
|
|
2000
|
+
</div>
|
|
2001
|
+
<div class="ws-cluster"><a class="ws-link" href="#mo-composer-12" data-jump>Play it in Composer: the focus glow</a></div>
|
|
2002
|
+
</div></article>
|
|
2003
|
+
<article class="ws-card" aria-label="Listening: the voice bars loop"><div class="ws-head">
|
|
2004
|
+
<div class="ws-stack ws-stack--tight">
|
|
2005
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">Listening: the voice bars loop</span></span>
|
|
2006
|
+
<span class="ws-meta">North: scaleY [1, 1.6, .7, 1] over .9 s, 80 ms apart</span>
|
|
2007
|
+
<span class="ws-meta">Kit: not yet: the kit voice act has no listening state</span>
|
|
2008
|
+
</div>
|
|
2009
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
2010
|
+
</div></article>
|
|
2011
|
+
<article class="ws-card" aria-label="A card in Google Chat"><div class="ws-head">
|
|
2012
|
+
<div class="ws-stack ws-stack--tight">
|
|
2013
|
+
<span class="ws-cluster"><span class="ws-chip" style="min-width: var(--space-6xl); justify-content: center;">Not yet</span><span class="ws-row-name">A card in Google Chat</span></span>
|
|
2014
|
+
<span class="ws-meta">North: the inner snapshot scales .755 to .79 over .45 s soft on hover; no lift</span>
|
|
2015
|
+
<span class="ws-meta">Kit: not yet: the kit has no Google Chat card</span>
|
|
2016
|
+
</div>
|
|
2017
|
+
<div class="ws-cluster"><span class="ws-muted">Nothing to play yet</span></div>
|
|
2018
|
+
</div></article>
|
|
2019
|
+
<article class="ws-card" aria-label="A navy button still loading"><div class="ws-head">
|
|
2020
|
+
<div class="ws-stack ws-stack--tight">
|
|
2021
|
+
<span class="ws-cluster"><span class="ws-chip ws-chip--live" style="min-width: var(--space-6xl); justify-content: center;">Exact</span><span class="ws-row-name">A navy button still loading</span></span>
|
|
2022
|
+
<span class="ws-meta">North: a shimmer block 116 x 38, 6 px corners (cc-shim-btn)</span>
|
|
2023
|
+
<span class="ws-meta">Kit: .ws-skeleton--button</span>
|
|
2024
|
+
</div>
|
|
2025
|
+
<div class="ws-cluster"><span class="ws-skeleton ws-skeleton--button" aria-hidden="true"></span></div>
|
|
2026
|
+
</div></article>
|
|
2027
|
+
</div>
|
|
2028
|
+
</section>
|
|
2029
|
+
|
|
2030
|
+
</div>
|
|
2031
|
+
</details>
|
|
2032
|
+
</section>
|
|
2033
|
+
</div>
|
|
2034
|
+
<script>
|
|
2035
|
+
(() => {
|
|
2036
|
+
/* The demo's wiring. Everything that moves is the kit's CSS; this only flips states the way an app does (aria
|
|
2037
|
+
attributes, classes, a popover or a dialog) and plays the one-shots again. morph() and reorder() are copies of the
|
|
2038
|
+
kit's helpers (import { morph, reorder, rollPlaceholder } from '@felloinnovations/brand-kit'): a preview cannot
|
|
2039
|
+
import the package. */
|
|
2040
|
+
const root = document.documentElement;
|
|
2041
|
+
const reduced = () => matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
2042
|
+
const $$ = (sel, el = document) => [...el.querySelectorAll(sel)];
|
|
2043
|
+
|
|
2044
|
+
/* Slow everything down 4x (this page only): every --ws-* time token becomes its own value times --ws-motion-slow, set
|
|
2045
|
+
on <html>, so CSS springs, curves, delays, staggers and view transitions all stretch together. The few raws a
|
|
2046
|
+
component keeps for itself (the chat and panel exits, the tooltip fade, the dialog's wait) are stretched on their
|
|
2047
|
+
own elements. Script waits (a toast's stay, a panel's exit) use slow() too. */
|
|
2048
|
+
const TIME = /^-?\d*\.?\d+m?s$/;
|
|
2049
|
+
const tokens = {};
|
|
2050
|
+
const computed = getComputedStyle(root);
|
|
2051
|
+
const names = new Set();
|
|
2052
|
+
for (let i = 0; i < computed.length; i++) names.add(computed[i]);
|
|
2053
|
+
const walk = (rules) => { for (const r of rules) { if (r.style) for (const p of r.style) names.add(p); if (r.cssRules) walk(r.cssRules); } };
|
|
2054
|
+
for (const sheet of document.styleSheets) try { walk(sheet.cssRules); } catch { /* a sheet from another origin */ }
|
|
2055
|
+
for (const name of names) {
|
|
2056
|
+
const v = typeof name === 'string' && name.startsWith('--ws-') ? computed.getPropertyValue(name).trim() : '';
|
|
2057
|
+
if (TIME.test(v)) tokens[name] = v;
|
|
2058
|
+
}
|
|
2059
|
+
const LOCAL = { '.ws-chat-shell': ['--ws-chat-out', '--ws-chat-unblur', '--ws-chat-head-after'], '.ws-panel': ['--ws-panel-out', '--ws-panel-unblur'], 'dialog.ws-dialog': ['--ws-dialog-after'], '.ws-tooltip': ['--ws-tooltip-out'] };
|
|
2060
|
+
let factor = 1;
|
|
2061
|
+
const slow = (ms) => ms * factor;
|
|
2062
|
+
const toMs = (v) => (v.endsWith('ms') ? parseFloat(v) : parseFloat(v) * 1000);
|
|
2063
|
+
const stretch = (el, name, raw) => (factor === 1 ? el.style.removeProperty(name) : el.style.setProperty(name, `calc(${raw} * var(--ws-motion-slow))`));
|
|
2064
|
+
const raws = new WeakMap();
|
|
2065
|
+
const stretchLocals = (scope = document) => {
|
|
2066
|
+
for (const [sel, list] of Object.entries(LOCAL)) for (const el of $$(sel, scope)) {
|
|
2067
|
+
if (!raws.has(el)) raws.set(el, Object.fromEntries(list.map((name) => [name, getComputedStyle(el).getPropertyValue(name).trim()])));
|
|
2068
|
+
for (const [name, raw] of Object.entries(raws.get(el))) if (TIME.test(raw)) stretch(el, name, raw);
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
document.querySelector('[data-slow]')?.addEventListener('change', (e) => {
|
|
2072
|
+
factor = e.target.checked ? 4 : 1;
|
|
2073
|
+
factor === 1 ? root.style.removeProperty('--ws-motion-slow') : root.style.setProperty('--ws-motion-slow', String(factor));
|
|
2074
|
+
for (const [name, raw] of Object.entries(tokens)) stretch(root, name, raw);
|
|
2075
|
+
stretchLocals();
|
|
2076
|
+
startRolls();
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
/* Curves: Play sends the dot to the other end of its track. */
|
|
2080
|
+
for (const demo of $$('[data-curve]')) {
|
|
2081
|
+
const dot = demo.querySelector('.ws-pace-bar__dot');
|
|
2082
|
+
demo.querySelector('button').addEventListener('click', () => {
|
|
2083
|
+
const out = dot.toggleAttribute('data-out');
|
|
2084
|
+
dot.style.left = out ? 'calc(100% - var(--h) / 2)' : 'calc(var(--h) / 2)';
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
/* Replay a one-shot: a fresh copy of the part runs its animations again. */
|
|
2089
|
+
for (const b of $$('[data-replay]')) b.addEventListener('click', () => {
|
|
2090
|
+
const el = document.getElementById(b.dataset.replay);
|
|
2091
|
+
const copy = el.cloneNode(true);
|
|
2092
|
+
el.replaceWith(copy);
|
|
2093
|
+
});
|
|
2094
|
+
|
|
2095
|
+
/* A row that points at a demo elsewhere on the page. */
|
|
2096
|
+
for (const a of $$('[data-jump]')) a.addEventListener('click', (e) => {
|
|
2097
|
+
e.preventDefault();
|
|
2098
|
+
document.querySelector(a.getAttribute('href'))?.scrollIntoView({ block: 'center', behavior: reduced() ? 'auto' : 'smooth' });
|
|
2099
|
+
});
|
|
2100
|
+
document.addEventListener('click', (e) => { if (e.target.closest('a[data-inert]')) e.preventDefault(); });
|
|
2101
|
+
|
|
2102
|
+
/* The navy button's light sits under the pointer (the page sets --mx / --my). */
|
|
2103
|
+
for (const b of $$('[data-light]')) b.addEventListener('pointermove', (e) => {
|
|
2104
|
+
const r = b.getBoundingClientRect();
|
|
2105
|
+
b.style.setProperty('--mx', `${e.clientX - r.left}px`);
|
|
2106
|
+
b.style.setProperty('--my', `${e.clientY - r.top}px`);
|
|
2107
|
+
});
|
|
2108
|
+
|
|
2109
|
+
/* Choices: the app keeps them; the indicator slides on its own. */
|
|
2110
|
+
for (const seg of $$('[data-choose]')) seg.addEventListener('click', (e) => {
|
|
2111
|
+
const item = e.target.closest('.ws-segmented__item');
|
|
2112
|
+
if (item) for (const i of $$('.ws-segmented__item', seg)) i.setAttribute('aria-pressed', String(i === item));
|
|
2113
|
+
});
|
|
2114
|
+
for (const tabs of $$('[data-tabs]')) tabs.addEventListener('click', (e) => {
|
|
2115
|
+
const tab = e.target.closest('.ws-tabs__tab');
|
|
2116
|
+
if (tab) for (const t of $$('.ws-tabs__tab', tabs)) { t.setAttribute('aria-selected', String(t === tab)); t.tabIndex = t === tab ? 0 : -1; }
|
|
2117
|
+
});
|
|
2118
|
+
for (const nav of $$('[data-nav]')) nav.addEventListener('click', (e) => {
|
|
2119
|
+
const row = e.target.closest('.ws-app-shell__row');
|
|
2120
|
+
if (!row) return;
|
|
2121
|
+
e.preventDefault();
|
|
2122
|
+
for (const r of $$('.ws-app-shell__row', nav)) r === row ? r.setAttribute('aria-current', 'page') : r.removeAttribute('aria-current');
|
|
2123
|
+
});
|
|
2124
|
+
for (const list of $$('[data-pick]')) list.addEventListener('click', (e) => {
|
|
2125
|
+
const pick = e.target.closest('.ws-side-list__pick, .ws-list-detail__open');
|
|
2126
|
+
if (pick) for (const p of $$('.ws-side-list__pick, .ws-list-detail__open', list)) p === pick ? p.setAttribute('aria-current', 'true') : p.removeAttribute('aria-current');
|
|
2127
|
+
});
|
|
2128
|
+
|
|
2129
|
+
/* A fix row opens in place (aria-expanded on its button, hidden on its panel). */
|
|
2130
|
+
for (const b of $$('.ws-check-row__open[aria-controls]')) b.addEventListener('click', () => {
|
|
2131
|
+
const open = b.getAttribute('aria-expanded') !== 'true';
|
|
2132
|
+
b.setAttribute('aria-expanded', String(open));
|
|
2133
|
+
document.getElementById(b.getAttribute('aria-controls')).hidden = !open;
|
|
2134
|
+
});
|
|
2135
|
+
|
|
2136
|
+
/* Linking: while the list row is pointed at (or focused), the squares it is not about step back. */
|
|
2137
|
+
for (const b of $$('[data-link]')) {
|
|
2138
|
+
const map = document.getElementById(b.dataset.link);
|
|
2139
|
+
const on = (lit) => { map.classList.toggle('ws-heatmap--linking', lit); for (const c of $$('[data-lit]', map)) c.classList.toggle('ws-heatmap__cell--lit', lit); };
|
|
2140
|
+
for (const [ev, lit] of [['pointerenter', true], ['pointerleave', false], ['focus', true], ['blur', false]]) b.addEventListener(ev, () => on(lit));
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
/* The build-in runs from the centre to the corners: each square's --i is its distance from the middle (rows weigh
|
|
2144
|
+
1.75, as North's). */
|
|
2145
|
+
const centreOut = (map) => {
|
|
2146
|
+
const rows = $$('.ws-heatmap__row', map).map((r) => $$('.ws-heatmap__cell', r));
|
|
2147
|
+
const rc = (rows.length - 1) / 2, cc = (Math.max(...rows.map((r) => r.length)) - 1) / 2;
|
|
2148
|
+
rows.forEach((cells, r) => cells.forEach((cell, c) => cell.style.setProperty('--i', String(Math.round(Math.abs(r - rc) * 1.75 + Math.abs(c - cc))))));
|
|
2149
|
+
};
|
|
2150
|
+
for (const b of $$('[data-build-of]')) b.addEventListener('click', () => {
|
|
2151
|
+
const el = document.getElementById(b.dataset.buildOf), copy = el.cloneNode(true), map = copy.querySelector('.ws-heatmap');
|
|
2152
|
+
map.classList.add('ws-heatmap--build');
|
|
2153
|
+
centreOut(map);
|
|
2154
|
+
el.replaceWith(copy);
|
|
2155
|
+
copy.scrollIntoView({ block: 'center', behavior: reduced() ? 'auto' : 'smooth' });
|
|
2156
|
+
});
|
|
2157
|
+
|
|
2158
|
+
/* Dialogs and the drawer. */
|
|
2159
|
+
for (const b of $$('[data-open-dialog]')) b.addEventListener('click', () => { const d = document.getElementById(b.dataset.openDialog); stretchLocals(d.parentElement); d.showModal(); });
|
|
2160
|
+
for (const b of $$('[data-close-dialog]')) b.addEventListener('click', () => b.closest('dialog').close());
|
|
2161
|
+
|
|
2162
|
+
/* The docked panel: it grows out of its edge; its close sends it back faster. */
|
|
2163
|
+
for (const frame of $$('[data-panel]')) frame.querySelector('[data-panel-open]').addEventListener('click', () => {
|
|
2164
|
+
if (frame.querySelector('.ws-panel:not([data-leaving])')) return;
|
|
2165
|
+
frame.append(frame.querySelector('template').content.cloneNode(true));
|
|
2166
|
+
const panel = frame.lastElementChild;
|
|
2167
|
+
stretchLocals(frame);
|
|
2168
|
+
panel.querySelector('[data-panel-close]').addEventListener('click', () => {
|
|
2169
|
+
panel.setAttribute('data-leaving', '');
|
|
2170
|
+
setTimeout(() => panel.remove(), slow(160));
|
|
2171
|
+
});
|
|
2172
|
+
});
|
|
2173
|
+
|
|
2174
|
+
/* Toast: up out of .96 on the settle spring, stays 3 s, leaves faster than it came. */
|
|
2175
|
+
for (const b of $$('[data-toast]')) {
|
|
2176
|
+
const slot = document.getElementById(b.dataset.toast);
|
|
2177
|
+
let timer = 0;
|
|
2178
|
+
b.addEventListener('click', () => {
|
|
2179
|
+
clearTimeout(timer);
|
|
2180
|
+
slot.replaceChildren();
|
|
2181
|
+
const toast = document.createElement('div');
|
|
2182
|
+
toast.className = 'ws-toast';
|
|
2183
|
+
toast.setAttribute('role', 'status');
|
|
2184
|
+
toast.innerHTML = '<svg class="ws-toast__icon" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M3.5 8.5l3 3 6-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg><div class="ws-toast__body"><p class="ws-toast__title">Draft saved</p></div>';
|
|
2185
|
+
slot.append(toast);
|
|
2186
|
+
timer = setTimeout(() => { toast.setAttribute('data-leaving', ''); timer = setTimeout(() => toast.remove(), slow(toMs(tokens['--ws-duration-exit'] || '120ms'))); }, slow(3000));
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
/* Chart tooltip: pops on the pop spring, follows bar to bar on the follow spring, goes 180 ms after the pointer leaves. */
|
|
2191
|
+
for (const chart of $$('[data-hover-chart]')) {
|
|
2192
|
+
let card = null, leave = 0;
|
|
2193
|
+
const place = (bar) => {
|
|
2194
|
+
const x = parseFloat(bar.style.left) + parseFloat(bar.style.width) / 2;
|
|
2195
|
+
card.style.left = `${x}%`;
|
|
2196
|
+
card.style.top = `${100 - parseFloat(bar.style.height)}%`;
|
|
2197
|
+
card.classList.toggle('ws-hover-card--start', x < 25);
|
|
2198
|
+
card.classList.toggle('ws-hover-card--end', x > 75);
|
|
2199
|
+
card.querySelector('.ws-hover-card__title').textContent = `${bar.dataset.calls} calls`;
|
|
2200
|
+
card.querySelector('[data-words]').textContent = bar.dataset.week;
|
|
2201
|
+
card.querySelector('.ws-hover-card__value').textContent = bar.dataset.answered;
|
|
2202
|
+
};
|
|
2203
|
+
for (const bar of chart.children) bar.addEventListener('pointerenter', () => {
|
|
2204
|
+
clearTimeout(leave);
|
|
2205
|
+
if (!card || card.hasAttribute('data-leaving')) {
|
|
2206
|
+
card?.remove();
|
|
2207
|
+
card = document.createElement('div');
|
|
2208
|
+
card.className = 'ws-hover-card ws-hover-card--above ws-hover-card--follow';
|
|
2209
|
+
card.setAttribute('role', 'tooltip');
|
|
2210
|
+
card.innerHTML = '<span class="ws-hover-card__eyebrow"><span class="ws-hover-card__swatch" style="--ws-hover-card-swatch: var(--color-text-heading);"></span><span data-words></span></span><span class="ws-hover-card__title"></span><span class="ws-hover-card__row"><span class="ws-hover-card__swatch" style="--ws-hover-card-swatch: var(--ws-chart-finished);"></span><span class="ws-hover-card__label">Answered</span><span class="ws-hover-card__value"></span></span>';
|
|
2211
|
+
place(bar);
|
|
2212
|
+
chart.append(card);
|
|
2213
|
+
} else place(bar);
|
|
2214
|
+
});
|
|
2215
|
+
chart.addEventListener('pointerleave', () => {
|
|
2216
|
+
clearTimeout(leave);
|
|
2217
|
+
leave = setTimeout(() => { const c = card; c?.setAttribute('data-leaving', ''); setTimeout(() => c?.remove(), slow(120)); }, slow(toMs(tokens['--ws-hover-grace'] || '180ms')));
|
|
2218
|
+
});
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
/* rollPlaceholder(): every 3.4 s the next question rolls up out of a blur on the roll spring. */
|
|
2222
|
+
const rolls = [];
|
|
2223
|
+
const startRolls = () => {
|
|
2224
|
+
for (const t of rolls.splice(0)) clearInterval(t);
|
|
2225
|
+
if (reduced()) return;
|
|
2226
|
+
for (const roll of $$('[data-roll]')) {
|
|
2227
|
+
const lines = [...roll.children];
|
|
2228
|
+
let at = lines.findIndex((l) => l.hasAttribute('data-on'));
|
|
2229
|
+
if (at < 0) { at = 0; lines[0].setAttribute('data-on', ''); }
|
|
2230
|
+
rolls.push(setInterval(() => {
|
|
2231
|
+
const was = lines[at];
|
|
2232
|
+
at = (at + 1) % lines.length;
|
|
2233
|
+
const next = lines[at];
|
|
2234
|
+
for (const l of lines) l.removeAttribute('data-off');
|
|
2235
|
+
next.removeAttribute('data-on');
|
|
2236
|
+
void next.offsetWidth;
|
|
2237
|
+
was.removeAttribute('data-on');
|
|
2238
|
+
was.setAttribute('data-off', '');
|
|
2239
|
+
next.setAttribute('data-on', '');
|
|
2240
|
+
}, slow(3400)));
|
|
2241
|
+
}
|
|
2242
|
+
};
|
|
2243
|
+
for (const roll of $$('[data-roll]')) roll.firstElementChild.setAttribute('data-on', '');
|
|
2244
|
+
startRolls();
|
|
2245
|
+
|
|
2246
|
+
/* morph(): the element goes to its new place as itself on Seth's curve for `as`. */
|
|
2247
|
+
// A copy of morph() from @felloinnovations/brand-kit (src/lib/motion.ts): a preview cannot import the package.
|
|
2248
|
+
// `full` lifts the element into the top layer while it is fixed, so no ancestor (a transform, a filter, the glass,
|
|
2249
|
+
// contain) can trap it; Escape runs the update again (a toggle) and focus comes back.
|
|
2250
|
+
const morph = (() => {
|
|
2251
|
+
const lifted = new WeakMap(), root = document.documentElement;
|
|
2252
|
+
const FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), summary, [tabindex]:not([tabindex="-1"])';
|
|
2253
|
+
let last = 0;
|
|
2254
|
+
const place = (el, close) => {
|
|
2255
|
+
const was = lifted.get(el);
|
|
2256
|
+
if (was) { lifted.delete(el); el.removeEventListener('keydown', was.onKey); if (el.matches(':popover-open')) el.hidePopover(); el.removeAttribute('popover'); delete el.dataset.wsLifted; }
|
|
2257
|
+
if (getComputedStyle(el).position === 'fixed' && el.showPopover) {
|
|
2258
|
+
const onKey = (e) => { if (e.key !== 'Escape' || e.defaultPrevented || el.querySelector(':popover-open, dialog[open]')) return; e.preventDefault(); morph(close, { as: 'full', el, close }); };
|
|
2259
|
+
el.dataset.wsLifted = ''; el.popover = 'manual'; el.showPopover(); el.addEventListener('keydown', onKey);
|
|
2260
|
+
lifted.set(el, { opener: was ? was.opener : document.activeElement, onKey });
|
|
2261
|
+
if (!el.contains(document.activeElement)) { const to = el.querySelector('[autofocus]') || el.querySelector(FOCUSABLE) || el; if (to === el && !el.hasAttribute('tabindex')) el.tabIndex = -1; to.focus({ preventScroll: true }); }
|
|
2262
|
+
} else if (was) { const o = was.opener, here = document.activeElement; if (o && o.isConnected && o !== here && (!here || here === document.body || el.contains(here))) o.focus({ preventScroll: true }); }
|
|
2263
|
+
};
|
|
2264
|
+
const morph = (update, { as = 'full', el, close } = {}) => {
|
|
2265
|
+
const run = as === 'full' && el ? async () => { await update(); place(el, close || update); } : update;
|
|
2266
|
+
if (!document.startViewTransition || matchMedia('(prefers-reduced-motion: reduce)').matches) return Promise.resolve(run()).then(() => {});
|
|
2267
|
+
const id = ++last;
|
|
2268
|
+
if (el) {
|
|
2269
|
+
const s = getComputedStyle(el);
|
|
2270
|
+
root.style.setProperty('--ws-morph-ground', s.backgroundColor);
|
|
2271
|
+
root.style.setProperty('--ws-morph-radius', s.borderRadius);
|
|
2272
|
+
root.style.setProperty('--ws-morph-backdrop', s.backdropFilter || 'none');
|
|
2273
|
+
el.style.viewTransitionName = 'ws-morph';
|
|
2274
|
+
}
|
|
2275
|
+
root.dataset.wsMorph = as;
|
|
2276
|
+
const move = document.startViewTransition(run);
|
|
2277
|
+
move.ready.catch(() => {});
|
|
2278
|
+
return move.finished.finally(() => {
|
|
2279
|
+
if (el) el.style.viewTransitionName = '';
|
|
2280
|
+
if (id !== last) return;
|
|
2281
|
+
delete root.dataset.wsMorph;
|
|
2282
|
+
for (const p of ['--ws-morph-ground', '--ws-morph-radius', '--ws-morph-backdrop']) root.style.removeProperty(p);
|
|
2283
|
+
});
|
|
2284
|
+
};
|
|
2285
|
+
return morph;
|
|
2286
|
+
})();
|
|
2287
|
+
for (const card of $$('[data-morph-card]')) {
|
|
2288
|
+
const go = card.querySelector('[data-morph-go]');
|
|
2289
|
+
go.addEventListener('click', () => morph(() => {
|
|
2290
|
+
const full = card.classList.toggle('ws-chat-card--full');
|
|
2291
|
+
go.textContent = full ? 'Back' : 'Full screen';
|
|
2292
|
+
go.setAttribute('aria-pressed', String(full));
|
|
2293
|
+
}, { as: 'full', el: card }));
|
|
2294
|
+
}
|
|
2295
|
+
for (const row of $$('[data-morph-row]')) for (const tile of row.children) tile.addEventListener('click', () => {
|
|
2296
|
+
const open = tile.getAttribute('aria-expanded') !== 'true';
|
|
2297
|
+
morph(() => {
|
|
2298
|
+
tile.setAttribute('aria-expanded', String(open));
|
|
2299
|
+
tile.style.gridColumn = open ? '1 / -1' : '';
|
|
2300
|
+
tile.style.minHeight = open ? 'var(--space-8xl)' : '';
|
|
2301
|
+
for (const other of row.children) if (other !== tile) other.style.display = open ? 'none' : '';
|
|
2302
|
+
}, { as: open ? 'grow' : 'shrink', el: tile });
|
|
2303
|
+
});
|
|
2304
|
+
for (const dock of $$('[data-chat]')) {
|
|
2305
|
+
const shell = dock.querySelector('.ws-chat-shell'), page = dock.querySelector('main'), mode = shell.querySelector('[data-mode]'), open = page.querySelector('[data-open]');
|
|
2306
|
+
mode.addEventListener('click', () => morph(() => {
|
|
2307
|
+
const full = shell.classList.toggle('ws-chat-shell--full');
|
|
2308
|
+
shell.classList.toggle('ws-chat-shell--dock', !full);
|
|
2309
|
+
shell.style.flex = full ? '1' : '';
|
|
2310
|
+
page.style.display = full ? 'none' : '';
|
|
2311
|
+
mode.setAttribute('aria-label', full ? 'Dock the chat' : 'Full screen');
|
|
2312
|
+
mode.title = full ? 'Dock' : 'Full screen';
|
|
2313
|
+
}, { as: 'shift', el: shell }));
|
|
2314
|
+
shell.querySelector('[data-close]').addEventListener('click', () => {
|
|
2315
|
+
stretchLocals(dock);
|
|
2316
|
+
shell.setAttribute('data-leaving', '');
|
|
2317
|
+
setTimeout(() => {
|
|
2318
|
+
shell.removeAttribute('data-leaving');
|
|
2319
|
+
shell.style.display = 'none';
|
|
2320
|
+
page.style.display = '';
|
|
2321
|
+
open.style.display = '';
|
|
2322
|
+
}, slow(160));
|
|
2323
|
+
});
|
|
2324
|
+
open.addEventListener('click', () => { open.style.display = 'none'; shell.style.display = ''; });
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
/* reorder(): rows that change places glide there on the reorder spring (a View Transition per row). */
|
|
2328
|
+
const reorder = (update, within) => {
|
|
2329
|
+
if (!document.startViewTransition || reduced()) { update(); return; }
|
|
2330
|
+
const rows = $$(':scope > li', within);
|
|
2331
|
+
rows.forEach((li) => { li.style.viewTransitionName = `ws-row-${li.dataset.key}`; });
|
|
2332
|
+
const t = document.startViewTransition(update);
|
|
2333
|
+
t.ready.then(() => {
|
|
2334
|
+
const timing = { duration: slow(toMs(tokens['--ws-spring-reorder-duration'] || '750ms')), easing: computed.getPropertyValue('--ws-spring-reorder').trim() };
|
|
2335
|
+
for (const a of document.getAnimations()) {
|
|
2336
|
+
const p = a.effect && a.effect.pseudoElement;
|
|
2337
|
+
if (p && p.startsWith('::view-transition-group(ws-row-')) a.effect.updateTiming(timing);
|
|
2338
|
+
}
|
|
2339
|
+
}, () => {});
|
|
2340
|
+
t.finished.finally(() => rows.forEach((li) => { li.style.viewTransitionName = ''; }));
|
|
2341
|
+
};
|
|
2342
|
+
for (const b of $$('[data-sort]')) {
|
|
2343
|
+
const list = document.getElementById(b.dataset.sort);
|
|
2344
|
+
let up = false;
|
|
2345
|
+
b.addEventListener('click', () => reorder(() => {
|
|
2346
|
+
up = !up;
|
|
2347
|
+
const sorted = $$(':scope > li', list).sort((x, y) => (up ? 1 : -1) * (Number(y.dataset.figure) - Number(x.dataset.figure)));
|
|
2348
|
+
list.append(...sorted);
|
|
2349
|
+
b.textContent = up ? 'Sort, smallest first' : 'Sort';
|
|
2350
|
+
}, list));
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
/* The playground: a product screen wired the way an app wires it. Each move is the kit's own (CSS, morph(),
|
|
2354
|
+
reorder(), a native popover or dialog); this only flips the states. */
|
|
2355
|
+
const play = document.querySelector('[data-play]');
|
|
2356
|
+
if (play) {
|
|
2357
|
+
const shell = play.querySelector('[data-shell]'), navMain = play.querySelector('[data-nav-main]'), navDrawer = play.querySelector('[data-nav-drawer]');
|
|
2358
|
+
const title = play.querySelector('.ws-page-bar__title'), fold = navMain.querySelector('[data-fold-nav]');
|
|
2359
|
+
|
|
2360
|
+
/* 2 and 6: the current row (the white pill slides on its own), the nav's fold, and on a phone the same nav in its
|
|
2361
|
+
drawer, its head's act closing it. */
|
|
2362
|
+
const navCopy = navMain.cloneNode(true);
|
|
2363
|
+
navCopy.removeAttribute('data-nav-main');
|
|
2364
|
+
navCopy.style.height = '100%';
|
|
2365
|
+
const closeNav = navCopy.querySelector('[data-fold-nav]');
|
|
2366
|
+
closeNav.removeAttribute('data-fold-nav');
|
|
2367
|
+
closeNav.removeAttribute('aria-expanded');
|
|
2368
|
+
closeNav.setAttribute('aria-label', 'Close the menu');
|
|
2369
|
+
closeNav.innerHTML = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
|
|
2370
|
+
closeNav.addEventListener('click', () => navDrawer.close());
|
|
2371
|
+
navDrawer.append(navCopy);
|
|
2372
|
+
play.querySelector('[data-open-nav]').addEventListener('click', () => { stretchLocals(play); navDrawer.showModal(); });
|
|
2373
|
+
for (const nav of [navMain, navCopy]) nav.addEventListener('click', (e) => {
|
|
2374
|
+
const row = e.target.closest('.ws-app-shell__row');
|
|
2375
|
+
if (!row) return;
|
|
2376
|
+
e.preventDefault();
|
|
2377
|
+
const to = row.getAttribute('href');
|
|
2378
|
+
for (const r of play.querySelectorAll('.ws-app-shell__row')) r.getAttribute('href') === to ? r.setAttribute('aria-current', 'page') : r.removeAttribute('aria-current');
|
|
2379
|
+
title.textContent = title.title = row.querySelector('.ws-app-shell__name').textContent;
|
|
2380
|
+
chatWhere.textContent = chatWhere.title = `On ${title.textContent}`;
|
|
2381
|
+
});
|
|
2382
|
+
const setFolded = (folded) => {
|
|
2383
|
+
shell.classList.toggle('ws-app-shell--folded', folded);
|
|
2384
|
+
fold.setAttribute('aria-expanded', String(!folded));
|
|
2385
|
+
fold.setAttribute('aria-label', folded ? 'Open the menu' : 'Fold the menu');
|
|
2386
|
+
};
|
|
2387
|
+
fold.addEventListener('click', () => setFolded(!shell.classList.contains('ws-app-shell--folded')));
|
|
2388
|
+
|
|
2389
|
+
/* 3, 5 and 7: the chart card, a TrendLine. Bars / Line sets --bars on it (the columns melt into the line and
|
|
2390
|
+
back, all CSS); the chart or Full screen sends the card to the window's full screen through morph(), Back or
|
|
2391
|
+
Escape brings it home. Pointing at a week (or a tap) places a HoverCard over its point from the chart's own
|
|
2392
|
+
table; it pops on the pop spring, follows on the follow spring and goes 180 ms after the pointer leaves. */
|
|
2393
|
+
const chart = play.querySelector('[data-play-chart]'), fullBtn = chart.querySelector('[data-chart-full]'), area = chart.querySelector('[data-chart-area]');
|
|
2394
|
+
const tl = () => area.querySelector('.ws-trend-line');
|
|
2395
|
+
for (const b of $$('[data-lens-to]', chart)) b.addEventListener('click', () => tl().classList.toggle('ws-trend-line--bars', b.dataset.lensTo === 'bars'));
|
|
2396
|
+
const toggleFull = () => morph(() => {
|
|
2397
|
+
const full = chart.classList.toggle('ws-chat-card--full');
|
|
2398
|
+
fullBtn.textContent = full ? 'Back' : 'Full screen';
|
|
2399
|
+
area.style.cursor = full ? '' : 'zoom-in';
|
|
2400
|
+
tl().style.setProperty('--ws-trend-line-h', full ? 'min(48vh, 420px)' : '180px');
|
|
2401
|
+
}, { as: 'full', el: chart });
|
|
2402
|
+
fullBtn.addEventListener('click', toggleFull);
|
|
2403
|
+
area.addEventListener('click', () => { if (!chart.classList.contains('ws-chat-card--full')) toggleFull(); });
|
|
2404
|
+
const reading = (fig) => {
|
|
2405
|
+
const plot = fig.querySelector('.ws-trend-line__area'), rows = $$('tbody tr', fig), n = rows.length;
|
|
2406
|
+
let card = null, leave = 0;
|
|
2407
|
+
const show = (pt) => {
|
|
2408
|
+
clearTimeout(leave);
|
|
2409
|
+
const i = Number(pt.style.getPropertyValue('--i')), x = ((i + 0.5) / n) * 100;
|
|
2410
|
+
for (const p of $$('.ws-trend-line__point--on', plot)) if (p !== pt) p.classList.remove('ws-trend-line__point--on');
|
|
2411
|
+
if (!card || card.hasAttribute('data-leaving')) {
|
|
2412
|
+
card?.remove();
|
|
2413
|
+
card = document.createElement('div');
|
|
2414
|
+
card.className = 'ws-hover-card ws-hover-card--above ws-hover-card--follow';
|
|
2415
|
+
card.setAttribute('role', 'tooltip');
|
|
2416
|
+
card.innerHTML = '<span class="ws-hover-card__eyebrow"><span class="ws-hover-card__swatch" style="--ws-hover-card-swatch: var(--color-text-heading);"></span><span></span></span><span class="ws-hover-card__title"></span>';
|
|
2417
|
+
plot.append(card);
|
|
2418
|
+
}
|
|
2419
|
+
card.style.left = `${x}%`;
|
|
2420
|
+
card.style.top = `calc(${pt.style.getPropertyValue('--y')} - ${fig.classList.contains('ws-trend-line--bars') ? '0px' : 'var(--ws-trend-line-dot)'})`;
|
|
2421
|
+
card.classList.toggle('ws-hover-card--start', x < 25);
|
|
2422
|
+
card.classList.toggle('ws-hover-card--end', x > 75);
|
|
2423
|
+
card.querySelector('.ws-hover-card__eyebrow > span:last-child').textContent = rows[i].querySelector('th').textContent;
|
|
2424
|
+
card.querySelector('.ws-hover-card__title').textContent = rows[i].querySelector('td').textContent;
|
|
2425
|
+
};
|
|
2426
|
+
const hide = () => {
|
|
2427
|
+
clearTimeout(leave);
|
|
2428
|
+
leave = setTimeout(() => {
|
|
2429
|
+
const c = card;
|
|
2430
|
+
card = null;
|
|
2431
|
+
c?.setAttribute('data-leaving', '');
|
|
2432
|
+
setTimeout(() => c?.remove(), slow(toMs(tokens['--ws-duration-exit'] || '120ms')));
|
|
2433
|
+
for (const p of $$('.ws-trend-line__point--on', plot)) p.classList.remove('ws-trend-line__point--on');
|
|
2434
|
+
}, slow(toMs(tokens['--ws-hover-grace'] || '180ms')));
|
|
2435
|
+
};
|
|
2436
|
+
for (const pt of $$('.ws-trend-line__point', plot)) {
|
|
2437
|
+
pt.addEventListener('pointerenter', (e) => { if (e.pointerType === 'mouse') show(pt); });
|
|
2438
|
+
pt.addEventListener('click', () => { pt.classList.add('ws-trend-line__point--on'); show(pt); });
|
|
2439
|
+
}
|
|
2440
|
+
plot.addEventListener('pointerleave', (e) => { if (e.pointerType === 'mouse') hide(); });
|
|
2441
|
+
document.addEventListener('pointerdown', (e) => { if (e.pointerType !== 'mouse' && card && fig.isConnected && !plot.contains(e.target)) hide(); });
|
|
2442
|
+
};
|
|
2443
|
+
reading(tl());
|
|
2444
|
+
|
|
2445
|
+
/* 15: the arrival again. Fresh copies of the tiles, the goals and the chart run their build-in (the kit's CSS:
|
|
2446
|
+
cards rise 70 ms apart, each chart draws as its card lands), and the chart card rises again. */
|
|
2447
|
+
play.querySelector('[data-replay-arrival]').addEventListener('click', () => {
|
|
2448
|
+
for (const el of $$('[data-arrival]', play)) el.replaceWith(el.cloneNode(true));
|
|
2449
|
+
reading(tl());
|
|
2450
|
+
chart.style.animation = 'none';
|
|
2451
|
+
void chart.offsetWidth;
|
|
2452
|
+
chart.style.animation = '';
|
|
2453
|
+
});
|
|
2454
|
+
|
|
2455
|
+
/* 4, 11 and 9: the sort menu (a native popover), the rows gliding to their new order once it has closed, and a
|
|
2456
|
+
name opening its drawer. */
|
|
2457
|
+
const list = play.querySelector('#mo-play-list'), sortLabel = play.querySelector('[data-sort-label]'), leadDrawer = play.querySelector('[data-lead-drawer]');
|
|
2458
|
+
for (const item of $$('[data-sort-by]', play)) item.addEventListener('click', () => {
|
|
2459
|
+
for (const i of $$('[data-sort-by]', play)) i.setAttribute('aria-checked', String(i === item));
|
|
2460
|
+
sortLabel.textContent = item.textContent.trim();
|
|
2461
|
+
const by = item.dataset.sortBy;
|
|
2462
|
+
setTimeout(() => reorder(() => {
|
|
2463
|
+
const rows = $$(':scope > li', list).sort((x, y) => (by === 'name' ? x.dataset.name.localeCompare(y.dataset.name) : (by === 'big' ? 1 : -1) * (Number(y.dataset.figure) - Number(x.dataset.figure))));
|
|
2464
|
+
list.append(...rows);
|
|
2465
|
+
}, list), slow(toMs(tokens['--ws-duration-exit'] || '120ms')));
|
|
2466
|
+
});
|
|
2467
|
+
list.addEventListener('click', (e) => {
|
|
2468
|
+
const pick = e.target.closest('[data-drawer-lead]');
|
|
2469
|
+
if (!pick) return;
|
|
2470
|
+
leadDrawer.querySelector('.ws-title').textContent = pick.closest('li').dataset.name;
|
|
2471
|
+
leadDrawer.querySelector('[data-lead-sub]').textContent = `${pick.querySelector('.ws-side-list__sub').textContent}.`;
|
|
2472
|
+
stretchLocals(play);
|
|
2473
|
+
leadDrawer.showModal();
|
|
2474
|
+
});
|
|
2475
|
+
|
|
2476
|
+
/* 10: the chat in its three modes, the same element all the way: a bar over a veiled page, a column docked beside
|
|
2477
|
+
the page (the sidebar folds to its rail, North's dock), the full screen. A change of mode goes through
|
|
2478
|
+
morph(), as: 'shift'; Close plays its exit. */
|
|
2479
|
+
const chat = play.querySelector('[data-play-chat]'), chatRow = play.querySelector('[data-chat-row]'), body = play.querySelector('[data-play-body]'), veil = play.querySelector('[data-chat-veil]');
|
|
2480
|
+
const chatHead = chat.querySelector('.ws-chat-shell__head'), thread = chat.querySelector('.ws-chat-shell__thread'), field = chat.querySelector('textarea');
|
|
2481
|
+
const chatWhere = chat.querySelector('.ws-chat-shell__where'), toFull = chatHead.querySelector('[data-chat-to="full"]'), toDock = chatHead.querySelector('[data-chat-to="dock"]');
|
|
2482
|
+
const BAR = { position: 'absolute', top: 'calc(var(--ws-header-h) + var(--space-md))', left: '50%', translate: '-50% 0', width: 'min(35rem, calc(100% - var(--space-xl)))', zIndex: '1' };
|
|
2483
|
+
let mode = 'closed';
|
|
2484
|
+
const setMode = (to) => {
|
|
2485
|
+
mode = to;
|
|
2486
|
+
const show = (el, on) => { el.style.display = on ? '' : 'none'; };
|
|
2487
|
+
show(chat, to !== 'closed');
|
|
2488
|
+
for (const m of ['bar', 'dock', 'full']) chat.classList.toggle(`ws-chat-shell--${m}`, to === m);
|
|
2489
|
+
for (const [k, v] of Object.entries(BAR)) chat.style[k] = to === 'bar' ? v : '';
|
|
2490
|
+
chat.style.flex = to === 'full' ? '1' : '';
|
|
2491
|
+
show(chatHead, to === 'dock' || to === 'full');
|
|
2492
|
+
show(thread, to === 'dock' || to === 'full');
|
|
2493
|
+
for (const el of $$('[data-bar-only]', chat)) show(el, to === 'bar');
|
|
2494
|
+
show(toFull, to === 'dock');
|
|
2495
|
+
show(toDock, to === 'full');
|
|
2496
|
+
veil.hidden = to !== 'bar';
|
|
2497
|
+
chatRow.classList.toggle('ws-chat-dock', to === 'dock');
|
|
2498
|
+
show(body, to !== 'full' && !(to === 'dock' && matchMedia('(max-width: 60rem)').matches));
|
|
2499
|
+
setFolded(to === 'dock');
|
|
2500
|
+
};
|
|
2501
|
+
const shift = (to) => morph(() => setMode(to), { as: 'shift', el: chat });
|
|
2502
|
+
const closeChat = () => {
|
|
2503
|
+
if (mode === 'closed' || chat.hasAttribute('data-leaving')) return;
|
|
2504
|
+
stretchLocals(play);
|
|
2505
|
+
chat.setAttribute('data-leaving', '');
|
|
2506
|
+
setTimeout(() => { chat.removeAttribute('data-leaving'); setMode('closed'); play.querySelector('[data-chat-open]').focus({ preventScroll: true }); }, slow(160));
|
|
2507
|
+
};
|
|
2508
|
+
play.querySelector('[data-chat-open]').addEventListener('click', () => {
|
|
2509
|
+
if (mode === 'closed') { setMode('bar'); stretchLocals(play); }
|
|
2510
|
+
setTimeout(() => field.focus({ preventScroll: true }), slow(60));
|
|
2511
|
+
});
|
|
2512
|
+
for (const b of $$('[data-chat-to]', chat)) b.addEventListener('click', () => shift(b.dataset.chatTo));
|
|
2513
|
+
chat.querySelector('[data-chat-close]').addEventListener('click', closeChat);
|
|
2514
|
+
veil.addEventListener('click', closeChat);
|
|
2515
|
+
chat.addEventListener('keydown', (e) => { if (e.key === 'Escape' && mode === 'bar') closeChat(); });
|
|
2516
|
+
|
|
2517
|
+
/* 14: the sources load: a shimmer in the chart colours, then each line settles in, top to bottom. */
|
|
2518
|
+
const sources = play.querySelector('[data-play-sources]'), sourcesView = sources.querySelector('[data-sources-view]');
|
|
2519
|
+
let loading = 0;
|
|
2520
|
+
const load = () => {
|
|
2521
|
+
clearTimeout(loading);
|
|
2522
|
+
sources.setAttribute('aria-busy', 'true');
|
|
2523
|
+
sourcesView.replaceChildren(sources.querySelector('[data-sources-loading]').content.cloneNode(true));
|
|
2524
|
+
loading = setTimeout(() => { sources.removeAttribute('aria-busy'); sourcesView.replaceChildren(sources.querySelector('[data-sources-ready]').content.cloneNode(true)); }, slow(1800));
|
|
2525
|
+
};
|
|
2526
|
+
sources.querySelector('[data-play-refresh]').addEventListener('click', load);
|
|
2527
|
+
load();
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
/* What this browser asks for. */
|
|
2531
|
+
const readout = () => { for (const p of $$('[data-reduced-readout]')) p.textContent = reduced() ? 'This browser asks for reduced motion: every demo on this page is still.' : 'This browser asks for full motion. Turn on reduced motion in the system settings and every demo here goes still.'; };
|
|
2532
|
+
matchMedia('(prefers-reduced-motion: reduce)').addEventListener('change', readout);
|
|
2533
|
+
readout();
|
|
2534
|
+
})();
|
|
2535
|
+
</script>
|
|
2536
|
+
</body>
|
|
2537
|
+
</html>
|