Compare commits

...

6 Commits

Author SHA1 Message Date
Claude
95e8ef9939 Fix tracking empty preset code in init routes
Guard against tracking an empty preset value in both /init and /init/v0
routes. When no valid preset code is in the URL, getPresetCode encodes
one from the parsed config params. The conditional spread ensures an
empty string never reaches analytics.

https://claude.ai/code/session_018Mm7WJAaSUGSqamSm3RiyC
2026-03-21 10:15:16 +00:00
Claude
900f099583 Fix tracking empty preset code in init route
When no valid preset code is provided in the URL, encode one from the
parsed config params instead of tracking an empty value.

https://claude.ai/code/session_018Mm7WJAaSUGSqamSm3RiyC
2026-03-21 10:05:48 +00:00
shadcn
5b40b9de5a Revert "feat: update customizer (#10129)" (#10130)
This reverts commit e327cef2c1.
2026-03-20 16:56:57 +04:00
shadcn
e327cef2c1 feat: update customizer (#10129) 2026-03-20 16:46:40 +04:00
github-actions[bot]
563d572ba0 chore(release): version packages (#10120)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-19 23:36:28 +04:00
shadcn
687f09817b feat: chartColor and fontHeading (#10115)
* feat: chart color

* fix

* fix

* fix: chart color

* chore: changeset

* chore: restore directory registry formatting

* feat: add fontHeading

* feat: rebuild registry

* fix: v0

* refactor

* fix

* fix

* fix

* fix

* fix

* fix: refactor preset handling

* fix

* fix

* fix
2026-03-19 23:35:01 +04:00
617 changed files with 13276 additions and 1384 deletions

View File

@@ -0,0 +1,22 @@
---
description: Keep registry base and radix trees in sync when editing shared UI
globs: apps/v4/registry/bases/**/*
alwaysApply: false
---
# Registry bases: Base UI ↔ Radix parity
`apps/v4/registry/bases/base` and `apps/v4/registry/bases/radix` are **parallel registries**. Anything that exists in both trees for the same purpose (preview blocks, mirrored examples, shared card layouts, etc.) **must stay in sync**.
## When editing
- If you change a file under **`bases/base/...`**, apply the **same behavioral and visual change** to the matching path under **`bases/radix/...`** (and the reverse).
- Only diverge where APIs differ (e.g. import paths like `@/registry/bases/base/ui/*` vs `@/registry/bases/radix/ui/*`, or Base UI vs Radix component props).
- Do **not** update only one side unless the user explicitly asks for a single-base change.
## Typical mirrored paths
- `blocks/preview/**` — preview cards and blocks
- Parallel `ui/*` components when both exist for the same component
After edits, briefly confirm both trees were updated (or state why one side is intentionally unchanged).

View File

@@ -79,7 +79,7 @@ export default function ChangelogPage() {
})}
{olderPages.length > 0 && (
<div id="more-updates" className="mb-24 scroll-mt-24">
<h2 className="font-heading mb-6 text-xl font-semibold tracking-tight">
<h2 className="mb-6 font-heading text-xl font-semibold tracking-tight">
More Updates
</h2>
<div className="grid auto-rows-fr gap-3 sm:grid-cols-2">

View File

@@ -0,0 +1,136 @@
"use client"
import * as React from "react"
import { useMounted } from "@/hooks/use-mounted"
import {
BASE_COLORS,
getThemesForBaseColor,
type ChartColorName,
} from "@/registry/config"
import { LockButton } from "@/app/(create)/components/lock-button"
import {
Picker,
PickerContent,
PickerGroup,
PickerRadioGroup,
PickerRadioItem,
PickerSeparator,
PickerTrigger,
} from "@/app/(create)/components/picker"
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
export function ChartColorPicker({
isMobile,
anchorRef,
}: {
isMobile: boolean
anchorRef: React.RefObject<HTMLDivElement | null>
}) {
const mounted = useMounted()
const [params, setParams] = useDesignSystemSearchParams()
const availableChartColors = React.useMemo(
() => getThemesForBaseColor(params.baseColor),
[params.baseColor]
)
const currentChartColor = React.useMemo(
() =>
availableChartColors.find((theme) => theme.name === params.chartColor),
[availableChartColors, params.chartColor]
)
const currentChartColorIsBaseColor = React.useMemo(
() => BASE_COLORS.find((baseColor) => baseColor.name === params.chartColor),
[params.chartColor]
)
React.useEffect(() => {
if (!currentChartColor && availableChartColors.length > 0) {
setParams({ chartColor: availableChartColors[0].name })
}
}, [currentChartColor, availableChartColors, setParams])
return (
<div className="group/picker relative">
<Picker>
<PickerTrigger>
<div className="flex flex-col justify-start text-left">
<div className="text-xs text-muted-foreground">Chart Color</div>
<div className="text-sm font-medium text-foreground">
{currentChartColor?.title}
</div>
</div>
{mounted && (
<div
style={
{
"--color":
currentChartColor?.cssVars?.dark?.[
currentChartColorIsBaseColor
? "muted-foreground"
: "primary"
],
} as React.CSSProperties
}
className="pointer-events-none absolute top-1/2 right-4 size-4 -translate-y-1/2 rounded-full bg-(--color) select-none md:right-2.5"
/>
)}
</PickerTrigger>
<PickerContent
anchor={isMobile ? anchorRef : undefined}
side={isMobile ? "top" : "right"}
align={isMobile ? "center" : "start"}
className="max-h-92"
>
<PickerRadioGroup
value={currentChartColor?.name}
onValueChange={(value) => {
setParams({ chartColor: value as ChartColorName })
}}
>
<PickerGroup>
{availableChartColors
.filter((theme) =>
BASE_COLORS.find((baseColor) => baseColor.name === theme.name)
)
.map((theme) => (
<PickerRadioItem
key={theme.name}
value={theme.name}
closeOnClick={isMobile}
>
{theme.title}
</PickerRadioItem>
))}
</PickerGroup>
<PickerSeparator />
<PickerGroup>
{availableChartColors
.filter(
(theme) =>
!BASE_COLORS.find(
(baseColor) => baseColor.name === theme.name
)
)
.map((theme) => (
<PickerRadioItem
key={theme.name}
value={theme.name}
closeOnClick={isMobile}
>
{theme.title}
</PickerRadioItem>
))}
</PickerGroup>
</PickerRadioGroup>
</PickerContent>
</Picker>
<LockButton
param="chartColor"
className="absolute top-1/2 right-8 -translate-y-1/2"
/>
</div>
)
}

View File

@@ -7,7 +7,7 @@ import {
CardFooter,
CardHeader,
} from "@/examples/base/ui/card"
import { FieldGroup } from "@/examples/base/ui/field"
import { FieldGroup, FieldSeparator } from "@/examples/base/ui/field"
import { type RegistryItem } from "shadcn/schema"
import { useIsMobile } from "@/hooks/use-mobile"
@@ -16,6 +16,7 @@ import { MenuAccentPicker } from "@/app/(create)/components/accent-picker"
import { ActionMenu } from "@/app/(create)/components/action-menu"
import { BaseColorPicker } from "@/app/(create)/components/base-color-picker"
import { BasePicker } from "@/app/(create)/components/base-picker"
import { ChartColorPicker } from "@/app/(create)/components/chart-color-picker"
import { CopyPreset } from "@/app/(create)/components/copy-preset"
import { FontPicker } from "@/app/(create)/components/font-picker"
import { IconLibraryPicker } from "@/app/(create)/components/icon-library-picker"
@@ -27,7 +28,7 @@ import { ResetDialog } from "@/app/(create)/components/reset-button"
import { StylePicker } from "@/app/(create)/components/style-picker"
import { ThemePicker } from "@/app/(create)/components/theme-picker"
import { V0Button } from "@/app/(create)/components/v0-button"
import { FONTS } from "@/app/(create)/lib/fonts"
import { FONT_HEADING_OPTIONS, FONTS } from "@/app/(create)/lib/fonts"
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
export function Customizer({
@@ -54,22 +55,40 @@ export function Customizer({
<MainMenu />
</CardHeader>
<CardContent className="no-scrollbar min-h-0 flex-1 overflow-x-auto overflow-y-hidden md:overflow-y-auto">
<FieldGroup className="flex-row gap-2.5 py-px md:flex-col md:gap-3.25">
<FieldGroup className="flex-row gap-2.5 py-px **:data-[slot=field-separator]:-mx-4 **:data-[slot=field-separator]:w-auto md:flex-col md:gap-3.25">
{isMobile && <BasePicker isMobile={isMobile} anchorRef={anchorRef} />}
<StylePicker
styles={STYLES}
isMobile={isMobile}
anchorRef={anchorRef}
/>
<FieldSeparator className="hidden md:block" />
<BaseColorPicker isMobile={isMobile} anchorRef={anchorRef} />
<ThemePicker
themes={availableThemes}
isMobile={isMobile}
anchorRef={anchorRef}
/>
<ChartColorPicker isMobile={isMobile} anchorRef={anchorRef} />
<FieldSeparator className="hidden md:block" />
<FontPicker
label="Heading"
param="fontHeading"
fonts={FONT_HEADING_OPTIONS}
isMobile={isMobile}
anchorRef={anchorRef}
/>
<FontPicker
label="Font"
param="font"
fonts={FONTS}
isMobile={isMobile}
anchorRef={anchorRef}
/>
<FieldSeparator className="hidden md:block" />
<IconLibraryPicker isMobile={isMobile} anchorRef={anchorRef} />
<FontPicker fonts={FONTS} isMobile={isMobile} anchorRef={anchorRef} />
<RadiusPicker isMobile={isMobile} anchorRef={anchorRef} />
<FieldSeparator className="hidden md:block" />
<MenuColorPicker isMobile={isMobile} anchorRef={anchorRef} />
<MenuAccentPicker isMobile={isMobile} anchorRef={anchorRef} />
</FieldGroup>

View File

@@ -64,18 +64,37 @@ export function DesignSystemProvider({
history: "replace", // …or push updates into the iframe history.
})
const [isReady, setIsReady] = React.useState(false)
const { style, theme, font, baseColor, menuAccent, menuColor, radius } =
searchParams
const {
style,
theme,
font,
fontHeading,
baseColor,
chartColor,
menuAccent,
menuColor,
radius,
} = searchParams
const effectiveRadius = style === "lyra" ? "none" : radius
const selectedFont = React.useMemo(
() => FONTS.find((fontOption) => fontOption.value === font),
[font]
)
const selectedHeadingFont = React.useMemo(() => {
if (fontHeading === "inherit" || fontHeading === font) {
return selectedFont
}
return FONTS.find((fontOption) => fontOption.value === fontHeading)
}, [font, fontHeading, selectedFont])
const initialFontSansRef = React.useRef<string | null>(null)
const initialFontHeadingRef = React.useRef<string | null>(null)
React.useEffect(() => {
initialFontSansRef.current =
document.documentElement.style.getPropertyValue("--font-sans")
initialFontHeadingRef.current =
document.documentElement.style.getPropertyValue("--font-heading")
return () => {
removeManagedBodyClasses(document.body)
@@ -86,10 +105,18 @@ export function DesignSystemProvider({
"--font-sans",
initialFontSansRef.current
)
return
} else {
document.documentElement.style.removeProperty("--font-sans")
}
document.documentElement.style.removeProperty("--font-sans")
if (initialFontHeadingRef.current) {
document.documentElement.style.setProperty(
"--font-heading",
initialFontHeadingRef.current
)
} else {
document.documentElement.style.removeProperty("--font-heading")
}
}
}, [])
@@ -124,12 +151,29 @@ export function DesignSystemProvider({
// Always set --font-sans for the preview so the selected font is visible.
// The font type (sans/serif/mono) is metadata for the CLI updater.
if (selectedFont) {
const fontFamily = selectedFont.font.style.fontFamily
document.documentElement.style.setProperty("--font-sans", fontFamily)
document.documentElement.style.setProperty(
"--font-sans",
selectedFont.font.style.fontFamily
)
}
if (selectedHeadingFont) {
document.documentElement.style.setProperty(
"--font-heading",
selectedHeadingFont.font.style.fontFamily
)
}
setIsReady(true)
}, [style, theme, font, baseColor, selectedFont])
}, [
style,
theme,
font,
fontHeading,
baseColor,
selectedFont,
selectedHeadingFont,
])
const registryTheme = React.useMemo(() => {
if (!baseColor || !theme || !menuAccent || !effectiveRadius) {
@@ -140,12 +184,13 @@ export function DesignSystemProvider({
...DEFAULT_CONFIG,
baseColor,
theme,
chartColor,
menuAccent,
radius: effectiveRadius,
}
return buildRegistryTheme(config)
}, [baseColor, theme, menuAccent, effectiveRadius])
}, [baseColor, theme, chartColor, menuAccent, effectiveRadius])
// Use useLayoutEffect for synchronous CSS var updates.
React.useLayoutEffect(() => {

View File

@@ -2,13 +2,6 @@
import * as React from "react"
import {
Item,
ItemContent,
ItemDescription,
ItemTitle,
} from "@/registry/bases/radix/ui/item"
import { type FontValue } from "@/registry/config"
import { LockButton } from "@/app/(create)/components/lock-button"
import {
Picker,
@@ -20,28 +13,68 @@ import {
PickerSeparator,
PickerTrigger,
} from "@/app/(create)/components/picker"
import { type Font } from "@/app/(create)/lib/fonts"
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
import { FONTS } from "@/app/(create)/lib/fonts"
import {
useDesignSystemSearchParams,
type DesignSystemSearchParams,
} from "@/app/(create)/lib/search-params"
type FontPickerOption = {
name: string
value: string
type: string
font: {
style: {
fontFamily: string
}
} | null
}
export function FontPicker({
label,
param,
fonts,
isMobile,
anchorRef,
}: {
fonts: readonly Font[]
label: string
param: "font" | "fontHeading"
fonts: readonly FontPickerOption[]
isMobile: boolean
anchorRef: React.RefObject<HTMLDivElement | null>
}) {
const [params, setParams] = useDesignSystemSearchParams()
const currentValue = param === "font" ? params.font : params.fontHeading
const handleFontChange = React.useCallback(
(value: string) => {
setParams({
[param]: value,
} as Partial<DesignSystemSearchParams>)
},
[param, setParams]
)
const currentFont = React.useMemo(
() => fonts.find((font) => font.value === params.font),
[fonts, params.font]
() => fonts.find((font) => font.value === currentValue),
[fonts, currentValue]
)
const currentBodyFont = React.useMemo(
() => FONTS.find((font) => font.value === params.font),
[params.font]
)
const inheritsBodyFont = param === "fontHeading" && currentValue === "inherit"
const displayFontName = inheritsBodyFont
? currentBodyFont?.name
: currentFont?.name
const inheritFontLabel = currentBodyFont ? currentBodyFont.name : "Body font"
const groupedFonts = React.useMemo(() => {
const groups = new Map<Font["type"], Font[]>()
const pickerFonts =
param === "fontHeading"
? fonts.filter((font) => font.value !== "inherit")
: fonts
const groups = new Map<string, FontPickerOption[]>()
for (const font of fonts) {
for (const font of pickerFonts) {
const existing = groups.get(font.type)
if (existing) {
existing.push(font)
@@ -56,21 +89,25 @@ export function FontPicker({
label: `${type.charAt(0).toUpperCase()}${type.slice(1)}`,
items,
}))
}, [fonts])
}, [fonts, param])
return (
<div className="group/picker relative">
<Picker>
<PickerTrigger>
<div className="flex flex-col justify-start text-left">
<div className="text-xs text-muted-foreground">Font</div>
<div className="text-xs text-muted-foreground">{label}</div>
<div className="text-sm font-medium text-foreground">
{currentFont?.name}
{displayFontName}
</div>
</div>
<div
className="pointer-events-none absolute top-1/2 right-4 flex size-4 -translate-y-1/2 items-center justify-center text-base text-foreground select-none md:right-2.5"
style={{ fontFamily: currentFont?.font.style.fontFamily }}
style={{
fontFamily:
currentFont?.font?.style.fontFamily ??
currentBodyFont?.font.style.fontFamily,
}}
>
Aa
</div>
@@ -82,11 +119,19 @@ export function FontPicker({
className="max-h-96"
>
<PickerRadioGroup
value={currentFont?.value}
onValueChange={(value) => {
setParams({ font: value as FontValue })
}}
value={currentValue}
onValueChange={handleFontChange}
>
{param === "fontHeading" ? (
<>
<PickerGroup>
<PickerRadioItem value="inherit" closeOnClick={isMobile}>
{inheritFontLabel}
</PickerRadioItem>
</PickerGroup>
<PickerSeparator />
</>
) : null}
{groupedFonts.map((group) => (
<PickerGroup key={group.type}>
<PickerLabel>{group.label}</PickerLabel>
@@ -105,7 +150,7 @@ export function FontPicker({
</PickerContent>
</Picker>
<LockButton
param="font"
param={param}
className="absolute top-1/2 right-8 -translate-y-1/2"
/>
</div>

View File

@@ -31,8 +31,10 @@ export function PresetPicker({
preset.style === params.style &&
preset.baseColor === params.baseColor &&
preset.theme === params.theme &&
preset.chartColor === params.chartColor &&
preset.iconLibrary === params.iconLibrary &&
preset.font === params.font &&
preset.fontHeading === params.fontHeading &&
preset.menuAccent === params.menuAccent &&
preset.menuColor === params.menuColor &&
preset.radius === params.radius
@@ -43,8 +45,10 @@ export function PresetPicker({
params.style,
params.baseColor,
params.theme,
params.chartColor,
params.iconLibrary,
params.font,
params.fontHeading,
params.menuAccent,
params.menuColor,
params.radius,
@@ -67,8 +71,10 @@ export function PresetPicker({
style: preset.style,
baseColor: preset.baseColor,
theme: preset.theme,
chartColor: preset.chartColor,
iconLibrary: preset.iconLibrary,
font: preset.font,
fontHeading: preset.fontHeading,
menuAccent: preset.menuAccent,
menuColor: preset.menuColor,
radius: preset.radius,

View File

@@ -87,7 +87,7 @@ export function ProjectForm({
const rtlFlag = params.rtl ? " --rtl" : ""
const flags = `${presetFlag}${baseFlag}${templateFlag}${monorepoFlag}${rtlFlag}`
return IS_LOCAL_DEV && !process.env.NEXT_PUBLIC_RC
return IS_LOCAL_DEV
? {
pnpm: `shadcn init${flags}`,
npm: `shadcn init${flags}`,
@@ -130,7 +130,7 @@ export function ProjectForm({
<DialogTrigger render={<Button className={cn(className)} />}>
Create Project
</DialogTrigger>
<DialogContent className="no-scrollbar max-h-[calc(100svh-2rem)] overflow-y-auto sm:max-w-sm">
<DialogContent className="dark no-scrollbar max-h-[calc(100svh-2rem)] overflow-y-auto rounded-2xl border-0 bg-neutral-800 p-6 text-foreground shadow-xl ring-1 ring-neutral-950/80 backdrop-blur-xl [--border:var(--color-neutral-700)]! sm:max-w-sm">
<DialogHeader>
<DialogTitle>Create Project</DialogTitle>
<DialogDescription>
@@ -139,16 +139,17 @@ export function ProjectForm({
</DialogHeader>
<div>
<FieldGroup>
<Field>
<FieldSeparator className="-mx-6" />
<Field className="-mt-2 gap-3">
<FieldLabel>Template</FieldLabel>
<TemplateGrid template={params.template} setParams={setParams} />
</Field>
<FieldSeparator />
<FieldSeparator className="-mx-6" />
<Field className="-mt-2">
<FieldLabel>Base</FieldLabel>
<BaseGrid base={params.base} setParams={setParams} />
</Field>
<FieldSeparator />
<FieldSeparator className="-mx-6" />
<FieldSet>
<FieldLegend variant="label" className="sr-only">
Options
@@ -159,7 +160,7 @@ export function ProjectForm({
>
<FieldLabel htmlFor="monorepo">
<span
className="size-4 text-foreground [&_svg]:size-4 [&_svg]:fill-current"
className="size-4 text-neutral-100 [&_svg]:size-4 [&_svg]:fill-current"
dangerouslySetInnerHTML={{
__html: TURBOREPO_LOGO,
}}
@@ -181,7 +182,7 @@ export function ProjectForm({
}}
/>
</Field>
<FieldSeparator />
<FieldSeparator className="-mx-6" />
<Field orientation="horizontal">
<FieldLabel htmlFor="rtl">
<HugeiconsIcon icon={Globe02Icon} className="size-4" />
@@ -198,7 +199,7 @@ export function ProjectForm({
</FieldSet>
</FieldGroup>
</div>
<DialogFooter className="min-w-0">
<DialogFooter className="-mx-6 -mb-6 min-w-0">
<div className="flex w-full min-w-0 flex-col gap-3">
<Tabs
value={packageManager}
@@ -208,16 +209,16 @@ export function ProjectForm({
packageManager: value as PackageManager,
}))
}}
className="min-w-0 gap-0 overflow-hidden rounded-lg border bg-surface"
className="min-w-0 gap-0 overflow-hidden rounded-xl border-0 bg-neutral-950/20 ring-1 ring-neutral-950/80 dark:bg-neutral-900/50 dark:ring-neutral-700/50"
>
<div className="flex items-center gap-2 px-1 py-1">
<TabsList className="font-mono">
<div className="flex items-center gap-2 py-1 pr-1.5 pl-1">
<TabsList className="bg-transparent font-mono">
{PACKAGE_MANAGERS.map((manager) => {
return (
<TabsTrigger
key={manager}
value={manager}
className="data-[state=active]:shadow-none"
className="py-0 leading-none data-[state=active]:shadow-none"
>
{manager}
</TabsTrigger>
@@ -241,7 +242,7 @@ export function ProjectForm({
{Object.entries(commands).map(([key, cmd]) => {
return (
<TabsContent key={key} value={key}>
<div className="relative overflow-hidden border-t border-border/50 bg-surface px-3 py-3 text-surface-foreground">
<div className="relative overflow-hidden border-t border-neutral-700/50 bg-neutral-900/50 px-3 py-3 text-neutral-100">
<div className="no-scrollbar overflow-x-auto">
<code className="font-mono text-sm whitespace-nowrap">
{cmd}
@@ -288,23 +289,26 @@ const TemplateGrid = React.memo(function TemplateGrid({
<RadioGroup
value={framework}
onValueChange={handleTemplateChange}
className="grid grid-cols-3 gap-2"
className="grid grid-cols-2 gap-2"
>
{TEMPLATES.map((item) => (
<FieldLabel
key={item.value}
htmlFor={`template-${item.value}`}
className="py-1"
className="block w-full"
>
<Field className="gap-0" orientation="horizontal">
<FieldContent className="flex flex-col items-center justify-center gap-2">
<Field
orientation="horizontal"
className="w-full rounded-md transition-colors duration-150 hover:bg-neutral-700/45"
>
<FieldContent className="flex flex-row items-center gap-2 px-2.5 py-1.5">
<div
className="size-6 text-foreground [&_svg]:size-6 *:[svg]:text-foreground!"
className="size-4 text-neutral-100 [&_svg]:size-4 *:[svg]:text-neutral-100!"
dangerouslySetInnerHTML={{
__html: item.logo,
}}
></div>
<FieldTitle className="text-xs">{item.title}</FieldTitle>
<FieldTitle>{item.title}</FieldTitle>
</FieldContent>
<RadioGroupItem
value={item.value}
@@ -343,17 +347,20 @@ const BaseGrid = React.memo(function BaseGrid({
<FieldLabel
key={item.name}
htmlFor={`base-${item.name}`}
className="py-1"
className="block w-full"
>
<Field className="gap-0" orientation="horizontal">
<FieldContent className="flex flex-col items-center justify-center gap-2">
<Field
orientation="horizontal"
className="w-full rounded-md transition-colors duration-150 hover:bg-neutral-700/45"
>
<FieldContent className="flex flex-row items-center gap-2 px-2.5 py-1.5">
<div
className="size-6 text-foreground [&_svg]:size-6 *:[svg]:text-foreground!"
className="size-4 text-neutral-100 [&_svg]:size-4 *:[svg]:text-neutral-100!"
dangerouslySetInnerHTML={{
__html: item.meta?.logo ?? "",
}}
/>
<FieldTitle className="text-xs">{item.title}</FieldTitle>
<FieldTitle>{item.title}</FieldTitle>
</FieldContent>
<RadioGroupItem
value={item.name}

View File

@@ -1,40 +1,11 @@
"use client"
import * as React from "react"
import { encodePreset, isPresetCode } from "shadcn/preset"
import { getPresetCode } from "@/app/(create)/lib/preset-code"
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
// Returns the current preset code derived from search params.
// Returns the canonical preset code derived from the current search params.
export function usePresetCode() {
const [params] = useDesignSystemSearchParams()
return React.useMemo(() => {
// If preset is already in the URL, return it.
if (params.preset && isPresetCode(params.preset)) {
return params.preset
}
// Otherwise encode current params (e.g. on initial load before first interaction).
return encodePreset({
style: params.style ?? undefined,
baseColor: params.baseColor ?? undefined,
theme: params.theme ?? undefined,
iconLibrary: params.iconLibrary ?? undefined,
font: params.font ?? undefined,
radius: params.radius ?? undefined,
menuAccent: params.menuAccent ?? undefined,
menuColor: params.menuColor ?? undefined,
} as Parameters<typeof encodePreset>[0])
}, [
params.preset,
params.style,
params.baseColor,
params.theme,
params.iconLibrary,
params.font,
params.radius,
params.menuAccent,
params.menuColor,
])
return getPresetCode(params)
}

View File

@@ -6,8 +6,10 @@ export type LockableParam =
| "style"
| "baseColor"
| "theme"
| "chartColor"
| "iconLibrary"
| "font"
| "fontHeading"
| "menuAccent"
| "menuColor"
| "radius"

View File

@@ -10,6 +10,7 @@ import {
MENU_COLORS,
RADII,
STYLES,
type FontHeadingValue,
} from "@/registry/config"
import { useLocks } from "@/app/(create)/hooks/use-locks"
import { FONTS } from "@/app/(create)/lib/fonts"
@@ -62,9 +63,41 @@ export function useRandom() {
const selectedTheme = locks.has("theme")
? paramsRef.current.theme
: randomItem(availableThemes).name
context.theme = selectedTheme
const availableChartColors = applyBias(
getThemesForBaseColor(baseColor),
context,
RANDOMIZE_BIASES.chartColors
)
const selectedChartColor = locks.has("chartColor")
? paramsRef.current.chartColor
: randomItem(availableChartColors).name
context.chartColor = selectedChartColor
const selectedFont = locks.has("font")
? paramsRef.current.font
: randomItem(availableFonts).value
context.font = selectedFont
// Pick heading font: ~70% inherit, ~30% distinct with cross-category contrast.
let selectedFontHeading: FontHeadingValue
if (locks.has("fontHeading")) {
selectedFontHeading = paramsRef.current.fontHeading
} else if (Math.random() < 0.7) {
selectedFontHeading = "inherit"
} else {
const bodyType = availableFonts.find(
(f) => f.value === selectedFont
)?.type
const contrastFonts = availableFonts.filter(
(f) => f.type !== bodyType && f.value !== selectedFont
)
selectedFontHeading = (
contrastFonts.length > 0
? randomItem(contrastFonts)
: randomItem(availableFonts)
).value as FontHeadingValue
}
const selectedRadius = locks.has("radius")
? paramsRef.current.radius
: randomItem(availableRadii).name
@@ -91,16 +124,16 @@ export function useRandom() {
: paramsRef.current.menuAccent
: randomItem(MENU_ACCENTS).value
context.theme = selectedTheme
context.font = selectedFont
context.radius = selectedRadius
const nextParams = {
style: selectedStyle,
baseColor,
theme: selectedTheme,
chartColor: selectedChartColor,
iconLibrary: selectedIconLibrary,
font: selectedFont,
fontHeading: selectedFontHeading,
menuAccent: selectedMenuAccent,
menuColor: selectedMenuColor,
radius: selectedRadius,

View File

@@ -24,8 +24,10 @@ export function useReset() {
style: DEFAULT_CONFIG.style,
baseColor: DEFAULT_CONFIG.baseColor,
theme: DEFAULT_CONFIG.theme,
chartColor: DEFAULT_CONFIG.chartColor,
iconLibrary: DEFAULT_CONFIG.iconLibrary,
font: DEFAULT_CONFIG.font,
fontHeading: DEFAULT_CONFIG.fontHeading,
menuAccent: DEFAULT_CONFIG.menuAccent,
menuColor: DEFAULT_CONFIG.menuColor,
radius: DEFAULT_CONFIG.radius,

View File

@@ -3,13 +3,17 @@ import dedent from "dedent"
import { UI_COMPONENTS } from "@/lib/components"
import {
buildRegistryBase,
fonts,
getBodyFont,
getHeadingFont,
getInheritedHeadingFontValue,
type DesignSystemConfig,
} from "@/registry/config"
// Builds step-by-step markdown instructions for manually setting up a project.
export function buildInstructions(config: DesignSystemConfig) {
const registryBase = buildRegistryBase(config)
const normalizedFontHeading =
config.fontHeading === config.font ? "inherit" : config.fontHeading
const dependencies = [
...(registryBase.dependencies ?? []),
@@ -25,13 +29,23 @@ export function buildInstructions(config: DesignSystemConfig) {
.map(([key, value]) => ` --${key}: ${value};`)
.join("\n")
const font = fonts.find((f) => f.name === `font-${config.font}`)
const font = getBodyFont(config.font)
const headingFont =
normalizedFontHeading === "inherit"
? undefined
: getHeadingFont(normalizedFontHeading)
const sections = [
buildDependenciesSection(dependencies),
buildUtilsSection(),
buildCssSection(lightVars, darkVars),
buildFontSection(font),
buildCssSection(
lightVars,
darkVars,
normalizedFontHeading === "inherit"
? getInheritedHeadingFontValue(config.font)
: "var(--font-heading)"
),
buildFontSection(font, headingFont),
buildComponentsJsonSection(config),
buildAvailableComponentsSection(config),
config.rtl ? buildRtlSection(config) : null,
@@ -67,7 +81,11 @@ function buildUtilsSection() {
`
}
function buildCssSection(lightVars: string, darkVars: string) {
function buildCssSection(
lightVars: string,
darkVars: string,
fontHeadingValue: string
) {
return dedent`
## Step 3: Set up CSS
@@ -80,6 +98,7 @@ function buildCssSection(lightVars: string, darkVars: string) {
@theme inline {
--font-sans: var(--font-sans);
--font-heading: ${fontHeadingValue};
--font-mono: var(--font-mono);
--color-background: var(--background);
--color-foreground: var(--foreground);
@@ -142,40 +161,74 @@ function buildCssSection(lightVars: string, darkVars: string) {
`
}
function buildFontSection(font: (typeof fonts)[number] | undefined) {
function buildFontSection(
font: ReturnType<typeof getBodyFont>,
headingFont: ReturnType<typeof getHeadingFont>
) {
if (!font) {
return null
}
const googleFontsUrl = `https://fonts.google.com/specimen/${font.font.import.replace(/_/g, "+")}`
const headingGoogleFontsUrl = headingFont
? `https://fonts.google.com/specimen/${headingFont.font.import.replace(/_/g, "+")}`
: null
const nextImports = headingFont
? `${font.font.import}, ${headingFont.font.import}`
: font.font.import
const nextDeclarations = [
`const fontSans = ${font.font.import}({`,
` subsets: ["latin"],`,
` variable: "${font.font.variable}",`,
`})`,
headingFont ? `const fontHeading = ${headingFont.font.import}({` : null,
headingFont ? ` subsets: ["latin"],` : null,
headingFont ? ` variable: "${headingFont.font.variable}",` : null,
headingFont ? `})` : null,
]
.filter(Boolean)
.join("\n")
const nextHtmlClassName = headingFont
? 'className={fontSans.variable + " " + fontHeading.variable}'
: `className={fontSans.variable}`
const otherFrameworkCss = [
":root {",
` ${font.font.variable}: ${font.font.family};`,
...(headingFont
? [` ${headingFont.font.variable}: ${headingFont.font.family};`]
: []),
"}",
].join("\n")
const headingSection = headingFont
? dedent`
This config also uses **${headingFont.title.replace(" (Heading)", "")}** for headings (\`${headingFont.font.variable}\`).
`
: ""
return dedent`
## Step 4: Set up the font
This config uses **${font.title}** (\`${font.font.variable}\`).
${headingSection}
### Next.js
\`\`\`tsx
import { ${font.font.import} } from "next/font/google"
import { ${nextImports} } from "next/font/google"
const fontSans = ${font.font.import}({
subsets: ["latin"],
variable: "${font.font.variable}",
})
${nextDeclarations}
// Add fontSans.variable to your <html> className.
// <html className={fontSans.variable}>
// Add the font variable classes to your <html> className.
// <html ${nextHtmlClassName}>
\`\`\`
### Other frameworks
Add the font from [Google Fonts](${googleFontsUrl}) and set the \`${font.font.variable}\` CSS variable to the font family:
Add the font${headingFont ? "s" : ""} from [Google Fonts](${googleFontsUrl})${headingGoogleFontsUrl ? ` and [Google Fonts](${headingGoogleFontsUrl})` : ""} and set the CSS variable${headingFont ? "s" : ""} to the font famil${headingFont ? "ies" : "y"}:
\`\`\`css
:root {
${font.font.variable}: ${font.font.family};
}
${otherFrameworkCss}
\`\`\`
`
}

View File

@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest"
import { parseDesignSystemConfig } from "./parse-config"
describe("parseDesignSystemConfig", () => {
it("honors explicit fontHeading and chartColor overrides when a preset is present", () => {
const result = parseDesignSystemConfig(
new URLSearchParams(
"preset=a0&fontHeading=playfair-display&chartColor=emerald"
)
)
expect(result.success).toBe(true)
if (!result.success) {
throw new Error(result.error)
}
expect(result.data.fontHeading).toBe("playfair-display")
expect(result.data.chartColor).toBe("emerald")
})
})

View File

@@ -4,6 +4,7 @@ import {
designSystemConfigSchema,
type DesignSystemConfig,
} from "@/registry/config"
import { resolvePresetOverrides } from "@/app/(create)/lib/preset-query"
// Parses design system config from URL search params.
export function parseDesignSystemConfig(searchParams: URLSearchParams) {
@@ -15,8 +16,10 @@ export function parseDesignSystemConfig(searchParams: URLSearchParams) {
if (!decoded) {
return { success: false as const, error: "Invalid preset code" }
}
const presetOverrides = resolvePresetOverrides(searchParams, decoded)
configInput = {
...decoded,
...presetOverrides,
base: searchParams.get("base") ?? "radix",
template: searchParams.get("template") ?? undefined,
rtl: searchParams.get("rtl") === "true",
@@ -28,7 +31,9 @@ export function parseDesignSystemConfig(searchParams: URLSearchParams) {
iconLibrary: searchParams.get("iconLibrary"),
baseColor: searchParams.get("baseColor"),
theme: searchParams.get("theme"),
chartColor: searchParams.get("chartColor") ?? undefined,
font: searchParams.get("font"),
fontHeading: searchParams.get("fontHeading") ?? undefined,
menuAccent: searchParams.get("menuAccent"),
menuColor: searchParams.get("menuColor"),
radius: searchParams.get("radius"),

View File

@@ -1,10 +1,11 @@
import { NextResponse, type NextRequest } from "next/server"
import { track } from "@vercel/analytics/server"
import { encodePreset, isPresetCode } from "shadcn/preset"
import { isPresetCode } from "shadcn/preset"
import { registryItemSchema } from "shadcn/schema"
import { buildRegistryBase } from "@/registry/config"
import { parseDesignSystemConfig } from "@/app/(create)/init/parse-config"
import { getPresetCode } from "@/app/(create)/lib/preset-code"
export async function GET(request: NextRequest) {
try {
@@ -15,21 +16,11 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: result.error }, { status: 400 })
}
// Use the preset code from the URL if provided, otherwise encode one.
const presetParam = searchParams.get("preset")
const rawPreset = searchParams.get("preset")
const presetCode =
presetParam && isPresetCode(presetParam)
? presetParam
: encodePreset({
style: result.data.style,
baseColor: result.data.baseColor,
theme: result.data.theme,
iconLibrary: result.data.iconLibrary,
font: result.data.font,
radius: result.data.radius,
menuAccent: result.data.menuAccent,
menuColor: result.data.menuColor,
} as Parameters<typeof encodePreset>[0])
rawPreset && isPresetCode(rawPreset)
? rawPreset
: getPresetCode(result.data)
const registryBase = buildRegistryBase(result.data)
const parseResult = registryItemSchema.safeParse(registryBase)
@@ -47,7 +38,7 @@ export async function GET(request: NextRequest) {
if (searchParams.get("track") === "1") {
track("create_app", {
...result.data,
preset: presetCode,
...(presetCode && { preset: presetCode }),
})
}

View File

@@ -1,7 +1,9 @@
import { after, NextResponse, type NextRequest } from "next/server"
import { track } from "@vercel/analytics/server"
import { isPresetCode } from "shadcn/preset"
import { parseDesignSystemConfig } from "@/app/(create)/init/parse-config"
import { getPresetCode } from "@/app/(create)/lib/preset-code"
import { buildV0Payload } from "@/app/(create)/lib/v0"
export async function GET(request: NextRequest) {
@@ -13,11 +15,17 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: result.error }, { status: 400 })
}
const rawPreset = searchParams.get("preset")
const presetCode =
rawPreset && isPresetCode(rawPreset)
? rawPreset
: getPresetCode(result.data)
// Defer analytics to after response is sent.
after(() => {
track("create_open_in_v0", {
...result.data,
preset: searchParams.get("preset") ?? "",
...(presetCode && { preset: presetCode }),
})
})

View File

@@ -3,21 +3,37 @@ import {
Figtree,
Geist,
Geist_Mono,
IBM_Plex_Sans,
Instrument_Sans,
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<typeof Inter>
const geistSans = Geist({
subsets: ["latin"],
variable: "--font-geist-sans",
})
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
@@ -38,21 +54,6 @@ const figtree = Figtree({
variable: "--font-figtree",
})
const jetbrainsMono = JetBrains_Mono({
subsets: ["latin"],
variable: "--font-jetbrains-mono",
})
const geistSans = Geist({
subsets: ["latin"],
variable: "--font-geist-sans",
})
const geistMono = Geist_Mono({
subsets: ["latin"],
variable: "--font-geist-mono",
})
const roboto = Roboto({
subsets: ["latin"],
variable: "--font-roboto",
@@ -78,6 +79,51 @@ const outfit = Outfit({
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",
@@ -103,109 +149,85 @@ const playfairDisplay = Playfair_Display({
variable: "--font-playfair-display",
})
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,
} satisfies Record<FontName, PreviewFont>
function createFontOption(name: FontName) {
const definition = FONT_DEFINITIONS.find((font) => font.name === name)
if (!definition) {
throw new Error(`Unknown font definition: ${name}`)
}
return {
name: definition.title,
value: definition.name,
font: PREVIEW_FONTS[name],
type: definition.type,
} as const
}
export const FONTS = [
{
name: "Geist",
value: "geist",
font: geistSans,
type: "sans",
},
{
name: "Inter",
value: "inter",
font: inter,
type: "sans",
},
{
name: "Noto Sans",
value: "noto-sans",
font: notoSans,
type: "sans",
},
{
name: "Nunito Sans",
value: "nunito-sans",
font: nunitoSans,
type: "sans",
},
{
name: "Figtree",
value: "figtree",
font: figtree,
type: "sans",
},
{
name: "Roboto",
value: "roboto",
font: roboto,
type: "sans",
},
{
name: "Raleway",
value: "raleway",
font: raleway,
type: "sans",
},
{
name: "DM Sans",
value: "dm-sans",
font: dmSans,
type: "sans",
},
{
name: "Public Sans",
value: "public-sans",
font: publicSans,
type: "sans",
},
{
name: "Outfit",
value: "outfit",
font: outfit,
type: "sans",
},
{
name: "Geist Mono",
value: "geist-mono",
font: geistMono,
type: "mono",
},
{
name: "JetBrains Mono",
value: "jetbrains-mono",
font: jetbrainsMono,
type: "mono",
},
{
name: "Noto Serif",
value: "noto-serif",
font: notoSerif,
type: "serif",
},
{
name: "Roboto Slab",
value: "roboto-slab",
font: robotoSlab,
type: "serif",
},
{
name: "Merriweather",
value: "merriweather",
font: merriweather,
type: "serif",
},
{
name: "Lora",
value: "lora",
font: lora,
type: "serif",
},
{
name: "Playfair Display",
value: "playfair-display",
font: playfairDisplay,
type: "serif",
},
createFontOption("geist"),
createFontOption("inter"),
createFontOption("noto-sans"),
createFontOption("nunito-sans"),
createFontOption("figtree"),
createFontOption("roboto"),
createFontOption("raleway"),
createFontOption("dm-sans"),
createFontOption("public-sans"),
createFontOption("outfit"),
createFontOption("oxanium"),
createFontOption("manrope"),
createFontOption("space-grotesk"),
createFontOption("montserrat"),
createFontOption("ibm-plex-sans"),
createFontOption("source-sans-3"),
createFontOption("instrument-sans"),
createFontOption("geist-mono"),
createFontOption("jetbrains-mono"),
createFontOption("noto-serif"),
createFontOption("roboto-slab"),
createFontOption("merriweather"),
createFontOption("lora"),
createFontOption("playfair-display"),
] as const
export type Font = (typeof FONTS)[number]
export const FONT_HEADING_OPTIONS = [
{
name: "Inherit",
value: "inherit",
font: null,
type: "default",
},
...FONTS,
] as const
export type FontHeadingOption = (typeof FONT_HEADING_OPTIONS)[number]

View File

@@ -0,0 +1,34 @@
import { encodePreset, type PresetConfig } from "shadcn/preset"
import { type DesignSystemConfig } from "@/registry/config"
type PresetCodeConfig = Pick<
DesignSystemConfig,
| "style"
| "baseColor"
| "theme"
| "chartColor"
| "iconLibrary"
| "font"
| "fontHeading"
| "radius"
| "menuAccent"
| "menuColor"
>
export function getPresetCode(config: PresetCodeConfig) {
const presetConfig: Partial<PresetConfig> = {
style: config.style as PresetConfig["style"],
baseColor: config.baseColor as PresetConfig["baseColor"],
theme: config.theme as PresetConfig["theme"],
chartColor: config.chartColor as PresetConfig["chartColor"],
iconLibrary: config.iconLibrary as PresetConfig["iconLibrary"],
font: config.font as PresetConfig["font"],
fontHeading: config.fontHeading as PresetConfig["fontHeading"],
radius: config.radius as PresetConfig["radius"],
menuAccent: config.menuAccent as PresetConfig["menuAccent"],
menuColor: config.menuColor as PresetConfig["menuColor"],
}
return encodePreset(presetConfig)
}

View File

@@ -0,0 +1,34 @@
import { describe, expect, it } from "vitest"
import { resolvePresetOverrides } from "./preset-query"
describe("resolvePresetOverrides", () => {
it("prefers explicit fontHeading and chartColor query params", () => {
const overrides = resolvePresetOverrides(
new URLSearchParams("fontHeading=playfair-display&chartColor=emerald"),
{
theme: "neutral",
chartColor: "blue",
fontHeading: "inherit",
}
)
expect(overrides).toEqual({
fontHeading: "playfair-display",
chartColor: "emerald",
})
})
it("falls back to decoded preset values when no overrides are present", () => {
const overrides = resolvePresetOverrides(new URLSearchParams(), {
theme: "neutral",
chartColor: "blue",
fontHeading: "inherit",
})
expect(overrides).toEqual({
fontHeading: "inherit",
chartColor: "blue",
})
})
})

View File

@@ -0,0 +1,30 @@
import { V1_CHART_COLOR_MAP, type PresetConfig } from "shadcn/preset"
import { type ChartColorName, type FontHeadingValue } from "@/registry/config"
type SearchParamsLike = Pick<URLSearchParams, "get" | "has">
export function resolvePresetOverrides(
searchParams: SearchParamsLike,
decoded: Pick<PresetConfig, "theme" | "chartColor" | "fontHeading">
) {
const hasFontHeadingOverride = searchParams.has("fontHeading")
const hasChartColorOverride = searchParams.has("chartColor")
const fontHeading = hasFontHeadingOverride
? ((searchParams.get("fontHeading") ??
decoded.fontHeading) as FontHeadingValue)
: decoded.fontHeading
const chartColor = hasChartColorOverride
? ((searchParams.get("chartColor") ??
decoded.chartColor ??
V1_CHART_COLOR_MAP[decoded.theme] ??
decoded.theme) as ChartColorName)
: (decoded.chartColor ?? V1_CHART_COLOR_MAP[decoded.theme] ?? decoded.theme)
return {
fontHeading,
chartColor,
}
}

View File

@@ -3,6 +3,7 @@ import type {
BaseColorName,
Radius,
StyleName,
Theme,
ThemeName,
} from "@/registry/config"
@@ -12,6 +13,7 @@ export type RandomizeContext = {
style?: StyleName
baseColor?: BaseColorName
theme?: ThemeName
chartColor?: string
iconLibrary?: string
font?: string
menuAccent?: string
@@ -26,12 +28,30 @@ export type BiasFilter<T> = (
export type RandomizeBiases = {
baseColors?: BiasFilter<BaseColor>
chartColors?: BiasFilter<Theme>
fonts?: BiasFilter<(typeof FONTS)[number]>
radius?: BiasFilter<Radius>
// Add more bias filters as needed:
// styles?: BiasFilter<Style>
// themes?: BiasFilter<Theme>
// etc.
}
// Theme → chart color pairings for randomization.
const CHART_COLOR_PAIRINGS: Record<string, string[]> = {
red: ["teal", "sky"],
orange: ["teal", "blue"],
amber: ["cyan", "indigo"],
yellow: ["sky", "violet"],
lime: ["indigo", "pink"],
green: ["purple", "rose"],
emerald: ["purple", "red"],
teal: ["fuchsia", "red"],
cyan: ["rose", "amber"],
sky: ["red", "yellow"],
blue: ["orange", "yellow"],
indigo: ["amber", "yellow"],
violet: ["yellow", "lime"],
purple: ["green", "lime"],
fuchsia: ["lime", "teal"],
pink: ["green", "cyan"],
rose: ["emerald", "sky"],
}
/**
@@ -51,21 +71,25 @@ export const RANDOMIZE_BIASES: RandomizeBiases = {
return fonts
},
radius: (radii, context) => {
// When style is lyra, always use "none" radius
// When style is lyra, always use "none" radius.
if (context.style === "lyra") {
return radii.filter((radius) => radius.name === "none")
}
return radii
},
// Add more biases here as needed:
// Example: When baseColor is "blue", prefer certain themes
// themes: (themes, context) => {
// if (context.baseColor === "blue") {
// return themes.filter(theme => theme.name.includes("dark"))
// }
// return themes
// },
chartColors: (chartColors, context) => {
// When theme has a pairing, restrict chart colors to the paired values.
const pairing = context.theme ? CHART_COLOR_PAIRINGS[context.theme] : null
if (pairing) {
const filtered = chartColors.filter((c) => pairing.includes(c.name))
if (filtered.length > 0) {
return filtered
}
}
return chartColors
},
}
/**

View File

@@ -1,4 +1,5 @@
import * as React from "react"
import { useSearchParams } from "next/navigation"
import { useQueryStates } from "nuqs"
import {
createLoader,
@@ -10,12 +11,13 @@ import {
type inferParserType,
type Options,
} from "nuqs/server"
import { decodePreset, encodePreset, isPresetCode } from "shadcn/preset"
import { decodePreset, isPresetCode } from "shadcn/preset"
import {
BASE_COLORS,
BASES,
DEFAULT_CONFIG,
getThemesForBaseColor,
iconLibraries,
MENU_ACCENTS,
MENU_COLORS,
@@ -24,6 +26,8 @@ import {
THEMES,
type BaseColorName,
type BaseName,
type ChartColorName,
type FontHeadingValue,
type FontValue,
type IconLibraryName,
type MenuAccentValue,
@@ -33,9 +37,11 @@ import {
type ThemeName,
} from "@/registry/config"
import { FONTS } from "@/app/(create)/lib/fonts"
import { getPresetCode } from "@/app/(create)/lib/preset-code"
import { resolvePresetOverrides } from "@/app/(create)/lib/preset-query"
const designSystemSearchParams = {
preset: parseAsString.withDefault("a0"),
preset: parseAsString.withDefault("b0"),
base: parseAsStringLiteral<BaseName>(BASES.map((b) => b.name)).withDefault(
DEFAULT_CONFIG.base
),
@@ -49,9 +55,16 @@ const designSystemSearchParams = {
theme: parseAsStringLiteral<ThemeName>(THEMES.map((t) => t.name)).withDefault(
DEFAULT_CONFIG.theme
),
chartColor: parseAsStringLiteral<ChartColorName>(
THEMES.map((t) => t.name)
).withDefault(DEFAULT_CONFIG.chartColor ?? "neutral"),
font: parseAsStringLiteral<FontValue>(FONTS.map((f) => f.value)).withDefault(
DEFAULT_CONFIG.font
),
fontHeading: parseAsStringLiteral<FontHeadingValue>([
"inherit",
...FONTS.map((f) => f.value),
]).withDefault(DEFAULT_CONFIG.fontHeading),
baseColor: parseAsStringLiteral<BaseColorName>(
BASE_COLORS.map((b) => b.name)
).withDefault(DEFAULT_CONFIG.baseColor),
@@ -87,13 +100,24 @@ const DESIGN_SYSTEM_KEYS = [
"style",
"baseColor",
"theme",
"chartColor",
"iconLibrary",
"font",
"fontHeading",
"radius",
"menuAccent",
"menuColor",
] as const
function normalizeFontHeading(
font: FontValue,
fontHeading: FontHeadingValue
): FontHeadingValue {
// Persist "same as body" as an explicit inherit sentinel so the body font
// can change later without freezing headings to a concrete previous value.
return fontHeading === font ? "inherit" : fontHeading
}
// Non-design-system keys that get passed through as-is.
// `base` is not encoded in preset codes — it's an architectural choice, not visual.
const NON_DESIGN_SYSTEM_KEYS = [
@@ -145,39 +169,83 @@ function normalizePartialDesignSystemParams(
function normalizeDesignSystemParams(
params: DesignSystemSearchParams
): DesignSystemSearchParams {
let result = {
...params,
fontHeading: normalizeFontHeading(params.font, params.fontHeading),
}
// Validate theme and chartColor against baseColor.
if (result.baseColor) {
const available = getThemesForBaseColor(result.baseColor)
const themeValid = available.some((t) => t.name === result.theme)
const chartColorValid = available.some((t) => t.name === result.chartColor)
if (!themeValid || !chartColorValid) {
const fallback = (available[0]?.name ?? result.baseColor) as ThemeName
result = {
...result,
...(!themeValid && { theme: fallback }),
...(!chartColorValid && { chartColor: fallback as ChartColorName }),
}
}
}
if (
params.menuAccent === "bold" &&
isTranslucentMenuColor(params.menuColor)
result.menuAccent === "bold" &&
isTranslucentMenuColor(result.menuColor)
) {
return {
...params,
...result,
menuAccent: "subtle",
}
}
return params
return result
}
// If preset param exists, decode it and overlay on raw params.
// V1 presets don't encode chartColor — fall back to the colored
// theme that base-color themes originally borrowed charts from.
type SearchParamsLike = Pick<URLSearchParams, "get" | "has">
function resolvePresetParams(
rawParams: DesignSystemSearchParams,
searchParams: SearchParamsLike
) {
if (rawParams.preset && isPresetCode(rawParams.preset)) {
const decoded = decodePreset(rawParams.preset)
if (decoded) {
const presetOverrides = resolvePresetOverrides(searchParams, decoded)
return normalizeDesignSystemParams({
...decoded,
...presetOverrides,
base: rawParams.base,
item: rawParams.item,
preset: rawParams.preset,
template: rawParams.template,
rtl: rawParams.rtl,
size: rawParams.size,
custom: rawParams.custom,
})
}
}
return normalizeDesignSystemParams(rawParams)
}
// Wraps nuqs useQueryStates with transparent preset encoding/decoding.
// - Reads: if ?preset=CODE is in the URL, decodes it and returns individual values.
// - Writes: when design system params are set, encodes them into a preset code.
export function useDesignSystemSearchParams(options: Options = {}) {
const searchParams = useSearchParams()
const [rawParams, rawSetParams] = useQueryStates(designSystemSearchParams, {
shallow: false,
history: "push",
...options,
})
// If preset param exists, decode it and overlay on raw params.
const params = React.useMemo(
() =>
rawParams.preset && isPresetCode(rawParams.preset)
? normalizeDesignSystemParams({
...rawParams,
...(decodePreset(rawParams.preset) ?? {}),
})
: normalizeDesignSystemParams(rawParams),
[rawParams]
() => resolvePresetParams(rawParams, searchParams),
[rawParams, searchParams]
)
// Use ref so setParams callback stays stable across renders.
@@ -215,21 +283,10 @@ export function useDesignSystemSearchParams(options: Options = {}) {
...paramsRef.current,
...resolvedUpdates,
})
// Encode design system fields into a preset code.
// Cast needed: merged values may include null from nuqs resets,
// but encodePreset handles missing values by falling back to defaults.
const code = encodePreset({
style: merged.style ?? undefined,
baseColor: merged.baseColor ?? undefined,
theme: merged.theme ?? undefined,
iconLibrary: merged.iconLibrary ?? undefined,
font: merged.font ?? undefined,
radius: merged.radius ?? undefined,
menuAccent: merged.menuAccent ?? undefined,
menuColor: merged.menuColor ?? undefined,
} as Parameters<typeof encodePreset>[0])
const code = getPresetCode(merged)
// Build update: set preset, clear individual DS params from URL.
const rawUpdate: Record<string, unknown> = { preset: code }
for (const key of DESIGN_SYSTEM_KEYS) {

View File

@@ -7,7 +7,7 @@ export const TEMPLATES = [
{
value: "vite",
title: "Vite",
logo: '<svg xmlns="http://www.w3.org/2000/svg" width="410" height="404" fill="none" viewBox="0 0 410 404"><path fill="var(--foreground)" d="m399.641 59.525-183.998 329.02c-3.799 6.793-13.559 6.833-17.415.073L10.582 59.556C6.38 52.19 12.68 43.266 21.028 44.76l184.195 32.923c1.175.21 2.378.208 3.553-.006l180.343-32.87c8.32-1.517 14.649 7.337 10.522 14.719"/><path fill="var(--background)" d="M292.965 1.574 156.801 28.255a5 5 0 0 0-4.03 4.611l-8.376 141.464c-.197 3.332 2.863 5.918 6.115 5.168l37.91-8.749c3.547-.818 6.752 2.306 6.023 5.873l-11.263 55.153c-.758 3.712 2.727 6.886 6.352 5.785l23.415-7.114c3.63-1.102 7.118 2.081 6.35 5.796l-17.899 86.633c-1.12 5.419 6.088 8.374 9.094 3.728l2.008-3.103 110.954-221.428c1.858-3.707-1.346-7.935-5.418-7.15l-39.022 7.532c-3.667.707-6.787-2.708-5.752-6.296l25.469-88.291c1.036-3.594-2.095-7.012-5.766-6.293"/></svg>',
logo: '<svg xmlns="http://www.w3.org/2000/svg" width="410" height="404" fill="none" viewBox="0 0 410 404"><path fill="var(--foreground)" d="m399.641 59.525-183.998 329.02c-3.799 6.793-13.559 6.833-17.415.073L10.582 59.556C6.38 52.19 12.68 43.266 21.028 44.76l184.195 32.923c1.175.21 2.378.208 3.553-.006l180.343-32.87c8.32-1.517 14.649 7.337 10.522 14.719"/><path fill="var(--color-neutral-800)" d="M292.965 1.574 156.801 28.255a5 5 0 0 0-4.03 4.611l-8.376 141.464c-.197 3.332 2.863 5.918 6.115 5.168l37.91-8.749c3.547-.818 6.752 2.306 6.023 5.873l-11.263 55.153c-.758 3.712 2.727 6.886 6.352 5.785l23.415-7.114c3.63-1.102 7.118 2.081 6.35 5.796l-17.899 86.633c-1.12 5.419 6.088 8.374 9.094 3.728l2.008-3.103 110.954-221.428c1.858-3.707-1.346-7.935-5.418-7.15l-39.022 7.532c-3.667.707-6.787-2.708-5.752-6.296l25.469-88.291c1.036-3.594-2.095-7.012-5.766-6.293"/></svg>',
},
{
value: "start",

View File

@@ -0,0 +1,115 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
import { DEFAULT_CONFIG } from "@/registry/config"
import { buildV0Payload } from "@/app/(create)/lib/v0"
vi.mock("shadcn/schema", async () => {
return await vi.importActual("shadcn/schema")
})
vi.mock("shadcn/utils", async () => {
const actual = (await vi.importActual("shadcn/utils")) as {
transformFont: unknown
}
return {
transformFont: actual.transformFont,
transformIcons: async ({ sourceFile }: { sourceFile: unknown }) =>
sourceFile,
transformMenu: async ({ sourceFile }: { sourceFile: unknown }) =>
sourceFile,
transformRender: async ({ sourceFile }: { sourceFile: unknown }) =>
sourceFile,
}
})
vi.mock("@/registry/bases/__index__", () => ({
Index: {
base: {
card: {
name: "card",
type: "registry:ui",
},
},
radix: {
card: {
name: "card",
type: "registry:ui",
},
},
},
}))
describe("buildV0Payload", () => {
beforeEach(() => {
process.env.NEXT_PUBLIC_APP_URL = "http://example.test"
vi.stubGlobal(
"fetch",
vi.fn(async (input: string | URL | Request) => {
const url =
typeof input === "string"
? input
: input instanceof URL
? input.toString()
: input.url
const name = url.split("/").pop()?.replace(".json", "") ?? "component"
return new Response(
JSON.stringify({
name,
type: "registry:ui",
files: [
{
path: `registry/base-nova/ui/${name}.tsx`,
type: "registry:ui",
content: `import * as React from "react"\n\nexport function Component() {\n return <div className="cn-font-heading text-xl" />\n}\n`,
},
],
}),
{
status: 200,
headers: {
"Content-Type": "application/json",
},
}
)
})
)
})
afterEach(() => {
vi.unstubAllGlobals()
delete process.env.NEXT_PUBLIC_APP_URL
})
it("rewrites cn-font-heading to font-heading when heading inherits the body font", async () => {
const payload = await buildV0Payload({
...DEFAULT_CONFIG,
item: undefined,
fontHeading: "inherit",
})
const cardFile = payload.files?.find(
(file) => file.target === "components/ui/card.tsx"
)
expect(cardFile?.content).toContain("font-heading")
expect(cardFile?.content).not.toContain("cn-font-heading")
})
it("rewrites cn-font-heading to font-heading when a distinct heading font is selected", async () => {
const payload = await buildV0Payload({
...DEFAULT_CONFIG,
item: undefined,
fontHeading: "playfair-display",
})
const cardFile = payload.files?.find(
(file) => file.target === "components/ui/card.tsx"
)
expect(cardFile?.content).toContain("font-heading")
expect(cardFile?.content).not.toContain("cn-font-heading")
})
})

View File

@@ -5,19 +5,28 @@ import {
type configSchema,
type RegistryItem,
} from "shadcn/schema"
import { transformIcons, transformMenu, transformRender } from "shadcn/utils"
import { Project, ScriptKind } from "ts-morph"
import {
transformFont,
transformIcons,
transformMenu,
transformRender,
} from "shadcn/utils"
import { Project, ScriptKind, type SourceFile } from "ts-morph"
import { z } from "zod"
import {
buildRegistryBase,
fonts,
getBodyFont,
getHeadingFont,
getInheritedHeadingFontValue,
type DesignSystemConfig,
} from "@/registry/config"
const { Index } = await import("@/registry/bases/__index__")
const THEME_INLINE = `--font-sans: var(--font-sans);
function buildThemeInline(fontHeadingValue: string) {
return `--font-sans: var(--font-sans);
--font-heading: ${fontHeadingValue};
--font-mono: var(--font-mono);
--font-serif: var(--font-serif);
--color-background: var(--background);
@@ -59,6 +68,7 @@ const THEME_INLINE = `--font-sans: var(--font-sans);
--radius-2xl: calc(var(--radius) * 1.8);
--radius-3xl: calc(var(--radius) * 2.2);
--radius-4xl: calc(var(--radius) * 2.6);`
}
// Static file — parsed once at module level.
const themeProviderFile = registryItemFileSchema.parse({
@@ -148,7 +158,20 @@ const ALIASES = {
hooks: "@/hooks",
} as const
const transformers = [transformIcons, transformMenu, transformRender]
type V0Transformer = (opts: {
filename: string
raw: string
sourceFile: SourceFile
config: z.infer<typeof configSchema>
supportedFontMarkers?: string[]
}) => Promise<unknown>
const transformers: V0Transformer[] = [
transformIcons as V0Transformer,
transformMenu as V0Transformer,
transformRender as V0Transformer,
transformFont as V0Transformer,
]
function getStyle(designSystemConfig: DesignSystemConfig) {
return `${designSystemConfig.base}-${designSystemConfig.style}`
@@ -156,10 +179,18 @@ function getStyle(designSystemConfig: DesignSystemConfig) {
export async function buildV0Payload(designSystemConfig: DesignSystemConfig) {
const registryBase = buildRegistryBase(designSystemConfig)
const normalizedFontHeading =
designSystemConfig.fontHeading === designSystemConfig.font
? "inherit"
: designSystemConfig.fontHeading
// Only buildComponentFiles is async — run sync builders directly.
const globalsCss = buildGlobalsCss(registryBase)
const layoutFile = buildLayoutFile(designSystemConfig)
const globalsCss = buildGlobalsCss(
registryBase,
designSystemConfig.font,
normalizedFontHeading
)
const layoutFile = buildLayoutFile(designSystemConfig, normalizedFontHeading)
const componentFiles = await buildComponentFiles(designSystemConfig)
const dependencies = [...(registryBase.dependencies ?? []), "next-themes"]
@@ -181,7 +212,11 @@ export async function buildV0Payload(designSystemConfig: DesignSystemConfig) {
})
}
function buildGlobalsCss(registryBase: RegistryItem) {
function buildGlobalsCss(
registryBase: RegistryItem,
font: DesignSystemConfig["font"],
fontHeading: DesignSystemConfig["fontHeading"]
) {
const lightVars = Object.entries(registryBase.cssVars?.light ?? {})
.map(([key, value]) => ` --${key}: ${value};`)
.join("\n")
@@ -194,11 +229,15 @@ function buildGlobalsCss(registryBase: RegistryItem) {
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@custom-variant dark (&:is(.dark *));
@custom-variant dark (&:is(.dark *));
@theme inline {
${THEME_INLINE}
}
@theme inline {
${buildThemeInline(
fontHeading === "inherit"
? getInheritedHeadingFontValue(font)
: "var(--font-heading)"
)}
}
:root {
${lightVars}
@@ -332,18 +371,23 @@ function buildPackageJson(dependencies: string[]) {
})
}
function buildLayoutFile(designSystemConfig: DesignSystemConfig) {
const font = fonts.find(
(font) => font.name === `font-${designSystemConfig.font}`
)
function buildLayoutFile(
designSystemConfig: DesignSystemConfig,
fontHeading: DesignSystemConfig["fontHeading"]
) {
const font = getBodyFont(designSystemConfig.font)
if (!font) {
throw new Error(`Font "${designSystemConfig.font}" not found`)
}
const headingFont =
fontHeading === "inherit" ? undefined : getHeadingFont(fontHeading)
// Derive const name from the font's CSS variable (e.g. --font-sans → fontSans).
const constName = font.font.variable
.replace(/^--/, "")
.replace(/-./g, (m) => m[1].toUpperCase())
const headingConstName = "fontHeading"
// Add font-serif or font-mono class to body when needed. Sans is the default.
const fontClass =
@@ -354,14 +398,26 @@ function buildLayoutFile(designSystemConfig: DesignSystemConfig) {
: ""
const bodyClassName = fontClass ? `antialiased ${fontClass}` : "antialiased"
const imports = headingFont
? Array.from(new Set([font.font.import, headingFont.font.import])).join(
", "
)
: font.font.import
const headingDeclaration = headingFont
? `\nconst ${headingConstName} = ${headingFont.font.import}({subsets:['latin'],variable:'${headingFont.font.variable}'});\n`
: ""
const htmlClassName = headingFont
? `{${constName}.variable + " " + ${headingConstName}.variable}`
: `{${constName}.variable}`
const content = dedent`
import type { Metadata } from "next";
import { ${font.font.import} } from "next/font/google";
import { ${imports} } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
const ${constName} = ${font.font.import}({subsets:['latin'],variable:'${font.font.variable}'});
${headingDeclaration}
export const metadata: Metadata = {
title: "Create Next App",
@@ -374,7 +430,7 @@ function buildLayoutFile(designSystemConfig: DesignSystemConfig) {
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning className={${constName}.variable}>
<html lang="en" suppressHydrationWarning className=${htmlClassName}>
<body
className="${bodyClassName}"
>
@@ -401,13 +457,14 @@ async function buildComponentFiles(designSystemConfig: DesignSystemConfig) {
// Build config once for all components.
const config = buildTransformConfig(designSystemConfig)
// Fetch UI components and the item component in parallel.
const [registryItemFiles, itemComponentFile] = await Promise.all([
// Fetch UI components, the demo, and the item component in parallel.
const [registryItemFiles, demoFile, itemComponentFile] = await Promise.all([
Promise.all(
allItemsForBase.map((name) =>
getRegistryItemFile(name, designSystemConfig, config)
)
),
getRegistryItemFile("demo", designSystemConfig, config),
designSystemConfig.item
? getRegistryItemFile(designSystemConfig.item, designSystemConfig, config)
: null,
@@ -415,29 +472,24 @@ async function buildComponentFiles(designSystemConfig: DesignSystemConfig) {
const files = [...registryItemFiles.filter(Boolean)]
// Include the demo component.
if (demoFile) {
files.push({
...demoFile,
target: "components/demo.tsx",
type: "registry:component",
})
}
const pageFile = {
path: "app/page.tsx",
type: "registry:page",
target: "app/page.tsx",
content: dedent`
import { Button } from "@/components/ui/button"
import { Demo } from "@/components/demo"
export default function Page() {
return (
<div className="flex min-h-svh p-6">
<div className="flex max-w-md min-w-0 flex-col gap-4 text-sm leading-loose">
<div>
<h1 className="font-medium">Project ready!</h1>
<p>You may now add components and start building.</p>
<p>We&apos;ve already added the button component for you.</p>
<Button className="mt-2">Button</Button>
</div>
<div className="font-mono text-xs text-muted-foreground">
(Press <kbd>d</kbd> to toggle dark mode)
</div>
</div>
</div>
)
return <Demo />
}
`,
}
@@ -557,6 +609,7 @@ async function transformFileContent(
raw: content,
sourceFile,
config,
supportedFontMarkers: ["cn-font-heading"],
})
}

View File

@@ -116,7 +116,7 @@ function AlertDialogTitle({
<AlertDialogPrimitive.Title
data-slot="alert-dialog-title"
className={cn(
"text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
className
)}
{...props}

View File

@@ -38,7 +38,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="alert-title"
className={cn(
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
"cn-font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
className
)}
{...props}

View File

@@ -37,7 +37,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="card-title"
className={cn(
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
"cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
className
)}
{...props}

View File

@@ -119,7 +119,10 @@ function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-base leading-none font-medium", className)}
className={cn(
"cn-font-heading text-base leading-none font-medium",
className
)}
{...props}
/>
)

View File

@@ -97,7 +97,10 @@ function DrawerTitle({
return (
<DrawerPrimitive.Title
data-slot="drawer-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -58,7 +58,10 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn("text-sm font-medium tracking-tight", className)}
className={cn(
"cn-font-heading text-sm font-medium tracking-tight",
className
)}
{...props}
/>
)

View File

@@ -129,7 +129,7 @@ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
"cn-font-heading line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
className
)}
{...props}

View File

@@ -60,7 +60,7 @@ function PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {
return (
<PopoverPrimitive.Title
data-slot="popover-title"
className={cn("font-medium", className)}
className={cn("cn-font-heading font-medium", className)}
{...props}
/>
)

View File

@@ -102,7 +102,10 @@ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -116,7 +116,7 @@ function AlertDialogTitle({
<AlertDialogPrimitive.Title
data-slot="alert-dialog-title"
className={cn(
"text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
className
)}
{...props}

View File

@@ -38,7 +38,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="alert-title"
className={cn(
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
"cn-font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
className
)}
{...props}

View File

@@ -37,7 +37,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="card-title"
className={cn(
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
"cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
className
)}
{...props}

View File

@@ -119,7 +119,10 @@ function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-base leading-none font-medium", className)}
className={cn(
"cn-font-heading text-base leading-none font-medium",
className
)}
{...props}
/>
)

View File

@@ -97,7 +97,10 @@ function DrawerTitle({
return (
<DrawerPrimitive.Title
data-slot="drawer-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -58,7 +58,10 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn("text-sm font-medium tracking-tight", className)}
className={cn(
"cn-font-heading text-sm font-medium tracking-tight",
className
)}
{...props}
/>
)

View File

@@ -129,7 +129,7 @@ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
"cn-font-heading line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
className
)}
{...props}

View File

@@ -60,7 +60,7 @@ function PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {
return (
<PopoverPrimitive.Title
data-slot="popover-title"
className={cn("font-medium", className)}
className={cn("cn-font-heading font-medium", className)}
{...props}
/>
)

View File

@@ -102,7 +102,10 @@ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -122,7 +122,7 @@ function AlertDialogTitle({
<AlertDialogPrimitive.Title
data-slot="alert-dialog-title"
className={cn(
"text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
className
)}
{...props}

View File

@@ -38,7 +38,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="alert-title"
className={cn(
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
"cn-font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
className
)}
{...props}

View File

@@ -37,7 +37,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="card-title"
className={cn(
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
"cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
className
)}
{...props}

View File

@@ -127,7 +127,10 @@ function DialogTitle({
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-base leading-none font-medium", className)}
className={cn(
"cn-font-heading text-base leading-none font-medium",
className
)}
{...props}
/>
)

View File

@@ -97,7 +97,10 @@ function DrawerTitle({
return (
<DrawerPrimitive.Title
data-slot="drawer-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -58,7 +58,10 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn("text-sm font-medium tracking-tight", className)}
className={cn(
"cn-font-heading text-sm font-medium tracking-tight",
className
)}
{...props}
/>
)

View File

@@ -124,7 +124,7 @@ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
"cn-font-heading line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
className
)}
{...props}

View File

@@ -58,7 +58,7 @@ function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
return (
<div
data-slot="popover-title"
className={cn("font-medium", className)}
className={cn("cn-font-heading font-medium", className)}
{...props}
/>
)

View File

@@ -111,7 +111,10 @@ function SheetTitle({
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -122,7 +122,7 @@ function AlertDialogTitle({
<AlertDialogPrimitive.Title
data-slot="alert-dialog-title"
className={cn(
"text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
className
)}
{...props}

View File

@@ -38,7 +38,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="alert-title"
className={cn(
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
"cn-font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
className
)}
{...props}

View File

@@ -37,7 +37,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="card-title"
className={cn(
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
"cn-font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
className
)}
{...props}

View File

@@ -127,7 +127,10 @@ function DialogTitle({
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-base leading-none font-medium", className)}
className={cn(
"cn-font-heading text-base leading-none font-medium",
className
)}
{...props}
/>
)

View File

@@ -97,7 +97,10 @@ function DrawerTitle({
return (
<DrawerPrimitive.Title
data-slot="drawer-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -58,7 +58,10 @@ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn("text-sm font-medium tracking-tight", className)}
className={cn(
"cn-font-heading text-sm font-medium tracking-tight",
className
)}
{...props}
/>
)

View File

@@ -124,7 +124,7 @@ function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
<div
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
"cn-font-heading line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4",
className
)}
{...props}

View File

@@ -58,7 +58,7 @@ function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
return (
<div
data-slot="popover-title"
className={cn("font-medium", className)}
className={cn("cn-font-heading font-medium", className)}
{...props}
/>
)

View File

@@ -111,7 +111,10 @@ function SheetTitle({
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-base font-medium text-foreground", className)}
className={cn(
"cn-font-heading text-base font-medium text-foreground",
className
)}
{...props}
/>
)

View File

@@ -0,0 +1,306 @@
export type FontDefinition = {
name: string
title: string
type: "sans" | "mono" | "serif"
family: string
registryVariable: "--font-sans" | "--font-mono" | "--font-serif"
previewVariable: string
provider: "google"
import: string
dependency: string
subsets: readonly string[]
weight?: readonly string[]
}
export const FONT_DEFINITIONS = [
{
name: "geist",
title: "Geist",
type: "sans",
family: "'Geist Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-geist-sans",
provider: "google",
import: "Geist",
dependency: "@fontsource-variable/geist",
subsets: ["latin"],
},
{
name: "inter",
title: "Inter",
type: "sans",
family: "'Inter Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-inter",
provider: "google",
import: "Inter",
dependency: "@fontsource-variable/inter",
subsets: ["latin"],
},
{
name: "noto-sans",
title: "Noto Sans",
type: "sans",
family: "'Noto Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-noto-sans",
provider: "google",
import: "Noto_Sans",
dependency: "@fontsource-variable/noto-sans",
subsets: ["latin"],
},
{
name: "nunito-sans",
title: "Nunito Sans",
type: "sans",
family: "'Nunito Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-nunito-sans",
provider: "google",
import: "Nunito_Sans",
dependency: "@fontsource-variable/nunito-sans",
subsets: ["latin"],
},
{
name: "figtree",
title: "Figtree",
type: "sans",
family: "'Figtree Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-figtree",
provider: "google",
import: "Figtree",
dependency: "@fontsource-variable/figtree",
subsets: ["latin"],
},
{
name: "roboto",
title: "Roboto",
type: "sans",
family: "'Roboto Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-roboto",
provider: "google",
import: "Roboto",
dependency: "@fontsource-variable/roboto",
subsets: ["latin"],
},
{
name: "raleway",
title: "Raleway",
type: "sans",
family: "'Raleway Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-raleway",
provider: "google",
import: "Raleway",
dependency: "@fontsource-variable/raleway",
subsets: ["latin"],
},
{
name: "dm-sans",
title: "DM Sans",
type: "sans",
family: "'DM Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-dm-sans",
provider: "google",
import: "DM_Sans",
dependency: "@fontsource-variable/dm-sans",
subsets: ["latin"],
},
{
name: "public-sans",
title: "Public Sans",
type: "sans",
family: "'Public Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-public-sans",
provider: "google",
import: "Public_Sans",
dependency: "@fontsource-variable/public-sans",
subsets: ["latin"],
},
{
name: "outfit",
title: "Outfit",
type: "sans",
family: "'Outfit Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-outfit",
provider: "google",
import: "Outfit",
dependency: "@fontsource-variable/outfit",
subsets: ["latin"],
},
{
name: "oxanium",
title: "Oxanium",
type: "sans",
family: "'Oxanium Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-oxanium",
provider: "google",
import: "Oxanium",
dependency: "@fontsource-variable/oxanium",
subsets: ["latin"],
},
{
name: "manrope",
title: "Manrope",
type: "sans",
family: "'Manrope Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-manrope",
provider: "google",
import: "Manrope",
dependency: "@fontsource-variable/manrope",
subsets: ["latin"],
},
{
name: "space-grotesk",
title: "Space Grotesk",
type: "sans",
family: "'Space Grotesk Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-space-grotesk",
provider: "google",
import: "Space_Grotesk",
dependency: "@fontsource-variable/space-grotesk",
subsets: ["latin"],
},
{
name: "montserrat",
title: "Montserrat",
type: "sans",
family: "'Montserrat Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-montserrat",
provider: "google",
import: "Montserrat",
dependency: "@fontsource-variable/montserrat",
subsets: ["latin"],
},
{
name: "ibm-plex-sans",
title: "IBM Plex Sans",
type: "sans",
family: "'IBM Plex Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-ibm-plex-sans",
provider: "google",
import: "IBM_Plex_Sans",
dependency: "@fontsource-variable/ibm-plex-sans",
subsets: ["latin"],
},
{
name: "source-sans-3",
title: "Source Sans 3",
type: "sans",
family: "'Source Sans 3 Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-source-sans-3",
provider: "google",
import: "Source_Sans_3",
dependency: "@fontsource-variable/source-sans-3",
subsets: ["latin"],
},
{
name: "instrument-sans",
title: "Instrument Sans",
type: "sans",
family: "'Instrument Sans Variable', sans-serif",
registryVariable: "--font-sans",
previewVariable: "--font-instrument-sans",
provider: "google",
import: "Instrument_Sans",
dependency: "@fontsource-variable/instrument-sans",
subsets: ["latin"],
},
{
name: "jetbrains-mono",
title: "JetBrains Mono",
type: "mono",
family: "'JetBrains Mono Variable', monospace",
registryVariable: "--font-mono",
previewVariable: "--font-jetbrains-mono",
provider: "google",
import: "JetBrains_Mono",
dependency: "@fontsource-variable/jetbrains-mono",
subsets: ["latin"],
},
{
name: "geist-mono",
title: "Geist Mono",
type: "mono",
family: "'Geist Mono Variable', monospace",
registryVariable: "--font-mono",
previewVariable: "--font-geist-mono",
provider: "google",
import: "Geist_Mono",
dependency: "@fontsource-variable/geist-mono",
subsets: ["latin"],
},
{
name: "noto-serif",
title: "Noto Serif",
type: "serif",
family: "'Noto Serif Variable', serif",
registryVariable: "--font-serif",
previewVariable: "--font-noto-serif",
provider: "google",
import: "Noto_Serif",
dependency: "@fontsource-variable/noto-serif",
subsets: ["latin"],
},
{
name: "roboto-slab",
title: "Roboto Slab",
type: "serif",
family: "'Roboto Slab Variable', serif",
registryVariable: "--font-serif",
previewVariable: "--font-roboto-slab",
provider: "google",
import: "Roboto_Slab",
dependency: "@fontsource-variable/roboto-slab",
subsets: ["latin"],
},
{
name: "merriweather",
title: "Merriweather",
type: "serif",
family: "'Merriweather Variable', serif",
registryVariable: "--font-serif",
previewVariable: "--font-merriweather",
provider: "google",
import: "Merriweather",
dependency: "@fontsource-variable/merriweather",
subsets: ["latin"],
},
{
name: "lora",
title: "Lora",
type: "serif",
family: "'Lora Variable', serif",
registryVariable: "--font-serif",
previewVariable: "--font-lora",
provider: "google",
import: "Lora",
dependency: "@fontsource-variable/lora",
subsets: ["latin"],
},
{
name: "playfair-display",
title: "Playfair Display",
type: "serif",
family: "'Playfair Display Variable', serif",
registryVariable: "--font-serif",
previewVariable: "--font-playfair-display",
provider: "google",
import: "Playfair_Display",
dependency: "@fontsource-variable/playfair-display",
subsets: ["latin"],
},
] as const satisfies readonly FontDefinition[]
export type FontName = (typeof FONT_DEFINITIONS)[number]["name"]

View File

@@ -7,7 +7,7 @@ import {
transformRender,
transformStyle,
} from "shadcn/utils"
import { Project, ScriptKind } from "ts-morph"
import { Project, ScriptKind, type SourceFile } from "ts-morph"
import { BASES } from "@/registry/bases"
@@ -50,6 +50,13 @@ function buildDisplayConfig(styleName: string) {
}
}
type DisplayTransformer = (opts: {
filename: string
raw: string
sourceFile: SourceFile
config: ReturnType<typeof buildDisplayConfig>
}) => Promise<unknown>
const styleMapCache = new Map<string, Record<string, string>>()
async function getStyleMap(styleName: string) {
@@ -94,7 +101,11 @@ export async function formatCode(code: string, styleName: string) {
scriptKind: ScriptKind.TSX,
})
const transformers = [transformIcons, transformMenu, transformRender]
const transformers: DisplayTransformer[] = [
transformIcons as DisplayTransformer,
transformMenu as DisplayTransformer,
transformRender as DisplayTransformer,
]
for (const transformer of transformers) {
await transformer({
filename: "component.tsx",

View File

@@ -59,7 +59,7 @@ export const mdxComponents = {
h1: ({ className, ...props }: React.ComponentProps<"h1">) => (
<h1
className={cn(
"font-heading mt-2 scroll-m-28 text-3xl font-bold tracking-tight",
"mt-2 scroll-m-28 font-heading text-3xl font-bold tracking-tight",
className
)}
{...props}
@@ -75,7 +75,7 @@ export const mdxComponents = {
.replace(/\?/g, "")
.toLowerCase()}
className={cn(
"font-heading [&+]*:[code]:text-xl mt-10 scroll-m-28 text-xl font-medium tracking-tight first:mt-0 lg:mt-12 [&+.steps]:mt-0! [&+.steps>h3]:mt-4! [&+h3]:mt-6! [&+p]:mt-4!",
"[&+]*:[code]:text-xl mt-10 scroll-m-28 font-heading text-xl font-medium tracking-tight first:mt-0 lg:mt-12 [&+.steps]:mt-0! [&+.steps>h3]:mt-4! [&+h3]:mt-6! [&+p]:mt-4!",
className
)}
{...props}
@@ -85,7 +85,7 @@ export const mdxComponents = {
h3: ({ className, ...props }: React.ComponentProps<"h3">) => (
<h3
className={cn(
"font-heading mt-12 scroll-m-28 text-lg font-medium tracking-tight [&+p]:mt-4! *:[code]:text-xl",
"mt-12 scroll-m-28 font-heading text-lg font-medium tracking-tight [&+p]:mt-4! *:[code]:text-xl",
className
)}
{...props}
@@ -94,7 +94,7 @@ export const mdxComponents = {
h4: ({ className, ...props }: React.ComponentProps<"h4">) => (
<h4
className={cn(
"font-heading mt-8 scroll-m-28 text-base font-medium tracking-tight",
"mt-8 scroll-m-28 font-heading text-base font-medium tracking-tight",
className
)}
{...props}
@@ -279,7 +279,7 @@ export const mdxComponents = {
Step: ({ className, ...props }: React.ComponentProps<"h3">) => (
<h3
className={cn(
"font-heading mt-8 scroll-m-32 text-lg font-medium tracking-tight",
"mt-8 scroll-m-32 font-heading text-lg font-medium tracking-tight",
className
)}
{...props}

View File

@@ -76,7 +76,7 @@
"rehype-pretty-code": "^0.14.1",
"rimraf": "^6.0.1",
"server-only": "^0.0.1",
"shadcn": "4.0.8",
"shadcn": "4.1.0",
"shiki": "^1.10.1",
"sonner": "^2.0.0",
"swr": "^2.3.6",

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.922 0.005 325.62)",
"input": "oklch(0.922 0.005 325.62)",
"ring": "oklch(0.711 0.019 323.02)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0.008 326)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.542 0.034 322.5)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"sidebar": "oklch(0.212 0.019 322.12)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.922 0.005 325.62)",
"input": "oklch(0.922 0.005 325.62)",
"ring": "oklch(0.711 0.019 323.02)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0.008 326)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.542 0.034 322.5)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"sidebar": "oklch(0.212 0.019 322.12)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.922 0.005 325.62)",
"input": "oklch(0.922 0.005 325.62)",
"ring": "oklch(0.711 0.019 323.02)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0.008 326)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.542 0.034 322.5)",
"chart-1": "oklch(0.845 0.143 164.978)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.596 0.145 163.225)",
"chart-4": "oklch(0.508 0.118 165.612)",
"chart-5": "oklch(0.432 0.095 166.913)",
"chart-1": "oklch(0.865 0.012 325.68)",
"chart-2": "oklch(0.542 0.034 322.5)",
"chart-3": "oklch(0.435 0.029 321.78)",
"chart-4": "oklch(0.364 0.029 323.89)",
"chart-5": "oklch(0.263 0.024 320.12)",
"sidebar": "oklch(0.212 0.019 322.12)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0.008 326);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0.008 326);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0.008 326);\n --primary: oklch(0.212 0.019 322.12);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.96 0.003 325.6);\n --secondary-foreground: oklch(0.212 0.019 322.12);\n --muted: oklch(0.96 0.003 325.6);\n --muted-foreground: oklch(0.542 0.034 322.5);\n --accent: oklch(0.96 0.003 325.6);\n --accent-foreground: oklch(0.212 0.019 322.12);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0.005 325.62);\n --input: oklch(0.922 0.005 325.62);\n --ring: oklch(0.711 0.019 323.02);\n --chart-1: oklch(0.845 0.143 164.978);\n --chart-2: oklch(0.696 0.17 162.48);\n --chart-3: oklch(0.596 0.145 163.225);\n --chart-4: oklch(0.508 0.118 165.612);\n --chart-5: oklch(0.432 0.095 166.913);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.145 0.008 326);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.212 0.019 322.12);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.212 0.019 322.12);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0.005 325.62);\n --primary-foreground: oklch(0.212 0.019 322.12);\n --secondary: oklch(0.263 0.024 320.12);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.263 0.024 320.12);\n --muted-foreground: oklch(0.711 0.019 323.02);\n --accent: oklch(0.263 0.024 320.12);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.542 0.034 322.5);\n --chart-1: oklch(0.845 0.143 164.978);\n --chart-2: oklch(0.696 0.17 162.48);\n --chart-3: oklch(0.596 0.145 163.225);\n --chart-4: oklch(0.508 0.118 165.612);\n --chart-5: oklch(0.432 0.095 166.913);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0.008 326);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0.008 326);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0.008 326);\n --primary: oklch(0.212 0.019 322.12);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.96 0.003 325.6);\n --secondary-foreground: oklch(0.212 0.019 322.12);\n --muted: oklch(0.96 0.003 325.6);\n --muted-foreground: oklch(0.542 0.034 322.5);\n --accent: oklch(0.96 0.003 325.6);\n --accent-foreground: oklch(0.212 0.019 322.12);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0.005 325.62);\n --input: oklch(0.922 0.005 325.62);\n --ring: oklch(0.711 0.019 323.02);\n --chart-1: oklch(0.865 0.012 325.68);\n --chart-2: oklch(0.542 0.034 322.5);\n --chart-3: oklch(0.435 0.029 321.78);\n --chart-4: oklch(0.364 0.029 323.89);\n --chart-5: oklch(0.263 0.024 320.12);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.145 0.008 326);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.212 0.019 322.12);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.212 0.019 322.12);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0.005 325.62);\n --primary-foreground: oklch(0.212 0.019 322.12);\n --secondary: oklch(0.263 0.024 320.12);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.263 0.024 320.12);\n --muted-foreground: oklch(0.711 0.019 323.02);\n --accent: oklch(0.263 0.024 320.12);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.542 0.034 322.5);\n --chart-1: oklch(0.865 0.012 325.68);\n --chart-2: oklch(0.542 0.034 322.5);\n --chart-3: oklch(0.435 0.029 321.78);\n --chart-4: oklch(0.364 0.029 323.89);\n --chart-5: oklch(0.263 0.024 320.12);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.925 0.005 214.3)",
"input": "oklch(0.925 0.005 214.3)",
"ring": "oklch(0.723 0.014 214.4)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"radius": "0.625rem",
"sidebar": "oklch(0.987 0.002 197.1)",
"sidebar-foreground": "oklch(0.148 0.004 228.8)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.56 0.021 213.5)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"sidebar": "oklch(0.218 0.008 223.9)",
"sidebar-foreground": "oklch(0.987 0.002 197.1)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.925 0.005 214.3)",
"input": "oklch(0.925 0.005 214.3)",
"ring": "oklch(0.723 0.014 214.4)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"radius": "0.625rem",
"sidebar": "oklch(0.987 0.002 197.1)",
"sidebar-foreground": "oklch(0.148 0.004 228.8)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.56 0.021 213.5)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"sidebar": "oklch(0.218 0.008 223.9)",
"sidebar-foreground": "oklch(0.987 0.002 197.1)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.925 0.005 214.3)",
"input": "oklch(0.925 0.005 214.3)",
"ring": "oklch(0.723 0.014 214.4)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"radius": "0.625rem",
"sidebar": "oklch(0.987 0.002 197.1)",
"sidebar-foreground": "oklch(0.148 0.004 228.8)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.56 0.021 213.5)",
"chart-1": "oklch(0.81 0.117 11.638)",
"chart-2": "oklch(0.645 0.246 16.439)",
"chart-3": "oklch(0.586 0.253 17.585)",
"chart-4": "oklch(0.514 0.222 16.935)",
"chart-5": "oklch(0.455 0.188 13.697)",
"chart-1": "oklch(0.872 0.007 219.6)",
"chart-2": "oklch(0.56 0.021 213.5)",
"chart-3": "oklch(0.45 0.017 213.2)",
"chart-4": "oklch(0.378 0.015 216)",
"chart-5": "oklch(0.275 0.011 216.9)",
"sidebar": "oklch(0.218 0.008 223.9)",
"sidebar-foreground": "oklch(0.987 0.002 197.1)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.148 0.004 228.8);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.148 0.004 228.8);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.148 0.004 228.8);\n --primary: oklch(0.218 0.008 223.9);\n --primary-foreground: oklch(0.987 0.002 197.1);\n --secondary: oklch(0.963 0.002 197.1);\n --secondary-foreground: oklch(0.218 0.008 223.9);\n --muted: oklch(0.963 0.002 197.1);\n --muted-foreground: oklch(0.56 0.021 213.5);\n --accent: oklch(0.963 0.002 197.1);\n --accent-foreground: oklch(0.218 0.008 223.9);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.925 0.005 214.3);\n --input: oklch(0.925 0.005 214.3);\n --ring: oklch(0.723 0.014 214.4);\n --chart-1: oklch(0.81 0.117 11.638);\n --chart-2: oklch(0.645 0.246 16.439);\n --chart-3: oklch(0.586 0.253 17.585);\n --chart-4: oklch(0.514 0.222 16.935);\n --chart-5: oklch(0.455 0.188 13.697);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.148 0.004 228.8);\n --foreground: oklch(0.987 0.002 197.1);\n --card: oklch(0.218 0.008 223.9);\n --card-foreground: oklch(0.987 0.002 197.1);\n --popover: oklch(0.218 0.008 223.9);\n --popover-foreground: oklch(0.987 0.002 197.1);\n --primary: oklch(0.925 0.005 214.3);\n --primary-foreground: oklch(0.218 0.008 223.9);\n --secondary: oklch(0.275 0.011 216.9);\n --secondary-foreground: oklch(0.987 0.002 197.1);\n --muted: oklch(0.275 0.011 216.9);\n --muted-foreground: oklch(0.723 0.014 214.4);\n --accent: oklch(0.275 0.011 216.9);\n --accent-foreground: oklch(0.987 0.002 197.1);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.56 0.021 213.5);\n --chart-1: oklch(0.81 0.117 11.638);\n --chart-2: oklch(0.645 0.246 16.439);\n --chart-3: oklch(0.586 0.253 17.585);\n --chart-4: oklch(0.514 0.222 16.935);\n --chart-5: oklch(0.455 0.188 13.697);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.148 0.004 228.8);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.148 0.004 228.8);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.148 0.004 228.8);\n --primary: oklch(0.218 0.008 223.9);\n --primary-foreground: oklch(0.987 0.002 197.1);\n --secondary: oklch(0.963 0.002 197.1);\n --secondary-foreground: oklch(0.218 0.008 223.9);\n --muted: oklch(0.963 0.002 197.1);\n --muted-foreground: oklch(0.56 0.021 213.5);\n --accent: oklch(0.963 0.002 197.1);\n --accent-foreground: oklch(0.218 0.008 223.9);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.925 0.005 214.3);\n --input: oklch(0.925 0.005 214.3);\n --ring: oklch(0.723 0.014 214.4);\n --chart-1: oklch(0.872 0.007 219.6);\n --chart-2: oklch(0.56 0.021 213.5);\n --chart-3: oklch(0.45 0.017 213.2);\n --chart-4: oklch(0.378 0.015 216);\n --chart-5: oklch(0.275 0.011 216.9);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.148 0.004 228.8);\n --foreground: oklch(0.987 0.002 197.1);\n --card: oklch(0.218 0.008 223.9);\n --card-foreground: oklch(0.987 0.002 197.1);\n --popover: oklch(0.218 0.008 223.9);\n --popover-foreground: oklch(0.987 0.002 197.1);\n --primary: oklch(0.925 0.005 214.3);\n --primary-foreground: oklch(0.218 0.008 223.9);\n --secondary: oklch(0.275 0.011 216.9);\n --secondary-foreground: oklch(0.987 0.002 197.1);\n --muted: oklch(0.275 0.011 216.9);\n --muted-foreground: oklch(0.723 0.014 214.4);\n --accent: oklch(0.275 0.011 216.9);\n --accent-foreground: oklch(0.987 0.002 197.1);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.56 0.021 213.5);\n --chart-1: oklch(0.872 0.007 219.6);\n --chart-2: oklch(0.56 0.021 213.5);\n --chart-3: oklch(0.45 0.017 213.2);\n --chart-4: oklch(0.378 0.015 216);\n --chart-5: oklch(0.275 0.011 216.9);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.922 0 0)",
"input": "oklch(0.922 0 0)",
"ring": "oklch(0.708 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0 0)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.556 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"sidebar": "oklch(0.205 0 0)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.922 0 0)",
"input": "oklch(0.922 0 0)",
"ring": "oklch(0.708 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0 0)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.556 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"sidebar": "oklch(0.205 0 0)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.922 0 0)",
"input": "oklch(0.922 0 0)",
"ring": "oklch(0.708 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0 0)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.556 0 0)",
"chart-1": "oklch(0.809 0.105 251.813)",
"chart-2": "oklch(0.623 0.214 259.815)",
"chart-3": "oklch(0.546 0.245 262.881)",
"chart-4": "oklch(0.488 0.243 264.376)",
"chart-5": "oklch(0.424 0.199 265.638)",
"chart-1": "oklch(0.87 0 0)",
"chart-2": "oklch(0.556 0 0)",
"chart-3": "oklch(0.439 0 0)",
"chart-4": "oklch(0.371 0 0)",
"chart-5": "oklch(0.269 0 0)",
"sidebar": "oklch(0.205 0 0)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.809 0.105 251.813);\n --chart-2: oklch(0.623 0.214 259.815);\n --chart-3: oklch(0.546 0.245 262.881);\n --chart-4: oklch(0.488 0.243 264.376);\n --chart-5: oklch(0.424 0.199 265.638);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.809 0.105 251.813);\n --chart-2: oklch(0.623 0.214 259.815);\n --chart-3: oklch(0.546 0.245 262.881);\n --chart-4: oklch(0.488 0.243 264.376);\n --chart-5: oklch(0.424 0.199 265.638);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.87 0 0);\n --chart-2: oklch(0.556 0 0);\n --chart-3: oklch(0.439 0 0);\n --chart-4: oklch(0.371 0 0);\n --chart-5: oklch(0.269 0 0);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.87 0 0);\n --chart-2: oklch(0.556 0 0);\n --chart-3: oklch(0.439 0 0);\n --chart-4: oklch(0.371 0 0);\n --chart-5: oklch(0.269 0 0);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.93 0.007 106.5)",
"input": "oklch(0.93 0.007 106.5)",
"ring": "oklch(0.737 0.021 106.9)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"radius": "0.625rem",
"sidebar": "oklch(0.988 0.003 106.5)",
"sidebar-foreground": "oklch(0.153 0.006 107.1)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.58 0.031 107.3)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"sidebar": "oklch(0.228 0.013 107.4)",
"sidebar-foreground": "oklch(0.988 0.003 106.5)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.93 0.007 106.5)",
"input": "oklch(0.93 0.007 106.5)",
"ring": "oklch(0.737 0.021 106.9)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"radius": "0.625rem",
"sidebar": "oklch(0.988 0.003 106.5)",
"sidebar-foreground": "oklch(0.153 0.006 107.1)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.58 0.031 107.3)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"sidebar": "oklch(0.228 0.013 107.4)",
"sidebar-foreground": "oklch(0.988 0.003 106.5)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.93 0.007 106.5)",
"input": "oklch(0.93 0.007 106.5)",
"ring": "oklch(0.737 0.021 106.9)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"radius": "0.625rem",
"sidebar": "oklch(0.988 0.003 106.5)",
"sidebar-foreground": "oklch(0.153 0.006 107.1)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.58 0.031 107.3)",
"chart-1": "oklch(0.811 0.111 293.571)",
"chart-2": "oklch(0.606 0.25 292.717)",
"chart-3": "oklch(0.541 0.281 293.009)",
"chart-4": "oklch(0.491 0.27 292.581)",
"chart-5": "oklch(0.432 0.232 292.759)",
"chart-1": "oklch(0.88 0.011 106.6)",
"chart-2": "oklch(0.58 0.031 107.3)",
"chart-3": "oklch(0.466 0.025 107.3)",
"chart-4": "oklch(0.394 0.023 107.4)",
"chart-5": "oklch(0.286 0.016 107.4)",
"sidebar": "oklch(0.228 0.013 107.4)",
"sidebar-foreground": "oklch(0.988 0.003 106.5)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.153 0.006 107.1);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.153 0.006 107.1);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.153 0.006 107.1);\n --primary: oklch(0.228 0.013 107.4);\n --primary-foreground: oklch(0.988 0.003 106.5);\n --secondary: oklch(0.966 0.005 106.5);\n --secondary-foreground: oklch(0.228 0.013 107.4);\n --muted: oklch(0.966 0.005 106.5);\n --muted-foreground: oklch(0.58 0.031 107.3);\n --accent: oklch(0.966 0.005 106.5);\n --accent-foreground: oklch(0.228 0.013 107.4);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.93 0.007 106.5);\n --input: oklch(0.93 0.007 106.5);\n --ring: oklch(0.737 0.021 106.9);\n --chart-1: oklch(0.811 0.111 293.571);\n --chart-2: oklch(0.606 0.25 292.717);\n --chart-3: oklch(0.541 0.281 293.009);\n --chart-4: oklch(0.491 0.27 292.581);\n --chart-5: oklch(0.432 0.232 292.759);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.153 0.006 107.1);\n --foreground: oklch(0.988 0.003 106.5);\n --card: oklch(0.228 0.013 107.4);\n --card-foreground: oklch(0.988 0.003 106.5);\n --popover: oklch(0.228 0.013 107.4);\n --popover-foreground: oklch(0.988 0.003 106.5);\n --primary: oklch(0.93 0.007 106.5);\n --primary-foreground: oklch(0.228 0.013 107.4);\n --secondary: oklch(0.286 0.016 107.4);\n --secondary-foreground: oklch(0.988 0.003 106.5);\n --muted: oklch(0.286 0.016 107.4);\n --muted-foreground: oklch(0.737 0.021 106.9);\n --accent: oklch(0.286 0.016 107.4);\n --accent-foreground: oklch(0.988 0.003 106.5);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.58 0.031 107.3);\n --chart-1: oklch(0.811 0.111 293.571);\n --chart-2: oklch(0.606 0.25 292.717);\n --chart-3: oklch(0.541 0.281 293.009);\n --chart-4: oklch(0.491 0.27 292.581);\n --chart-5: oklch(0.432 0.232 292.759);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.153 0.006 107.1);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.153 0.006 107.1);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.153 0.006 107.1);\n --primary: oklch(0.228 0.013 107.4);\n --primary-foreground: oklch(0.988 0.003 106.5);\n --secondary: oklch(0.966 0.005 106.5);\n --secondary-foreground: oklch(0.228 0.013 107.4);\n --muted: oklch(0.966 0.005 106.5);\n --muted-foreground: oklch(0.58 0.031 107.3);\n --accent: oklch(0.966 0.005 106.5);\n --accent-foreground: oklch(0.228 0.013 107.4);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.93 0.007 106.5);\n --input: oklch(0.93 0.007 106.5);\n --ring: oklch(0.737 0.021 106.9);\n --chart-1: oklch(0.88 0.011 106.6);\n --chart-2: oklch(0.58 0.031 107.3);\n --chart-3: oklch(0.466 0.025 107.3);\n --chart-4: oklch(0.394 0.023 107.4);\n --chart-5: oklch(0.286 0.016 107.4);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.153 0.006 107.1);\n --foreground: oklch(0.988 0.003 106.5);\n --card: oklch(0.228 0.013 107.4);\n --card-foreground: oklch(0.988 0.003 106.5);\n --popover: oklch(0.228 0.013 107.4);\n --popover-foreground: oklch(0.988 0.003 106.5);\n --primary: oklch(0.93 0.007 106.5);\n --primary-foreground: oklch(0.228 0.013 107.4);\n --secondary: oklch(0.286 0.016 107.4);\n --secondary-foreground: oklch(0.988 0.003 106.5);\n --muted: oklch(0.286 0.016 107.4);\n --muted-foreground: oklch(0.737 0.021 106.9);\n --accent: oklch(0.286 0.016 107.4);\n --accent-foreground: oklch(0.988 0.003 106.5);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.58 0.031 107.3);\n --chart-1: oklch(0.88 0.011 106.6);\n --chart-2: oklch(0.58 0.031 107.3);\n --chart-3: oklch(0.466 0.025 107.3);\n --chart-4: oklch(0.394 0.023 107.4);\n --chart-5: oklch(0.286 0.016 107.4);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.923 0.003 48.717)",
"input": "oklch(0.923 0.003 48.717)",
"ring": "oklch(0.709 0.01 56.259)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.001 106.423)",
"sidebar-foreground": "oklch(0.147 0.004 49.25)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.553 0.013 58.071)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"sidebar": "oklch(0.216 0.006 56.043)",
"sidebar-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.923 0.003 48.717)",
"input": "oklch(0.923 0.003 48.717)",
"ring": "oklch(0.709 0.01 56.259)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.001 106.423)",
"sidebar-foreground": "oklch(0.147 0.004 49.25)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.553 0.013 58.071)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"sidebar": "oklch(0.216 0.006 56.043)",
"sidebar-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.923 0.003 48.717)",
"input": "oklch(0.923 0.003 48.717)",
"ring": "oklch(0.709 0.01 56.259)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.001 106.423)",
"sidebar-foreground": "oklch(0.147 0.004 49.25)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.553 0.013 58.071)",
"chart-1": "oklch(0.897 0.196 126.665)",
"chart-2": "oklch(0.768 0.233 130.85)",
"chart-3": "oklch(0.648 0.2 131.684)",
"chart-4": "oklch(0.532 0.157 131.589)",
"chart-5": "oklch(0.453 0.124 130.933)",
"chart-1": "oklch(0.869 0.005 56.366)",
"chart-2": "oklch(0.553 0.013 58.071)",
"chart-3": "oklch(0.444 0.011 73.639)",
"chart-4": "oklch(0.374 0.01 67.558)",
"chart-5": "oklch(0.268 0.007 34.298)",
"sidebar": "oklch(0.216 0.006 56.043)",
"sidebar-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.147 0.004 49.25);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.147 0.004 49.25);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.147 0.004 49.25);\n --primary: oklch(0.216 0.006 56.043);\n --primary-foreground: oklch(0.985 0.001 106.423);\n --secondary: oklch(0.97 0.001 106.424);\n --secondary-foreground: oklch(0.216 0.006 56.043);\n --muted: oklch(0.97 0.001 106.424);\n --muted-foreground: oklch(0.553 0.013 58.071);\n --accent: oklch(0.97 0.001 106.424);\n --accent-foreground: oklch(0.216 0.006 56.043);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.923 0.003 48.717);\n --input: oklch(0.923 0.003 48.717);\n --ring: oklch(0.709 0.01 56.259);\n --chart-1: oklch(0.897 0.196 126.665);\n --chart-2: oklch(0.768 0.233 130.85);\n --chart-3: oklch(0.648 0.2 131.684);\n --chart-4: oklch(0.532 0.157 131.589);\n --chart-5: oklch(0.453 0.124 130.933);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.147 0.004 49.25);\n --foreground: oklch(0.985 0.001 106.423);\n --card: oklch(0.216 0.006 56.043);\n --card-foreground: oklch(0.985 0.001 106.423);\n --popover: oklch(0.216 0.006 56.043);\n --popover-foreground: oklch(0.985 0.001 106.423);\n --primary: oklch(0.923 0.003 48.717);\n --primary-foreground: oklch(0.216 0.006 56.043);\n --secondary: oklch(0.268 0.007 34.298);\n --secondary-foreground: oklch(0.985 0.001 106.423);\n --muted: oklch(0.268 0.007 34.298);\n --muted-foreground: oklch(0.709 0.01 56.259);\n --accent: oklch(0.268 0.007 34.298);\n --accent-foreground: oklch(0.985 0.001 106.423);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.553 0.013 58.071);\n --chart-1: oklch(0.897 0.196 126.665);\n --chart-2: oklch(0.768 0.233 130.85);\n --chart-3: oklch(0.648 0.2 131.684);\n --chart-4: oklch(0.532 0.157 131.589);\n --chart-5: oklch(0.453 0.124 130.933);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.147 0.004 49.25);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.147 0.004 49.25);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.147 0.004 49.25);\n --primary: oklch(0.216 0.006 56.043);\n --primary-foreground: oklch(0.985 0.001 106.423);\n --secondary: oklch(0.97 0.001 106.424);\n --secondary-foreground: oklch(0.216 0.006 56.043);\n --muted: oklch(0.97 0.001 106.424);\n --muted-foreground: oklch(0.553 0.013 58.071);\n --accent: oklch(0.97 0.001 106.424);\n --accent-foreground: oklch(0.216 0.006 56.043);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.923 0.003 48.717);\n --input: oklch(0.923 0.003 48.717);\n --ring: oklch(0.709 0.01 56.259);\n --chart-1: oklch(0.869 0.005 56.366);\n --chart-2: oklch(0.553 0.013 58.071);\n --chart-3: oklch(0.444 0.011 73.639);\n --chart-4: oklch(0.374 0.01 67.558);\n --chart-5: oklch(0.268 0.007 34.298);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.147 0.004 49.25);\n --foreground: oklch(0.985 0.001 106.423);\n --card: oklch(0.216 0.006 56.043);\n --card-foreground: oklch(0.985 0.001 106.423);\n --popover: oklch(0.216 0.006 56.043);\n --popover-foreground: oklch(0.985 0.001 106.423);\n --primary: oklch(0.923 0.003 48.717);\n --primary-foreground: oklch(0.216 0.006 56.043);\n --secondary: oklch(0.268 0.007 34.298);\n --secondary-foreground: oklch(0.985 0.001 106.423);\n --muted: oklch(0.268 0.007 34.298);\n --muted-foreground: oklch(0.709 0.01 56.259);\n --accent: oklch(0.268 0.007 34.298);\n --accent-foreground: oklch(0.985 0.001 106.423);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.553 0.013 58.071);\n --chart-1: oklch(0.869 0.005 56.366);\n --chart-2: oklch(0.553 0.013 58.071);\n --chart-3: oklch(0.444 0.011 73.639);\n --chart-4: oklch(0.374 0.01 67.558);\n --chart-5: oklch(0.268 0.007 34.298);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.922 0.005 34.3)",
"input": "oklch(0.922 0.005 34.3)",
"ring": "oklch(0.714 0.014 41.2)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"radius": "0.625rem",
"sidebar": "oklch(0.986 0.002 67.8)",
"sidebar-foreground": "oklch(0.147 0.004 49.3)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.547 0.021 43.1)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"sidebar": "oklch(0.214 0.009 43.1)",
"sidebar-foreground": "oklch(0.986 0.002 67.8)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.922 0.005 34.3)",
"input": "oklch(0.922 0.005 34.3)",
"ring": "oklch(0.714 0.014 41.2)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"radius": "0.625rem",
"sidebar": "oklch(0.986 0.002 67.8)",
"sidebar-foreground": "oklch(0.147 0.004 49.3)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.547 0.021 43.1)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"sidebar": "oklch(0.214 0.009 43.1)",
"sidebar-foreground": "oklch(0.986 0.002 67.8)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.922 0.005 34.3)",
"input": "oklch(0.922 0.005 34.3)",
"ring": "oklch(0.714 0.014 41.2)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"radius": "0.625rem",
"sidebar": "oklch(0.986 0.002 67.8)",
"sidebar-foreground": "oklch(0.147 0.004 49.3)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.547 0.021 43.1)",
"chart-1": "oklch(0.865 0.127 207.078)",
"chart-2": "oklch(0.715 0.143 215.221)",
"chart-3": "oklch(0.609 0.126 221.723)",
"chart-4": "oklch(0.52 0.105 223.128)",
"chart-5": "oklch(0.45 0.085 224.283)",
"chart-1": "oklch(0.868 0.007 39.5)",
"chart-2": "oklch(0.547 0.021 43.1)",
"chart-3": "oklch(0.438 0.017 39.3)",
"chart-4": "oklch(0.367 0.016 35.7)",
"chart-5": "oklch(0.268 0.011 36.5)",
"sidebar": "oklch(0.214 0.009 43.1)",
"sidebar-foreground": "oklch(0.986 0.002 67.8)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.147 0.004 49.3);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.147 0.004 49.3);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.147 0.004 49.3);\n --primary: oklch(0.214 0.009 43.1);\n --primary-foreground: oklch(0.986 0.002 67.8);\n --secondary: oklch(0.96 0.002 17.2);\n --secondary-foreground: oklch(0.214 0.009 43.1);\n --muted: oklch(0.96 0.002 17.2);\n --muted-foreground: oklch(0.547 0.021 43.1);\n --accent: oklch(0.96 0.002 17.2);\n --accent-foreground: oklch(0.214 0.009 43.1);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0.005 34.3);\n --input: oklch(0.922 0.005 34.3);\n --ring: oklch(0.714 0.014 41.2);\n --chart-1: oklch(0.865 0.127 207.078);\n --chart-2: oklch(0.715 0.143 215.221);\n --chart-3: oklch(0.609 0.126 221.723);\n --chart-4: oklch(0.52 0.105 223.128);\n --chart-5: oklch(0.45 0.085 224.283);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.147 0.004 49.3);\n --foreground: oklch(0.986 0.002 67.8);\n --card: oklch(0.214 0.009 43.1);\n --card-foreground: oklch(0.986 0.002 67.8);\n --popover: oklch(0.214 0.009 43.1);\n --popover-foreground: oklch(0.986 0.002 67.8);\n --primary: oklch(0.922 0.005 34.3);\n --primary-foreground: oklch(0.214 0.009 43.1);\n --secondary: oklch(0.268 0.011 36.5);\n --secondary-foreground: oklch(0.986 0.002 67.8);\n --muted: oklch(0.268 0.011 36.5);\n --muted-foreground: oklch(0.714 0.014 41.2);\n --accent: oklch(0.268 0.011 36.5);\n --accent-foreground: oklch(0.986 0.002 67.8);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.547 0.021 43.1);\n --chart-1: oklch(0.865 0.127 207.078);\n --chart-2: oklch(0.715 0.143 215.221);\n --chart-3: oklch(0.609 0.126 221.723);\n --chart-4: oklch(0.52 0.105 223.128);\n --chart-5: oklch(0.45 0.085 224.283);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.147 0.004 49.3);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.147 0.004 49.3);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.147 0.004 49.3);\n --primary: oklch(0.214 0.009 43.1);\n --primary-foreground: oklch(0.986 0.002 67.8);\n --secondary: oklch(0.96 0.002 17.2);\n --secondary-foreground: oklch(0.214 0.009 43.1);\n --muted: oklch(0.96 0.002 17.2);\n --muted-foreground: oklch(0.547 0.021 43.1);\n --accent: oklch(0.96 0.002 17.2);\n --accent-foreground: oklch(0.214 0.009 43.1);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0.005 34.3);\n --input: oklch(0.922 0.005 34.3);\n --ring: oklch(0.714 0.014 41.2);\n --chart-1: oklch(0.868 0.007 39.5);\n --chart-2: oklch(0.547 0.021 43.1);\n --chart-3: oklch(0.438 0.017 39.3);\n --chart-4: oklch(0.367 0.016 35.7);\n --chart-5: oklch(0.268 0.011 36.5);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.147 0.004 49.3);\n --foreground: oklch(0.986 0.002 67.8);\n --card: oklch(0.214 0.009 43.1);\n --card-foreground: oklch(0.986 0.002 67.8);\n --popover: oklch(0.214 0.009 43.1);\n --popover-foreground: oklch(0.986 0.002 67.8);\n --primary: oklch(0.922 0.005 34.3);\n --primary-foreground: oklch(0.214 0.009 43.1);\n --secondary: oklch(0.268 0.011 36.5);\n --secondary-foreground: oklch(0.986 0.002 67.8);\n --muted: oklch(0.268 0.011 36.5);\n --muted-foreground: oklch(0.714 0.014 41.2);\n --accent: oklch(0.268 0.011 36.5);\n --accent-foreground: oklch(0.986 0.002 67.8);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.547 0.021 43.1);\n --chart-1: oklch(0.868 0.007 39.5);\n --chart-2: oklch(0.547 0.021 43.1);\n --chart-3: oklch(0.438 0.017 39.3);\n --chart-4: oklch(0.367 0.016 35.7);\n --chart-5: oklch(0.268 0.011 36.5);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -19,11 +19,11 @@
"border": "oklch(0.92 0.004 286.32)",
"input": "oklch(0.92 0.004 286.32)",
"ring": "oklch(0.705 0.015 286.067)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
@@ -53,11 +53,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.552 0.016 285.938)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"sidebar": "oklch(0.21 0.006 285.885)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -88,11 +88,11 @@
"border": "oklch(0.92 0.004 286.32)",
"input": "oklch(0.92 0.004 286.32)",
"ring": "oklch(0.705 0.015 286.067)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
@@ -122,11 +122,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.552 0.016 285.938)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"sidebar": "oklch(0.21 0.006 285.885)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -157,11 +157,11 @@
"border": "oklch(0.92 0.004 286.32)",
"input": "oklch(0.92 0.004 286.32)",
"ring": "oklch(0.705 0.015 286.067)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
@@ -191,11 +191,11 @@
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.552 0.016 285.938)",
"chart-1": "oklch(0.879 0.169 91.605)",
"chart-2": "oklch(0.769 0.188 70.08)",
"chart-3": "oklch(0.666 0.179 58.318)",
"chart-4": "oklch(0.555 0.163 48.998)",
"chart-5": "oklch(0.473 0.137 46.201)",
"chart-1": "oklch(0.871 0.006 286.286)",
"chart-2": "oklch(0.552 0.016 285.938)",
"chart-3": "oklch(0.442 0.017 285.786)",
"chart-4": "oklch(0.37 0.013 285.805)",
"chart-5": "oklch(0.274 0.006 286.033)",
"sidebar": "oklch(0.21 0.006 285.885)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
@@ -207,5 +207,5 @@
}
},
"inlineColorsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n ",
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.141 0.005 285.823);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.141 0.005 285.823);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.141 0.005 285.823);\n --primary: oklch(0.21 0.006 285.885);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.967 0.001 286.375);\n --secondary-foreground: oklch(0.21 0.006 285.885);\n --muted: oklch(0.967 0.001 286.375);\n --muted-foreground: oklch(0.552 0.016 285.938);\n --accent: oklch(0.967 0.001 286.375);\n --accent-foreground: oklch(0.21 0.006 285.885);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.92 0.004 286.32);\n --input: oklch(0.92 0.004 286.32);\n --ring: oklch(0.705 0.015 286.067);\n --chart-1: oklch(0.879 0.169 91.605);\n --chart-2: oklch(0.769 0.188 70.08);\n --chart-3: oklch(0.666 0.179 58.318);\n --chart-4: oklch(0.555 0.163 48.998);\n --chart-5: oklch(0.473 0.137 46.201);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.141 0.005 285.823);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.21 0.006 285.885);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.21 0.006 285.885);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.92 0.004 286.32);\n --primary-foreground: oklch(0.21 0.006 285.885);\n --secondary: oklch(0.274 0.006 286.033);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.274 0.006 286.033);\n --muted-foreground: oklch(0.705 0.015 286.067);\n --accent: oklch(0.274 0.006 286.033);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.552 0.016 285.938);\n --chart-1: oklch(0.879 0.169 91.605);\n --chart-2: oklch(0.769 0.188 70.08);\n --chart-3: oklch(0.666 0.179 58.318);\n --chart-4: oklch(0.555 0.163 48.998);\n --chart-5: oklch(0.473 0.137 46.201);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
"cssVarsTemplate": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.141 0.005 285.823);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.141 0.005 285.823);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.141 0.005 285.823);\n --primary: oklch(0.21 0.006 285.885);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.967 0.001 286.375);\n --secondary-foreground: oklch(0.21 0.006 285.885);\n --muted: oklch(0.967 0.001 286.375);\n --muted-foreground: oklch(0.552 0.016 285.938);\n --accent: oklch(0.967 0.001 286.375);\n --accent-foreground: oklch(0.21 0.006 285.885);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.92 0.004 286.32);\n --input: oklch(0.92 0.004 286.32);\n --ring: oklch(0.705 0.015 286.067);\n --chart-1: oklch(0.871 0.006 286.286);\n --chart-2: oklch(0.552 0.016 285.938);\n --chart-3: oklch(0.442 0.017 285.786);\n --chart-4: oklch(0.37 0.013 285.805);\n --chart-5: oklch(0.274 0.006 286.033);\n --radius: 0.625rem;\n }\n\n .dark {\n --background: oklch(0.141 0.005 285.823);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.21 0.006 285.885);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.21 0.006 285.885);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.92 0.004 286.32);\n --primary-foreground: oklch(0.21 0.006 285.885);\n --secondary: oklch(0.274 0.006 286.033);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.274 0.006 286.033);\n --muted-foreground: oklch(0.705 0.015 286.067);\n --accent: oklch(0.274 0.006 286.033);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.552 0.016 285.938);\n --chart-1: oklch(0.871 0.006 286.286);\n --chart-2: oklch(0.552 0.016 285.938);\n --chart-3: oklch(0.442 0.017 285.786);\n --chart-4: oklch(0.37 0.013 285.805);\n --chart-5: oklch(0.274 0.006 286.033);\n }\n}\n\n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}"
}

View File

@@ -8,8 +8,10 @@
"style": "vega",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "lucide",
"font": "inter",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -24,8 +26,10 @@
"style": "nova",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "lucide",
"font": "geist",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -40,8 +44,10 @@
"style": "maia",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "hugeicons",
"font": "figtree",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -56,8 +62,10 @@
"style": "lyra",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "phosphor",
"font": "jetbrains-mono",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -72,8 +80,10 @@
"style": "vega",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "lucide",
"font": "inter",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -88,8 +98,10 @@
"style": "nova",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "lucide",
"font": "geist",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -104,8 +116,10 @@
"style": "maia",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "hugeicons",
"font": "figtree",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -120,8 +134,10 @@
"style": "lyra",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "phosphor",
"font": "jetbrains-mono",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -136,8 +152,10 @@
"style": "mira",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "hugeicons",
"font": "inter",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",
@@ -152,8 +170,10 @@
"style": "mira",
"baseColor": "neutral",
"theme": "neutral",
"chartColor": "neutral",
"iconLibrary": "hugeicons",
"font": "inter",
"fontHeading": "inherit",
"item": "Item",
"rtl": false,
"menuAccent": "subtle",

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-lyra/ui/alert.tsx",
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nconst alertVariants = cva(\n \"group/alert relative grid w-full gap-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-xs/relaxed text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-action\"\n className={cn(\n \"absolute top-[calc(--spacing(1.25))] right-[calc(--spacing(1.25))]\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertAction }\n",
"content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nconst alertVariants = cva(\n \"group/alert relative grid w-full gap-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"cn-font-heading font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-xs/relaxed text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-action\"\n className={cn(\n \"absolute top-[calc(--spacing(1.25))] right-[calc(--spacing(1.25))]\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertAction }\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-lyra/ui/card.tsx",
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"group/card flex flex-col gap-4 overflow-hidden rounded-none bg-card py-4 text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"text-sm font-medium group-data-[size=sm]/card:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-xs/relaxed text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center rounded-none border-t p-4 group-data-[size=sm]/card:p-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n",
"content": "import * as React from \"react\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"group/card flex flex-col gap-4 overflow-hidden rounded-none bg-card py-4 text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"cn-font-heading text-sm font-medium group-data-[size=sm]/card:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-xs/relaxed text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center rounded-none border-t p-4 group-data-[size=sm]/card:p-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n",
"type": "registry:ui"
}
],

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@
"files": [
{
"path": "registry/base-lyra/ui/dialog.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { IconPlaceholder } from \"@/app/(create)/components/icon-placeholder\"\n\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: DialogPrimitive.Backdrop.Props) {\n return (\n <DialogPrimitive.Backdrop\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: DialogPrimitive.Popup.Props & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Popup\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-none bg-background p-4 text-xs/relaxed ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n render={\n <Button\n variant=\"ghost\"\n className=\"absolute top-2 right-2\"\n size=\"icon-sm\"\n />\n }\n >\n <IconPlaceholder\n lucide=\"XIcon\"\n tabler=\"IconX\"\n hugeicons=\"Cancel01Icon\"\n phosphor=\"XIcon\"\n remixicon=\"RiCloseLine\"\n />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Popup>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-1 text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close render={<Button variant=\"outline\" />}>\n Close\n </DialogPrimitive.Close>\n )}\n </div>\n )\n}\n\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: DialogPrimitive.Description.Props) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\n \"text-xs/relaxed text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\nimport { Button } from \"@/registry/base-lyra/ui/button\"\nimport { IconPlaceholder } from \"@/app/(create)/components/icon-placeholder\"\n\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: DialogPrimitive.Backdrop.Props) {\n return (\n <DialogPrimitive.Backdrop\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: DialogPrimitive.Popup.Props & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Popup\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-none bg-background p-4 text-xs/relaxed ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n render={\n <Button\n variant=\"ghost\"\n className=\"absolute top-2 right-2\"\n size=\"icon-sm\"\n />\n }\n >\n <IconPlaceholder\n lucide=\"XIcon\"\n tabler=\"IconX\"\n hugeicons=\"Cancel01Icon\"\n phosphor=\"XIcon\"\n remixicon=\"RiCloseLine\"\n />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Popup>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-1 text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close render={<Button variant=\"outline\" />}>\n Close\n </DialogPrimitive.Close>\n )}\n </div>\n )\n}\n\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"cn-font-heading text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: DialogPrimitive.Description.Props) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\n \"text-xs/relaxed text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n",
"type": "registry:ui"
}
],

View File

@@ -7,7 +7,7 @@
"files": [
{
"path": "registry/base-lyra/ui/drawer.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-xs/relaxed data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-none data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-none data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-none data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-none data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-none bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\"text-sm font-medium text-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-xs/relaxed text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-xs/relaxed data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-none data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-none data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-none data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-none data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-none bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\n \"cn-font-heading text-sm font-medium text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-xs/relaxed text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n",
"type": "registry:ui"
}
],

View File

@@ -4,7 +4,7 @@
"files": [
{
"path": "registry/base-lyra/ui/empty.tsx",
"content": "import { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Empty({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty\"\n className={cn(\n \"flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-none border-dashed p-6 text-center text-balance\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn(\"flex max-w-sm flex-col items-center gap-2\", className)}\n {...props}\n />\n )\n}\n\nconst emptyMediaVariants = cva(\n \"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"flex size-8 shrink-0 items-center justify-center rounded-none bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction EmptyMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof emptyMediaVariants>) {\n return (\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(emptyMediaVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <div\n data-slot=\"empty-description\"\n className={cn(\n \"text-xs/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(\n \"flex w-full max-w-sm min-w-0 flex-col items-center gap-2.5 text-xs text-balance\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Empty,\n EmptyHeader,\n EmptyTitle,\n EmptyDescription,\n EmptyContent,\n EmptyMedia,\n}\n",
"content": "import { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/registry/base-lyra/lib/utils\"\n\nfunction Empty({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty\"\n className={cn(\n \"flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-none border-dashed p-6 text-center text-balance\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn(\"flex max-w-sm flex-col items-center gap-2\", className)}\n {...props}\n />\n )\n}\n\nconst emptyMediaVariants = cva(\n \"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"flex size-8 shrink-0 items-center justify-center rounded-none bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction EmptyMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof emptyMediaVariants>) {\n return (\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(emptyMediaVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn(\"cn-font-heading text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <div\n data-slot=\"empty-description\"\n className={cn(\n \"text-xs/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(\n \"flex w-full max-w-sm min-w-0 flex-col items-center gap-2.5 text-xs text-balance\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Empty,\n EmptyHeader,\n EmptyTitle,\n EmptyDescription,\n EmptyContent,\n EmptyMedia,\n}\n",
"type": "registry:ui"
}
],

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-dm-sans",
"title": "DM Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'DM Sans Variable', sans-serif",
"provider": "google",
"import": "DM_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/dm-sans"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-figtree",
"title": "Figtree (Heading)",
"type": "registry:font",
"font": {
"family": "'Figtree Variable', sans-serif",
"provider": "google",
"import": "Figtree",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/figtree"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-geist-mono",
"title": "Geist Mono (Heading)",
"type": "registry:font",
"font": {
"family": "'Geist Mono Variable', monospace",
"provider": "google",
"import": "Geist_Mono",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/geist-mono"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-geist",
"title": "Geist (Heading)",
"type": "registry:font",
"font": {
"family": "'Geist Variable', sans-serif",
"provider": "google",
"import": "Geist",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/geist"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-ibm-plex-sans",
"title": "IBM Plex Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'IBM Plex Sans Variable', sans-serif",
"provider": "google",
"import": "IBM_Plex_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/ibm-plex-sans"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-instrument-sans",
"title": "Instrument Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'Instrument Sans Variable', sans-serif",
"provider": "google",
"import": "Instrument_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/instrument-sans"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-inter",
"title": "Inter (Heading)",
"type": "registry:font",
"font": {
"family": "'Inter Variable', sans-serif",
"provider": "google",
"import": "Inter",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/inter"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-jetbrains-mono",
"title": "JetBrains Mono (Heading)",
"type": "registry:font",
"font": {
"family": "'JetBrains Mono Variable', monospace",
"provider": "google",
"import": "JetBrains_Mono",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/jetbrains-mono"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-lora",
"title": "Lora (Heading)",
"type": "registry:font",
"font": {
"family": "'Lora Variable', serif",
"provider": "google",
"import": "Lora",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/lora"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-manrope",
"title": "Manrope (Heading)",
"type": "registry:font",
"font": {
"family": "'Manrope Variable', sans-serif",
"provider": "google",
"import": "Manrope",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/manrope"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-merriweather",
"title": "Merriweather (Heading)",
"type": "registry:font",
"font": {
"family": "'Merriweather Variable', serif",
"provider": "google",
"import": "Merriweather",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/merriweather"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-montserrat",
"title": "Montserrat (Heading)",
"type": "registry:font",
"font": {
"family": "'Montserrat Variable', sans-serif",
"provider": "google",
"import": "Montserrat",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/montserrat"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-noto-sans",
"title": "Noto Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'Noto Sans Variable', sans-serif",
"provider": "google",
"import": "Noto_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/noto-sans"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-noto-serif",
"title": "Noto Serif (Heading)",
"type": "registry:font",
"font": {
"family": "'Noto Serif Variable', serif",
"provider": "google",
"import": "Noto_Serif",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/noto-serif"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-nunito-sans",
"title": "Nunito Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'Nunito Sans Variable', sans-serif",
"provider": "google",
"import": "Nunito_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/nunito-sans"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-outfit",
"title": "Outfit (Heading)",
"type": "registry:font",
"font": {
"family": "'Outfit Variable', sans-serif",
"provider": "google",
"import": "Outfit",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/outfit"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-oxanium",
"title": "Oxanium (Heading)",
"type": "registry:font",
"font": {
"family": "'Oxanium Variable', sans-serif",
"provider": "google",
"import": "Oxanium",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/oxanium"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-playfair-display",
"title": "Playfair Display (Heading)",
"type": "registry:font",
"font": {
"family": "'Playfair Display Variable', serif",
"provider": "google",
"import": "Playfair_Display",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/playfair-display"
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-heading-public-sans",
"title": "Public Sans (Heading)",
"type": "registry:font",
"font": {
"family": "'Public Sans Variable', sans-serif",
"provider": "google",
"import": "Public_Sans",
"variable": "--font-heading",
"subsets": [
"latin"
],
"dependency": "@fontsource-variable/public-sans"
}
}

Some files were not shown because too many files have changed in this diff Show More