create-reactivite 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +76 -1
- package/package.json +1 -1
- package/template/.storybook/main.ts +20 -0
- package/template/.storybook/preview.tsx +55 -0
- package/template/_gitignore +3 -0
- package/template/index.html +1 -1
- package/template/package.json +7 -1
- package/template/src/components/ui-lib/auth-form.stories.tsx +26 -0
- package/template/src/components/ui-lib/auth-form.tsx +116 -0
- package/template/src/components/ui-lib/empty-state.stories.tsx +32 -0
- package/template/src/components/ui-lib/empty-state.tsx +54 -0
- package/template/src/components/ui-lib/feature-card.stories.tsx +45 -0
- package/template/src/components/ui-lib/feature-card.tsx +52 -0
- package/template/src/components/ui-lib/index.ts +13 -0
- package/template/src/components/ui-lib/page-header.stories.tsx +49 -0
- package/template/src/components/ui-lib/page-header.tsx +46 -0
- package/template/src/components/ui-lib/pricing-card.stories.tsx +58 -0
- package/template/src/components/ui-lib/pricing-card.tsx +86 -0
- package/template/src/components/ui-lib/stat-card.stories.tsx +55 -0
- package/template/src/components/ui-lib/stat-card.tsx +73 -0
- package/template/src/components/ui-lib/themes.stories.tsx +68 -0
- package/template/src/global.css +122 -0
- package/template/pnpm-lock.yaml +0 -3274
- package/template3/package-lock.json +0 -3934
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
|
|
3
|
+
import { PricingCard } from "./pricing-card";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "UI Library/PricingCard",
|
|
7
|
+
component: PricingCard,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
} satisfies Meta<typeof PricingCard>;
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof meta>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
plan: "Pro",
|
|
17
|
+
price: "$29",
|
|
18
|
+
description: "For growing teams that need more power.",
|
|
19
|
+
features: ["Unlimited projects", "Priority support", "Advanced analytics", "Custom domains"],
|
|
20
|
+
featured: false,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Featured: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
...Default.args,
|
|
27
|
+
featured: true,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const Tiers: Story = {
|
|
32
|
+
args: { plan: "Pro", price: "$29", features: [] },
|
|
33
|
+
render: () => (
|
|
34
|
+
<div className="grid w-full max-w-4xl grid-cols-1 gap-6 sm:grid-cols-3">
|
|
35
|
+
<PricingCard
|
|
36
|
+
plan="Starter"
|
|
37
|
+
price="$0"
|
|
38
|
+
description="For side projects."
|
|
39
|
+
features={["1 project", "Community support", "1 GB storage"]}
|
|
40
|
+
cta="Start free"
|
|
41
|
+
/>
|
|
42
|
+
<PricingCard
|
|
43
|
+
plan="Pro"
|
|
44
|
+
price="$29"
|
|
45
|
+
description="For growing teams."
|
|
46
|
+
features={["Unlimited projects", "Priority support", "Analytics"]}
|
|
47
|
+
featured
|
|
48
|
+
/>
|
|
49
|
+
<PricingCard
|
|
50
|
+
plan="Enterprise"
|
|
51
|
+
price="$99"
|
|
52
|
+
description="For large orgs."
|
|
53
|
+
features={["SSO + SAML", "Dedicated support", "SLA", "Audit logs"]}
|
|
54
|
+
cta="Contact sales"
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Check } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { Badge } from "@/components/ui/badge"
|
|
6
|
+
import { Button } from "@/components/ui/button"
|
|
7
|
+
import {
|
|
8
|
+
Card,
|
|
9
|
+
CardContent,
|
|
10
|
+
CardDescription,
|
|
11
|
+
CardFooter,
|
|
12
|
+
CardHeader,
|
|
13
|
+
CardTitle,
|
|
14
|
+
} from "@/components/ui/card"
|
|
15
|
+
|
|
16
|
+
export interface PricingCardProps extends React.ComponentProps<typeof Card> {
|
|
17
|
+
plan: string
|
|
18
|
+
price: string
|
|
19
|
+
period?: string
|
|
20
|
+
description?: string
|
|
21
|
+
features: string[]
|
|
22
|
+
cta?: string
|
|
23
|
+
/** Highlights the card with a ring + badge — the "recommended" plan. */
|
|
24
|
+
featured?: boolean
|
|
25
|
+
onSelect?: () => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* PricingCard — pricing tier composed from Card + Badge + Button + check list.
|
|
30
|
+
*/
|
|
31
|
+
export function PricingCard({
|
|
32
|
+
plan,
|
|
33
|
+
price,
|
|
34
|
+
period = "/mo",
|
|
35
|
+
description,
|
|
36
|
+
features,
|
|
37
|
+
cta = "Get started",
|
|
38
|
+
featured = false,
|
|
39
|
+
onSelect,
|
|
40
|
+
className,
|
|
41
|
+
...props
|
|
42
|
+
}: PricingCardProps) {
|
|
43
|
+
return (
|
|
44
|
+
<Card
|
|
45
|
+
className={cn(
|
|
46
|
+
"relative gap-6",
|
|
47
|
+
featured && "ring-primary ring-2",
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
>
|
|
52
|
+
{featured && (
|
|
53
|
+
<Badge className="absolute -top-3 left-6">Most popular</Badge>
|
|
54
|
+
)}
|
|
55
|
+
<CardHeader>
|
|
56
|
+
<CardDescription>{plan}</CardDescription>
|
|
57
|
+
<CardTitle className="flex items-baseline gap-1">
|
|
58
|
+
<span className="text-4xl font-bold tracking-tight">{price}</span>
|
|
59
|
+
<span className="text-muted-foreground text-sm font-normal">
|
|
60
|
+
{period}
|
|
61
|
+
</span>
|
|
62
|
+
</CardTitle>
|
|
63
|
+
{description && <CardDescription>{description}</CardDescription>}
|
|
64
|
+
</CardHeader>
|
|
65
|
+
<CardContent>
|
|
66
|
+
<ul className="space-y-2.5 text-sm">
|
|
67
|
+
{features.map((f) => (
|
|
68
|
+
<li key={f} className="flex items-center gap-2">
|
|
69
|
+
<Check className="text-primary size-4 shrink-0" />
|
|
70
|
+
<span>{f}</span>
|
|
71
|
+
</li>
|
|
72
|
+
))}
|
|
73
|
+
</ul>
|
|
74
|
+
</CardContent>
|
|
75
|
+
<CardFooter>
|
|
76
|
+
<Button
|
|
77
|
+
className="w-full"
|
|
78
|
+
variant={featured ? "default" : "outline"}
|
|
79
|
+
onClick={onSelect}
|
|
80
|
+
>
|
|
81
|
+
{cta}
|
|
82
|
+
</Button>
|
|
83
|
+
</CardFooter>
|
|
84
|
+
</Card>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { DollarSign, Users, Activity } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
import { StatCard } from "./stat-card";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "UI Library/StatCard",
|
|
8
|
+
component: StatCard,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
argTypes: {
|
|
11
|
+
delta: { control: { type: "number" } },
|
|
12
|
+
},
|
|
13
|
+
} satisfies Meta<typeof StatCard>;
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof meta>;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
args: {
|
|
20
|
+
label: "Total revenue",
|
|
21
|
+
value: "$48,120",
|
|
22
|
+
delta: 12.4,
|
|
23
|
+
hint: "vs last month",
|
|
24
|
+
icon: DollarSign,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const Negative: Story = {
|
|
29
|
+
args: {
|
|
30
|
+
label: "Churn rate",
|
|
31
|
+
value: "3.8%",
|
|
32
|
+
delta: -2.1,
|
|
33
|
+
hint: "vs last month",
|
|
34
|
+
icon: Activity,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const NoDelta: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
label: "Active users",
|
|
41
|
+
value: "12,840",
|
|
42
|
+
icon: Users,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Grid: Story = {
|
|
47
|
+
args: { label: "Total revenue", value: "$48,120", delta: 12.4, icon: DollarSign },
|
|
48
|
+
render: () => (
|
|
49
|
+
<div className="grid w-full max-w-3xl grid-cols-1 gap-4 sm:grid-cols-3">
|
|
50
|
+
<StatCard label="Revenue" value="$48,120" delta={12.4} icon={DollarSign} />
|
|
51
|
+
<StatCard label="Users" value="12,840" delta={4.2} icon={Users} />
|
|
52
|
+
<StatCard label="Churn" value="3.8%" delta={-2.1} icon={Activity} />
|
|
53
|
+
</div>
|
|
54
|
+
),
|
|
55
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { type LucideIcon, TrendingDown, TrendingUp } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { Badge } from "@/components/ui/badge"
|
|
6
|
+
import {
|
|
7
|
+
Card,
|
|
8
|
+
CardAction,
|
|
9
|
+
CardContent,
|
|
10
|
+
CardDescription,
|
|
11
|
+
CardHeader,
|
|
12
|
+
CardTitle,
|
|
13
|
+
} from "@/components/ui/card"
|
|
14
|
+
|
|
15
|
+
export interface StatCardProps extends React.ComponentProps<typeof Card> {
|
|
16
|
+
/** Metric label, e.g. "Total revenue". */
|
|
17
|
+
label: string
|
|
18
|
+
/** Big value, e.g. "$48,120". */
|
|
19
|
+
value: React.ReactNode
|
|
20
|
+
/** Optional period / context line under the value. */
|
|
21
|
+
hint?: string
|
|
22
|
+
/** Signed percentage change. Positive renders up + accent, negative down + destructive. */
|
|
23
|
+
delta?: number
|
|
24
|
+
/** Icon shown top-right. */
|
|
25
|
+
icon?: LucideIcon
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* StatCard — a dashboard KPI tile composed from Card + Badge.
|
|
30
|
+
* Purely var-driven, so it adopts whatever `data-theme` is active.
|
|
31
|
+
*/
|
|
32
|
+
export function StatCard({
|
|
33
|
+
label,
|
|
34
|
+
value,
|
|
35
|
+
hint,
|
|
36
|
+
delta,
|
|
37
|
+
icon: Icon,
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: StatCardProps) {
|
|
41
|
+
const up = (delta ?? 0) >= 0
|
|
42
|
+
return (
|
|
43
|
+
<Card className={cn("gap-3", className)} {...props}>
|
|
44
|
+
<CardHeader>
|
|
45
|
+
<CardDescription>{label}</CardDescription>
|
|
46
|
+
<CardTitle className="text-3xl font-semibold tabular-nums tracking-tight">
|
|
47
|
+
{value}
|
|
48
|
+
</CardTitle>
|
|
49
|
+
{Icon ? (
|
|
50
|
+
<CardAction>
|
|
51
|
+
<span className="bg-muted text-muted-foreground flex size-9 items-center justify-center rounded-md">
|
|
52
|
+
<Icon className="size-4" />
|
|
53
|
+
</span>
|
|
54
|
+
</CardAction>
|
|
55
|
+
) : null}
|
|
56
|
+
</CardHeader>
|
|
57
|
+
{(delta !== undefined || hint) && (
|
|
58
|
+
<CardContent className="flex items-center gap-2">
|
|
59
|
+
{delta !== undefined && (
|
|
60
|
+
<Badge variant={up ? "default" : "destructive"}>
|
|
61
|
+
{up ? <TrendingUp /> : <TrendingDown />}
|
|
62
|
+
{up ? "+" : ""}
|
|
63
|
+
{delta}%
|
|
64
|
+
</Badge>
|
|
65
|
+
)}
|
|
66
|
+
{hint && (
|
|
67
|
+
<span className="text-muted-foreground text-xs">{hint}</span>
|
|
68
|
+
)}
|
|
69
|
+
</CardContent>
|
|
70
|
+
)}
|
|
71
|
+
</Card>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { DollarSign, Zap } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
import { StatCard } from "./stat-card";
|
|
5
|
+
import { FeatureCard } from "./feature-card";
|
|
6
|
+
import { PricingCard } from "./pricing-card";
|
|
7
|
+
import { Button } from "@/components/ui/button";
|
|
8
|
+
import { Badge } from "@/components/ui/badge";
|
|
9
|
+
|
|
10
|
+
const THEMES = ["minimal", "brutalist", "aurora"] as const;
|
|
11
|
+
|
|
12
|
+
/** A compact sampler rendered once per theme, side by side. */
|
|
13
|
+
function Sampler() {
|
|
14
|
+
return (
|
|
15
|
+
<div className="grid w-72 gap-4">
|
|
16
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
17
|
+
<Button size="sm">Primary</Button>
|
|
18
|
+
<Button size="sm" variant="outline">
|
|
19
|
+
Outline
|
|
20
|
+
</Button>
|
|
21
|
+
<Badge>New</Badge>
|
|
22
|
+
</div>
|
|
23
|
+
<StatCard label="Revenue" value="$48,120" delta={12.4} icon={DollarSign} />
|
|
24
|
+
<FeatureCard
|
|
25
|
+
icon={Zap}
|
|
26
|
+
title="Themeable"
|
|
27
|
+
description="One attribute re-skins everything."
|
|
28
|
+
/>
|
|
29
|
+
<PricingCard
|
|
30
|
+
plan="Pro"
|
|
31
|
+
price="$29"
|
|
32
|
+
features={["Unlimited", "Support", "Analytics"]}
|
|
33
|
+
featured
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const meta = {
|
|
40
|
+
title: "UI Library/Themes",
|
|
41
|
+
parameters: { layout: "fullscreen" },
|
|
42
|
+
} satisfies Meta;
|
|
43
|
+
|
|
44
|
+
export default meta;
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* All three themes at once. Each column hard-sets its own `data-theme`,
|
|
49
|
+
* overriding the toolbar selection — this is the "3 variants" overview.
|
|
50
|
+
*/
|
|
51
|
+
export const AllThemes: Story = {
|
|
52
|
+
render: () => (
|
|
53
|
+
<div className="flex flex-wrap gap-6 p-2">
|
|
54
|
+
{THEMES.map((t) => (
|
|
55
|
+
<div
|
|
56
|
+
key={t}
|
|
57
|
+
data-theme={t}
|
|
58
|
+
className="bg-background text-foreground rounded-xl border p-5"
|
|
59
|
+
>
|
|
60
|
+
<p className="text-muted-foreground mb-4 text-xs font-medium tracking-wide uppercase">
|
|
61
|
+
{t}
|
|
62
|
+
</p>
|
|
63
|
+
<Sampler />
|
|
64
|
+
</div>
|
|
65
|
+
))}
|
|
66
|
+
</div>
|
|
67
|
+
),
|
|
68
|
+
};
|
package/template/src/global.css
CHANGED
|
@@ -74,6 +74,128 @@
|
|
|
74
74
|
--sidebar-ring: oklch(0.439 0 0);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/* ──────────────────────────────────────────────────────────────
|
|
78
|
+
UI LIBRARY THEMES
|
|
79
|
+
3 distinct, var-driven looks. Switch by setting `data-theme` on
|
|
80
|
+
<html>: "minimal" | "brutalist" | "aurora". Every shadcn + ui-lib
|
|
81
|
+
component reads these vars, so themes need ZERO component changes.
|
|
82
|
+
Default theme is set in index.html. The base :root above stays the
|
|
83
|
+
neutral-dark fallback when no data-theme is present.
|
|
84
|
+
────────────────────────────────────────────────────────────── */
|
|
85
|
+
|
|
86
|
+
/* Theme 1 — MINIMAL: light, calm neutrals, soft radius, editorial. */
|
|
87
|
+
[data-theme="minimal"] {
|
|
88
|
+
--background: oklch(1 0 0);
|
|
89
|
+
--foreground: oklch(0.18 0 0);
|
|
90
|
+
--card: oklch(1 0 0);
|
|
91
|
+
--card-foreground: oklch(0.18 0 0);
|
|
92
|
+
--popover: oklch(1 0 0);
|
|
93
|
+
--popover-foreground: oklch(0.18 0 0);
|
|
94
|
+
--primary: oklch(0.21 0 0);
|
|
95
|
+
--primary-foreground: oklch(0.98 0 0);
|
|
96
|
+
--secondary: oklch(0.97 0 0);
|
|
97
|
+
--secondary-foreground: oklch(0.21 0 0);
|
|
98
|
+
--muted: oklch(0.97 0 0);
|
|
99
|
+
--muted-foreground: oklch(0.52 0 0);
|
|
100
|
+
--accent: oklch(0.96 0 0);
|
|
101
|
+
--accent-foreground: oklch(0.21 0 0);
|
|
102
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
103
|
+
--destructive-foreground: oklch(0.98 0 0);
|
|
104
|
+
--border: oklch(0.92 0 0);
|
|
105
|
+
--input: oklch(0.92 0 0);
|
|
106
|
+
--ring: oklch(0.7 0 0);
|
|
107
|
+
--radius: 0.625rem;
|
|
108
|
+
--sidebar: oklch(0.985 0 0);
|
|
109
|
+
--sidebar-foreground: oklch(0.18 0 0);
|
|
110
|
+
--sidebar-primary: oklch(0.21 0 0);
|
|
111
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
112
|
+
--sidebar-accent: oklch(0.96 0 0);
|
|
113
|
+
--sidebar-accent-foreground: oklch(0.21 0 0);
|
|
114
|
+
--sidebar-border: oklch(0.92 0 0);
|
|
115
|
+
--sidebar-ring: oklch(0.7 0 0);
|
|
116
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
117
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
118
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
119
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
120
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Theme 2 — BRUTALIST: stark black/white, acid-yellow accent, 0 radius,
|
|
124
|
+
pure-black borders. High-contrast, raw, intentionally loud. */
|
|
125
|
+
[data-theme="brutalist"] {
|
|
126
|
+
--background: oklch(0.98 0 0);
|
|
127
|
+
--foreground: oklch(0 0 0);
|
|
128
|
+
--card: oklch(1 0 0);
|
|
129
|
+
--card-foreground: oklch(0 0 0);
|
|
130
|
+
--popover: oklch(1 0 0);
|
|
131
|
+
--popover-foreground: oklch(0 0 0);
|
|
132
|
+
--primary: oklch(0 0 0);
|
|
133
|
+
--primary-foreground: oklch(1 0 0);
|
|
134
|
+
--secondary: oklch(0.93 0.19 102);
|
|
135
|
+
--secondary-foreground: oklch(0 0 0);
|
|
136
|
+
--muted: oklch(0.95 0 0);
|
|
137
|
+
--muted-foreground: oklch(0.35 0 0);
|
|
138
|
+
--accent: oklch(0.93 0.19 102);
|
|
139
|
+
--accent-foreground: oklch(0 0 0);
|
|
140
|
+
--destructive: oklch(0.55 0.24 27);
|
|
141
|
+
--destructive-foreground: oklch(1 0 0);
|
|
142
|
+
--border: oklch(0 0 0);
|
|
143
|
+
--input: oklch(0 0 0);
|
|
144
|
+
--ring: oklch(0 0 0);
|
|
145
|
+
--radius: 0rem;
|
|
146
|
+
--sidebar: oklch(1 0 0);
|
|
147
|
+
--sidebar-foreground: oklch(0 0 0);
|
|
148
|
+
--sidebar-primary: oklch(0 0 0);
|
|
149
|
+
--sidebar-primary-foreground: oklch(1 0 0);
|
|
150
|
+
--sidebar-accent: oklch(0.93 0.19 102);
|
|
151
|
+
--sidebar-accent-foreground: oklch(0 0 0);
|
|
152
|
+
--sidebar-border: oklch(0 0 0);
|
|
153
|
+
--sidebar-ring: oklch(0 0 0);
|
|
154
|
+
--chart-1: oklch(0 0 0);
|
|
155
|
+
--chart-2: oklch(0.93 0.19 102);
|
|
156
|
+
--chart-3: oklch(0.55 0.24 27);
|
|
157
|
+
--chart-4: oklch(0.5 0 0);
|
|
158
|
+
--chart-5: oklch(0.75 0 0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Theme 3 — AURORA: deep violet dark, neon violet/cyan accents,
|
|
162
|
+
generous radius. Glowy, premium, night-mode product feel. */
|
|
163
|
+
[data-theme="aurora"] {
|
|
164
|
+
--background: oklch(0.16 0.02 280);
|
|
165
|
+
--foreground: oklch(0.96 0.01 280);
|
|
166
|
+
--card: oklch(0.2 0.03 280);
|
|
167
|
+
--card-foreground: oklch(0.96 0.01 280);
|
|
168
|
+
--popover: oklch(0.2 0.03 280);
|
|
169
|
+
--popover-foreground: oklch(0.96 0.01 280);
|
|
170
|
+
--primary: oklch(0.7 0.18 295);
|
|
171
|
+
--primary-foreground: oklch(0.16 0.02 280);
|
|
172
|
+
--secondary: oklch(0.28 0.04 280);
|
|
173
|
+
--secondary-foreground: oklch(0.96 0.01 280);
|
|
174
|
+
--muted: oklch(0.26 0.03 280);
|
|
175
|
+
--muted-foreground: oklch(0.72 0.03 280);
|
|
176
|
+
--accent: oklch(0.55 0.16 230);
|
|
177
|
+
--accent-foreground: oklch(0.98 0 0);
|
|
178
|
+
--destructive: oklch(0.62 0.24 18);
|
|
179
|
+
--destructive-foreground: oklch(0.98 0 0);
|
|
180
|
+
--border: oklch(0.32 0.04 280);
|
|
181
|
+
--input: oklch(0.3 0.04 280);
|
|
182
|
+
--ring: oklch(0.7 0.18 295);
|
|
183
|
+
--radius: 1rem;
|
|
184
|
+
--sidebar: oklch(0.18 0.025 280);
|
|
185
|
+
--sidebar-foreground: oklch(0.96 0.01 280);
|
|
186
|
+
--sidebar-primary: oklch(0.7 0.18 295);
|
|
187
|
+
--sidebar-primary-foreground: oklch(0.16 0.02 280);
|
|
188
|
+
--sidebar-accent: oklch(0.28 0.04 280);
|
|
189
|
+
--sidebar-accent-foreground: oklch(0.96 0.01 280);
|
|
190
|
+
--sidebar-border: oklch(0.32 0.04 280);
|
|
191
|
+
--sidebar-ring: oklch(0.7 0.18 295);
|
|
192
|
+
--chart-1: oklch(0.7 0.18 295);
|
|
193
|
+
--chart-2: oklch(0.6 0.16 230);
|
|
194
|
+
--chart-3: oklch(0.75 0.17 160);
|
|
195
|
+
--chart-4: oklch(0.7 0.19 20);
|
|
196
|
+
--chart-5: oklch(0.8 0.16 90);
|
|
197
|
+
}
|
|
198
|
+
|
|
77
199
|
@theme inline {
|
|
78
200
|
--font-sans: var(--font-geist-sans);
|
|
79
201
|
--font-mono: var(--font-geist-mono);
|