@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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<!-- @dsCard group="Marketing" height=
|
|
1
|
+
<!-- @dsCard group="Marketing" height=740 -->
|
|
2
2
|
<!doctype html>
|
|
3
|
-
<html>
|
|
3
|
+
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<title>KitButton</title>
|
|
@@ -21,8 +21,19 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
|
+
<div class="ws-stack" inert>
|
|
25
|
+
<span class="ws-muted">Hover (a picture of the state): a colour change; primary and navy brighten, navy also deepens its shadow, clean underlines</span>
|
|
26
|
+
<div class="ws-cluster ws-cluster--component">
|
|
27
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-hover">Book a demo</button>
|
|
28
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary is-hover">Talk to sales</button>
|
|
29
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--navy is-hover">Start free trial</button>
|
|
30
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--tertiary is-hover">Watch the tour</button>
|
|
31
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--clean is-hover">See pricing</button>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
24
35
|
<div class="ws-stack">
|
|
25
|
-
<span class="ws-muted">Medium (36px) and small (28px)</span>
|
|
36
|
+
<span class="ws-muted">Medium (36px) and small (28px); on touch each takes a 44px hit area</span>
|
|
26
37
|
<div class="ws-cluster ws-cluster--component">
|
|
27
38
|
<button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary">Book a demo</button>
|
|
28
39
|
<button class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary">Talk to sales</button>
|
|
@@ -32,7 +43,7 @@
|
|
|
32
43
|
</div>
|
|
33
44
|
|
|
34
45
|
<div class="ws-stack">
|
|
35
|
-
<span class="ws-muted">Leading and trailing icons, and with shadow</span>
|
|
46
|
+
<span class="ws-muted">Leading and trailing icons (16px, 12px at small), and with shadow</span>
|
|
36
47
|
<div class="ws-cluster ws-cluster--component">
|
|
37
48
|
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary">
|
|
38
49
|
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 1.5a2 2 0 0 0-2 2v4a2 2 0 0 0 4 0v-4a2 2 0 0 0-2-2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M4.5 7.5a3.5 3.5 0 0 0 7 0" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 11v2.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
@@ -42,27 +53,38 @@
|
|
|
42
53
|
Read the case study
|
|
43
54
|
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M5 11 11 5M5.5 5h5.5v5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
44
55
|
</button>
|
|
45
|
-
<button class="ws-kit-button ws-kit-button--
|
|
56
|
+
<button class="ws-kit-button ws-kit-button--small ws-kit-button--secondary">
|
|
57
|
+
Download the guide
|
|
58
|
+
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 2.5v8M4.5 7 8 10.5 11.5 7M3 13.5h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
59
|
+
</button>
|
|
60
|
+
<button class="ws-kit-button ws-kit-button--medium ws-kit-button--primary ws-kit-button--shadow">With shadow</button>
|
|
46
61
|
</div>
|
|
47
62
|
</div>
|
|
48
63
|
|
|
49
|
-
<div class="ws-stack">
|
|
50
|
-
<span class="ws-muted">Pressed: the 3px lift collapses (primary and navy only)</span>
|
|
64
|
+
<div class="ws-stack" inert>
|
|
65
|
+
<span class="ws-muted">Pressed: the 3px lift collapses (primary and navy only); focus: the 2px navy ring, 2px out</span>
|
|
51
66
|
<div class="ws-cluster ws-cluster--component">
|
|
52
67
|
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-pressed">Book a demo</button>
|
|
53
68
|
<button class="ws-kit-button ws-kit-button--large ws-kit-button--navy is-pressed">Start free trial</button>
|
|
69
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary is-focus">Book a demo</button>
|
|
70
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary is-focus">Talk to sales</button>
|
|
54
71
|
</div>
|
|
55
72
|
</div>
|
|
56
73
|
|
|
57
74
|
<div class="ws-stack">
|
|
58
|
-
<span class="ws-muted">Disabled,
|
|
59
|
-
<div class="ws-cluster ws-cluster--component
|
|
75
|
+
<span class="ws-muted">Disabled, and a link that looks like the act</span>
|
|
76
|
+
<div class="ws-cluster ws-cluster--component">
|
|
60
77
|
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary" disabled>Book a demo</button>
|
|
61
78
|
<button class="ws-kit-button ws-kit-button--large ws-kit-button--secondary" disabled>Talk to sales</button>
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
<a class="ws-kit-button ws-kit-button--large ws-kit-button--primary" href="#" onclick="return false;">Book a demo</a>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="ws-stack">
|
|
84
|
+
<span class="ws-muted">Full width (the phone's act), and a label too long for its column: it wraps to two balanced lines</span>
|
|
85
|
+
<div class="ws-stack ws-stack--component" style="width: 320px; max-width: 100%;">
|
|
86
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--primary ws-kit-button--full">Book your onboarding call</button>
|
|
87
|
+
<button class="ws-kit-button ws-kit-button--large ws-kit-button--navy ws-kit-button--full">Start the free trial your whole team can run on from day one</button>
|
|
66
88
|
</div>
|
|
67
89
|
</div>
|
|
68
90
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* ---- KitButton: the kit's marketing button, the salmon gradient with its lift ---- */
|
|
2
|
+
/* The sizes are floors, not fixed heights: a label too long for its column wraps to a second, balanced line instead of
|
|
3
|
+
running out of the button. Focus is the house ring (2 px navy, 2 px out); nothing here turns it off. */
|
|
4
|
+
.ws-kit-button { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs); max-width: 100%; font-family: var(--font-body); font-weight: 600; text-align: center; text-wrap: balance; text-decoration: none; cursor: pointer; appearance: none; border: 0; }
|
|
5
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
6
|
+
.ws-kit-button { transition: filter var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast), color var(--transition-fast), transform var(--transition-fast); }
|
|
7
|
+
}
|
|
8
|
+
.ws-kit-button:disabled, .ws-kit-button[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
|
|
9
|
+
.ws-kit-button.is-focus { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
|
|
10
|
+
.ws-kit-button svg { width: var(--ws-icon); height: var(--ws-icon); flex-shrink: 0; }
|
|
11
|
+
/* Sizes: large 45, medium 36, small 28 (the kit's own dimensions table). */
|
|
12
|
+
.ws-kit-button--large { min-height: calc(var(--space-2xl) + var(--space-xxs) + var(--ws-line)); min-width: calc(var(--space-5xl) + var(--space-md) + var(--space-xxs)); padding: var(--space-xs) calc(var(--space-md) + var(--space-xxs)); font-size: var(--font-size-md); line-height: calc(var(--space-md) + var(--space-xxs)); border-radius: var(--ws-radius-card); }
|
|
13
|
+
.ws-kit-button--medium { min-height: calc(var(--space-xl) + var(--space-xxs)); min-width: var(--space-5xl); padding: var(--space-xxs-plus) var(--space-md); font-size: var(--font-size-sm); line-height: var(--ws-leading-control); border-radius: var(--ws-radius-card); }
|
|
14
|
+
.ws-kit-button--small { min-height: calc(var(--space-lg) + var(--space-xxs)); min-width: calc(var(--space-3xl) + var(--space-sm)); padding: var(--space-xxs) var(--space-sm); font-size: var(--font-size-2xs); line-height: var(--space-md); font-weight: 500; border-radius: var(--ws-radius-row); }
|
|
15
|
+
.ws-kit-button--small svg { width: var(--ws-icon-sm); height: var(--ws-icon-sm); }
|
|
16
|
+
/* Primary: the salmon gradient and the 3 px lift. Not decoration: pressing collapses it. Its words are white, as
|
|
17
|
+
fello.ai draws them (Amit, 4 Nov 2026: "it should be white on salmon"). White on the gradient is 2.44 to 2.65:1, so
|
|
18
|
+
this is the kit's one logged exception to D2: the act is large, semibold and a few words long. Literal in every theme. */
|
|
19
|
+
.ws-kit-button--primary { background-image: var(--gradient-btn-primary); color: var(--color-white); border-bottom: calc(var(--space-xxs) * 0.75) solid var(--color-button-border); }
|
|
20
|
+
.ws-kit-button--secondary { background: var(--color-bg-page); color: var(--color-text-interactive); border: var(--ws-line) solid var(--color-border-hairline); }
|
|
21
|
+
.ws-kit-button--navy { background-image: linear-gradient(180deg, var(--color-brand-mid-blue), color-mix(in srgb, var(--color-brand-navy) 35%, var(--color-brand-mid-blue))); color: var(--color-white); border-bottom: calc(var(--space-xxs) * 0.75) solid var(--color-brand-navy); box-shadow: var(--shadow-btn); }
|
|
22
|
+
.ws-kit-button--tertiary { background: transparent; color: var(--color-text-heading); border: var(--ws-line) solid var(--color-text-heading); }
|
|
23
|
+
.ws-kit-button--clean { background: transparent; color: var(--color-text-heading); min-width: 0; padding-inline: 0; }
|
|
24
|
+
.ws-kit-button--shadow { box-shadow: var(--shadow-btn); }
|
|
25
|
+
.ws-kit-button--full { width: 100%; }
|
|
26
|
+
/* Hover is a colour change (D7): the two fills brighten 4%, which also shows on a dark ground where a shadow cannot;
|
|
27
|
+
a button that already casts a shadow deepens it as well. Only where the pointer really hovers: a phone keeps :hover
|
|
28
|
+
after a tap, so ungated it stuck on the tapped button. .is-hover draws the state in a static preview on any device. */
|
|
29
|
+
.ws-kit-button--primary.is-hover, .ws-kit-button--navy.is-hover { filter: brightness(1.04); }
|
|
30
|
+
.ws-kit-button--secondary.is-hover { background: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)), var(--color-bg-page); }
|
|
31
|
+
.ws-kit-button--navy.is-hover, .ws-kit-button--shadow.is-hover { box-shadow: var(--shadow-btn-hover); }
|
|
32
|
+
.ws-kit-button--tertiary.is-hover { background: var(--color-text-heading); color: var(--ws-on-act); }
|
|
33
|
+
.ws-kit-button--clean.is-hover { text-decoration: underline; }
|
|
34
|
+
@media (hover: hover) {
|
|
35
|
+
.ws-kit-button--primary:hover, .ws-kit-button--navy:hover { filter: brightness(1.04); }
|
|
36
|
+
.ws-kit-button--secondary:hover { background: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)), var(--color-bg-page); }
|
|
37
|
+
.ws-kit-button--navy:hover, .ws-kit-button--shadow:hover { box-shadow: var(--shadow-btn-hover); }
|
|
38
|
+
.ws-kit-button--tertiary:hover { background: var(--color-text-heading); color: var(--ws-on-act); }
|
|
39
|
+
.ws-kit-button--clean:hover { text-decoration: underline; }
|
|
40
|
+
}
|
|
41
|
+
.ws-kit-button--primary:active, .ws-kit-button--primary.is-pressed, .ws-kit-button--navy:active, .ws-kit-button--navy.is-pressed { transform: translateY(calc(var(--space-xxs) / 2)); border-bottom-color: transparent; }
|
|
42
|
+
.ws-kit-button--navy:active, .ws-kit-button--navy.is-pressed, .ws-kit-button--shadow:active { box-shadow: none; }
|
|
43
|
+
/* Touch: every act on a public page is a 44 px target. Medium and small keep their look and take the rest as a hit area. */
|
|
44
|
+
@media (pointer: coarse) {
|
|
45
|
+
.ws-kit-button--medium::after, .ws-kit-button--small::after { content: ""; position: absolute; inset: min(0px, calc((100% - var(--ws-touch-public)) / 2)) 0; }
|
|
46
|
+
}
|
|
@@ -6,95 +6,126 @@ The kit's one bounded surface: white, a 4px ceiling on its corners, flat unless
|
|
|
6
6
|
|
|
7
7
|
- A feature section, a pricing plan or a testimonial on a public page needs a bounded surface.
|
|
8
8
|
- The whole block should read as one unit with a header, a body and a footer act (`CardHeader`/`CardContent`/`CardFooter`).
|
|
9
|
-
- A card should visibly react to the pointer because the whole thing is a link
|
|
9
|
+
- A card should visibly react to the pointer because the whole thing is a link: pass `interactive` and make it an `<a>`.
|
|
10
10
|
- A block should recede slightly from the page: `surface="tinted"`, or disappear into it: `surface="transparent"`.
|
|
11
11
|
|
|
12
12
|
## Not for
|
|
13
13
|
|
|
14
14
|
- Any product screen inside a product built on this system: use the product's own card (`ws-card`), which is
|
|
15
|
-
cream, 8px, and never raises a shadow at all, including on hover.
|
|
15
|
+
cream, 8px, rimmed, and never raises a shadow at all, including on hover.
|
|
16
16
|
- A list row with its own hover state: a row, not a card.
|
|
17
17
|
- A floating surface over the page: a dialog or a popover, not this.
|
|
18
18
|
|
|
19
19
|
## Anatomy
|
|
20
20
|
|
|
21
|
-
- The card: `--radius-
|
|
22
|
-
|
|
23
|
-
- `CardHeader
|
|
24
|
-
- `CardTitle
|
|
25
|
-
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
28
|
-
-
|
|
21
|
+
- The card: `--ws-radius-control` (4px) corners, 1px border. White and tinted border in `--color-border-default`;
|
|
22
|
+
transparent in the lighter `--color-border-hairline`. No width of its own; it fills the column it is given.
|
|
23
|
+
- `CardHeader` (`__header`): `--space-lg` (24px) padding on every side, title and description `--space-xs` (8px) apart.
|
|
24
|
+
- `CardTitle` (`__title`): `--font-size-2xl` (26px), medium, 32px line height, `--color-text-heading`. A word wider
|
|
25
|
+
than the card breaks (hyphenated where the page sets `lang`) instead of running out of it.
|
|
26
|
+
- `CardDescription` (`__desc`): `--font-size-sm` (14px), 20px line height, `--color-text-muted`.
|
|
27
|
+
- `CardContent` (`__content`): `--space-lg` padding, no top padding (it sits under the header).
|
|
28
|
+
- `CardFooter` (`__footer`): `--space-lg` padding, no top padding, its acts `--space-sm` (12px) apart, wrapping.
|
|
29
|
+
- No shadow, at rest or on hover, on any surface. `interactive` tints the card on hover: the `--color-nav-hover-bg`
|
|
30
|
+
wash laid over its own surface.
|
|
29
31
|
|
|
30
32
|
## Variants and sizes
|
|
31
33
|
|
|
32
34
|
| Surface | Fill | Border | Use |
|
|
33
35
|
| --- | --- | --- | --- |
|
|
34
|
-
| `white` (default) | `--color-
|
|
35
|
-
| `tinted` | `--
|
|
36
|
+
| `white` (default) | `--color-surface` (white; follows the theme) | `--color-border-default` | the default surface for a feature, plan or quote |
|
|
37
|
+
| `tinted` | `--ws-surface-sunk` | `--color-border-default` | a block that should recede a little |
|
|
36
38
|
| `transparent` | none | `--color-border-hairline` | a block that should all but disappear into the page |
|
|
37
39
|
|
|
38
|
-
`interactive` is a boolean, not a surface: it layers the hover
|
|
40
|
+
`interactive` is a boolean, not a surface: it layers the hover tint onto any of the three.
|
|
41
|
+
|
|
42
|
+
Classes: white is the bare `ws-kit-card`; `ws-kit-card--tinted` and `ws-kit-card--transparent` are the other two
|
|
43
|
+
surfaces; `ws-kit-card--interactive` goes on the `<a>` that is the card.
|
|
39
44
|
|
|
40
45
|
## States
|
|
41
46
|
|
|
42
47
|
- **Default:** flat, the 1px border, no shadow, on every surface.
|
|
43
|
-
- **Hover** (`interactive` only): `--
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
51
|
-
- **Narrow:** the card has no fixed width of its own; it was given one here (180px) to show the title wrapping.
|
|
48
|
+
- **Hover** (`interactive` only): the `--color-nav-hover-bg` tint over the card's own surface, the same wash as
|
|
49
|
+
`KitButton`'s secondary; the edge and words stay. Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
|
|
50
|
+
`.is-hover` draws it in a static preview.
|
|
51
|
+
- **Focus** (`interactive` only): the card is the `<a>`, so it takes the house ring, 2px navy, 2px out.
|
|
52
|
+
- **Selected / pending / error / disabled / empty:** not applicable; disable the link or button inside instead.
|
|
53
|
+
- **Long label:** the title wraps inside the fixed padding; nothing clips.
|
|
54
|
+
- **Narrow:** the card has no fixed width; the preview gives one 200px to show the title wrapping.
|
|
55
|
+
- **Dark:** the surface, edge and words are tokens, so the card follows `data-theme` with nothing extra.
|
|
52
56
|
|
|
53
57
|
## Behaviour
|
|
54
58
|
|
|
55
|
-
- Keyboard:
|
|
56
|
-
|
|
57
|
-
- Pointer: only `interactive` cards react, with the hover
|
|
58
|
-
- Touch: no touch
|
|
59
|
-
- Motion:
|
|
59
|
+
- Keyboard: a static card is a plain `<div>`. A clickable card is an `<a class="ws-kit-card ws-kit-card--interactive">`,
|
|
60
|
+
so it is one target and announces as a link. `interactive` alone changes no semantics.
|
|
61
|
+
- Pointer: only `interactive` cards react, with the hover tint.
|
|
62
|
+
- Touch: no touch rule of its own; the 44px public floor comes from what is tappable inside it (a `KitButton`).
|
|
63
|
+
- Motion: none. The tint is a colour change and lands at once, in every motion setting.
|
|
60
64
|
|
|
61
65
|
## Content
|
|
62
66
|
|
|
63
67
|
- Sentence case, no em dashes.
|
|
64
68
|
- One title per card that names the thing, one short description under it.
|
|
65
|
-
- One footer act at most
|
|
69
|
+
- One footer act at most, a `KitButton`; a second act is a text link. Never the product's `ws-btn` on a public page.
|
|
66
70
|
|
|
67
71
|
## Props
|
|
68
72
|
|
|
69
73
|
| Name | Type | Meaning |
|
|
70
74
|
| --- | --- | --- |
|
|
71
75
|
| `surface` | `'white' \| 'tinted' \| 'transparent'` | the fill, default `white` |
|
|
72
|
-
| `interactive` | `boolean` | adds the hover
|
|
76
|
+
| `interactive` | `boolean` | adds the hover tint and the house focus ring for a card that is a link |
|
|
73
77
|
| `className` | string | merged last, via `tailwind-merge` |
|
|
74
78
|
|
|
75
|
-
`CardHeader`, `CardTitle`, `CardDescription`, `CardContent` and `CardFooter` take no props beyond
|
|
76
|
-
|
|
79
|
+
`CardHeader`, `CardTitle`, `CardDescription`, `CardContent` and `CardFooter` take no props beyond `className` and native
|
|
80
|
+
element attributes; they are plain structural wrappers.
|
|
77
81
|
|
|
78
82
|
## Rules
|
|
79
83
|
|
|
80
84
|
- "4px radius. That is the ceiling for cards, decided 2026-09-21, and it is deliberately tighter than the kit's
|
|
81
|
-
own Feature Card at 8px: a soft corner at card scale reads as a toy
|
|
82
|
-
|
|
83
|
-
on `cardVariants`.)
|
|
84
|
-
- "White by default, not Gray 1. A tinted card on a cream page muddies both... `surface='tinted'` is there for the
|
|
85
|
-
cases that genuinely need to recede." (same doc comment.)
|
|
85
|
+
own Feature Card at 8px: a soft corner at card scale reads as a toy." (`dist/index.d.ts`, doc comment on `cardVariants`.)
|
|
86
|
+
- "White by default, not Gray 1. A tinted card on a cream page muddies both." (same doc comment.)
|
|
86
87
|
- "No shadow by default. Elevation is a signal, and a page where every card is raised has no signal left."
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
- **Hover is a tint, not a lift** (4 Nov 2026, D7, open to Amit's veto): `interactive` used to raise
|
|
89
|
+
`--shadow-card-default` on hover. D7 makes every hover a colour change, and on the dark ground that shadow moved the
|
|
90
|
+
pixels by at most 14 levels of 255, so the hover all but vanished. It is the nav's hover wash now, as `KitButton`'s
|
|
91
|
+
secondary, over whichever surface the card has.
|
|
92
|
+
- **Kit-owned corners** (4 Nov 2026): the corners read `--ws-radius-*`, not Tailwind's `--radius-*`. A shadcn host
|
|
93
|
+
derives `--radius-sm` to `--radius-lg` from its own `--radius` in `@layer theme`, which beats the kit, so in a
|
|
94
|
+
shadcn app the card drew 6px corners, over its 4px ceiling. The `--ws-radius-*` lengths are the kit's alone.
|
|
95
|
+
- **Tinted is the sunk step now** (4 Nov 2026): it was `--color-gray-1` (#F9F9F9), a literal that stayed near white in
|
|
96
|
+
dark. `--ws-surface-sunk` is the house's recede step in both themes; in light it is a touch warmer and deeper.
|
|
97
|
+
- The product's card diverges on purpose: cream, 8px corners, rimmed, never a shadow even when interactive. Both
|
|
98
|
+
stand: this one scoped to a public page, the product's to everything inside a signed-in workspace.
|
|
91
99
|
|
|
92
100
|
## Source
|
|
93
101
|
|
|
94
102
|
- **Derived from**: the kit's own `cardVariants` and `Card`/`CardHeader`/`CardTitle`/`CardDescription`/
|
|
95
|
-
`CardContent`/`CardFooter
|
|
96
|
-
reported rather than resolved: the kit's own doc comment implies `interactive`'s hover uses a named hover
|
|
97
|
-
shadow, but its actual class string reaches for `--shadow-card-default`, leaving `--shadow-card-hover` an
|
|
98
|
-
unused token; this preview follows the code, since code is truth.
|
|
103
|
+
`CardContent`/`CardFooter`, the dark-safe surface names (D12) and the geometry check's title overflow at 180px.
|
|
99
104
|
- **Precedent**: the first product built on the system, whose own card stands apart from this one for every
|
|
100
105
|
signed-in screen.
|
|
106
|
+
|
|
107
|
+
## Markup
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<div class="ws-kit-card">
|
|
111
|
+
<div class="ws-kit-card__header">
|
|
112
|
+
<h3 class="ws-kit-card__title">Daily goals</h3>
|
|
113
|
+
<p class="ws-kit-card__desc">Set once, visible to the whole team every morning.</p>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="ws-kit-card__content"><p class="ws-body">Each agent sees their own number before their first call.</p></div>
|
|
116
|
+
<div class="ws-kit-card__footer"><a class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary" href="/goals">Read more</a></div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div class="ws-kit-card ws-kit-card--tinted">
|
|
120
|
+
<div class="ws-kit-card__header"><h3 class="ws-kit-card__title">Seller leads</h3></div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<a class="ws-kit-card ws-kit-card--interactive" href="/content">
|
|
124
|
+
<div class="ws-kit-card__header">
|
|
125
|
+
<h3 class="ws-kit-card__title">Content</h3>
|
|
126
|
+
<p class="ws-kit-card__desc">Content that keeps you top of mind.</p>
|
|
127
|
+
</div>
|
|
128
|
+
</a>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Styles: the `KitCard` block (`components/KitCard/style.css`), plus `KitButton` for a footer act.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- @dsCard group="Marketing" height=644 -->
|
|
2
2
|
<!doctype html>
|
|
3
|
-
<html>
|
|
3
|
+
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<title>KitCard</title>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<p class="ws-body">Each agent sees their own number, next to the team's, before their first call.</p>
|
|
22
22
|
</div>
|
|
23
23
|
<div class="ws-kit-card__footer">
|
|
24
|
-
<button class="ws-
|
|
24
|
+
<button class="ws-kit-button ws-kit-button--medium ws-kit-button--secondary">Read more</button>
|
|
25
25
|
</div>
|
|
26
26
|
</div></div>
|
|
27
27
|
</div>
|
|
@@ -47,16 +47,24 @@
|
|
|
47
47
|
</div>
|
|
48
48
|
|
|
49
49
|
<div class="ws-stack">
|
|
50
|
-
<span class="ws-muted">Interactive:
|
|
51
|
-
<div
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
<span class="ws-muted">Interactive: the whole card is the link; a tint on hover, never a lift</span>
|
|
51
|
+
<div class="ws-cluster ws-cluster--component ws-cluster--start">
|
|
52
|
+
<a class="ws-kit-card ws-kit-card--interactive" href="#" onclick="return false;" style="width: 260px; max-width: 100%;">
|
|
53
|
+
<div class="ws-kit-card__header">
|
|
54
|
+
<h3 class="ws-kit-card__title">Content</h3>
|
|
55
|
+
<p class="ws-kit-card__desc">At rest: flat, like any card.</p>
|
|
56
|
+
</div>
|
|
57
|
+
</a>
|
|
58
|
+
<a class="ws-kit-card ws-kit-card--interactive is-hover" inert href="#" onclick="return false;" style="width: 260px; max-width: 100%;">
|
|
59
|
+
<div class="ws-kit-card__header">
|
|
60
|
+
<h3 class="ws-kit-card__title">Content</h3>
|
|
61
|
+
<p class="ws-kit-card__desc">Hover: the card tints, nothing lifts.</p>
|
|
62
|
+
</div>
|
|
63
|
+
</a>
|
|
64
|
+
</div>
|
|
57
65
|
</div>
|
|
58
66
|
|
|
59
|
-
<div class="ws-stack" style="width:
|
|
67
|
+
<div class="ws-stack" style="width: 200px; max-width: 100%;">
|
|
60
68
|
<span class="ws-muted">Narrow, and a title long enough to wrap</span>
|
|
61
69
|
<div class="ws-kit-card">
|
|
62
70
|
<div class="ws-kit-card__header">
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* ---- KitCard: the kit's marketing card, white, 4 px corners, the hairline edge; no width of its own ---- */
|
|
2
|
+
.ws-kit-card { min-width: 0; border-radius: var(--ws-radius-control); border: var(--ws-line) solid var(--color-border-default); background: var(--color-surface); }
|
|
3
|
+
.ws-kit-card--tinted { background: var(--ws-surface-sunk); }
|
|
4
|
+
.ws-kit-card--transparent { background: transparent; border-color: var(--color-border-hairline); }
|
|
5
|
+
/* A card that is itself the link: an <a>, so it takes focus (the house ring) and reads as one target. */
|
|
6
|
+
.ws-kit-card--interactive { display: block; color: inherit; text-decoration: none; cursor: pointer; }
|
|
7
|
+
/* Hover is a tint, not a lift (D7): the nav's hover wash laid over whichever surface the card has, as KitButton's
|
|
8
|
+
secondary does. A shadow barely showed on the dark ground. */
|
|
9
|
+
.ws-kit-card--interactive.is-hover { background-image: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)); }
|
|
10
|
+
@media (hover: hover) { .ws-kit-card--interactive:hover { background-image: linear-gradient(var(--color-nav-hover-bg), var(--color-nav-hover-bg)); } }
|
|
11
|
+
.ws-kit-card__header { display: flex; flex-direction: column; gap: var(--space-xs); padding: var(--space-lg); }
|
|
12
|
+
.ws-kit-card__title { font-size: var(--font-size-2xl); line-height: var(--space-xl); font-weight: 500; color: var(--color-text-heading); text-wrap: balance; overflow-wrap: break-word; hyphens: auto; }
|
|
13
|
+
.ws-kit-card__desc { font-size: var(--font-size-sm); line-height: calc(var(--space-md) + var(--space-xxs)); color: var(--color-text-muted); }
|
|
14
|
+
.ws-kit-card__content { padding: 0 var(--space-lg) var(--space-lg); }
|
|
15
|
+
.ws-kit-card__footer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm); padding: 0 var(--space-lg) var(--space-lg); }
|
|
@@ -12,48 +12,49 @@ The kit's one text field: for a lead form, a demo request or a waitlist on a pub
|
|
|
12
12
|
|
|
13
13
|
- Any product screen inside a product built on this system: use the product's own `Input` (32px, 4px radius,
|
|
14
14
|
white ground, mid-blue focus edge).
|
|
15
|
-
- Several lines of text: there is no kit `TextArea`;
|
|
15
|
+
- Several lines of text: there is no kit `TextArea`; the product's `TextArea` is the nearest piece.
|
|
16
16
|
- A checkbox, a radio or a select: the kit ships `Checkbox`, `Radio`/`RadioGroup` and no `Select` at all.
|
|
17
17
|
|
|
18
18
|
## Anatomy
|
|
19
19
|
|
|
20
|
-
- Box: 40px tall, `--radius-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
`--
|
|
26
|
-
-
|
|
20
|
+
- Box: 40px tall (44 on touch), `--ws-radius-row` (6px) corners, the field ground `--ws-field` (white in light), a 1px
|
|
21
|
+
`--color-border-default` edge.
|
|
22
|
+
- Padding: 0 top and bottom (the height centres the words), 12px (`--space-sm`) left and right.
|
|
23
|
+
- Words: `--font-size-sm` (14px; 16px on touch) in `--ws-field-ink`. Placeholder: `--color-text-placeholder`.
|
|
24
|
+
- Label (`__label`, the kit's `Label`): `--font-size-2xs` (12px), medium, 16px line height, `--color-text-body`,
|
|
25
|
+
`--space-xxs` (4px) above the field.
|
|
26
|
+
- Message (`__msg`, hint or error) under the field: 12/16; `--color-text-muted` for a hint,
|
|
27
|
+
`--color-text-error-strong` for an error.
|
|
27
28
|
|
|
28
29
|
## Variants and sizes
|
|
29
30
|
|
|
30
|
-
One size, one look: there is no `size` prop. The only axis is state (default, focus, error, disabled).
|
|
31
|
+
One size, one look: there is no `size` prop. The only axis is state (default, hover, focus, error, disabled).
|
|
31
32
|
|
|
32
33
|
## States
|
|
33
34
|
|
|
34
|
-
- **Default:**
|
|
35
|
-
- **Hover:**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
an accessible error state."
|
|
35
|
+
- **Default:** the field ground, the hairline edge, the placeholder word.
|
|
36
|
+
- **Hover:** the edge firms to the muted word mixed 60% into the field: gray-5 in light, a quiet cool step in dark
|
|
37
|
+
(raw `--color-gray-5` was a bright neutral edge on the dark field). A disabled field does not react, and a field in
|
|
38
|
+
error keeps its salmon edge under the pointer. Only on a pointer that hovers (`@media (hover: hover)`), so a tap on a phone leaves nothing behind.
|
|
39
|
+
- **Focus:** the house ring on `:focus-visible`, 2px `--ws-focus-color` (navy), 2px out. The edge does not change, so
|
|
40
|
+
focus never looks like an error. `.is-focus` draws it in a static preview.
|
|
41
|
+
- **Error:** the edge turns salmon (`--ws-chart-under-half`) and a message appears below in `--color-text-error-strong`, wired by
|
|
42
|
+
`aria-invalid` and `aria-describedby`. The message carries the meaning; the edge is the second cue.
|
|
43
43
|
- **Disabled:** 50% opacity, not editable.
|
|
44
44
|
- **Empty / loading:** not applicable; a text field has no loading state of its own.
|
|
45
|
-
- **Long label / narrow:** the label wraps onto a second line above the field; the field
|
|
46
|
-
|
|
47
|
-
- **Touch:**
|
|
48
|
-
|
|
45
|
+
- **Long label / narrow:** the label wraps onto a second line above the field; the field keeps its height and takes
|
|
46
|
+
its container's width; a long value scrolls inside the field.
|
|
47
|
+
- **Touch:** 44px tall (`--ws-touch-public`), the public page's floor, with 16px words so a phone does not zoom the
|
|
48
|
+
page when the field takes focus.
|
|
49
49
|
|
|
50
50
|
## Behaviour
|
|
51
51
|
|
|
52
|
-
- Keyboard: a real `<input>`; Tab moves to and from it in document order; the label's `
|
|
52
|
+
- Keyboard: a real `<input>`; Tab moves to and from it in document order; the label's `for` makes a click on
|
|
53
53
|
the label focus the field.
|
|
54
|
-
- Pointer: hover changes the
|
|
55
|
-
- Touch: the native
|
|
56
|
-
|
|
54
|
+
- Pointer: hover changes the edge only.
|
|
55
|
+
- Touch: the native keyboard and autofill behave as the browser provides. Give every field about the person its
|
|
56
|
+
`type` and `autocomplete` (`email`, `organization`, `tel`).
|
|
57
|
+
- Motion: the edge colour moves over 150ms (`--transition-fast`), only under `prefers-reduced-motion: no-preference`.
|
|
57
58
|
|
|
58
59
|
## Content
|
|
59
60
|
|
|
@@ -64,7 +65,9 @@ One size, one look: there is no `size` prop. The only axis is state (default, fo
|
|
|
64
65
|
|
|
65
66
|
## Props
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
The React `Input` (`@felloinnovations/brand-kit`) renders this field with Tailwind utilities on the same tokens.
|
|
69
|
+
|
|
70
|
+
| Prop | Type | Meaning |
|
|
68
71
|
| --- | --- | --- |
|
|
69
72
|
| `label` | `string` | rendered above the field via the kit's `Label` |
|
|
70
73
|
| `error` | `string` | its presence puts the field in the error state and wires `aria-invalid`/`aria-describedby` |
|
|
@@ -73,19 +76,31 @@ One size, one look: there is no `size` prop. The only axis is state (default, fo
|
|
|
73
76
|
|
|
74
77
|
## Rules
|
|
75
78
|
|
|
76
|
-
- "40px tall, 6px radius, 1px Gray Stroke,
|
|
77
|
-
|
|
79
|
+
- "40px tall, 6px radius, 1px Gray Stroke, 12px sides, 14px words, salmon border on error" (`dist/index.d.ts`, doc
|
|
80
|
+
comment on `Input`, citing `docs-cache/design-system/cards-and-components.md §3`).
|
|
78
81
|
- "`error` is a string, not a boolean, because an error state with no message is not an accessible error state."
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
field
|
|
83
|
-
|
|
84
|
-
which is the divergence this component's README is pointing at.
|
|
82
|
+
- **Focus is the house ring now** (D8, 4 Nov 2026). The old salmon edge and salmon halo were the error's colour, so a
|
|
83
|
+
field being typed in read as refused, and the halo was 1.21:1 on the cream.
|
|
84
|
+
- **44px on touch** (4 Nov 2026): closes the open item "KitInput 40 px against the public page's 44 px floor". The
|
|
85
|
+
desktop field stays 40, the kit's drawn size.
|
|
86
|
+
- The error word is `--color-text-error-strong` (AA); the old `--color-feedback-error` was 3.0:1 on white.
|
|
85
87
|
|
|
86
88
|
## Source
|
|
87
89
|
|
|
88
|
-
- **Derived from**: the kit's own `Input` and `Label
|
|
89
|
-
|
|
90
|
-
- **Precedent**: the first product built on the system, whose own `Input` took the mid-blue focus
|
|
91
|
-
|
|
90
|
+
- **Derived from**: the kit's own `Input` and `Label`, its gap table on the focus-ring contradiction, the house focus
|
|
91
|
+
ring (D8), the dark-safe field names (D12) and the touch floors (`14-accessibility.md`).
|
|
92
|
+
- **Precedent**: the first product built on the system, whose own `Input` took the mid-blue focus stopgap.
|
|
93
|
+
|
|
94
|
+
## Markup
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<div class="ws-kit-input">
|
|
98
|
+
<label class="ws-kit-input__label" for="demo-email">Work email</label>
|
|
99
|
+
<input class="ws-kit-input__control" id="demo-email" type="email" autocomplete="email" placeholder="you@teamname.com" aria-describedby="demo-email-msg">
|
|
100
|
+
<p class="ws-kit-input__msg" id="demo-email-msg">We send the invite here.</p>
|
|
101
|
+
</div>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
For an error, add `aria-invalid="true"` to the input and `ws-kit-input__msg--error` to the message.
|
|
105
|
+
|
|
106
|
+
Styles: the `KitInput` block (`components/KitInput/style.css`), in `fello.css`. Nothing else.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- @dsCard group="Marketing" height=316 -->
|
|
2
2
|
<!doctype html>
|
|
3
|
-
<html>
|
|
3
|
+
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<title>KitInput</title>
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
<span class="ws-muted">Default, with a label</span>
|
|
15
15
|
<div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
|
|
16
16
|
<label class="ws-kit-input__label" for="ki-email">Work email</label>
|
|
17
|
-
<input class="ws-kit-input__control" id="ki-email" type="email" placeholder="you@teamname.com">
|
|
17
|
+
<input class="ws-kit-input__control" id="ki-email" type="email" autocomplete="email" placeholder="you@teamname.com">
|
|
18
18
|
</div></div>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
<div class="ws-stack">
|
|
22
|
-
<span class="ws-muted">Focus: the
|
|
21
|
+
<div class="ws-stack" inert>
|
|
22
|
+
<span class="ws-muted">Focus: the 2px navy ring, 2px out</span>
|
|
23
23
|
<div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
|
|
24
24
|
<label class="ws-kit-input__label" for="ki-name">Team name</label>
|
|
25
|
-
<input class="ws-kit-input__control is-focus" id="ki-name" value="Nair Realty Group">
|
|
25
|
+
<input class="ws-kit-input__control is-focus" id="ki-name" autocomplete="organization" value="Nair Realty Group">
|
|
26
26
|
</div></div>
|
|
27
27
|
</div>
|
|
28
28
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span class="ws-muted">With a hint</span>
|
|
31
31
|
<div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
|
|
32
32
|
<label class="ws-kit-input__label" for="ki-size">Team size</label>
|
|
33
|
-
<input class="ws-kit-input__control" id="ki-size" aria-describedby="ki-size-hint" placeholder="12">
|
|
33
|
+
<input class="ws-kit-input__control" id="ki-size" inputmode="numeric" aria-describedby="ki-size-hint" placeholder="12">
|
|
34
34
|
<p class="ws-kit-input__msg" id="ki-size-hint">Agents on the team today, not counting admin.</p>
|
|
35
35
|
</div></div>
|
|
36
36
|
</div>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<span class="ws-muted">Error: a string, not a boolean, so the reason is always on screen</span>
|
|
40
40
|
<div style="width: 220px; max-width: 100%;"><div class="ws-kit-input">
|
|
41
41
|
<label class="ws-kit-input__label" for="ki-email-err">Work email</label>
|
|
42
|
-
<input class="ws-kit-input__control is-error" id="ki-email-err" aria-invalid="true" aria-describedby="ki-email-err-msg" value="priya@">
|
|
42
|
+
<input class="ws-kit-input__control is-error" id="ki-email-err" type="email" autocomplete="email" aria-invalid="true" aria-describedby="ki-email-err-msg" value="priya@">
|
|
43
43
|
<p class="ws-kit-input__msg ws-kit-input__msg--error" id="ki-email-err-msg">Enter a work email we can reach you at.</p>
|
|
44
44
|
</div></div>
|
|
45
45
|
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* ---- KitInput: the kit's marketing field, 40 px (44 and 16 px words on touch), on the field ground, the house focus ring ---- */
|
|
2
|
+
.ws-kit-input { display: flex; flex-direction: column; gap: var(--space-xxs); min-width: 0; }
|
|
3
|
+
.ws-kit-input__label { font-size: var(--font-size-2xs); font-weight: 500; line-height: var(--space-md); color: var(--color-text-body); }
|
|
4
|
+
.ws-kit-input__control { height: var(--space-2xl); width: 100%; border-radius: var(--ws-radius-row); padding: 0 var(--space-sm); background: var(--ws-field); border: var(--ws-line) solid var(--color-border-default); font-size: var(--font-size-sm); color: var(--ws-field-ink); }
|
|
5
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
6
|
+
.ws-kit-input__control { transition: border-color var(--transition-fast); }
|
|
7
|
+
}
|
|
8
|
+
.ws-kit-input__control::placeholder { color: var(--color-text-placeholder); }
|
|
9
|
+
/* Hover firms the edge to the controls' hover edge (--ws-edge-hover: North's warm grey in light, a cool step in dark,
|
|
10
|
+
where raw gray-5 would be a bright neutral edge on the navy-black field). A disabled field does not
|
|
11
|
+
react; :where keeps the selector's weight, so the error edge below still wins. Pointers that hover only: a tap
|
|
12
|
+
would leave the edge firmed. */
|
|
13
|
+
@media (hover: hover) { .ws-kit-input__control:hover:where(:not(:disabled)) { border-color: var(--ws-edge-hover); } }
|
|
14
|
+
/* Focus is the house ring on :focus-visible (2 px navy, 2 px out); .is-focus draws it in a static preview. */
|
|
15
|
+
.ws-kit-input__control.is-focus { outline: var(--ws-focus-width) solid var(--ws-focus-color); outline-offset: var(--ws-focus-offset); }
|
|
16
|
+
.ws-kit-input__control[aria-invalid="true"], .ws-kit-input__control.is-error { border-color: var(--ws-chart-under-half); }
|
|
17
|
+
.ws-kit-input__control:disabled { cursor: not-allowed; opacity: 0.5; }
|
|
18
|
+
.ws-kit-input__msg { font-size: var(--font-size-2xs); line-height: var(--space-md); color: var(--color-text-muted); }
|
|
19
|
+
.ws-kit-input__msg--error { color: var(--color-text-error-strong); }
|
|
20
|
+
/* Touch: the public page's 44 px target, and 16 px words so a phone does not zoom the page when the field takes focus. */
|
|
21
|
+
@media (pointer: coarse) {
|
|
22
|
+
.ws-kit-input__control { height: var(--ws-touch-public); font-size: var(--font-size-md); }
|
|
23
|
+
}
|