@once-ui-system/core 1.7.11 → 1.7.12
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/ai/catalog.json +1650 -0
- package/ai/catalog.seed.json +411 -0
- package/ai/components/Accordion.json +136 -0
- package/ai/components/AccordionGroup.json +128 -0
- package/ai/components/Animation.json +146 -0
- package/ai/components/Arrow.json +128 -0
- package/ai/components/AutoScroll.json +130 -0
- package/ai/components/Avatar.json +133 -0
- package/ai/components/AvatarGroup.json +129 -0
- package/ai/components/Background.json +131 -0
- package/ai/components/Badge.json +132 -0
- package/ai/components/Banner.json +122 -0
- package/ai/components/BarChart.json +123 -0
- package/ai/components/BlobFx.json +125 -0
- package/ai/components/BlockQuote.json +132 -0
- package/ai/components/Button.json +26 -0
- package/ai/components/Card.json +129 -0
- package/ai/components/Carousel.json +134 -0
- package/ai/components/CelebrationFx.json +132 -0
- package/ai/components/ChartHeader.json +130 -0
- package/ai/components/ChartStatus.json +12 -0
- package/ai/components/Checkbox.json +13 -0
- package/ai/components/Chip.json +132 -0
- package/ai/components/CodeBlock.json +122 -0
- package/ai/components/ColorInput.json +13 -0
- package/ai/components/Column.json +128 -0
- package/ai/components/CompareImage.json +126 -0
- package/ai/components/ContextMenu.json +22 -0
- package/ai/components/CountFx.json +82 -0
- package/ai/components/CountdownFx.json +11 -0
- package/ai/components/Cursor.json +9 -0
- package/ai/components/CursorCard.json +128 -0
- package/ai/components/DataTooltip.json +15 -0
- package/ai/components/DateInput.json +21 -0
- package/ai/components/DatePicker.json +143 -0
- package/ai/components/DateRangeInput.json +18 -0
- package/ai/components/DateRangePicker.json +129 -0
- package/ai/components/Dialog.json +134 -0
- package/ai/components/DialogProvider.json +8 -0
- package/ai/components/Dropdown.json +128 -0
- package/ai/components/DropdownWrapper.json +28 -0
- package/ai/components/EmojiPicker.json +129 -0
- package/ai/components/EmojiPickerDropdown.json +13 -0
- package/ai/components/Fade.json +130 -0
- package/ai/components/FadingLettersFx.json +77 -0
- package/ai/components/Feedback.json +132 -0
- package/ai/components/Flex.json +125 -0
- package/ai/components/FlipFx.json +133 -0
- package/ai/components/GlitchFx.json +128 -0
- package/ai/components/Grid.json +121 -0
- package/ai/components/Heading.json +75 -0
- package/ai/components/HeadingLink.json +127 -0
- package/ai/components/HeadingNav.json +124 -0
- package/ai/components/HoloFx.json +128 -0
- package/ai/components/Hover.json +130 -0
- package/ai/components/HoverCard.json +122 -0
- package/ai/components/Icon.json +132 -0
- package/ai/components/IconButton.json +22 -0
- package/ai/components/InfiniteScroll.json +130 -0
- package/ai/components/InlineCode.json +126 -0
- package/ai/components/Input.json +24 -0
- package/ai/components/InteractiveDetails.json +14 -0
- package/ai/components/Kbar.json +10 -0
- package/ai/components/Kbd.json +127 -0
- package/ai/components/Legend.json +14 -0
- package/ai/components/LetterFx.json +14 -0
- package/ai/components/Line.json +125 -0
- package/ai/components/LineBarChart.json +123 -0
- package/ai/components/LineChart.json +123 -0
- package/ai/components/LinearGauge.json +130 -0
- package/ai/components/LinearGradient.json +15 -0
- package/ai/components/List.json +127 -0
- package/ai/components/ListItem.json +77 -0
- package/ai/components/Logo.json +16 -0
- package/ai/components/LogoCloud.json +124 -0
- package/ai/components/Mask.json +131 -0
- package/ai/components/MasonryGrid.json +132 -0
- package/ai/components/MatrixFx.json +135 -0
- package/ai/components/Media.json +142 -0
- package/ai/components/MediaUpload.json +122 -0
- package/ai/components/MegaMenu.json +125 -0
- package/ai/components/MobileMegaMenu.json +125 -0
- package/ai/components/Modal.json +12 -0
- package/ai/components/NavIcon.json +127 -0
- package/ai/components/NumberInput.json +16 -0
- package/ai/components/OTPInput.json +13 -0
- package/ai/components/OgCard.json +135 -0
- package/ai/components/Option.json +137 -0
- package/ai/components/Particle.json +135 -0
- package/ai/components/PasswordInput.json +8 -0
- package/ai/components/PieChart.json +123 -0
- package/ai/components/ProgressBar.json +131 -0
- package/ai/components/Pulse.json +129 -0
- package/ai/components/RadialGauge.json +134 -0
- package/ai/components/RadialGradient.json +16 -0
- package/ai/components/RadioButton.json +17 -0
- package/ai/components/RevealFx.json +131 -0
- package/ai/components/Row.json +128 -0
- package/ai/components/Schema.json +17 -0
- package/ai/components/ScrollContainer.json +126 -0
- package/ai/components/ScrollToTop.json +124 -0
- package/ai/components/Scroller.json +128 -0
- package/ai/components/SegmentedControl.json +132 -0
- package/ai/components/Select.json +21 -0
- package/ai/components/ShineFx.json +80 -0
- package/ai/components/Skeleton.json +129 -0
- package/ai/components/Slider.json +17 -0
- package/ai/components/SmartLink.json +17 -0
- package/ai/components/Spinner.json +127 -0
- package/ai/components/SplitView.json +129 -0
- package/ai/components/StatusIndicator.json +128 -0
- package/ai/components/StyleOverlay.json +126 -0
- package/ai/components/StylePanel.json +125 -0
- package/ai/components/Swiper.json +130 -0
- package/ai/components/Switch.json +20 -0
- package/ai/components/Table.json +125 -0
- package/ai/components/Tag.json +129 -0
- package/ai/components/TagInput.json +12 -0
- package/ai/components/Text.json +72 -0
- package/ai/components/Textarea.json +24 -0
- package/ai/components/ThemeSwitcher.json +122 -0
- package/ai/components/TiltFx.json +126 -0
- package/ai/components/Timeline.json +126 -0
- package/ai/components/Toast.json +13 -0
- package/ai/components/Toaster.json +14 -0
- package/ai/components/ToggleButton.json +24 -0
- package/ai/components/Tooltip.json +129 -0
- package/ai/components/TypeFx.json +15 -0
- package/ai/components/User.json +15 -0
- package/ai/components/UserMenu.json +16 -0
- package/ai/components/WeatherFx.json +133 -0
- package/ai/examples/auth.tsx +105 -0
- package/ai/examples/blocks/Background6.tsx +25 -0
- package/ai/examples/blocks/Chat1.tsx +70 -0
- package/ai/examples/blocks/Dashboard1.tsx +404 -0
- package/ai/examples/blocks/Feed3.tsx +151 -0
- package/ai/examples/blocks/Footer1.tsx +30 -0
- package/ai/examples/blocks/Footer2.tsx +96 -0
- package/ai/examples/blocks/Footer3.tsx +127 -0
- package/ai/examples/blocks/Footer4.tsx +406 -0
- package/ai/examples/blocks/Header1.tsx +370 -0
- package/ai/examples/blocks/Header2.tsx +98 -0
- package/ai/examples/blocks/Header3.tsx +133 -0
- package/ai/examples/blocks/Header4.tsx +123 -0
- package/ai/examples/blocks/Productivity1.tsx +318 -0
- package/ai/examples/blocks/Roadmap1.tsx +133 -0
- package/ai/examples/blocks/Sidebar1.tsx +34 -0
- package/ai/examples/blocks/Sidebar2.tsx +17 -0
- package/ai/examples/blocks/Sidebar4.tsx +92 -0
- package/ai/examples/blocks/Sidebar5.tsx +73 -0
- package/ai/examples/blocks/Streaming1.tsx +353 -0
- package/ai/examples/blocks/Table1.tsx +303 -0
- package/ai/examples/blocks/Waitlist1.tsx +141 -0
- package/ai/examples/blocks/content/chat1content.ts +65 -0
- package/ai/examples/blocks/content/resources.ts +5 -0
- package/ai/examples/blocks/content/roadmap1content.ts +51 -0
- package/ai/examples/blocks/manifest.json +191 -0
- package/ai/examples/dashboard.tsx +150 -0
- package/ai/examples/marketing-hero.tsx +152 -0
- package/ai/examples/pricing.tsx +219 -0
- package/ai/examples/settings.tsx +140 -0
- package/ai/gotchas.json +85 -0
- package/ai/manifest.json +21 -0
- package/ai/rules.compact.md +73 -0
- package/ai/spec.json +2679 -2701
- package/ai/tasks/auth.json +23 -0
- package/ai/tasks/chat.json +28 -0
- package/ai/tasks/dashboard.json +39 -0
- package/ai/tasks/index.json +12 -0
- package/ai/tasks/marketing-hero.json +38 -0
- package/ai/tasks/pricing.json +42 -0
- package/ai/tasks/roadmap.json +22 -0
- package/ai/tasks/settings.json +34 -0
- package/dist/ai/catalog.json +1650 -0
- package/dist/ai/catalog.seed.json +411 -0
- package/dist/ai/components/Accordion.json +136 -0
- package/dist/ai/components/AccordionGroup.json +128 -0
- package/dist/ai/components/Animation.json +146 -0
- package/dist/ai/components/Arrow.json +128 -0
- package/dist/ai/components/AutoScroll.json +130 -0
- package/dist/ai/components/Avatar.json +133 -0
- package/dist/ai/components/AvatarGroup.json +129 -0
- package/dist/ai/components/Background.json +131 -0
- package/dist/ai/components/Badge.json +132 -0
- package/dist/ai/components/Banner.json +122 -0
- package/dist/ai/components/BarChart.json +123 -0
- package/dist/ai/components/BlobFx.json +125 -0
- package/dist/ai/components/BlockQuote.json +132 -0
- package/dist/ai/components/Button.json +26 -0
- package/dist/ai/components/Card.json +129 -0
- package/dist/ai/components/Carousel.json +134 -0
- package/dist/ai/components/CelebrationFx.json +132 -0
- package/dist/ai/components/ChartHeader.json +130 -0
- package/dist/ai/components/ChartStatus.json +12 -0
- package/dist/ai/components/Checkbox.json +13 -0
- package/dist/ai/components/Chip.json +132 -0
- package/dist/ai/components/CodeBlock.json +122 -0
- package/dist/ai/components/ColorInput.json +13 -0
- package/dist/ai/components/Column.json +128 -0
- package/dist/ai/components/CompareImage.json +126 -0
- package/dist/ai/components/ContextMenu.json +22 -0
- package/dist/ai/components/CountFx.json +82 -0
- package/dist/ai/components/CountdownFx.json +11 -0
- package/dist/ai/components/Cursor.json +9 -0
- package/dist/ai/components/CursorCard.json +128 -0
- package/dist/ai/components/DataTooltip.json +15 -0
- package/dist/ai/components/DateInput.json +21 -0
- package/dist/ai/components/DatePicker.json +143 -0
- package/dist/ai/components/DateRangeInput.json +18 -0
- package/dist/ai/components/DateRangePicker.json +129 -0
- package/dist/ai/components/Dialog.json +134 -0
- package/dist/ai/components/DialogProvider.json +8 -0
- package/dist/ai/components/Dropdown.json +128 -0
- package/dist/ai/components/DropdownWrapper.json +28 -0
- package/dist/ai/components/EmojiPicker.json +129 -0
- package/dist/ai/components/EmojiPickerDropdown.json +13 -0
- package/dist/ai/components/Fade.json +130 -0
- package/dist/ai/components/FadingLettersFx.json +77 -0
- package/dist/ai/components/Feedback.json +132 -0
- package/dist/ai/components/Flex.json +125 -0
- package/dist/ai/components/FlipFx.json +133 -0
- package/dist/ai/components/GlitchFx.json +128 -0
- package/dist/ai/components/Grid.json +121 -0
- package/dist/ai/components/Heading.json +75 -0
- package/dist/ai/components/HeadingLink.json +127 -0
- package/dist/ai/components/HeadingNav.json +124 -0
- package/dist/ai/components/HoloFx.json +128 -0
- package/dist/ai/components/Hover.json +130 -0
- package/dist/ai/components/HoverCard.json +122 -0
- package/dist/ai/components/Icon.json +132 -0
- package/dist/ai/components/IconButton.json +22 -0
- package/dist/ai/components/InfiniteScroll.json +130 -0
- package/dist/ai/components/InlineCode.json +126 -0
- package/dist/ai/components/Input.json +24 -0
- package/dist/ai/components/InteractiveDetails.json +14 -0
- package/dist/ai/components/Kbar.json +10 -0
- package/dist/ai/components/Kbd.json +127 -0
- package/dist/ai/components/Legend.json +14 -0
- package/dist/ai/components/LetterFx.json +14 -0
- package/dist/ai/components/Line.json +125 -0
- package/dist/ai/components/LineBarChart.json +123 -0
- package/dist/ai/components/LineChart.json +123 -0
- package/dist/ai/components/LinearGauge.json +130 -0
- package/dist/ai/components/LinearGradient.json +15 -0
- package/dist/ai/components/List.json +127 -0
- package/dist/ai/components/ListItem.json +77 -0
- package/dist/ai/components/Logo.json +16 -0
- package/dist/ai/components/LogoCloud.json +124 -0
- package/dist/ai/components/Mask.json +131 -0
- package/dist/ai/components/MasonryGrid.json +132 -0
- package/dist/ai/components/MatrixFx.json +135 -0
- package/dist/ai/components/Media.json +142 -0
- package/dist/ai/components/MediaUpload.json +122 -0
- package/dist/ai/components/MegaMenu.json +125 -0
- package/dist/ai/components/MobileMegaMenu.json +125 -0
- package/dist/ai/components/Modal.json +12 -0
- package/dist/ai/components/NavIcon.json +127 -0
- package/dist/ai/components/NumberInput.json +16 -0
- package/dist/ai/components/OTPInput.json +13 -0
- package/dist/ai/components/OgCard.json +135 -0
- package/dist/ai/components/Option.json +137 -0
- package/dist/ai/components/Particle.json +135 -0
- package/dist/ai/components/PasswordInput.json +8 -0
- package/dist/ai/components/PieChart.json +123 -0
- package/dist/ai/components/ProgressBar.json +131 -0
- package/dist/ai/components/Pulse.json +129 -0
- package/dist/ai/components/RadialGauge.json +134 -0
- package/dist/ai/components/RadialGradient.json +16 -0
- package/dist/ai/components/RadioButton.json +17 -0
- package/dist/ai/components/RevealFx.json +131 -0
- package/dist/ai/components/Row.json +128 -0
- package/dist/ai/components/Schema.json +17 -0
- package/dist/ai/components/ScrollContainer.json +126 -0
- package/dist/ai/components/ScrollToTop.json +124 -0
- package/dist/ai/components/Scroller.json +128 -0
- package/dist/ai/components/SegmentedControl.json +132 -0
- package/dist/ai/components/Select.json +21 -0
- package/dist/ai/components/ShineFx.json +80 -0
- package/dist/ai/components/Skeleton.json +129 -0
- package/dist/ai/components/Slider.json +17 -0
- package/dist/ai/components/SmartLink.json +17 -0
- package/dist/ai/components/Spinner.json +127 -0
- package/dist/ai/components/SplitView.json +129 -0
- package/dist/ai/components/StatusIndicator.json +128 -0
- package/dist/ai/components/StyleOverlay.json +126 -0
- package/dist/ai/components/StylePanel.json +125 -0
- package/dist/ai/components/Swiper.json +130 -0
- package/dist/ai/components/Switch.json +20 -0
- package/dist/ai/components/Table.json +125 -0
- package/dist/ai/components/Tag.json +129 -0
- package/dist/ai/components/TagInput.json +12 -0
- package/dist/ai/components/Text.json +72 -0
- package/dist/ai/components/Textarea.json +24 -0
- package/dist/ai/components/ThemeSwitcher.json +122 -0
- package/dist/ai/components/TiltFx.json +126 -0
- package/dist/ai/components/Timeline.json +126 -0
- package/dist/ai/components/Toast.json +13 -0
- package/dist/ai/components/Toaster.json +14 -0
- package/dist/ai/components/ToggleButton.json +24 -0
- package/dist/ai/components/Tooltip.json +129 -0
- package/dist/ai/components/TypeFx.json +15 -0
- package/dist/ai/components/User.json +15 -0
- package/dist/ai/components/UserMenu.json +16 -0
- package/dist/ai/components/WeatherFx.json +133 -0
- package/dist/ai/eval-tasks.md +71 -0
- package/dist/ai/examples/blocks/manifest.json +191 -0
- package/dist/ai/gotchas.json +85 -0
- package/dist/ai/manifest.json +21 -0
- package/dist/ai/recipes.md +149 -0
- package/dist/ai/rules.compact.md +73 -0
- package/dist/ai/rules.md +217 -0
- package/dist/ai/spec.json +2680 -0
- package/dist/ai/tasks/auth.json +23 -0
- package/dist/ai/tasks/chat.json +28 -0
- package/dist/ai/tasks/dashboard.json +39 -0
- package/dist/ai/tasks/index.json +12 -0
- package/dist/ai/tasks/marketing-hero.json +38 -0
- package/dist/ai/tasks/pricing.json +42 -0
- package/dist/ai/tasks/roadmap.json +22 -0
- package/dist/ai/tasks/settings.json +34 -0
- package/dist/data/emoji-data.json +0 -18
- package/dist/package.json +13 -2
- package/package.json +139 -127
- package/LICENSE.md +0 -21
- package/next-env.d.ts +0 -5
package/dist/ai/rules.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Once UI — code generation rules
|
|
2
|
+
|
|
3
|
+
Rules for writing Once UI code. Follow every rule; each shows the correct form first.
|
|
4
|
+
|
|
5
|
+
## Before you build
|
|
6
|
+
|
|
7
|
+
When the request doesn't specify design intent, ask these five questions first (one short message, all at once), then build:
|
|
8
|
+
|
|
9
|
+
1. **Content style** — bold / restrained / conservative?
|
|
10
|
+
2. **Layout** — wide or narrow, centered or left-aligned?
|
|
11
|
+
3. **Color** — single accent, bold colors, visually distinct sections?
|
|
12
|
+
4. **Decoration** — gradients, MatrixFx, animated blobs, none?
|
|
13
|
+
5. **Imagery** — placeholder images, or avatars/logos/icons only?
|
|
14
|
+
|
|
15
|
+
If you can't ask (or the user says "you decide"), default to: restrained, centered with `maxWidth="m"` content, single brand accent, one subtle gradient (recipes.md #1), no placeholder images (use `Avatar`, `Logo`, `Icon`).
|
|
16
|
+
|
|
17
|
+
## Layout primitives
|
|
18
|
+
|
|
19
|
+
1. Use `Row` and `Column` for layout. `Flex` with `direction` is only for dynamic direction.
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// Good
|
|
23
|
+
<Column gap="16">...</Column>
|
|
24
|
+
// Bad
|
|
25
|
+
<Flex direction="column" gap="16">...</Flex>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Use shorthands — they replace multi-prop combinations:
|
|
29
|
+
|
|
30
|
+
| Write | Instead of |
|
|
31
|
+
|-------|------------|
|
|
32
|
+
| `fill` | `fillWidth fillHeight` |
|
|
33
|
+
| `fit` | `fitWidth fitHeight` |
|
|
34
|
+
| `center` | `horizontal="center" vertical="center"` |
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
// Good
|
|
38
|
+
<Row fill center>...</Row>
|
|
39
|
+
// Bad
|
|
40
|
+
<Row fillWidth fillHeight horizontal="center" vertical="center">...</Row>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. Never write a prop that equals its default. The spec marks defaults with `= value`. Common offenders:
|
|
44
|
+
- `position="relative"` (default on all layout components)
|
|
45
|
+
- `direction="row"` on `Row`, `direction="column"` on `Column`
|
|
46
|
+
- `variant="primary"`, `size="m"` on `Button`
|
|
47
|
+
|
|
48
|
+
## Spacing and sizing
|
|
49
|
+
|
|
50
|
+
4. Use spacing tokens, never raw CSS: `gap`, `padding`, `margin`, `paddingX/Y`, `marginX/Y` accept tokens (`"2" "4" "8" "12" "16" "20" "24" "32" "40" "48" "64"` or `"xs" "s" "m" "l" "xl"`).
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
// Good
|
|
54
|
+
<Column gap="8" padding="24">
|
|
55
|
+
// Bad
|
|
56
|
+
<div style={{ gap: 8, padding: 24 }}>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
5. `width`/`height`/`maxWidth`/`minHeight` accept numbers (rem), tokens, or CSS units. Prefer numbers/tokens.
|
|
60
|
+
|
|
61
|
+
6. Only use `style={{}}` for things no token prop covers (e.g. `isolation`, custom filters). If a prop exists, the prop wins.
|
|
62
|
+
|
|
63
|
+
## Color and surfaces
|
|
64
|
+
|
|
65
|
+
7. Colors are semantic tokens, never hex/rgb: `{scheme}-{weight}` or `{scheme}-alpha-{weight}` where scheme = `neutral | brand | accent | info | danger | warning | success` and weight = `weak | medium | strong`.
|
|
66
|
+
- `background` also accepts `surface | overlay | page | transparent`
|
|
67
|
+
- `onBackground` colors text/icons on a background
|
|
68
|
+
|
|
69
|
+
8. Standard surface recipe: `background="surface"` (or `"overlay"` over imagery) + `border="neutral-alpha-weak"` (or `-medium`) + `radius="l"`.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Column background="surface" border="neutral-alpha-weak" radius="l" padding="24" gap="16">
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Text
|
|
76
|
+
|
|
77
|
+
9. Use `Text` and `Heading` with `variant="{type}-{weight}-{size}"`: type = `body | heading | display | label | code`, weight = `default | strong`, size = `xs | s | m | l | xl`. Examples: `body-default-m`, `heading-strong-s`, `label-default-s`, `display-strong-m`.
|
|
78
|
+
|
|
79
|
+
10. If a layout component only wraps text, put `textVariant` (and `onBackground`) directly on it instead of nesting a `Text`:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
// Good
|
|
83
|
+
<Row textVariant="label-default-s" onBackground="neutral-weak">Updated today</Row>
|
|
84
|
+
// Bad
|
|
85
|
+
<Row><Text variant="label-default-s" onBackground="neutral-weak">Updated today</Text></Row>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Responsive
|
|
89
|
+
|
|
90
|
+
11. Use breakpoint props (`xl l m s xs`) with override objects — never media queries or conditional rendering for layout:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Row gap="24" s={{ direction: "column" }}>
|
|
94
|
+
<Grid columns="3" s={{ columns: 1 }}>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Components over primitives
|
|
98
|
+
|
|
99
|
+
12. Reach for the purpose-built component before composing primitives:
|
|
100
|
+
- `Card` is for **interactive** surfaces only (`href` or `onClick`). Static panels (pricing tiers, testimonials, stat boxes) = `Column`/`Row` with the surface recipe (#8), not `Card`
|
|
101
|
+
- Image/video → `Media`, not `img`
|
|
102
|
+
- Links → `SmartLink` / `Button href`, not `a`
|
|
103
|
+
- Status dot → `StatusIndicator`; progress → `ProgressBar`; loading → `Spinner` / `Skeleton`
|
|
104
|
+
- Labels/metadata → `Tag`, `Chip`, `Badge`, `Kbd`, `InlineCode`
|
|
105
|
+
|
|
106
|
+
13. Use the distinctive features when the design calls for them — they exist and are cheap:
|
|
107
|
+
- `Dialog` supports `stack` (stacked dialogs) and `base` props
|
|
108
|
+
- Effects: `RevealFx`, `LetterFx`, `TypeFx`, `CountFx`, `GlitchFx`, `HoloFx`, `TiltFx`, `FlipFx`, `MatrixFx`, `BlobFx`, `Particle`, `ShineFx`, `CelebrationFx`
|
|
109
|
+
- `CursorCard`, `HoverCard`, `ContextMenu`, `EmojiPicker`, `CompareImage`, `OgCard`, `Timeline`, `MasonryGrid`, `InfiniteScroll`, `SegmentedControl`, `Kbar` (command palette)
|
|
110
|
+
- Forms: `Input`, `PasswordInput`, `OTPInput`, `NumberInput`, `TagInput`, `Select`, `DatePicker`, `DateRangePicker`, `ColorInput`, `Slider`, `Switch`, `Checkbox`, `Chip`
|
|
111
|
+
|
|
112
|
+
14. Buttons: `variant` = `primary | secondary | tertiary | danger`; pair with `prefixIcon`/`suffixIcon` (icon names, not elements). `IconButton` for icon-only actions with `tooltip`.
|
|
113
|
+
|
|
114
|
+
14b. Icon names must come from the `IconName` list in spec.json — never invent names (`more`, `bell`, and `arrowRight` don't exist; `close`, `chevronRight`, and `smiley` do). If no icon fits, omit the icon.
|
|
115
|
+
|
|
116
|
+
14c. Components with a text prop render it — never pass the same text as both prop and children, it renders twice:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
// Good
|
|
120
|
+
<Badge>{unread}</Badge> or <Tag size="s">Save 20%</Tag>
|
|
121
|
+
// Bad: renders "2 unread2" / "Save 20%Save 20%"
|
|
122
|
+
<Badge title={`${unread} unread`}>{unread}</Badge>
|
|
123
|
+
<Tag label="Save 20%">Save 20%</Tag>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
14d. `Fade` is an **edge overlay strip** (scroll-fade at the boundary of a scroll container), not a content wrapper. Wrapping a message list or section in `Fade` washes the whole content out:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
// Good: thin absolute strip over the scroll edge
|
|
130
|
+
<Column flex={1} overflowY="auto">...</Column>
|
|
131
|
+
<Fade position="absolute" top="0" left="0" fillWidth height="40" to="bottom" base="surface" pointerEvents="none" />
|
|
132
|
+
// Bad
|
|
133
|
+
<Fade to="top" fill><Column overflowY="auto">...</Column></Fade>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Composition rhythm
|
|
137
|
+
|
|
138
|
+
15. Page skeleton: `Column as="main" fillWidth horizontal="center"` → content `Column maxWidth={...}` → sections. Gaps between siblings, padding inside surfaces; avoid margins for layout when a parent `gap` can do it.
|
|
139
|
+
|
|
140
|
+
`maxWidth` conventions: primary page containers `"xl"`–`"m"` (marketing/landing toward `"xl"`/`"l"`, app and docs content `"m"`). `"s"` is only for narrow reading content (about, legal); `"xs"` for special surfaces (drawers, popovers).
|
|
141
|
+
|
|
142
|
+
16. Data attributes for one-off theme overrides: `data-border="rounded"`, `data-brand="emerald"`, `data-solid="contrast"` — not custom CSS.
|
|
143
|
+
|
|
144
|
+
## Scale and hierarchy (marketing/landing pages)
|
|
145
|
+
|
|
146
|
+
17. Vertical rhythm is generous. Gap between page sections: `"80"`–`"160"` (typical `"104"`). Gap inside a section: `"24"`–`"40"`. Spacing tokens go up to `"160"` — use the top of the scale between sections, not `"48"`.
|
|
147
|
+
|
|
148
|
+
18. Heading scale: hero = `display-strong-l` (or `xl`), section headings = `display-strong-xs` or `display-strong-s` — never `heading-*` variants for section titles. Hero supporting text = `body-default-l`; section supporting text = `body-default-m`.
|
|
149
|
+
|
|
150
|
+
19. Type hierarchy must be monotonic: quotes, testimonials, and body content never render larger than the section heading above them. Testimonial quotes = `body-default-m` max, not `BlockQuote` default size.
|
|
151
|
+
|
|
152
|
+
20. Don't repeat the same centered heading + subtitle block for every section — it reads dated. Vary: left-aligned headers, heading-only sections, or an eyebrow label above the heading. Eyebrow = plain text, not a `Tag` with an icon:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// Good eyebrow
|
|
156
|
+
<Text variant="label-default-s" onBackground="brand-medium">Pricing</Text>
|
|
157
|
+
// Bad eyebrow
|
|
158
|
+
<Tag variant="neutral" prefixIcon="sparkle">Pricing</Tag>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Decorative layers
|
|
162
|
+
|
|
163
|
+
21. Every absolute decorative layer uses the full recipe — `top="0" left="0"` are required or the layer gets offset by parent padding:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
<Background position="absolute" top="0" left="0" fill pointerEvents="none" ... />
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Siblings holding content get `zIndex={1}`. `overflow="hidden"` goes on the parent **only when it has a radius** (cards, panels) — clipping a full-bleed section turns the glow into a hard-edged band.
|
|
170
|
+
|
|
171
|
+
21b. Ambient section layers (hero glows) live on the **full-width section wrapper**, outside the `maxWidth` content column, with generous room (`paddingY="80"`+). Inside a narrow container the gradient gets clipped at the container edge and reads as a misplaced card:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
// Good: full-bleed section, narrow content inside
|
|
175
|
+
<Column fillWidth horizontal="center" paddingY="80">
|
|
176
|
+
<Background position="absolute" top="0" left="0" fill pointerEvents="none" gradient={{...}} />
|
|
177
|
+
<Column zIndex={1} maxWidth={48}>...</Column>
|
|
178
|
+
</Column>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
22. `Background` gradient units: `x`/`y` are percent positions of the container (50/50 = center). `width`/`height` are quarter-percent units: `400` = 100% of the container, `100` = 25%. A soft corner glow is `width: 100–200`; `width: 500` overshoots the container.
|
|
182
|
+
|
|
183
|
+
23. Color visibility: `*-background-weak` is nearly the page color — it is invisible as an accent. For tints and glows use alpha tokens (`brand-alpha-medium`, `brand-alpha-strong`) or solid tokens (`brand-solid-strong`) and do not stack a low `opacity` on top of an already-weak color.
|
|
184
|
+
|
|
185
|
+
## Effect units
|
|
186
|
+
|
|
187
|
+
24. `RevealFx`: `delay` is in **seconds** — stagger with `delay={index * 0.1}`, never `index * 80`. `translateY` as a number is in **rem** — use `translateY={1}` or a token like `"16"` (1rem); `16` means 16rem.
|
|
188
|
+
|
|
189
|
+
25. `LogoCloud` extends `Grid` — always set `columns` (and responsive overrides), or logos stack in one column: `columns="4" m={{ columns: 3 }} s={{ columns: 2 }}`.
|
|
190
|
+
|
|
191
|
+
26. Use decoration recipes from `recipes.md` verbatim, then adjust. Budget: at most one ambient background layer per section, ambient motion in at most the hero and final CTA, one accent color family per page.
|
|
192
|
+
|
|
193
|
+
## Motion
|
|
194
|
+
|
|
195
|
+
27. Animations are **eye-leading, not eye-grabbing**: they direct attention to the one thing that should be read next, they don't announce themselves. Small distances (`translateY="8"`–`"16"`, i.e. 0.5–1rem), short staggers (`delay={index * 0.1}` max), and only on elements worth leading the eye to — the hero heading, stat numbers, the highlighted card in a set.
|
|
196
|
+
|
|
197
|
+
28. Do **not** wrap every section in `RevealFx` — uniform entrance animation on everything reads dated and makes scrolling feel slow. Entry-animation budget per page: the hero, plus at most one or two key moments (stats, a card set). Everything else just renders.
|
|
198
|
+
|
|
199
|
+
28b. Animate **coherent blocks, all-or-none**. Within a sibling set (cards, list items), either every sibling animates with a stagger or none do — never a single item out of the set (e.g. only the highlighted pricing card). For a hero, reveal it as 1–3 stacked chunks with increasing delay (`0 / 0.1 / 0.2`), not individual text fragments. One entrance moment per viewport: if the hero animates, the cards below it don't.
|
|
200
|
+
|
|
201
|
+
29. Trigger below-the-fold animations with `useInViewport`, latched so they play once. `RevealFx` takes `trigger`; `CountFx` has no trigger prop — drive its `value` instead:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
205
|
+
const inViewport = useInViewport(ref);
|
|
206
|
+
const [seen, setSeen] = useState(false);
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
if (inViewport) setSeen(true); // latch: useInViewport flips back to false on scroll-out
|
|
209
|
+
}, [inViewport]);
|
|
210
|
+
|
|
211
|
+
<Column ref={ref} gap="16">
|
|
212
|
+
<RevealFx trigger={seen} translateY="8">...</RevealFx>
|
|
213
|
+
<CountFx value={seen ? 2400 : 0} speed={1500} separator="," variant="display-strong-m" />
|
|
214
|
+
</Column>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Without this, mount-timed animations play while still off-screen and the user scrolls into an already-finished state.
|