+ {holding.data.map((item) => (
+
point.value))) * 100}%`,
+ }}
+ />
+ ))}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/empty-distribute-track.tsx b/apps/v4/app/(app)/(root)/cards/empty-distribute-track.tsx
new file mode 100644
index 0000000000..1f5e0ff504
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/empty-distribute-track.tsx
@@ -0,0 +1,37 @@
+import { Add01Icon } from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import { Button } from "@/styles/base-rhea/ui/button"
+import { Card, CardContent } from "@/styles/base-rhea/ui/card"
+import {
+ Empty,
+ EmptyContent,
+ EmptyDescription,
+ EmptyHeader,
+ EmptyMedia,
+ EmptyTitle,
+} from "@/styles/base-rhea/ui/empty"
+
+export function EmptyDistributeTrack() {
+ return (
+
+
+
+
+
+
+
+ Distribute Track
+
+ Upload your first master to start reaching listeners on Spotify,
+ Apple Music, and more.
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/index.tsx b/apps/v4/app/(app)/(root)/cards/index.tsx
new file mode 100644
index 0000000000..3a97c04ecf
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/index.tsx
@@ -0,0 +1,117 @@
+import { AccountAccess } from "./account-access"
+import { AnalyticsCard } from "./analytics-card"
+import { ClaimableBalance } from "./claimable-balance"
+import { ContributionHistory } from "./contribution-history"
+import { DividendIncome } from "./dividend-income"
+import { EmptyDistributeTrack } from "./empty-distribute-track"
+import { NewMilestone } from "./new-milestone"
+import { NotificationSettings } from "./notification-settings"
+import { Payments } from "./payments"
+import { PayoutThreshold } from "./payout-threshold"
+import { PowerUsage } from "./power-usage"
+import { QrConnect } from "./qr-connect"
+import { SavingsTargets } from "./savings-targets"
+import { SidebarNav } from "./sidebar-nav"
+import { AccountAccess as SkeletonAccountAccess } from "./skeleton/account-access"
+import { AnalyticsCard as SkeletonAnalyticsCard } from "./skeleton/analytics-card"
+import { ClaimableBalance as SkeletonClaimableBalance } from "./skeleton/claimable-balance"
+import { ContributionHistory as SkeletonContributionHistory } from "./skeleton/contribution-history"
+import { DividendIncome as SkeletonDividendIncome } from "./skeleton/dividend-income"
+import { EmptyDistributeTrack as SkeletonEmptyDistributeTrack } from "./skeleton/empty-distribute-track"
+import { NewMilestone as SkeletonNewMilestone } from "./skeleton/new-milestone"
+import { NotificationSettings as SkeletonNotificationSettings } from "./skeleton/notification-settings"
+import { Payments as SkeletonPayments } from "./skeleton/payments"
+import { PayoutThreshold as SkeletonPayoutThreshold } from "./skeleton/payout-threshold"
+import { PowerUsage as SkeletonPowerUsage } from "./skeleton/power-usage"
+import { QrConnect as SkeletonQrConnect } from "./skeleton/qr-connect"
+import { SavingsTargets as SkeletonSavingsTargets } from "./skeleton/savings-targets"
+import { TransferFunds as SkeletonTransferFunds } from "./skeleton/transfer-funds"
+import { UIElements as SkeletonUIElements } from "./skeleton/ui-elements"
+import { TransferFunds } from "./transfer-funds"
+import { UIElements } from "./ui-elements"
+
+function CardsSkeletonRails() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export function CardsDemo() {
+ return (
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/new-milestone.tsx b/apps/v4/app/(app)/(root)/cards/new-milestone.tsx
new file mode 100644
index 0000000000..d1bf86a7a6
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/new-milestone.tsx
@@ -0,0 +1,52 @@
+import { Button } from "@/styles/base-rhea/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
+import { Input } from "@/styles/base-rhea/ui/input"
+
+export function NewMilestone() {
+ return (
+
+
+ Set a new milestone
+
+ Define your financial target and we'll help you pace your
+ savings.
+
+
+
+
+
+ Goal Name
+
+
+
+
+ Target Amount
+
+
+
+ Target Date
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/notification-settings.tsx b/apps/v4/app/(app)/(root)/cards/notification-settings.tsx
new file mode 100644
index 0000000000..dcff8031f0
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/notification-settings.tsx
@@ -0,0 +1,76 @@
+import { Button } from "@/styles/base-rhea/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
+import {
+ Field,
+ FieldContent,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+} from "@/styles/base-rhea/ui/field"
+
+const NOTIFICATIONS = [
+ {
+ id: "transactions",
+ label: "Transaction alerts",
+ description: "Deposits, withdrawals, and transfers.",
+ defaultChecked: true,
+ },
+ {
+ id: "security",
+ label: "Security alerts",
+ description: "Login attempts and account changes.",
+ defaultChecked: true,
+ },
+ {
+ id: "goals",
+ label: "Goal milestones",
+ description: "Updates at 25%, 50%, 75%, and 100%.",
+ defaultChecked: false,
+ },
+ {
+ id: "market",
+ label: "Market updates",
+ description: "Daily portfolio summary and price alerts.",
+ defaultChecked: false,
+ },
+]
+
+export function NotificationSettings() {
+ return (
+
+
+ Notifications
+
+ Choose which email and push alerts you want to receive.
+
+
+
+
+ {NOTIFICATIONS.map((n) => (
+
+
+
+ {n.label}
+ {n.description}
+
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/payments.tsx b/apps/v4/app/(app)/(root)/cards/payments.tsx
new file mode 100644
index 0000000000..7102f33d9a
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/payments.tsx
@@ -0,0 +1,139 @@
+import {
+ ArrowRight01Icon,
+ Calendar03Icon,
+ MoreHorizontalCircle01Icon,
+ RefreshIcon,
+ Settings01Icon,
+} from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import {
+ Breadcrumb,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+} from "@/styles/base-rhea/ui/breadcrumb"
+import { Button } from "@/styles/base-rhea/ui/button"
+import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/styles/base-rhea/ui/dropdown-menu"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemGroup,
+ ItemMedia,
+ ItemTitle,
+} from "@/styles/base-rhea/ui/item"
+
+export function Payments() {
+ return (
+
+
+
+
+
+ Home
+
+
+
+
+
+ }
+ >
+
+ Account options
+
+
+
+ Profile
+ Statements
+ Documents
+
+
+
+
+
+
+ Payments
+
+
+
+
+
+
+
+ }>
+
+
+
+
+ Change transfer limit
+
+ Adjust how much you can send from your balance.
+
+
+
+
+
+
+ }>
+
+
+
+
+ Scheduled transfers
+
+ Set up a transfer to send at a later date.
+
+
+
+
+
+
+ }>
+
+
+
+
+ Recurring card payments
+
+ Manage your repeated card transactions.
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/payout-threshold.tsx b/apps/v4/app/(app)/(root)/cards/payout-threshold.tsx
new file mode 100644
index 0000000000..2df21ad581
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/payout-threshold.tsx
@@ -0,0 +1,112 @@
+import { Cancel01Icon } from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import { Button } from "@/styles/base-rhea/ui/button"
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import {
+ Field,
+ FieldDescription,
+ FieldGroup,
+ FieldLabel,
+} from "@/styles/base-rhea/ui/field"
+import { Progress } from "@/styles/base-rhea/ui/progress"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/styles/base-rhea/ui/select"
+import { Textarea } from "@/styles/base-rhea/ui/textarea"
+
+const CURRENCIES = [
+ { label: "USD — United States Dollar", value: "usd" },
+ { label: "EUR — Euro", value: "eur" },
+ { label: "GBP — British Pound", value: "gbp" },
+ { label: "JPY — Japanese Yen", value: "jpy" },
+]
+
+export function PayoutThreshold() {
+ return (
+
+
+ Payout Threshold
+
+ Set the minimum balance required before a payout is triggered.
+
+
+
+
+
+
+
+
+
+ Preferred Currency
+
+
+
+
+
+
+ Minimum Payout Amount
+
+
+ $2500.00
+
+
+
+
+ $50 (MIN)
+ $10,000 (MAX)
+
+
+
+ Notes
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/power-usage.tsx b/apps/v4/app/(app)/(root)/cards/power-usage.tsx
new file mode 100644
index 0000000000..7aa8e89e6c
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/power-usage.tsx
@@ -0,0 +1,67 @@
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import { Separator } from "@/styles/base-rhea/ui/separator"
+
+const chartData = [
+ { hour: "6a", usage: 1.2 },
+ { hour: "8a", usage: 2.8 },
+ { hour: "10a", usage: 3.1 },
+ { hour: "12p", usage: 2.4 },
+ { hour: "2p", usage: 3.4 },
+ { hour: "4p", usage: 2.9 },
+ { hour: "6p", usage: 3.8 },
+ { hour: "8p", usage: 3.2 },
+]
+
+export function PowerUsage() {
+ const maxUsage = Math.max(...chartData.map((item) => item.usage))
+
+ return (
+
+
+ Power Usage
+ Whole Home
+
+
+
+ {chartData.map((item) => (
+
+ ))}
+
+
+
+
+
+ Currently Using
+
+ 3.4 kW
+
+
+ Solar Gen
+ +1.2 kW
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/qr-connect.tsx b/apps/v4/app/(app)/(root)/cards/qr-connect.tsx
new file mode 100644
index 0000000000..28e1b65c25
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/qr-connect.tsx
@@ -0,0 +1,64 @@
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+
+const qrCells = [
+ "111111100101101111111",
+ "100000101001001000001",
+ "101110101111101011101",
+ "101110100100001011101",
+ "101110101010101011101",
+ "100000100111001000001",
+ "111111101010101111111",
+ "000000001101000000000",
+ "101011111001111010110",
+ "010100001110010101001",
+ "111010111011101111010",
+ "001101000101000010101",
+ "110111101111010111011",
+ "000000001001010001010",
+ "111111101101111101001",
+ "100000100010001001111",
+ "101110101011101110100",
+ "101110100110100010011",
+ "101110101000111101110",
+ "100000101101000011001",
+ "111111101011101101111",
+]
+
+export function QrConnect() {
+ return (
+
+
+
+
+
+
+
+ Scan to connect your mobile device
+
+ Open the Ledger mobile app and scan this code to link your device.
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/savings-targets.tsx b/apps/v4/app/(app)/(root)/cards/savings-targets.tsx
new file mode 100644
index 0000000000..1af2a3066d
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/savings-targets.tsx
@@ -0,0 +1,81 @@
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import {
+ Item,
+ ItemContent,
+ ItemDescription,
+ ItemFooter,
+ ItemGroup,
+} from "@/styles/base-rhea/ui/item"
+import { Progress } from "@/styles/base-rhea/ui/progress"
+
+export function SavingsTargets() {
+ return (
+
+
+ Savings Targets
+
+ Active milestones for 2024 across your portfolio. Monitor how close
+ you are to each savings goal.
+
+
+
+
+ -
+
+
+ Retirement
+
+
+ $420,000
+
+
+
+
+
+ 65% achieved
+
+ $273,000
+
+
+ -
+
+
+ Real Estate
+
+
+ $85,000
+
+
+
+
+
+ 32% achieved
+
+ $27,200
+
+
+
+
+
+
+ You have not met your targets for this year.
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/sidebar-nav.tsx b/apps/v4/app/(app)/(root)/cards/sidebar-nav.tsx
new file mode 100644
index 0000000000..f5377b4c36
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/sidebar-nav.tsx
@@ -0,0 +1,218 @@
+import * as React from "react"
+import {
+ ActivityIcon,
+ Analytics01Icon,
+ AnalyticsUpIcon,
+ ArrowDataTransferHorizontalIcon,
+ BankIcon,
+ BookOpen02Icon,
+ Calendar03Icon,
+ ChartBarLineIcon,
+ CreditCardIcon,
+ File02Icon,
+ Globe02Icon,
+ HelpCircleIcon,
+ Message01Icon,
+ Notification03Icon,
+ PaintBoardIcon,
+ PieChartIcon,
+ ShieldIcon,
+ Target02Icon,
+ UserIcon,
+ Wallet01Icon,
+} from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import { cn } from "@/lib/utils"
+import { Card } from "@/styles/base-rhea/ui/card"
+import {
+ Sidebar,
+ SidebarContent,
+ SidebarGroup,
+ SidebarGroupContent,
+ SidebarGroupLabel,
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ SidebarProvider,
+} from "@/styles/base-rhea/ui/sidebar"
+
+function SidebarSection({
+ label,
+ children,
+ className,
+}: {
+ label: string
+ children: React.ReactNode
+ className?: string
+}) {
+ return (
+
+
+
+
+
+ {label}
+
+ {children}
+
+
+
+
+
+
+ )
+}
+
+export function SidebarNav() {
+ return (
+
+
+
+
+
+ Analytics
+
+
+
+
+
+ Transactions
+
+
+
+
+
+ Investments
+
+
+
+
+
+ Accounts
+
+
+
+
+
+ Spending
+
+
+
+
+
+
+
+
+ Documents
+
+
+
+
+
+ Budget
+
+
+
+
+
+ Reports
+
+
+
+
+
+ Goals
+
+
+
+
+
+ Calendar
+
+
+
+
+
+
+
+
+ Help Center
+
+
+
+
+
+ Docs
+
+
+
+
+
+ Contact Us
+
+
+
+
+
+ Status
+
+
+
+
+
+ Community
+
+
+
+
+
+
+
+
+ Profile
+
+
+
+
+
+ Billing
+
+
+
+
+
+ Notifications
+
+
+
+
+
+ Security
+
+
+
+
+
+ Appearance
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/account-access.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/account-access.tsx
new file mode 100644
index 0000000000..65d1c20145
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/account-access.tsx
@@ -0,0 +1,35 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function AccountAccess() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/analytics-card.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/analytics-card.tsx
new file mode 100644
index 0000000000..dfb3d1a9db
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/analytics-card.tsx
@@ -0,0 +1,17 @@
+import { Card, CardAction, CardHeader } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function AnalyticsCard() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/claimable-balance.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/claimable-balance.tsx
new file mode 100644
index 0000000000..4f81f04393
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/claimable-balance.tsx
@@ -0,0 +1,41 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function ClaimableBalance() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/contribution-history.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/contribution-history.tsx
new file mode 100644
index 0000000000..6f0239eccc
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/contribution-history.tsx
@@ -0,0 +1,53 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const bars = [60, 80, 65, 95, 50, 100]
+
+export function ContributionHistory() {
+ return (
+
+
+
+
+
+
+
+ {bars.map((height, i) => (
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/dividend-income.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/dividend-income.tsx
new file mode 100644
index 0000000000..1cac5e12f9
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/dividend-income.tsx
@@ -0,0 +1,49 @@
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const rows = [0, 1, 2, 3]
+const miniBars = [40, 60, 80, 50]
+
+export function DividendIncome() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {rows.map((row) => (
+
+
+
+
+
+
+ {miniBars.map((h, i) => (
+
+ ))}
+
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/empty-distribute-track.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/empty-distribute-track.tsx
new file mode 100644
index 0000000000..9e7bc3e6cd
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/empty-distribute-track.tsx
@@ -0,0 +1,20 @@
+import { Card, CardContent } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function EmptyDistributeTrack() {
+ return (
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/index.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/index.tsx
new file mode 100644
index 0000000000..6e801bfc32
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/index.tsx
@@ -0,0 +1,56 @@
+import { AccountAccess } from "./account-access"
+import { AnalyticsCard } from "./analytics-card"
+import { ClaimableBalance } from "./claimable-balance"
+import { ContributionHistory } from "./contribution-history"
+import { DividendIncome } from "./dividend-income"
+import { EmptyDistributeTrack } from "./empty-distribute-track"
+import { NewMilestone } from "./new-milestone"
+import { NotificationSettings } from "./notification-settings"
+import { Payments } from "./payments"
+import { PayoutThreshold } from "./payout-threshold"
+import { PowerUsage } from "./power-usage"
+import { QrConnect } from "./qr-connect"
+import { SavingsTargets } from "./savings-targets"
+import { SidebarNav } from "./sidebar-nav"
+import { TransferFunds } from "./transfer-funds"
+import { UIElements } from "./ui-elements"
+
+export function CardsSkeletonDemo() {
+ return (
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/new-milestone.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/new-milestone.tsx
new file mode 100644
index 0000000000..adec64e021
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/new-milestone.tsx
@@ -0,0 +1,38 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function NewMilestone() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/notification-settings.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/notification-settings.tsx
new file mode 100644
index 0000000000..aa876bb6c6
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/notification-settings.tsx
@@ -0,0 +1,34 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const rows = [0, 1, 2, 3]
+
+export function NotificationSettings() {
+ return (
+
+
+
+
+
+
+ {rows.map((row) => (
+
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/payments.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/payments.tsx
new file mode 100644
index 0000000000..a65e4ff1df
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/payments.tsx
@@ -0,0 +1,37 @@
+import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const rows = [0, 1, 2]
+
+export function Payments() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {rows.map((row) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/payout-threshold.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/payout-threshold.tsx
new file mode 100644
index 0000000000..4b1649b203
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/payout-threshold.tsx
@@ -0,0 +1,43 @@
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function PayoutThreshold() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/power-usage.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/power-usage.tsx
new file mode 100644
index 0000000000..9f6b880a45
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/power-usage.tsx
@@ -0,0 +1,54 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const bars = [30, 70, 80, 60, 90, 75, 100, 85]
+
+export function PowerUsage() {
+ return (
+
+
+
+
+
+
+
+ {bars.map((height, i) => (
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/qr-connect.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/qr-connect.tsx
new file mode 100644
index 0000000000..449e7719c4
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/qr-connect.tsx
@@ -0,0 +1,17 @@
+import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function QrConnect() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/savings-targets.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/savings-targets.tsx
new file mode 100644
index 0000000000..bb0085b660
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/savings-targets.tsx
@@ -0,0 +1,44 @@
+import {
+ Card,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const rows = [0, 1]
+
+export function SavingsTargets() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {rows.map((row) => (
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/sidebar-nav.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/sidebar-nav.tsx
new file mode 100644
index 0000000000..522899039a
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/sidebar-nav.tsx
@@ -0,0 +1,39 @@
+import { Card } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+const groupA = [0, 1, 2, 3, 4]
+const groupB = [0, 1, 2, 3, 4]
+
+function NavSkeleton({ groups }: { groups: number[][] }) {
+ return (
+
+ {groups.map((items, gi) => (
+
+
+ {items.map((item) => (
+
+
+
+
+ ))}
+ {gi < groups.length - 1 && (
+
+ )}
+
+ ))}
+
+ )
+}
+
+export function SidebarNav() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/transfer-funds.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/transfer-funds.tsx
new file mode 100644
index 0000000000..d7921cd12b
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/transfer-funds.tsx
@@ -0,0 +1,55 @@
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardFooter,
+ CardHeader,
+} from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function TransferFunds() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/skeleton/ui-elements.tsx b/apps/v4/app/(app)/(root)/cards/skeleton/ui-elements.tsx
new file mode 100644
index 0000000000..3ab321df4f
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/skeleton/ui-elements.tsx
@@ -0,0 +1,45 @@
+import { Card, CardContent } from "@/styles/base-rhea/ui/card"
+import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
+
+export function UIElements() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/transfer-funds.tsx b/apps/v4/app/(app)/(root)/cards/transfer-funds.tsx
new file mode 100644
index 0000000000..0adf92f038
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/transfer-funds.tsx
@@ -0,0 +1,139 @@
+import { Cancel01Icon } from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import { Button } from "@/styles/base-rhea/ui/button"
+import {
+ Card,
+ CardAction,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/styles/base-rhea/ui/card"
+import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+ InputGroupText,
+} from "@/styles/base-rhea/ui/input-group"
+import { Item, ItemContent } from "@/styles/base-rhea/ui/item"
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/styles/base-rhea/ui/select"
+import { Separator } from "@/styles/base-rhea/ui/separator"
+
+const FROM_ACCOUNTS = [
+ { label: "Main Checking (··8402) — $12,450.00", value: "checking" },
+ { label: "Business (··7731) — $8,920.00", value: "business" },
+]
+
+const TO_ACCOUNTS = [
+ { label: "High Yield Savings (··1192) — $42,100.00", value: "savings" },
+ { label: "Investment (··3349) — $18,200.00", value: "investment" },
+]
+
+export function TransferFunds() {
+ return (
+
+
+ Transfer Funds
+
+ Move money between your connected accounts.
+
+
+
+
+
+
+
+
+
+ Amount to Transfer
+
+
+
+ $
+
+
+
+
+
+ From Account
+
+
+
+ To Account
+
+
+ -
+
+
+
+ Estimated arrival
+
+ Today, Apr 14
+
+
+
+
+ Transaction fee
+
+ $0.00
+
+
+
+ Total amount
+
+ $1,200.00
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/cards/ui-elements.tsx b/apps/v4/app/(app)/(root)/cards/ui-elements.tsx
new file mode 100644
index 0000000000..df6225eb05
--- /dev/null
+++ b/apps/v4/app/(app)/(root)/cards/ui-elements.tsx
@@ -0,0 +1,176 @@
+"use client"
+
+import {
+ ArrowRight02Icon,
+ ArrowUp01Icon,
+ Search01Icon,
+} from "@hugeicons/core-free-icons"
+import { HugeiconsIcon } from "@hugeicons/react"
+
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@/styles/base-rhea/ui/alert-dialog"
+import { Badge } from "@/styles/base-rhea/ui/badge"
+import { Button } from "@/styles/base-rhea/ui/button"
+import { ButtonGroup } from "@/styles/base-rhea/ui/button-group"
+import { Card, CardContent } from "@/styles/base-rhea/ui/card"
+import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/styles/base-rhea/ui/dropdown-menu"
+import { Field, FieldGroup } from "@/styles/base-rhea/ui/field"
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+ InputGroupText,
+} from "@/styles/base-rhea/ui/input-group"
+import { RadioGroup, RadioGroupItem } from "@/styles/base-rhea/ui/radio-group"
+import { Switch } from "@/styles/base-rhea/ui/switch"
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger,
+} from "@/styles/base-rhea/ui/tabs"
+import { Textarea } from "@/styles/base-rhea/ui/textarea"
+
+export function UIElements() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Badge
+ Secondary
+
+ Outline
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }>
+
+ Alert Dialog
+
+ Dialog
+
+
+
+ Allow accessory to connect?
+
+ Do you want to allow the USB accessory to connect to this
+ device and your data?
+
+
+
+ Don't allow
+ Allow
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+ Quick Actions
+ Mute Conversation
+ Mark as Read
+ Block User
+
+
+
+
+ Delete Conversation
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/v4/app/(app)/(root)/components/appearance-settings.tsx b/apps/v4/app/(app)/(root)/components/appearance-settings.tsx
deleted file mode 100644
index cf9609833e..0000000000
--- a/apps/v4/app/(app)/(root)/components/appearance-settings.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { IconMinus, IconPlus } from "@tabler/icons-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import { ButtonGroup } from "@/styles/radix-nova/ui/button-group"
-import {
- Field,
- FieldContent,
- FieldDescription,
- FieldGroup,
- FieldLabel,
- FieldLegend,
- FieldSeparator,
- FieldSet,
- FieldTitle,
-} from "@/styles/radix-nova/ui/field"
-import { Input } from "@/styles/radix-nova/ui/input"
-import { RadioGroup, RadioGroupItem } from "@/styles/radix-nova/ui/radio-group"
-import { Switch } from "@/styles/radix-nova/ui/switch"
-
-export function AppearanceSettings() {
- const [gpuCount, setGpuCount] = React.useState(8)
-
- const handleGpuAdjustment = React.useCallback((adjustment: number) => {
- setGpuCount((prevCount) =>
- Math.max(1, Math.min(99, prevCount + adjustment))
- )
- }, [])
-
- const handleGpuInputChange = React.useCallback(
- (e: React.ChangeEvent
) => {
- const value = parseInt(e.target.value, 10)
- if (!isNaN(value) && value >= 1 && value <= 99) {
- setGpuCount(value)
- }
- },
- []
- )
-
- return (
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/button-group-demo.tsx b/apps/v4/app/(app)/(root)/components/button-group-demo.tsx
deleted file mode 100644
index e515c5fbda..0000000000
--- a/apps/v4/app/(app)/(root)/components/button-group-demo.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-"use client"
-
-import * as React from "react"
-import {
- ArchiveIcon,
- ArrowLeftIcon,
- CalendarPlusIcon,
- ClockIcon,
- ListFilterIcon,
- MailCheckIcon,
- MoreHorizontalIcon,
- TagIcon,
- Trash2Icon,
-} from "lucide-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import { ButtonGroup } from "@/styles/radix-nova/ui/button-group"
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuRadioGroup,
- DropdownMenuRadioItem,
- DropdownMenuSeparator,
- DropdownMenuSub,
- DropdownMenuSubContent,
- DropdownMenuSubTrigger,
- DropdownMenuTrigger,
-} from "@/styles/radix-nova/ui/dropdown-menu"
-
-export function ButtonGroupDemo() {
- const [label, setLabel] = React.useState("personal")
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mark as Read
-
-
-
- Archive
-
-
-
-
-
-
- Snooze
-
-
-
- Add to Calendar
-
-
-
- Add to List
-
-
-
-
- Label As...
-
-
-
-
- Personal
-
-
- Work
-
-
- Other
-
-
-
-
-
-
-
-
-
- Trash
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/button-group-input-group.tsx b/apps/v4/app/(app)/(root)/components/button-group-input-group.tsx
deleted file mode 100644
index fa871a5722..0000000000
--- a/apps/v4/app/(app)/(root)/components/button-group-input-group.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { AudioLinesIcon, PlusIcon } from "lucide-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import { ButtonGroup } from "@/styles/radix-nova/ui/button-group"
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupInput,
-} from "@/styles/radix-nova/ui/input-group"
-import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from "@/styles/radix-nova/ui/tooltip"
-
-export function ButtonGroupInputGroup() {
- const [voiceEnabled, setVoiceEnabled] = React.useState(false)
- return (
-
-
-
-
-
-
-
-
-
-
- setVoiceEnabled(!voiceEnabled)}
- data-active={voiceEnabled}
- className="data-[active=true]:bg-primary data-[active=true]:text-primary-foreground"
- aria-pressed={voiceEnabled}
- size="icon-xs"
- aria-label="Voice Mode"
- >
-
-
-
- Voice Mode
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/button-group-nested.tsx b/apps/v4/app/(app)/(root)/components/button-group-nested.tsx
deleted file mode 100644
index 0226072797..0000000000
--- a/apps/v4/app/(app)/(root)/components/button-group-nested.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-"use client"
-
-import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import { ButtonGroup } from "@/styles/radix-nova/ui/button-group"
-
-export function ButtonGroupNested() {
- return (
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/button-group-popover.tsx b/apps/v4/app/(app)/(root)/components/button-group-popover.tsx
deleted file mode 100644
index e797d11e72..0000000000
--- a/apps/v4/app/(app)/(root)/components/button-group-popover.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { BotIcon, ChevronDownIcon } from "lucide-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import { ButtonGroup } from "@/styles/radix-nova/ui/button-group"
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "@/styles/radix-nova/ui/popover"
-import { Separator } from "@/styles/radix-nova/ui/separator"
-import { Textarea } from "@/styles/radix-nova/ui/textarea"
-
-export function ButtonGroupPopover() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
Start a new task with Copilot
-
- Describe your task in natural language. Copilot will work in the
- background and open a pull request for your review.
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/empty-avatar-group.tsx b/apps/v4/app/(app)/(root)/components/empty-avatar-group.tsx
deleted file mode 100644
index 39434bbdaa..0000000000
--- a/apps/v4/app/(app)/(root)/components/empty-avatar-group.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import { PlusIcon } from "lucide-react"
-
-import {
- Avatar,
- AvatarFallback,
- AvatarGroup,
- AvatarImage,
-} from "@/styles/radix-nova/ui/avatar"
-import { Button } from "@/styles/radix-nova/ui/button"
-import {
- Empty,
- EmptyContent,
- EmptyDescription,
- EmptyHeader,
- EmptyMedia,
- EmptyTitle,
-} from "@/styles/radix-nova/ui/empty"
-
-export function EmptyAvatarGroup() {
- return (
-
-
-
-
-
-
- CN
-
-
-
- LR
-
-
-
- ER
-
-
-
- No Team Members
-
- Invite your team to collaborate on this project.
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/empty-input-group.tsx b/apps/v4/app/(app)/(root)/components/empty-input-group.tsx
deleted file mode 100644
index f5e0891305..0000000000
--- a/apps/v4/app/(app)/(root)/components/empty-input-group.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { SearchIcon } from "lucide-react"
-
-import {
- Empty,
- EmptyContent,
- EmptyDescription,
- EmptyHeader,
- EmptyTitle,
-} from "@/registry/new-york-v4/ui/empty"
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupInput,
-} from "@/registry/new-york-v4/ui/input-group"
-import { Kbd } from "@/registry/new-york-v4/ui/kbd"
-
-export function EmptyInputGroup() {
- return (
-
-
- 404 - Not Found
-
- The page you're looking for doesn't exist. Try searching for
- what you need below.
-
-
-
-
-
-
-
-
-
- /
-
-
-
- Need help? Contact support
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/field-checkbox.tsx b/apps/v4/app/(app)/(root)/components/field-checkbox.tsx
deleted file mode 100644
index 8942fbd597..0000000000
--- a/apps/v4/app/(app)/(root)/components/field-checkbox.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Checkbox } from "@/styles/radix-nova/ui/checkbox"
-import { Field, FieldLabel } from "@/styles/radix-nova/ui/field"
-
-export function FieldCheckbox() {
- return (
-
-
-
-
- I agree to the terms and conditions
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/field-choice-card.tsx b/apps/v4/app/(app)/(root)/components/field-choice-card.tsx
deleted file mode 100644
index 359aba6200..0000000000
--- a/apps/v4/app/(app)/(root)/components/field-choice-card.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import {
- Field,
- FieldContent,
- FieldDescription,
- FieldGroup,
- FieldLabel,
- FieldSet,
- FieldTitle,
-} from "@/registry/new-york-v4/ui/field"
-import {
- RadioGroup,
- RadioGroupItem,
-} from "@/registry/new-york-v4/ui/radio-group"
-
-export function FieldChoiceCard() {
- return (
-
-
-
-
- Compute Environment
-
-
- Select the compute environment for your cluster.
-
-
-
-
-
-
- Kubernetes
-
- Run GPU workloads on a K8s configured cluster.
-
-
-
-
-
-
-
-
- Virtual Machine
-
- Access a VM configured cluster to run workloads.
-
-
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/field-demo.tsx b/apps/v4/app/(app)/(root)/components/field-demo.tsx
deleted file mode 100644
index a209ee6158..0000000000
--- a/apps/v4/app/(app)/(root)/components/field-demo.tsx
+++ /dev/null
@@ -1,158 +0,0 @@
-import { Button } from "@/styles/radix-nova/ui/button"
-import { Checkbox } from "@/styles/radix-nova/ui/checkbox"
-import {
- Field,
- FieldDescription,
- FieldGroup,
- FieldLabel,
- FieldLegend,
- FieldSeparator,
- FieldSet,
-} from "@/styles/radix-nova/ui/field"
-import { Input } from "@/styles/radix-nova/ui/input"
-import {
- Select,
- SelectContent,
- SelectGroup,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/styles/radix-nova/ui/select"
-import { Textarea } from "@/styles/radix-nova/ui/textarea"
-
-export function FieldDemo() {
- return (
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/field-hear.tsx b/apps/v4/app/(app)/(root)/components/field-hear.tsx
deleted file mode 100644
index 0d410f614a..0000000000
--- a/apps/v4/app/(app)/(root)/components/field-hear.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Card, CardContent } from "@/styles/radix-nova/ui/card"
-import { Checkbox } from "@/styles/radix-nova/ui/checkbox"
-import {
- Field,
- FieldDescription,
- FieldGroup,
- FieldLabel,
- FieldLegend,
- FieldSet,
- FieldTitle,
-} from "@/styles/radix-nova/ui/field"
-
-const options = [
- {
- label: "Social Media",
- value: "social-media",
- },
-
- {
- label: "Search Engine",
- value: "search-engine",
- },
- {
- label: "Referral",
- value: "referral",
- },
- {
- label: "Other",
- value: "other",
- },
-]
-
-export function FieldHear() {
- return (
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/field-slider.tsx b/apps/v4/app/(app)/(root)/components/field-slider.tsx
deleted file mode 100644
index cd44849c6f..0000000000
--- a/apps/v4/app/(app)/(root)/components/field-slider.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-"use client"
-
-import { useState } from "react"
-
-import {
- Field,
- FieldDescription,
- FieldTitle,
-} from "@/styles/radix-nova/ui/field"
-import { Slider } from "@/styles/radix-nova/ui/slider"
-
-export function FieldSlider() {
- const [value, setValue] = useState([200, 800])
- return (
-
-
- Price Range
-
- Set your budget range ($
- {value[0]} -{" "}
- {value[1]}).
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/index.tsx b/apps/v4/app/(app)/(root)/components/index.tsx
deleted file mode 100644
index c00f9c06e1..0000000000
--- a/apps/v4/app/(app)/(root)/components/index.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { FieldSeparator } from "@/styles/radix-nova/ui/field"
-
-import { AppearanceSettings } from "./appearance-settings"
-import { ButtonGroupDemo } from "./button-group-demo"
-import { ButtonGroupInputGroup } from "./button-group-input-group"
-import { ButtonGroupNested } from "./button-group-nested"
-import { ButtonGroupPopover } from "./button-group-popover"
-import { EmptyAvatarGroup } from "./empty-avatar-group"
-import { FieldCheckbox } from "./field-checkbox"
-import { FieldDemo } from "./field-demo"
-import { FieldHear } from "./field-hear"
-import { FieldSlider } from "./field-slider"
-import { InputGroupButtonExample } from "./input-group-button"
-import { InputGroupDemo } from "./input-group-demo"
-import { ItemDemo } from "./item-demo"
-import { NotionPromptForm } from "./notion-prompt-form"
-import { SpinnerBadge } from "./spinner-badge"
-import { SpinnerEmpty } from "./spinner-empty"
-
-export function RootComponents() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Appearance Settings
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/input-group-button.tsx b/apps/v4/app/(app)/(root)/components/input-group-button.tsx
deleted file mode 100644
index 3880a6543f..0000000000
--- a/apps/v4/app/(app)/(root)/components/input-group-button.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { IconInfoCircle, IconStar } from "@tabler/icons-react"
-
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupInput,
-} from "@/styles/radix-nova/ui/input-group"
-import { Label } from "@/styles/radix-nova/ui/label"
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "@/styles/radix-nova/ui/popover"
-
-export function InputGroupButtonExample() {
- const [isFavorite, setIsFavorite] = React.useState(false)
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
- Your connection is not secure.
- You should not enter any sensitive information on this site.
-
-
-
- https://
-
-
- setIsFavorite(!isFavorite)}
- size="icon-xs"
- aria-label="Favorite"
- >
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/input-group-demo.tsx b/apps/v4/app/(app)/(root)/components/input-group-demo.tsx
deleted file mode 100644
index 2e4101f973..0000000000
--- a/apps/v4/app/(app)/(root)/components/input-group-demo.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
-import { ArrowUpIcon, Search } from "lucide-react"
-
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from "@/styles/radix-nova/ui/dropdown-menu"
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupInput,
- InputGroupText,
- InputGroupTextarea,
-} from "@/styles/radix-nova/ui/input-group"
-import { Separator } from "@/styles/radix-nova/ui/separator"
-import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from "@/styles/radix-nova/ui/tooltip"
-
-export function InputGroupDemo() {
- return (
-
-
-
-
-
-
- 12 results
-
-
-
-
- https://
-
-
-
-
-
-
-
-
- This is content in a tooltip.
-
-
-
-
-
-
-
-
-
-
-
- Auto
-
-
- Auto
- Agent
- Manual
-
-
- 52% used
-
-
-
- Send
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/input-group-textarea.tsx b/apps/v4/app/(app)/(root)/components/input-group-textarea.tsx
deleted file mode 100644
index 4de7487d5b..0000000000
--- a/apps/v4/app/(app)/(root)/components/input-group-textarea.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import {
- IconBrandJavascript,
- IconCopy,
- IconCornerDownLeft,
- IconRefresh,
-} from "@tabler/icons-react"
-
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupText,
- InputGroupTextarea,
-} from "@/registry/new-york-v4/ui/input-group"
-
-export function InputGroupTextareaExample() {
- return (
-
-
-
-
- Line 1, Column 1
-
- Run
-
-
-
-
-
- script.js
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/item-avatar.tsx b/apps/v4/app/(app)/(root)/components/item-avatar.tsx
deleted file mode 100644
index e63a250a07..0000000000
--- a/apps/v4/app/(app)/(root)/components/item-avatar.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { Plus } from "lucide-react"
-
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
-} from "@/registry/new-york-v4/ui/avatar"
-import { Button } from "@/registry/new-york-v4/ui/button"
-import {
- Item,
- ItemActions,
- ItemContent,
- ItemDescription,
- ItemMedia,
- ItemTitle,
-} from "@/registry/new-york-v4/ui/item"
-
-export function ItemAvatar() {
- return (
-
-
-
-
-
-
- LR
-
-
-
- Max Leiter
- Last seen 5 months ago
-
-
-
-
-
-
-
-
-
-
-
- CN
-
-
-
- LR
-
-
-
- ER
-
-
-
-
- No Team Members
- Invite your team to collaborate.
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/item-demo.tsx b/apps/v4/app/(app)/(root)/components/item-demo.tsx
deleted file mode 100644
index 9f128396c7..0000000000
--- a/apps/v4/app/(app)/(root)/components/item-demo.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
-
-import { Button } from "@/styles/radix-nova/ui/button"
-import {
- Item,
- ItemActions,
- ItemContent,
- ItemDescription,
- ItemMedia,
- ItemTitle,
-} from "@/styles/radix-nova/ui/item"
-
-export function ItemDemo() {
- return (
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/notion-prompt-form.tsx b/apps/v4/app/(app)/(root)/components/notion-prompt-form.tsx
deleted file mode 100644
index 973c41cf3a..0000000000
--- a/apps/v4/app/(app)/(root)/components/notion-prompt-form.tsx
+++ /dev/null
@@ -1,453 +0,0 @@
-"use client"
-
-import { useMemo, useState } from "react"
-import {
- IconApps,
- IconArrowUp,
- IconAt,
- IconBook,
- IconCircleDashedPlus,
- IconPaperclip,
- IconPlus,
- IconWorld,
- IconX,
-} from "@tabler/icons-react"
-
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
-} from "@/styles/radix-nova/ui/avatar"
-import { Badge } from "@/styles/radix-nova/ui/badge"
-import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
-} from "@/styles/radix-nova/ui/command"
-import {
- DropdownMenu,
- DropdownMenuCheckboxItem,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuSub,
- DropdownMenuSubContent,
- DropdownMenuSubTrigger,
- DropdownMenuTrigger,
-} from "@/styles/radix-nova/ui/dropdown-menu"
-import { Field, FieldLabel } from "@/styles/radix-nova/ui/field"
-import {
- InputGroup,
- InputGroupAddon,
- InputGroupButton,
- InputGroupTextarea,
-} from "@/styles/radix-nova/ui/input-group"
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "@/styles/radix-nova/ui/popover"
-import { Switch } from "@/styles/radix-nova/ui/switch"
-import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from "@/styles/radix-nova/ui/tooltip"
-
-const SAMPLE_DATA = {
- mentionable: [
- {
- type: "page",
- title: "Meeting Notes",
- image: "📝",
- },
- {
- type: "page",
- title: "Project Dashboard",
- image: "📊",
- },
- {
- type: "page",
- title: "Ideas & Brainstorming",
- image: "💡",
- },
- {
- type: "page",
- title: "Calendar & Events",
- image: "📅",
- },
- {
- type: "page",
- title: "Documentation",
- image: "📚",
- },
- {
- type: "page",
- title: "Goals & Objectives",
- image: "🎯",
- },
- {
- type: "page",
- title: "Budget Planning",
- image: "💰",
- },
- {
- type: "page",
- title: "Team Directory",
- image: "👥",
- },
- {
- type: "page",
- title: "Technical Specs",
- image: "🔧",
- },
- {
- type: "page",
- title: "Analytics Report",
- image: "📈",
- },
- {
- type: "user",
- title: "shadcn",
- image: "https://github.com/shadcn.png",
- workspace: "Workspace",
- },
- {
- type: "user",
- title: "maxleiter",
- image: "https://github.com/maxleiter.png",
- workspace: "Workspace",
- },
- {
- type: "user",
- title: "evilrabbit",
- image: "https://github.com/evilrabbit.png",
- workspace: "Workspace",
- },
- ],
- models: [
- {
- name: "Auto",
- },
- {
- name: "Agent Mode",
- badge: "Beta",
- },
- {
- name: "Plan Mode",
- },
- ],
-}
-
-function MentionableIcon({
- item,
-}: {
- item: (typeof SAMPLE_DATA.mentionable)[0]
-}) {
- return item.type === "page" ? (
-
- {item.image}
-
- ) : (
-
-
- {item.title[0]}
-
- )
-}
-
-export function NotionPromptForm() {
- const [mentions, setMentions] = useState([])
- const [mentionPopoverOpen, setMentionPopoverOpen] = useState(false)
- const [modelPopoverOpen, setModelPopoverOpen] = useState(false)
- const [selectedModel, setSelectedModel] = useState<
- (typeof SAMPLE_DATA.models)[0]
- >(SAMPLE_DATA.models[0])
- const [scopeMenuOpen, setScopeMenuOpen] = useState(false)
-
- const grouped = useMemo(() => {
- return SAMPLE_DATA.mentionable.reduce(
- (acc, item) => {
- const isAvailable = !mentions.includes(item.title)
-
- if (isAvailable) {
- if (!acc[item.type]) {
- acc[item.type] = []
- }
- acc[item.type].push(item)
- }
- return acc
- },
- {} as Record
- )
- }, [mentions])
-
- const hasMentions = mentions.length > 0
-
- return (
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/spinner-badge.tsx b/apps/v4/app/(app)/(root)/components/spinner-badge.tsx
deleted file mode 100644
index 3c6c7264d5..0000000000
--- a/apps/v4/app/(app)/(root)/components/spinner-badge.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Badge } from "@/styles/radix-nova/ui/badge"
-import { Spinner } from "@/styles/radix-nova/ui/spinner"
-
-export function SpinnerBadge() {
- return (
-
-
-
- Syncing
-
-
-
- Updating
-
-
-
- Loading
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/components/spinner-empty.tsx b/apps/v4/app/(app)/(root)/components/spinner-empty.tsx
deleted file mode 100644
index 70914e98a7..0000000000
--- a/apps/v4/app/(app)/(root)/components/spinner-empty.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Button } from "@/styles/radix-nova/ui/button"
-import {
- Empty,
- EmptyContent,
- EmptyDescription,
- EmptyHeader,
- EmptyMedia,
- EmptyTitle,
-} from "@/styles/radix-nova/ui/empty"
-import { Spinner } from "@/styles/radix-nova/ui/spinner"
-
-export function SpinnerEmpty() {
- return (
-
-
-
-
-
- Processing your request
-
- Please wait while we process your request. Do not refresh the page.
-
-
-
-
-
-
- )
-}
diff --git a/apps/v4/app/(app)/(root)/page.tsx b/apps/v4/app/(app)/(root)/page.tsx
index f9bbb62761..6b2becb94b 100644
--- a/apps/v4/app/(app)/(root)/page.tsx
+++ b/apps/v4/app/(app)/(root)/page.tsx
@@ -1,6 +1,7 @@
import { type Metadata } from "next"
import Image from "next/image"
import Link from "next/link"
+import { IconArrowRight } from "@tabler/icons-react"
import { Announcement } from "@/components/announcement"
import {
@@ -9,9 +10,9 @@ import {
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
-import { Button } from "@/registry/new-york-v4/ui/button"
+import { Button } from "@/styles/radix-nova/ui/button"
-import { RootComponents } from "./components"
+import { CardsDemo } from "./cards"
const title = "The Foundation for your Design System"
const description =
@@ -47,21 +48,20 @@ export const metadata: Metadata = {
export default function IndexPage() {
return (
-
+
{title}
{description}
-
-
-
-
+
diff --git a/apps/v4/app/(app)/create/components/customizer.tsx b/apps/v4/app/(app)/create/components/customizer.tsx
index 934ccf8039..1030bd0468 100644
--- a/apps/v4/app/(app)/create/components/customizer.tsx
+++ b/apps/v4/app/(app)/create/components/customizer.tsx
@@ -55,7 +55,7 @@ export function Customizer({
return (
diff --git a/apps/v4/app/(app)/create/components/design-system-provider.tsx b/apps/v4/app/(app)/create/components/design-system-provider.tsx
index 98374e1a27..f6b5f67c45 100644
--- a/apps/v4/app/(app)/create/components/design-system-provider.tsx
+++ b/apps/v4/app/(app)/create/components/design-system-provider.tsx
@@ -143,6 +143,11 @@ export function DesignSystemProvider({
React.useEffect(() => {
if (style === "lyra" || (style === "sera" && radius !== "none")) {
setSearchParams({ radius: "none" })
+ return
+ }
+
+ if (style === "rhea" && radius === "large") {
+ setSearchParams({ radius: "default" })
}
}, [style, radius, setSearchParams])
diff --git a/apps/v4/app/(app)/create/components/radius-picker.tsx b/apps/v4/app/(app)/create/components/radius-picker.tsx
index 2156294005..a56eec7680 100644
--- a/apps/v4/app/(app)/create/components/radius-picker.tsx
+++ b/apps/v4/app/(app)/create/components/radius-picker.tsx
@@ -93,6 +93,7 @@ export function RadiusPicker({
key={radius.name}
value={radius.name}
closeOnClick={isMobile}
+ disabled={params.style === "rhea" && radius.name === "large"}
>
{radius.label}
diff --git a/apps/v4/app/(app)/create/lib/fonts.ts b/apps/v4/app/(app)/create/lib/fonts.ts
index 41f6644541..a05f858bfc 100644
--- a/apps/v4/app/(app)/create/lib/fonts.ts
+++ b/apps/v4/app/(app)/create/lib/fonts.ts
@@ -1,195 +1,14 @@
-import {
- DM_Sans,
- EB_Garamond,
- Figtree,
- Geist,
- Geist_Mono,
- IBM_Plex_Sans,
- Instrument_Sans,
- Instrument_Serif,
- Inter,
- JetBrains_Mono,
- Lora,
- Manrope,
- Merriweather,
- Montserrat,
- Noto_Sans,
- Noto_Serif,
- Nunito_Sans,
- Outfit,
- Oxanium,
- Playfair_Display,
- Public_Sans,
- Raleway,
- Roboto,
- Roboto_Slab,
- Source_Sans_3,
- Space_Grotesk,
-} from "next/font/google"
-
import { FONT_DEFINITIONS, type FontName } from "@/lib/font-definitions"
-type PreviewFont = ReturnType
-
-const geistSans = Geist({
- subsets: ["latin"],
- variable: "--font-geist-sans",
-})
-
-const inter = Inter({
- subsets: ["latin"],
- variable: "--font-inter",
-})
-
-const notoSans = Noto_Sans({
- subsets: ["latin"],
- variable: "--font-noto-sans",
-})
-
-const nunitoSans = Nunito_Sans({
- subsets: ["latin"],
- variable: "--font-nunito-sans",
-})
-
-const figtree = Figtree({
- subsets: ["latin"],
- variable: "--font-figtree",
-})
-
-const roboto = Roboto({
- subsets: ["latin"],
- variable: "--font-roboto",
-})
-
-const raleway = Raleway({
- subsets: ["latin"],
- variable: "--font-raleway",
-})
-
-const dmSans = DM_Sans({
- subsets: ["latin"],
- variable: "--font-dm-sans",
-})
-
-const publicSans = Public_Sans({
- subsets: ["latin"],
- variable: "--font-public-sans",
-})
-
-const outfit = Outfit({
- subsets: ["latin"],
- variable: "--font-outfit",
-})
-
-const oxanium = Oxanium({
- subsets: ["latin"],
- variable: "--font-oxanium",
-})
-
-const manrope = Manrope({
- subsets: ["latin"],
- variable: "--font-manrope",
-})
-
-const spaceGrotesk = Space_Grotesk({
- subsets: ["latin"],
- variable: "--font-space-grotesk",
-})
-
-const montserrat = Montserrat({
- subsets: ["latin"],
- variable: "--font-montserrat",
-})
-
-const ibmPlexSans = IBM_Plex_Sans({
- subsets: ["latin"],
- variable: "--font-ibm-plex-sans",
-})
-
-const sourceSans3 = Source_Sans_3({
- subsets: ["latin"],
- variable: "--font-source-sans-3",
-})
-
-const instrumentSans = Instrument_Sans({
- subsets: ["latin"],
- variable: "--font-instrument-sans",
-})
-
-const jetbrainsMono = JetBrains_Mono({
- subsets: ["latin"],
- variable: "--font-jetbrains-mono",
-})
-
-const geistMono = Geist_Mono({
- subsets: ["latin"],
- variable: "--font-geist-mono",
-})
-
-const notoSerif = Noto_Serif({
- subsets: ["latin"],
- variable: "--font-noto-serif",
-})
-
-const robotoSlab = Roboto_Slab({
- subsets: ["latin"],
- variable: "--font-roboto-slab",
-})
-
-const merriweather = Merriweather({
- subsets: ["latin"],
- variable: "--font-merriweather",
-})
-
-const lora = Lora({
- subsets: ["latin"],
- variable: "--font-lora",
-})
-
-const playfairDisplay = Playfair_Display({
- subsets: ["latin"],
- variable: "--font-playfair-display",
-})
-
-const ebGaramond = EB_Garamond({
- subsets: ["latin"],
- variable: "--font-eb-garamond",
-})
-
-const instrumentSerif = Instrument_Serif({
- subsets: ["latin"],
- weight: "400",
- variable: "--font-instrument-serif",
-})
-
-const PREVIEW_FONTS = {
- geist: geistSans,
- inter,
- "noto-sans": notoSans,
- "nunito-sans": nunitoSans,
- figtree,
- roboto,
- raleway,
- "dm-sans": dmSans,
- "public-sans": publicSans,
- outfit,
- oxanium,
- manrope,
- "space-grotesk": spaceGrotesk,
- montserrat,
- "ibm-plex-sans": ibmPlexSans,
- "source-sans-3": sourceSans3,
- "instrument-sans": instrumentSans,
- "jetbrains-mono": jetbrainsMono,
- "geist-mono": geistMono,
- "noto-serif": notoSerif,
- "roboto-slab": robotoSlab,
- merriweather,
- lora,
- "playfair-display": playfairDisplay,
- "eb-garamond": ebGaramond,
- "instrument-serif": instrumentSerif,
-} satisfies Record
+type CreateFont = {
+ family: string
+ import: string
+ previewVariable: string
+ style: {
+ fontFamily: string
+ }
+ variable: string
+}
function createFontOption(name: FontName) {
const definition = FONT_DEFINITIONS.find((font) => font.name === name)
@@ -201,7 +20,15 @@ function createFontOption(name: FontName) {
return {
name: definition.title,
value: definition.name,
- font: PREVIEW_FONTS[name],
+ font: {
+ family: definition.family,
+ import: definition.import,
+ previewVariable: definition.previewVariable,
+ style: {
+ fontFamily: `var(${definition.previewVariable}), ${definition.family}`,
+ },
+ variable: definition.registryVariable,
+ } satisfies CreateFont,
type: definition.type,
} as const
}
diff --git a/apps/v4/app/(app)/create/lib/randomize-biases.ts b/apps/v4/app/(app)/create/lib/randomize-biases.ts
index c73965143f..0183d92ace 100644
--- a/apps/v4/app/(app)/create/lib/randomize-biases.ts
+++ b/apps/v4/app/(app)/create/lib/randomize-biases.ts
@@ -76,6 +76,11 @@ export const RANDOMIZE_BIASES: RandomizeBiases = {
return radii.filter((radius) => radius.name === "none")
}
+ // Rhea does not support the "large" radius.
+ if (context.style === "rhea") {
+ return radii.filter((radius) => radius.name !== "large")
+ }
+
return radii
},
chartColors: (chartColors, context) => {
diff --git a/apps/v4/app/(app)/docs/[[...slug]]/page.tsx b/apps/v4/app/(app)/docs/[[...slug]]/page.tsx
index c01edaac4d..8c8165aa7b 100644
--- a/apps/v4/app/(app)/docs/[[...slug]]/page.tsx
+++ b/apps/v4/app/(app)/docs/[[...slug]]/page.tsx
@@ -93,7 +93,7 @@ export default async function Page(props: {
>
-
+
diff --git a/apps/v4/app/(app)/docs/changelog/page.tsx b/apps/v4/app/(app)/docs/changelog/page.tsx
index 3f7d37963e..64861a824b 100644
--- a/apps/v4/app/(app)/docs/changelog/page.tsx
+++ b/apps/v4/app/(app)/docs/changelog/page.tsx
@@ -46,7 +46,7 @@ export default function ChangelogPage() {
>
-
+
diff --git a/apps/v4/app/(create)/preview/[base]/[name]/page.tsx b/apps/v4/app/(create)/preview/[base]/[name]/page.tsx
index 30af6c8988..e5a795ff59 100644
--- a/apps/v4/app/(create)/preview/[base]/[name]/page.tsx
+++ b/apps/v4/app/(create)/preview/[base]/[name]/page.tsx
@@ -15,6 +15,8 @@ import { PreviewStyle } from "@/app/(app)/create/components/preview-style"
import { RandomizeScript } from "@/app/(app)/create/components/random-button"
import { getBaseComponent, getBaseItem } from "@/app/(app)/create/lib/api"
+import "@/app/style-registry.css"
+
export const revalidate = false
export const dynamic = "force-static"
export const dynamicParams = true
diff --git a/apps/v4/app/(create)/preview/font-variables.tsx b/apps/v4/app/(create)/preview/font-variables.tsx
new file mode 100644
index 0000000000..b657631ddb
--- /dev/null
+++ b/apps/v4/app/(create)/preview/font-variables.tsx
@@ -0,0 +1,21 @@
+"use client"
+
+import * as React from "react"
+
+export function PreviewFontVariables({ className }: { className: string }) {
+ React.useLayoutEffect(() => {
+ const classNames = className.split(/\s+/).filter(Boolean)
+
+ if (!classNames.length) {
+ return
+ }
+
+ document.documentElement.classList.add(...classNames)
+
+ return () => {
+ document.documentElement.classList.remove(...classNames)
+ }
+ }, [className])
+
+ return null
+}
diff --git a/apps/v4/app/(create)/preview/fonts.ts b/apps/v4/app/(create)/preview/fonts.ts
new file mode 100644
index 0000000000..5aca0e2001
--- /dev/null
+++ b/apps/v4/app/(create)/preview/fonts.ts
@@ -0,0 +1,190 @@
+import {
+ DM_Sans,
+ EB_Garamond,
+ Figtree,
+ Geist,
+ Geist_Mono,
+ IBM_Plex_Sans,
+ Instrument_Sans,
+ Instrument_Serif,
+ Inter,
+ JetBrains_Mono,
+ Lora,
+ Manrope,
+ Merriweather,
+ Montserrat,
+ Noto_Sans,
+ Noto_Serif,
+ Nunito_Sans,
+ Outfit,
+ Oxanium,
+ Playfair_Display,
+ Public_Sans,
+ Raleway,
+ Roboto,
+ Roboto_Slab,
+ Source_Sans_3,
+ Space_Grotesk,
+} from "next/font/google"
+
+import { cn } from "@/lib/utils"
+
+const geistSans = Geist({
+ subsets: ["latin"],
+ variable: "--font-geist-sans",
+})
+
+const inter = Inter({
+ subsets: ["latin"],
+ variable: "--font-inter",
+})
+
+const notoSans = Noto_Sans({
+ subsets: ["latin"],
+ variable: "--font-noto-sans",
+})
+
+const nunitoSans = Nunito_Sans({
+ subsets: ["latin"],
+ variable: "--font-nunito-sans",
+})
+
+const figtree = Figtree({
+ subsets: ["latin"],
+ variable: "--font-figtree",
+})
+
+const roboto = Roboto({
+ subsets: ["latin"],
+ variable: "--font-roboto",
+})
+
+const raleway = Raleway({
+ subsets: ["latin"],
+ variable: "--font-raleway",
+})
+
+const dmSans = DM_Sans({
+ subsets: ["latin"],
+ variable: "--font-dm-sans",
+})
+
+const publicSans = Public_Sans({
+ subsets: ["latin"],
+ variable: "--font-public-sans",
+})
+
+const outfit = Outfit({
+ subsets: ["latin"],
+ variable: "--font-outfit",
+})
+
+const oxanium = Oxanium({
+ subsets: ["latin"],
+ variable: "--font-oxanium",
+})
+
+const manrope = Manrope({
+ subsets: ["latin"],
+ variable: "--font-manrope",
+})
+
+const spaceGrotesk = Space_Grotesk({
+ subsets: ["latin"],
+ variable: "--font-space-grotesk",
+})
+
+const montserrat = Montserrat({
+ subsets: ["latin"],
+ variable: "--font-montserrat",
+})
+
+const ibmPlexSans = IBM_Plex_Sans({
+ subsets: ["latin"],
+ variable: "--font-ibm-plex-sans",
+})
+
+const sourceSans3 = Source_Sans_3({
+ subsets: ["latin"],
+ variable: "--font-source-sans-3",
+})
+
+const instrumentSans = Instrument_Sans({
+ subsets: ["latin"],
+ variable: "--font-instrument-sans",
+})
+
+const jetbrainsMono = JetBrains_Mono({
+ subsets: ["latin"],
+ variable: "--font-jetbrains-mono",
+})
+
+const geistMono = Geist_Mono({
+ subsets: ["latin"],
+ variable: "--font-geist-mono",
+})
+
+const notoSerif = Noto_Serif({
+ subsets: ["latin"],
+ variable: "--font-noto-serif",
+})
+
+const robotoSlab = Roboto_Slab({
+ subsets: ["latin"],
+ variable: "--font-roboto-slab",
+})
+
+const merriweather = Merriweather({
+ subsets: ["latin"],
+ variable: "--font-merriweather",
+})
+
+const lora = Lora({
+ subsets: ["latin"],
+ variable: "--font-lora",
+})
+
+const playfairDisplay = Playfair_Display({
+ subsets: ["latin"],
+ variable: "--font-playfair-display",
+})
+
+const ebGaramond = EB_Garamond({
+ subsets: ["latin"],
+ variable: "--font-eb-garamond",
+})
+
+const instrumentSerif = Instrument_Serif({
+ subsets: ["latin"],
+ weight: "400",
+ variable: "--font-instrument-serif",
+})
+
+export const previewFontVariables = cn(
+ geistSans.variable,
+ inter.variable,
+ notoSans.variable,
+ nunitoSans.variable,
+ figtree.variable,
+ roboto.variable,
+ raleway.variable,
+ dmSans.variable,
+ publicSans.variable,
+ outfit.variable,
+ oxanium.variable,
+ manrope.variable,
+ spaceGrotesk.variable,
+ montserrat.variable,
+ ibmPlexSans.variable,
+ sourceSans3.variable,
+ instrumentSans.variable,
+ geistMono.variable,
+ jetbrainsMono.variable,
+ notoSerif.variable,
+ robotoSlab.variable,
+ merriweather.variable,
+ lora.variable,
+ playfairDisplay.variable,
+ ebGaramond.variable,
+ instrumentSerif.variable
+)
diff --git a/apps/v4/app/(create)/preview/layout.tsx b/apps/v4/app/(create)/preview/layout.tsx
new file mode 100644
index 0000000000..a13564413e
--- /dev/null
+++ b/apps/v4/app/(create)/preview/layout.tsx
@@ -0,0 +1,15 @@
+import { PreviewFontVariables } from "@/app/(create)/preview/font-variables"
+import { previewFontVariables } from "@/app/(create)/preview/fonts"
+
+export default function PreviewLayout({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+
+ )
+}
diff --git a/apps/v4/app/globals.css b/apps/v4/app/globals.css
index 7837a22c5c..f4df0472d8 100644
--- a/apps/v4/app/globals.css
+++ b/apps/v4/app/globals.css
@@ -3,14 +3,6 @@
@import "shadcn/tailwind.css";
@import "./legacy-themes.css";
-@import "../registry/styles/style-vega.css" layer(base);
-@import "../registry/styles/style-nova.css" layer(base);
-@import "../registry/styles/style-lyra.css" layer(base);
-@import "../registry/styles/style-maia.css" layer(base);
-@import "../registry/styles/style-mira.css" layer(base);
-@import "../registry/styles/style-luma.css" layer(base);
-@import "../registry/styles/style-sera.css" layer(base);
-
@custom-variant style-vega (&:where(.style-vega *));
@custom-variant style-nova (&:where(.style-nova *));
@custom-variant style-lyra (&:where(.style-lyra *));
@@ -18,6 +10,7 @@
@custom-variant style-mira (&:where(.style-mira *));
@custom-variant style-luma (&:where(.style-luma *));
@custom-variant style-sera (&:where(.style-sera *));
+@custom-variant style-rhea (&:where(.style-rhea *));
@custom-variant dark (&:is(.dark *));
@custom-variant fixed (&:is(.layout-fixed *));
@@ -80,12 +73,12 @@
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
+ --foreground: oklch(0% 0 0);
--card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
+ --card-foreground: oklch(0% 0 0);
--popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
+ --popover-foreground: oklch(0% 0 0);
+ --primary: oklch(0% 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
@@ -104,7 +97,7 @@
--chart-4: var(--color-blue-700);
--chart-5: var(--color-blue-800);
--sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-foreground: oklch(0% 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
@@ -117,7 +110,7 @@
--code-foreground: var(--surface-foreground);
--code-highlight: oklch(0.96 0 0);
--code-number: oklch(0.56 0 0);
- --selection: oklch(0.145 0 0);
+ --selection: oklch(0% 0 0);
--selection-foreground: oklch(1 0 0);
}
@@ -211,7 +204,7 @@
}
@utility section-soft {
- @apply from-background to-surface/40 dark:bg-background 3xl:fixed:bg-none bg-linear-to-b;
+ @apply bg-linear-to-b from-background to-surface/40 dark:bg-background 3xl:fixed:bg-none;
}
@utility theme-container {
@@ -219,11 +212,11 @@
}
@utility container-wrapper {
- @apply 3xl:fixed:max-w-[calc(var(--breakpoint-2xl)+2rem)] mx-auto w-full px-2;
+ @apply mx-auto w-full px-2 3xl:fixed:max-w-[calc(var(--breakpoint-2xl)+2rem)];
}
@utility container {
- @apply 3xl:max-w-screen-2xl mx-auto max-w-[1400px] px-4 lg:px-8;
+ @apply mx-auto max-w-[1400px] px-4 3xl:max-w-screen-2xl lg:px-8;
}
@utility no-scrollbar {
@@ -236,14 +229,14 @@
}
@utility border-ghost {
- @apply after:border-border relative after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten;
+ @apply relative after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten;
}
@utility step {
counter-increment: step;
&:before {
- @apply border-background bg-muted mr-2 inline-flex size-6 items-center justify-center rounded-full text-center -indent-px font-mono text-sm font-medium md:absolute md:mt-[-4px] md:ml-[-50px] md:size-9 md:border-4;
+ @apply mr-2 inline-flex size-6 items-center justify-center rounded-full border-background bg-muted text-center -indent-px font-mono text-sm font-medium md:absolute md:mt-[-4px] md:ml-[-50px] md:size-9 md:border-4;
content: counter(step);
}
}
@@ -353,14 +346,8 @@
white-space: pre;
line-height: 0.95;
font-family:
- ui-monospace,
- SFMono-Regular,
- Menlo,
- Monaco,
- Consolas,
- "Liberation Mono",
- "Courier New",
- monospace;
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
+ "Courier New", monospace;
font-variant-ligatures: none;
}
diff --git a/apps/v4/app/layout.tsx b/apps/v4/app/layout.tsx
index f8de352018..7ae32643ed 100644
--- a/apps/v4/app/layout.tsx
+++ b/apps/v4/app/layout.tsx
@@ -4,7 +4,6 @@ import { NuqsAdapter } from "nuqs/adapters/next/app"
import { META_THEME_COLORS, siteConfig } from "@/lib/config"
import { fontVariables } from "@/lib/fonts"
import { cn } from "@/lib/utils"
-import { LayoutProvider } from "@/hooks/use-layout"
import { ActiveThemeProvider } from "@/components/active-theme"
import { Analytics } from "@/components/analytics"
import { TailwindIndicator } from "@/components/tailwind-indicator"
@@ -81,9 +80,6 @@ export default function RootLayout({
if (localStorage.theme === 'dark' || ((!('theme' in localStorage) || localStorage.theme === 'system') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '${META_THEME_COLORS.dark}')
}
- if (localStorage.layout) {
- document.documentElement.classList.add('layout-' + localStorage.layout)
- }
} catch (_) {}
`,
}}
@@ -92,24 +88,22 @@ export default function RootLayout({
-
-
-
-
-
- {children}
-
-
-
-
-
-
-
-
+
+
+
+
+ {children}
+
+
+
+
+
+
+