@once-ui-system/core 1.7.11 → 1.7.13
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 +53 -0
- package/README.md +27 -0
- package/agent/once-ui-codegen.mdc +27 -0
- 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 +140 -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 +2694 -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/AGENTS.md +53 -0
- package/dist/README.md +27 -0
- package/dist/agent/once-ui-codegen.mdc +27 -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 +140 -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 +2695 -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/components/ContextMenu.d.ts +2 -2
- package/dist/components/ContextMenu.d.ts.map +1 -1
- package/dist/components/ContextMenu.js +3 -3
- package/dist/components/ContextMenu.js.map +1 -1
- package/dist/components/ElementType.d.ts.map +1 -1
- package/dist/components/ElementType.js +6 -4
- package/dist/components/ElementType.js.map +1 -1
- package/dist/components/Media.d.ts.map +1 -1
- package/dist/components/Media.js +6 -3
- package/dist/components/Media.js.map +1 -1
- package/dist/components/MediaVideoPlayer.d.ts +12 -0
- package/dist/components/MediaVideoPlayer.d.ts.map +1 -0
- package/dist/components/MediaVideoPlayer.js +246 -0
- package/dist/components/MediaVideoPlayer.js.map +1 -0
- package/dist/components/MediaVideoPlayer.module.scss +90 -0
- package/dist/components/Table.d.ts +34 -6
- package/dist/components/Table.d.ts.map +1 -1
- package/dist/components/Table.js +114 -30
- package/dist/components/Table.js.map +1 -1
- package/dist/components/Table.module.scss +174 -3
- package/dist/components/ThemeInit.d.ts.map +1 -1
- package/dist/components/ThemeInit.js +2 -1
- package/dist/components/ThemeInit.js.map +1 -1
- package/dist/components/Timeline.d.ts +1 -1
- package/dist/components/Timeline.d.ts.map +1 -1
- package/dist/components/Timeline.js +16 -52
- package/dist/components/Timeline.js.map +1 -1
- package/dist/data/emoji-data.json +0 -10
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +7 -2
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/code/CodeBlock.impl.d.ts.map +1 -1
- package/dist/modules/code/CodeBlock.impl.js +11 -5
- package/dist/modules/code/CodeBlock.impl.js.map +1 -1
- package/dist/modules/seo/Schema.d.ts.map +1 -1
- package/dist/modules/seo/Schema.js +3 -4
- package/dist/modules/seo/Schema.js.map +1 -1
- package/dist/package.json +33 -3
- package/dist/server/og-url-validation.d.ts +10 -0
- package/dist/server/og-url-validation.d.ts.map +1 -0
- package/dist/server/og-url-validation.js +234 -0
- package/dist/server/og-url-validation.js.map +1 -0
- package/dist/server/og-utils.d.ts +5 -2
- package/dist/server/og-utils.d.ts.map +1 -1
- package/dist/server/og-utils.js +39 -14
- package/dist/server/og-utils.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/safe-html.d.ts +19 -0
- package/dist/utils/safe-html.d.ts.map +1 -0
- package/dist/utils/safe-html.js +43 -0
- package/dist/utils/safe-html.js.map +1 -0
- package/package.json +159 -127
- package/scripts/copy-files.js +103 -0
- package/scripts/generate-ai-spec.js +464 -0
- package/scripts/generate-emoji-data.js +128 -0
- package/scripts/init-agent.js +156 -0
- package/scripts/validate-ai-code.js +149 -0
- package/LICENSE.md +0 -21
- package/next-env.d.ts +0 -5
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gold example: pricing
|
|
5
|
+
* Target: three tiers, highlighted middle, comparison table, split FAQ, ambient CTA
|
|
6
|
+
*/
|
|
7
|
+
import { useEffect, useRef, useState } from "react";
|
|
8
|
+
import {
|
|
9
|
+
AccordionGroup,
|
|
10
|
+
Background,
|
|
11
|
+
BlobFx,
|
|
12
|
+
Button,
|
|
13
|
+
Column,
|
|
14
|
+
CountFx,
|
|
15
|
+
Grid,
|
|
16
|
+
Heading,
|
|
17
|
+
Icon,
|
|
18
|
+
MatrixFx,
|
|
19
|
+
RevealFx,
|
|
20
|
+
Row,
|
|
21
|
+
SegmentedControl,
|
|
22
|
+
Table,
|
|
23
|
+
Tag,
|
|
24
|
+
Text,
|
|
25
|
+
useInViewport,
|
|
26
|
+
} from "@once-ui-system/core";
|
|
27
|
+
|
|
28
|
+
type Billing = "monthly" | "yearly";
|
|
29
|
+
|
|
30
|
+
const tiers = [
|
|
31
|
+
{
|
|
32
|
+
name: "Starter",
|
|
33
|
+
description: "For solo builders shipping their first product.",
|
|
34
|
+
price: { monthly: 19, yearly: 15 },
|
|
35
|
+
features: ["3 projects", "5 team members", "Core analytics"],
|
|
36
|
+
cta: "Start with Starter",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Pro",
|
|
40
|
+
description: "For growing teams that need speed and depth.",
|
|
41
|
+
price: { monthly: 49, yearly: 39 },
|
|
42
|
+
features: ["Unlimited projects", "25 team members", "API access", "Priority support"],
|
|
43
|
+
cta: "Start free trial",
|
|
44
|
+
highlighted: true,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "Enterprise",
|
|
48
|
+
description: "For organizations with security and scale requirements.",
|
|
49
|
+
features: ["Unlimited everything", "SSO / SAML", "Dedicated success manager"],
|
|
50
|
+
cta: "Talk to sales",
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
export function PricingExample() {
|
|
55
|
+
const [billing, setBilling] = useState<Billing>("monthly");
|
|
56
|
+
const tiersRef = useRef<HTMLDivElement>(null);
|
|
57
|
+
const tiersInViewport = useInViewport(tiersRef);
|
|
58
|
+
const [tiersSeen, setTiersSeen] = useState(false);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (tiersInViewport) setTiersSeen(true);
|
|
61
|
+
}, [tiersInViewport]);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Column as="main" fillWidth horizontal="center" gap="104" paddingBottom="104">
|
|
65
|
+
<Column fillWidth center overflow="hidden" paddingY="80">
|
|
66
|
+
<MatrixFx
|
|
67
|
+
position="absolute"
|
|
68
|
+
top="0"
|
|
69
|
+
left="0"
|
|
70
|
+
fill
|
|
71
|
+
flicker
|
|
72
|
+
size={1.5}
|
|
73
|
+
spacing={8}
|
|
74
|
+
colors={["brand-solid-strong"]}
|
|
75
|
+
bulge={{ type: "wave", duration: 3, intensity: 20, repeat: true }}
|
|
76
|
+
/>
|
|
77
|
+
<Background
|
|
78
|
+
position="absolute"
|
|
79
|
+
top="0"
|
|
80
|
+
left="0"
|
|
81
|
+
fill
|
|
82
|
+
pointerEvents="none"
|
|
83
|
+
gradient={{ display: true, colorStart: "page-background", x: 0, y: 50, width: 150, height: 300 }}
|
|
84
|
+
/>
|
|
85
|
+
<Column zIndex={1} center gap="24" padding="48" maxWidth={48}>
|
|
86
|
+
<Text variant="label-default-s" onBackground="brand-medium">
|
|
87
|
+
Pricing
|
|
88
|
+
</Text>
|
|
89
|
+
<Heading as="h1" variant="display-strong-xl" align="center">
|
|
90
|
+
Pay for momentum, not seats
|
|
91
|
+
</Heading>
|
|
92
|
+
<Text variant="body-default-l" onBackground="neutral-weak" align="center">
|
|
93
|
+
Start free, scale when you're ready.
|
|
94
|
+
</Text>
|
|
95
|
+
</Column>
|
|
96
|
+
</Column>
|
|
97
|
+
|
|
98
|
+
<Column fillWidth horizontal="center">
|
|
99
|
+
<Column fillWidth maxWidth="l" gap="40">
|
|
100
|
+
<Row fillWidth horizontal="between" vertical="end" gap="24" s={{ direction: "column", horizontal: "start" }}>
|
|
101
|
+
<Heading as="h2" variant="display-strong-xs">
|
|
102
|
+
Three plans, one decision
|
|
103
|
+
</Heading>
|
|
104
|
+
<SegmentedControl
|
|
105
|
+
selected={billing}
|
|
106
|
+
onToggle={(value) => setBilling(value as Billing)}
|
|
107
|
+
buttons={[
|
|
108
|
+
{ value: "monthly", label: "Monthly" },
|
|
109
|
+
{ value: "yearly", label: "Yearly −20%" },
|
|
110
|
+
]}
|
|
111
|
+
/>
|
|
112
|
+
</Row>
|
|
113
|
+
|
|
114
|
+
<Grid ref={tiersRef} columns="3" gap="24" s={{ columns: 1 }}>
|
|
115
|
+
{tiers.map((tier, index) => (
|
|
116
|
+
<RevealFx key={tier.name} fill trigger={tiersSeen} translateY="8" delay={index * 0.1}>
|
|
117
|
+
<Column
|
|
118
|
+
fill
|
|
119
|
+
background="surface"
|
|
120
|
+
border={tier.highlighted ? "brand-alpha-medium" : "neutral-alpha-weak"}
|
|
121
|
+
radius="l"
|
|
122
|
+
padding="32"
|
|
123
|
+
overflow="hidden"
|
|
124
|
+
>
|
|
125
|
+
{tier.highlighted && (
|
|
126
|
+
<Background
|
|
127
|
+
position="absolute"
|
|
128
|
+
top="0"
|
|
129
|
+
left="0"
|
|
130
|
+
fill
|
|
131
|
+
pointerEvents="none"
|
|
132
|
+
gradient={{
|
|
133
|
+
display: true,
|
|
134
|
+
colorStart: "brand-alpha-medium",
|
|
135
|
+
colorEnd: "static-transparent",
|
|
136
|
+
x: 50,
|
|
137
|
+
y: 0,
|
|
138
|
+
width: 200,
|
|
139
|
+
height: 60,
|
|
140
|
+
opacity: 50,
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
144
|
+
<Column zIndex={1} fill gap="24">
|
|
145
|
+
<Row fillWidth horizontal="between" vertical="center">
|
|
146
|
+
<Heading as="h3" variant="heading-strong-m">
|
|
147
|
+
{tier.name}
|
|
148
|
+
</Heading>
|
|
149
|
+
{tier.highlighted && <Tag variant="brand" size="s" label="Most popular" />}
|
|
150
|
+
</Row>
|
|
151
|
+
<Text variant="body-default-s" onBackground="neutral-weak">
|
|
152
|
+
{tier.description}
|
|
153
|
+
</Text>
|
|
154
|
+
{tier.price ? (
|
|
155
|
+
<Row vertical="end" gap="2">
|
|
156
|
+
<Text variant="display-strong-s">$</Text>
|
|
157
|
+
<CountFx variant="display-strong-s" value={tier.price[billing]} effect="wheel" speed={400} />
|
|
158
|
+
<Text variant="label-default-s" onBackground="neutral-weak" paddingBottom="4" paddingLeft="4">
|
|
159
|
+
/ mo
|
|
160
|
+
</Text>
|
|
161
|
+
</Row>
|
|
162
|
+
) : (
|
|
163
|
+
<Text variant="display-strong-s">Custom</Text>
|
|
164
|
+
)}
|
|
165
|
+
<Column flex={1} gap="12">
|
|
166
|
+
{tier.features.map((feature) => (
|
|
167
|
+
<Row key={feature} gap="12" vertical="center">
|
|
168
|
+
<Icon name="checkbox" size="xs" onBackground="brand-medium" />
|
|
169
|
+
<Text variant="body-default-s">{feature}</Text>
|
|
170
|
+
</Row>
|
|
171
|
+
))}
|
|
172
|
+
</Column>
|
|
173
|
+
<Button fillWidth variant={tier.highlighted ? "primary" : "secondary"} arrowIcon={tier.highlighted}>
|
|
174
|
+
{tier.cta}
|
|
175
|
+
</Button>
|
|
176
|
+
</Column>
|
|
177
|
+
</Column>
|
|
178
|
+
</RevealFx>
|
|
179
|
+
))}
|
|
180
|
+
</Grid>
|
|
181
|
+
</Column>
|
|
182
|
+
</Column>
|
|
183
|
+
|
|
184
|
+
<Column fillWidth horizontal="center" background="neutral-alpha-weak" paddingY="80" paddingX="24">
|
|
185
|
+
<Column fillWidth maxWidth="l" gap="40">
|
|
186
|
+
<Heading as="h2" variant="display-strong-xs">
|
|
187
|
+
Every feature, side by side
|
|
188
|
+
</Heading>
|
|
189
|
+
<Table
|
|
190
|
+
fillWidth
|
|
191
|
+
data={{
|
|
192
|
+
headers: [
|
|
193
|
+
{ content: "Feature", key: "feature" },
|
|
194
|
+
{ content: "Starter", key: "starter" },
|
|
195
|
+
{ content: "Pro", key: "pro" },
|
|
196
|
+
],
|
|
197
|
+
rows: [
|
|
198
|
+
["Projects", "3", "Unlimited"],
|
|
199
|
+
["API access", "—", "✓"],
|
|
200
|
+
],
|
|
201
|
+
}}
|
|
202
|
+
/>
|
|
203
|
+
</Column>
|
|
204
|
+
</Column>
|
|
205
|
+
|
|
206
|
+
<Column fillWidth horizontal="center">
|
|
207
|
+
<Column fillWidth maxWidth="l" radius="xl" border="neutral-alpha-weak" overflow="hidden" padding="64" center>
|
|
208
|
+
<BlobFx position="absolute" top="0" left="0" fill opacity={60} seed={2} />
|
|
209
|
+
<Column zIndex={1} center gap="24" maxWidth={40}>
|
|
210
|
+
<Heading as="h2" variant="display-strong-s" align="center">
|
|
211
|
+
Ship your next launch on Pro
|
|
212
|
+
</Heading>
|
|
213
|
+
<Button arrowIcon>Start free trial</Button>
|
|
214
|
+
</Column>
|
|
215
|
+
</Column>
|
|
216
|
+
</Column>
|
|
217
|
+
</Column>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gold example: settings
|
|
5
|
+
* Target: split layout with sidebar nav, profile form sections, danger zone
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
Avatar,
|
|
9
|
+
Button,
|
|
10
|
+
Checkbox,
|
|
11
|
+
Column,
|
|
12
|
+
Heading,
|
|
13
|
+
Input,
|
|
14
|
+
Line,
|
|
15
|
+
Row,
|
|
16
|
+
Select,
|
|
17
|
+
SplitView,
|
|
18
|
+
Switch,
|
|
19
|
+
Text,
|
|
20
|
+
} from "@once-ui-system/core";
|
|
21
|
+
|
|
22
|
+
const sections = [
|
|
23
|
+
{ id: "profile", label: "Profile" },
|
|
24
|
+
{ id: "account", label: "Account" },
|
|
25
|
+
{ id: "notifications", label: "Notifications" },
|
|
26
|
+
{ id: "billing", label: "Billing" },
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export function SettingsExample() {
|
|
30
|
+
return (
|
|
31
|
+
<Column as="main" fillWidth horizontal="center" paddingY="48" paddingX="24">
|
|
32
|
+
<Column fillWidth maxWidth="l" gap="40">
|
|
33
|
+
<Column gap="12">
|
|
34
|
+
<Text variant="label-default-s" onBackground="brand-medium">
|
|
35
|
+
Settings
|
|
36
|
+
</Text>
|
|
37
|
+
<Heading as="h1" variant="display-strong-s">
|
|
38
|
+
Manage your workspace
|
|
39
|
+
</Heading>
|
|
40
|
+
</Column>
|
|
41
|
+
|
|
42
|
+
<SplitView fillWidth minHeight={48}>
|
|
43
|
+
<Column
|
|
44
|
+
width={20}
|
|
45
|
+
gap="4"
|
|
46
|
+
padding="16"
|
|
47
|
+
background="surface"
|
|
48
|
+
border="neutral-alpha-weak"
|
|
49
|
+
radius="l"
|
|
50
|
+
s={{ hide: true }}
|
|
51
|
+
>
|
|
52
|
+
{sections.map((section, index) => (
|
|
53
|
+
<Row
|
|
54
|
+
key={section.id}
|
|
55
|
+
padding="12"
|
|
56
|
+
radius="m"
|
|
57
|
+
background={index === 0 ? "neutral-alpha-weak" : undefined}
|
|
58
|
+
textVariant="label-default-s"
|
|
59
|
+
cursor="interactive"
|
|
60
|
+
>
|
|
61
|
+
{section.label}
|
|
62
|
+
</Row>
|
|
63
|
+
))}
|
|
64
|
+
</Column>
|
|
65
|
+
|
|
66
|
+
<Column flex={1} gap="24">
|
|
67
|
+
<Column background="surface" border="neutral-alpha-weak" radius="l" padding="24" gap="24">
|
|
68
|
+
<Heading as="h2" variant="heading-strong-m">
|
|
69
|
+
Profile
|
|
70
|
+
</Heading>
|
|
71
|
+
<Row gap="16" vertical="center">
|
|
72
|
+
<Avatar size="l" value="LO" />
|
|
73
|
+
<Column gap="8">
|
|
74
|
+
<Button size="s" variant="secondary">
|
|
75
|
+
Upload photo
|
|
76
|
+
</Button>
|
|
77
|
+
<Text variant="label-default-s" onBackground="neutral-weak">
|
|
78
|
+
JPG or PNG, max 2 MB
|
|
79
|
+
</Text>
|
|
80
|
+
</Column>
|
|
81
|
+
</Row>
|
|
82
|
+
<Input id="name" label="Display name" placeholder="Lorant One" />
|
|
83
|
+
<Input id="email" label="Email" placeholder="you@company.com" />
|
|
84
|
+
<Select
|
|
85
|
+
id="timezone"
|
|
86
|
+
label="Timezone"
|
|
87
|
+
options={[
|
|
88
|
+
{ value: "utc", label: "UTC" },
|
|
89
|
+
{ value: "est", label: "Eastern Time" },
|
|
90
|
+
]}
|
|
91
|
+
/>
|
|
92
|
+
<Row gap="12">
|
|
93
|
+
<Button>Save changes</Button>
|
|
94
|
+
<Button variant="secondary">Cancel</Button>
|
|
95
|
+
</Row>
|
|
96
|
+
</Column>
|
|
97
|
+
|
|
98
|
+
<Column background="surface" border="neutral-alpha-weak" radius="l" padding="24" gap="24">
|
|
99
|
+
<Heading as="h2" variant="heading-strong-m">
|
|
100
|
+
Notifications
|
|
101
|
+
</Heading>
|
|
102
|
+
<Row fillWidth horizontal="between" vertical="center">
|
|
103
|
+
<Column gap="4">
|
|
104
|
+
<Text variant="body-default-s">Product updates</Text>
|
|
105
|
+
<Text variant="label-default-s" onBackground="neutral-weak">
|
|
106
|
+
Release notes and changelog
|
|
107
|
+
</Text>
|
|
108
|
+
</Column>
|
|
109
|
+
<Switch checked />
|
|
110
|
+
</Row>
|
|
111
|
+
<Line />
|
|
112
|
+
<Row fillWidth horizontal="between" vertical="center">
|
|
113
|
+
<Column gap="4">
|
|
114
|
+
<Text variant="body-default-s">Marketing emails</Text>
|
|
115
|
+
<Text variant="label-default-s" onBackground="neutral-weak">
|
|
116
|
+
Tips, templates, and community highlights
|
|
117
|
+
</Text>
|
|
118
|
+
</Column>
|
|
119
|
+
<Switch />
|
|
120
|
+
</Row>
|
|
121
|
+
<Checkbox label="Weekly digest" isChecked />
|
|
122
|
+
</Column>
|
|
123
|
+
|
|
124
|
+
<Column background="surface" border="danger-alpha-medium" radius="l" padding="24" gap="16">
|
|
125
|
+
<Heading as="h2" variant="heading-strong-m" onBackground="danger-medium">
|
|
126
|
+
Danger zone
|
|
127
|
+
</Heading>
|
|
128
|
+
<Text variant="body-default-s" onBackground="neutral-weak">
|
|
129
|
+
Permanently delete your workspace and all associated data.
|
|
130
|
+
</Text>
|
|
131
|
+
<Button variant="danger" size="s">
|
|
132
|
+
Delete workspace
|
|
133
|
+
</Button>
|
|
134
|
+
</Column>
|
|
135
|
+
</Column>
|
|
136
|
+
</SplitView>
|
|
137
|
+
</Column>
|
|
138
|
+
</Column>
|
|
139
|
+
);
|
|
140
|
+
}
|
package/ai/gotchas.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Background.gradient.width": {
|
|
3
|
+
"rule": "Quarter-percent units: 400 = 100% of container. Soft glows use width 100–200, not 500.",
|
|
4
|
+
"components": ["Background"]
|
|
5
|
+
},
|
|
6
|
+
"Background.gradient.x": {
|
|
7
|
+
"rule": "x/y are percent positions of the container (50/50 = center).",
|
|
8
|
+
"components": ["Background"]
|
|
9
|
+
},
|
|
10
|
+
"Background.absolute": {
|
|
11
|
+
"rule": "Every absolute decorative layer needs top=\"0\" left=\"0\" or it offsets by parent padding.",
|
|
12
|
+
"components": ["Background", "MatrixFx", "BlobFx"]
|
|
13
|
+
},
|
|
14
|
+
"Card.interactive": {
|
|
15
|
+
"rule": "Card is for interactive surfaces only (href or onClick). Static panels use Column + background=\"surface\" border=\"neutral-alpha-weak\" radius=\"l\".",
|
|
16
|
+
"components": ["Card"]
|
|
17
|
+
},
|
|
18
|
+
"Fade.edge": {
|
|
19
|
+
"rule": "Fade is an edge overlay strip on scroll containers, not a content wrapper.",
|
|
20
|
+
"components": ["Fade"]
|
|
21
|
+
},
|
|
22
|
+
"RevealFx.delay": {
|
|
23
|
+
"rule": "delay is in seconds — stagger with delay={index * 0.1}, never index * 80.",
|
|
24
|
+
"components": ["RevealFx"]
|
|
25
|
+
},
|
|
26
|
+
"RevealFx.translateY": {
|
|
27
|
+
"rule": "translateY as a number is in rem. Use translateY={1} or token \"16\" (1rem); 16 means 16rem.",
|
|
28
|
+
"components": ["RevealFx"]
|
|
29
|
+
},
|
|
30
|
+
"LogoCloud.columns": {
|
|
31
|
+
"rule": "LogoCloud extends Grid — always set columns and responsive overrides or logos stack in one column.",
|
|
32
|
+
"components": ["LogoCloud"]
|
|
33
|
+
},
|
|
34
|
+
"StatusIndicator.color": {
|
|
35
|
+
"rule": "StatusIndicator uses color=\"green\" | \"red\" | \"orange\" | \"gray\" etc. — not variant or semantic scheme names.",
|
|
36
|
+
"components": ["StatusIndicator"]
|
|
37
|
+
},
|
|
38
|
+
"rule": "Icon names must come from IconName in spec.json — never invent names like more, bell, arrowRight.",
|
|
39
|
+
"components": ["Icon", "Button", "IconButton"]
|
|
40
|
+
},
|
|
41
|
+
"Badge.duplicate": {
|
|
42
|
+
"rule": "Do not pass the same text as both title prop and children — it renders twice.",
|
|
43
|
+
"components": ["Badge"]
|
|
44
|
+
},
|
|
45
|
+
"Tag.duplicate": {
|
|
46
|
+
"rule": "Do not pass the same text as both label prop and children — it renders twice.",
|
|
47
|
+
"components": ["Tag"]
|
|
48
|
+
},
|
|
49
|
+
"color.tokens": {
|
|
50
|
+
"rule": "Colors are semantic tokens ({scheme}-{weight}), never hex/rgb. background also accepts surface | overlay | page | transparent.",
|
|
51
|
+
"components": ["Column", "Row", "Text", "Button"]
|
|
52
|
+
},
|
|
53
|
+
"color.background-weak": {
|
|
54
|
+
"rule": "*-background-weak is nearly the page color — invisible as accent. Use alpha tokens (brand-alpha-medium) for glows.",
|
|
55
|
+
"components": ["Background"]
|
|
56
|
+
},
|
|
57
|
+
"layout.shorthands": {
|
|
58
|
+
"rule": "Use fill not fillWidth fillHeight; center not horizontal=\"center\" vertical=\"center\"; Row/Column not Flex direction=.",
|
|
59
|
+
"components": ["Row", "Column", "Flex", "Grid"]
|
|
60
|
+
},
|
|
61
|
+
"layout.defaults": {
|
|
62
|
+
"rule": "Never write props equal to defaults: position=\"relative\", direction on Row/Column, variant=\"primary\" on Button.",
|
|
63
|
+
"components": ["Row", "Column", "Button"]
|
|
64
|
+
},
|
|
65
|
+
"section.gaps": {
|
|
66
|
+
"rule": "Gap between page sections: 80–160 (typical 104). Inside sections: 24–40.",
|
|
67
|
+
"components": ["Column"]
|
|
68
|
+
},
|
|
69
|
+
"heading.scale": {
|
|
70
|
+
"rule": "Hero = display-strong-l/xl; section titles = display-strong-xs/s — never heading-* for section titles.",
|
|
71
|
+
"components": ["Heading"]
|
|
72
|
+
},
|
|
73
|
+
"animation.budget": {
|
|
74
|
+
"rule": "Entry animation budget: hero + at most 1–2 key moments. Animate coherent blocks all-or-none within a sibling set.",
|
|
75
|
+
"components": ["RevealFx", "CountFx"]
|
|
76
|
+
},
|
|
77
|
+
"CountFx.trigger": {
|
|
78
|
+
"rule": "CountFx has no trigger prop — drive value from useInViewport latch instead.",
|
|
79
|
+
"components": ["CountFx"]
|
|
80
|
+
},
|
|
81
|
+
"overflow.hero": {
|
|
82
|
+
"rule": "overflow=\"hidden\" on full-bleed sections clips glows into hard bands — only use when parent has radius.",
|
|
83
|
+
"components": ["Column", "Background"]
|
|
84
|
+
}
|
|
85
|
+
}
|
package/ai/manifest.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.7.13",
|
|
3
|
+
"generated": "2026-07-24",
|
|
4
|
+
"files": {
|
|
5
|
+
"spec": "spec.json",
|
|
6
|
+
"catalog": "catalog.json",
|
|
7
|
+
"rules": "rules.compact.md",
|
|
8
|
+
"rulesFull": "rules.md",
|
|
9
|
+
"recipes": "recipes.md",
|
|
10
|
+
"gotchas": "gotchas.json",
|
|
11
|
+
"tasks": "tasks/index.json",
|
|
12
|
+
"examples": "examples/",
|
|
13
|
+
"blocks": "examples/blocks/manifest.json",
|
|
14
|
+
"components": "components/"
|
|
15
|
+
},
|
|
16
|
+
"bootstrap": [
|
|
17
|
+
"rules.compact.md",
|
|
18
|
+
"catalog.json"
|
|
19
|
+
],
|
|
20
|
+
"resolve": "tasks/index.json"
|
|
21
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Once UI — compact codegen rules
|
|
2
|
+
|
|
3
|
+
Load with task bundle from `@once-ui-system/core/ai/tasks/{intent}.json`. For production-quality composition, read matching Pro blocks from `examples/blocks/manifest.json`. Fetch component slices on demand.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
| Write | Never write |
|
|
8
|
+
|-------|-------------|
|
|
9
|
+
| `<Column gap="16">` | `<Flex direction="column">` |
|
|
10
|
+
| `<Row gap="16">` | `<Flex direction="row">` |
|
|
11
|
+
| `fill` | `fillWidth fillHeight` |
|
|
12
|
+
| `fit` | `fitWidth fitHeight` |
|
|
13
|
+
| `center` | `horizontal="center" vertical="center"` |
|
|
14
|
+
|
|
15
|
+
- `Flex` only when direction changes at breakpoints: `<Row s={{ direction: "column" }}>`
|
|
16
|
+
- Page skeleton: `Column as="main" fillWidth horizontal="center"` → content `Column maxWidth="l"` → sections
|
|
17
|
+
- Section gaps: `"104"` between sections, `"24"`–`"40"` inside. Never `"48"` between major sections.
|
|
18
|
+
- Responsive: breakpoint props `xl l m s xs` — never media queries for layout
|
|
19
|
+
|
|
20
|
+
## Surfaces
|
|
21
|
+
|
|
22
|
+
Static panel recipe (pricing tiers, stats, settings sections):
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
<Column background="surface" border="neutral-alpha-weak" radius="l" padding="24" gap="16">
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- `Card` = interactive only (`href` or `onClick`). Static panels = Column + surface recipe.
|
|
29
|
+
- Colors: `{scheme}-{weight}` or `{scheme}-alpha-{weight}`. Never hex/rgb.
|
|
30
|
+
- `background` also: `surface | overlay | page | transparent`
|
|
31
|
+
|
|
32
|
+
## Typography
|
|
33
|
+
|
|
34
|
+
- Hero: `display-strong-l` or `display-strong-xl`
|
|
35
|
+
- Section titles: `display-strong-xs` or `display-strong-s` — not `heading-*`
|
|
36
|
+
- Eyebrow: `<Text variant="label-default-s" onBackground="brand-medium">`
|
|
37
|
+
- Text on layout: `textVariant` + `onBackground` on Row/Column instead of nesting Text
|
|
38
|
+
|
|
39
|
+
## Decoration
|
|
40
|
+
|
|
41
|
+
Absolute layers always: `position="absolute" top="0" left="0" fill pointerEvents="none"`, content `zIndex={1}`.
|
|
42
|
+
|
|
43
|
+
- Gradient `width`: quarter-percent (400 = 100%). Glows: 100–200.
|
|
44
|
+
- Glow colors: `brand-alpha-medium`, not `brand-background-weak`
|
|
45
|
+
- Ambient layers on full-bleed section wrapper, outside `maxWidth` column
|
|
46
|
+
- Budget: one ambient layer per section; motion in hero + one CTA max
|
|
47
|
+
|
|
48
|
+
## Motion
|
|
49
|
+
|
|
50
|
+
- `RevealFx delay` in **seconds**: `delay={index * 0.1}`
|
|
51
|
+
- `RevealFx translateY`: number = rem; prefer `"8"`–`"16"` tokens
|
|
52
|
+
- Viewport-trigger with `useInViewport` + latch; `CountFx` driven by `value`, no trigger prop
|
|
53
|
+
- Animate all siblings in a set or none — never one lone animated card
|
|
54
|
+
|
|
55
|
+
## Components
|
|
56
|
+
|
|
57
|
+
| Need | Use |
|
|
58
|
+
|------|-----|
|
|
59
|
+
| Image | `Media` |
|
|
60
|
+
| Link | `SmartLink` / `Button href` |
|
|
61
|
+
| Status dot | `StatusIndicator` |
|
|
62
|
+
| Loading | `Spinner` / `Skeleton` |
|
|
63
|
+
| Scroll fade | `Fade` as edge strip, not wrapper |
|
|
64
|
+
| Icons | `IconName` from spec only |
|
|
65
|
+
| Logos grid | `LogoCloud` with `columns` set |
|
|
66
|
+
|
|
67
|
+
## Defaults — omit these
|
|
68
|
+
|
|
69
|
+
`position="relative"`, `direction` on Row/Column, `variant="primary"` on Button, `size="m"` when default.
|
|
70
|
+
|
|
71
|
+
## Before building
|
|
72
|
+
|
|
73
|
+
If design intent unclear, ask: content style, layout width, color approach, decoration level, imagery. Default: restrained, centered `maxWidth="m"`, single brand accent, one subtle gradient, no placeholder images.
|