diff --git a/apps/v4/app/(app)/themes/layout.tsx b/apps/v4/app/(app)/themes/layout.tsx new file mode 100644 index 0000000000..15d1bf2467 --- /dev/null +++ b/apps/v4/app/(app)/themes/layout.tsx @@ -0,0 +1,64 @@ +import { Metadata } from "next" +import Link from "next/link" + +import { Announcement } from "@/components/announcement" +import { + PageActions, + PageHeader, + PageHeaderDescription, + PageHeaderHeading, +} from "@/components/page-header" +import { Button } from "@/registry/new-york-v4/ui/button" + +const title = "Pick a Color. Make it yours." +const description = + "Try our hand-picked themes. Copy and paste them into your project. New theme editor coming soon." + +export const metadata: Metadata = { + title, + description, + openGraph: { + images: [ + { + url: `/og?title=${encodeURIComponent( + title + )}&description=${encodeURIComponent(description)}`, + }, + ], + }, + twitter: { + card: "summary_large_image", + images: [ + { + url: `/og?title=${encodeURIComponent( + title + )}&description=${encodeURIComponent(description)}`, + }, + ], + }, +} + +export default function ThemesLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( +
+ + + {title} + {description} + + + + + + {children} +
+ ) +} diff --git a/apps/v4/app/(app)/themes/page.tsx b/apps/v4/app/(app)/themes/page.tsx new file mode 100644 index 0000000000..927462f41a --- /dev/null +++ b/apps/v4/app/(app)/themes/page.tsx @@ -0,0 +1,19 @@ +import { CardsDemo } from "@/components/cards" +import { ThemeCustomizer } from "@/components/theme-customizer" + +export default function ThemesPage() { + return ( + <> +
+
+ +
+
+
+
+ +
+
+ + ) +} diff --git a/apps/v4/components/cards/calendar.tsx b/apps/v4/components/cards/calendar.tsx index f3253fbb25..7e21c2432d 100644 --- a/apps/v4/components/cards/calendar.tsx +++ b/apps/v4/components/cards/calendar.tsx @@ -9,7 +9,7 @@ const start = new Date(2025, 5, 5) export function CardsCalendar() { return ( - + + dark: Record +} + +const THEMES = baseColors.filter( + (theme) => !["slate", "stone", "gray", "zinc"].includes(theme.name) +) + +export function ThemeCustomizer({ className }: React.ComponentProps<"div">) { + const { activeTheme = "neutral", setActiveTheme } = useThemeConfig() + + return ( +
+ +
+ {THEMES.map((theme) => ( + + ))} +
+ +
+
+ + +
+ +
+ ) +} + +export function CopyCodeButton({ + className, + ...props +}: React.ComponentProps) { + let { activeTheme: activeThemeName = "neutral" } = useThemeConfig() + activeThemeName = activeThemeName === "default" ? "neutral" : activeThemeName + + return ( + <> + + + + + + + + {activeThemeName === "neutral" ? "Default" : activeThemeName} + + + Copy and paste the following code into your CSS file. + + + + + + + + + + + + + {activeThemeName === "neutral" ? "Default" : activeThemeName} + + + Copy and paste the following code into your CSS file. + + + + + + + ) +} + +function CustomizerCode({ themeName }: { themeName: string }) { + const [hasCopied, setHasCopied] = React.useState(false) + const [tailwindVersion, setTailwindVersion] = React.useState("v4") + const activeTheme = React.useMemo( + () => baseColors.find((theme) => theme.name === themeName), + [themeName] + ) + const activeThemeOKLCH = React.useMemo( + () => baseColorsOKLCH[themeName as keyof typeof baseColorsOKLCH], + [themeName] + ) + + React.useEffect(() => { + if (hasCopied) { + setTimeout(() => { + setHasCopied(false) + }, 2000) + } + }, [hasCopied]) + + return ( + <> + + + Tailwind v4 + Tailwind v3 + + +
+
+ + app/globals.css +
+
+              
+              
+                
+                   :root {
+                
+                
+                     --radius: 0.65rem;
+                
+                {Object.entries(activeThemeOKLCH?.light).map(([key, value]) => (
+                  
+                       --{key}: {value};
+                  
+                ))}
+                
+                   }
+                
+                
+                   
+                
+                
+                   .dark {
+                
+                {Object.entries(activeThemeOKLCH?.dark).map(([key, value]) => (
+                  
+                       --{key}: {value};
+                  
+                ))}
+                
+                   }
+                
+              
+            
+
+
+ +
+
+ + app/globals.css +
+
+              
+              
+                
+                  @layer base {
+                
+                
+                    :root {
+                
+                
+                      --background:{" "}
+                  {activeTheme?.cssVars.light["background"]};
+                
+                
+                      --foreground:{" "}
+                  {activeTheme?.cssVars.light["foreground"]};
+                
+                {[
+                  "card",
+                  "popover",
+                  "primary",
+                  "secondary",
+                  "muted",
+                  "accent",
+                  "destructive",
+                ].map((prefix) => (
+                  
+                    
+                          --{prefix}:{" "}
+                      {
+                        activeTheme?.cssVars.light[
+                          prefix as keyof typeof activeTheme.cssVars.light
+                        ]
+                      }
+                      ;
+                    
+                    
+                          --{prefix}-foreground:{" "}
+                      {
+                        activeTheme?.cssVars.light[
+                          `${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
+                        ]
+                      }
+                      ;
+                    
+                  
+                ))}
+                
+                      --border:{" "}
+                  {activeTheme?.cssVars.light["border"]};
+                
+                
+                      --input:{" "}
+                  {activeTheme?.cssVars.light["input"]};
+                
+                
+                      --ring:{" "}
+                  {activeTheme?.cssVars.light["ring"]};
+                
+                
+                      --radius: 0.5rem;
+                
+                {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
+                  (prefix) => (
+                    
+                      
+                            --{prefix}:{" "}
+                        {
+                          activeTheme?.cssVars.light[
+                            prefix as keyof typeof activeTheme.cssVars.light
+                          ]
+                        }
+                        ;
+                      
+                    
+                  )
+                )}
+                
+                    }
+                
+                
+                   
+                
+                
+                    .dark {
+                
+                
+                      --background:{" "}
+                  {activeTheme?.cssVars.dark["background"]};
+                
+                
+                      --foreground:{" "}
+                  {activeTheme?.cssVars.dark["foreground"]};
+                
+                {[
+                  "card",
+                  "popover",
+                  "primary",
+                  "secondary",
+                  "muted",
+                  "accent",
+                  "destructive",
+                ].map((prefix) => (
+                  
+                    
+                          --{prefix}:{" "}
+                      {
+                        activeTheme?.cssVars.dark[
+                          prefix as keyof typeof activeTheme.cssVars.dark
+                        ]
+                      }
+                      ;
+                    
+                    
+                          --{prefix}-foreground:{" "}
+                      {
+                        activeTheme?.cssVars.dark[
+                          `${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
+                        ]
+                      }
+                      ;
+                    
+                  
+                ))}
+                
+                      --border:{" "}
+                  {activeTheme?.cssVars.dark["border"]};
+                
+                
+                      --input:{" "}
+                  {activeTheme?.cssVars.dark["input"]};
+                
+                
+                      --ring:{" "}
+                  {activeTheme?.cssVars.dark["ring"]};
+                
+                {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
+                  (prefix) => (
+                    
+                      
+                            --{prefix}:{" "}
+                        {
+                          activeTheme?.cssVars.dark[
+                            prefix as keyof typeof activeTheme.cssVars.dark
+                          ]
+                        }
+                        ;
+                      
+                    
+                  )
+                )}
+                
+                    }
+                
+                
+                  }
+                
+              
+            
+
+
+
+ + ) +} + +function getThemeCodeOKLCH(theme: BaseColorOKLCH | undefined, radius: number) { + if (!theme) { + return "" + } + + const rootSection = + ":root {\n --radius: " + + radius + + "rem;\n" + + Object.entries(theme.light) + .map((entry) => " --" + entry[0] + ": " + entry[1] + ";") + .join("\n") + + "\n}\n\n.dark {\n" + + Object.entries(theme.dark) + .map((entry) => " --" + entry[0] + ": " + entry[1] + ";") + .join("\n") + + "\n}\n" + + return rootSection +} + +function getThemeCode(theme: BaseColor | undefined, radius: number) { + if (!theme) { + return "" + } + + return template(BASE_STYLES_WITH_VARIABLES)({ + colors: theme.cssVars, + radius: radius.toString(), + }) +} + +const BASE_STYLES_WITH_VARIABLES = ` +@layer base { + :root { + --background: <%- colors.light["background"] %>; + --foreground: <%- colors.light["foreground"] %>; + --card: <%- colors.light["card"] %>; + --card-foreground: <%- colors.light["card-foreground"] %>; + --popover: <%- colors.light["popover"] %>; + --popover-foreground: <%- colors.light["popover-foreground"] %>; + --primary: <%- colors.light["primary"] %>; + --primary-foreground: <%- colors.light["primary-foreground"] %>; + --secondary: <%- colors.light["secondary"] %>; + --secondary-foreground: <%- colors.light["secondary-foreground"] %>; + --muted: <%- colors.light["muted"] %>; + --muted-foreground: <%- colors.light["muted-foreground"] %>; + --accent: <%- colors.light["accent"] %>; + --accent-foreground: <%- colors.light["accent-foreground"] %>; + --destructive: <%- colors.light["destructive"] %>; + --destructive-foreground: <%- colors.light["destructive-foreground"] %>; + --border: <%- colors.light["border"] %>; + --input: <%- colors.light["input"] %>; + --ring: <%- colors.light["ring"] %>; + --radius: <%- radius %>rem; + --chart-1: <%- colors.light["chart-1"] %>; + --chart-2: <%- colors.light["chart-2"] %>; + --chart-3: <%- colors.light["chart-3"] %>; + --chart-4: <%- colors.light["chart-4"] %>; + --chart-5: <%- colors.light["chart-5"] %>; + } + + .dark { + --background: <%- colors.dark["background"] %>; + --foreground: <%- colors.dark["foreground"] %>; + --card: <%- colors.dark["card"] %>; + --card-foreground: <%- colors.dark["card-foreground"] %>; + --popover: <%- colors.dark["popover"] %>; + --popover-foreground: <%- colors.dark["popover-foreground"] %>; + --primary: <%- colors.dark["primary"] %>; + --primary-foreground: <%- colors.dark["primary-foreground"] %>; + --secondary: <%- colors.dark["secondary"] %>; + --secondary-foreground: <%- colors.dark["secondary-foreground"] %>; + --muted: <%- colors.dark["muted"] %>; + --muted-foreground: <%- colors.dark["muted-foreground"] %>; + --accent: <%- colors.dark["accent"] %>; + --accent-foreground: <%- colors.dark["accent-foreground"] %>; + --destructive: <%- colors.dark["destructive"] %>; + --destructive-foreground: <%- colors.dark["destructive-foreground"] %>; + --border: <%- colors.dark["border"] %>; + --input: <%- colors.dark["input"] %>; + --ring: <%- colors.dark["ring"] %>; + --chart-1: <%- colors.dark["chart-1"] %>; + --chart-2: <%- colors.dark["chart-2"] %>; + --chart-3: <%- colors.dark["chart-3"] %>; + --chart-4: <%- colors.dark["chart-4"] %>; + --chart-5: <%- colors.dark["chart-5"] %>; + } +} +` diff --git a/apps/v4/lib/config.ts b/apps/v4/lib/config.ts index 6a9e9824f4..d1bb96894d 100644 --- a/apps/v4/lib/config.ts +++ b/apps/v4/lib/config.ts @@ -25,6 +25,10 @@ export const siteConfig = { href: "/charts/area", label: "Charts", }, + { + href: "/themes", + label: "Themes", + }, { href: "/colors", label: "Colors", diff --git a/apps/v4/next.config.mjs b/apps/v4/next.config.mjs index c49caccf98..9de11809c1 100644 --- a/apps/v4/next.config.mjs +++ b/apps/v4/next.config.mjs @@ -63,6 +63,11 @@ const nextConfig = { destination: "/charts/area", permanent: true, }, + { + source: "/view/styles/:style/:name", + destination: "/view/:name", + permanent: true, + }, ] }, } diff --git a/apps/v4/package.json b/apps/v4/package.json index e4a6f80bde..27fd91b973 100644 --- a/apps/v4/package.json +++ b/apps/v4/package.json @@ -70,6 +70,7 @@ "fumadocs-ui": "^15.3.1", "input-otp": "^1.4.2", "jotai": "^2.1.0", + "lodash": "^4.17.21", "lucide-react": "0.474.0", "motion": "^12.12.1", "next": "15.3.1", @@ -95,6 +96,7 @@ "@eslint/eslintrc": "^3", "@ianvs/prettier-plugin-sort-imports": "^4.4.1", "@tailwindcss/postcss": "^4", + "@types/lodash": "^4.17.7", "@types/mdx": "^2.0.13", "@types/node": "^20", "@types/react": "19.1.2", diff --git a/apps/v4/registry/registry-base-colors.ts b/apps/v4/registry/registry-base-colors.ts index badbf61fa0..ecaf0af324 100644 --- a/apps/v4/registry/registry-base-colors.ts +++ b/apps/v4/registry/registry-base-colors.ts @@ -1104,6 +1104,144 @@ export const baseColorsV4 = { } as const export const baseColorsOKLCH = { + default: { + light: { + background: "oklch(1 0 0)", // --color-neutral-50 + foreground: "oklch(0.145 0 0)", // --color-neutral-950 + card: "oklch(1 0 0)", // --color-neutral-50 + "card-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + popover: "oklch(1 0 0)", // --color-neutral-50 + "popover-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + primary: "oklch(0.205 0 0)", // --color-neutral-900 + "primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + secondary: "oklch(0.97 0 0)", // --color-neutral-100 + "secondary-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + muted: "oklch(0.97 0 0)", // --color-neutral-100 + "muted-foreground": "oklch(0.556 0 0)", // --color-neutral-500 + accent: "oklch(0.97 0 0)", // --color-neutral-100 + "accent-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 + border: "oklch(0.922 0 0)", // --color-neutral-200 + input: "oklch(0.922 0 0)", // --color-neutral-200 + ring: "oklch(0.708 0 0)", // --color-neutral-400 + "chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 + "chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 + "chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 + "chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 + "chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 + radius: "0.625rem", + sidebar: "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + "sidebar-primary": "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-accent": "oklch(0.97 0 0)", // --color-neutral-100 + "sidebar-accent-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-border": "oklch(0.922 0 0)", // --color-neutral-200 + "sidebar-ring": "oklch(0.708 0 0)", // --color-neutral-400 + }, + dark: { + background: "oklch(0.145 0 0)", // --color-neutral-950 + foreground: "oklch(0.985 0 0)", // --color-neutral-50 + card: "oklch(0.205 0 0)", // --color-neutral-900 + "card-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + popover: "oklch(0.205 0 0)", // --color-neutral-900 + "popover-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + primary: "oklch(0.922 0 0)", // --color-neutral-200 + "primary-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + secondary: "oklch(0.269 0 0)", // --color-neutral-800 + "secondary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + muted: "oklch(0.269 0 0)", // --color-neutral-800 + "muted-foreground": "oklch(0.708 0 0)", // --color-neutral-400 + accent: "oklch(0.269 0 0)", // --color-neutral-800 + "accent-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 + border: "oklch(1 0 0 / 10%)", // --color-white + input: "oklch(1 0 0 / 15%)", // --color-white + ring: "oklch(0.556 0 0)", // --color-neutral-500 + "chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 + "chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 + "chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 + "chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 + "chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 + sidebar: "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-primary": "oklch(0.488 0.243 264.376)", // --color-blue-700 + "sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-accent": "oklch(0.269 0 0)", // --color-neutral-800 + "sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-border": "oklch(1 0 0 / 10%)", // --color-white + "sidebar-ring": "oklch(0.556 0 0)", // --color-neutral-500 + }, + }, + neutral: { + light: { + background: "oklch(1 0 0)", // --color-neutral-50 + foreground: "oklch(0.145 0 0)", // --color-neutral-950 + card: "oklch(1 0 0)", // --color-neutral-50 + "card-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + popover: "oklch(1 0 0)", // --color-neutral-50 + "popover-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + primary: "oklch(0.205 0 0)", // --color-neutral-900 + "primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + secondary: "oklch(0.97 0 0)", // --color-neutral-100 + "secondary-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + muted: "oklch(0.97 0 0)", // --color-neutral-100 + "muted-foreground": "oklch(0.556 0 0)", // --color-neutral-500 + accent: "oklch(0.97 0 0)", // --color-neutral-100 + "accent-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 + border: "oklch(0.922 0 0)", // --color-neutral-200 + input: "oklch(0.922 0 0)", // --color-neutral-200 + ring: "oklch(0.708 0 0)", // --color-neutral-400 + "chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 + "chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 + "chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 + "chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 + "chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 + radius: "0.625rem", + sidebar: "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-foreground": "oklch(0.145 0 0)", // --color-neutral-950 + "sidebar-primary": "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-accent": "oklch(0.97 0 0)", // --color-neutral-100 + "sidebar-accent-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-border": "oklch(0.922 0 0)", // --color-neutral-200 + "sidebar-ring": "oklch(0.708 0 0)", // --color-neutral-400 + }, + dark: { + background: "oklch(0.145 0 0)", // --color-neutral-950 + foreground: "oklch(0.985 0 0)", // --color-neutral-50 + card: "oklch(0.205 0 0)", // --color-neutral-900 + "card-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + popover: "oklch(0.205 0 0)", // --color-neutral-900 + "popover-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + primary: "oklch(0.922 0 0)", // --color-neutral-200 + "primary-foreground": "oklch(0.205 0 0)", // --color-neutral-900 + secondary: "oklch(0.269 0 0)", // --color-neutral-800 + "secondary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + muted: "oklch(0.269 0 0)", // --color-neutral-800 + "muted-foreground": "oklch(0.708 0 0)", // --color-neutral-400 + accent: "oklch(0.269 0 0)", // --color-neutral-800 + "accent-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 + border: "oklch(1 0 0 / 10%)", // --color-white + input: "oklch(1 0 0 / 15%)", // --color-white + ring: "oklch(0.556 0 0)", // --color-neutral-500 + "chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 + "chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 + "chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 + "chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 + "chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 + sidebar: "oklch(0.205 0 0)", // --color-neutral-900 + "sidebar-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-primary": "oklch(0.488 0.243 264.376)", // --color-blue-700 + "sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-accent": "oklch(0.269 0 0)", // --color-neutral-800 + "sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-neutral-50 + "sidebar-border": "oklch(1 0 0 / 10%)", // --color-white + "sidebar-ring": "oklch(0.556 0 0)", // --color-neutral-500 + }, + }, zinc: { light: { background: "oklch(1 0 0)", // --color-zinc-50 diff --git a/apps/v4/styles/themes.css b/apps/v4/styles/themes.css index 31813a65e5..5b4286408b 100644 --- a/apps/v4/styles/themes.css +++ b/apps/v4/styles/themes.css @@ -263,3 +263,72 @@ padding-bottom: 0; } } + +.theme-red .theme-container { + --primary: var(--color-red-600); + --primary-foreground: var(--color-red-50); + --ring: var(--color-red-400); + --chart-1: var(--color-red-300); + --chart-2: var(--color-red-500); + --chart-3: var(--color-red-600); + --chart-4: var(--color-red-700); + --chart-5: var(--color-red-800); + --sidebar-primary: var(--color-red-600); + --sidebar-primary-foreground: var(--color-red-50); + --sidebar-ring: var(--color-red-400); + + @variant dark { + --primary: var(--color-red-500); + --primary-foreground: var(--color-red-50); + --ring: var(--color-red-900); + --sidebar-primary: var(--color-red-500); + --sidebar-primary-foreground: var(--color-red-50); + --sidebar-ring: var(--color-red-900); + } +} + +.theme-yellow .theme-container { + --primary: var(--color-yellow-400); + --primary-foreground: var(--color-yellow-900); + --ring: var(--color-yellow-400); + --chart-1: var(--color-yellow-300); + --chart-2: var(--color-yellow-500); + --chart-3: var(--color-yellow-600); + --chart-4: var(--color-yellow-700); + --chart-5: var(--color-yellow-800); + --sidebar-primary: var(--color-yellow-600); + --sidebar-primary-foreground: var(--color-yellow-50); + --sidebar-ring: var(--color-yellow-400); + + @variant dark { + --primary: var(--color-yellow-500); + --primary-foreground: var(--color-yellow-900); + --ring: var(--color-yellow-900); + --sidebar-primary: var(--color-yellow-500); + --sidebar-primary-foreground: var(--color-yellow-50); + --sidebar-ring: var(--color-yellow-900); + } +} + +.theme-violet .theme-container { + --primary: var(--color-violet-600); + --primary-foreground: var(--color-violet-50); + --ring: var(--color-violet-400); + --chart-1: var(--color-violet-300); + --chart-2: var(--color-violet-500); + --chart-3: var(--color-violet-600); + --chart-4: var(--color-violet-700); + --chart-5: var(--color-violet-800); + --sidebar-primary: var(--color-violet-600); + --sidebar-primary-foreground: var(--color-violet-50); + --sidebar-ring: var(--color-violet-400); + + @variant dark { + --primary: var(--color-violet-500); + --primary-foreground: var(--color-violet-50); + --ring: var(--color-violet-900); + --sidebar-primary: var(--color-violet-500); + --sidebar-primary-foreground: var(--color-violet-50); + --sidebar-ring: var(--color-violet-900); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e7cf7f683..ec7400682b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -273,6 +273,9 @@ importers: jotai: specifier: ^2.1.0 version: 2.11.3(@types/react@19.1.2)(react@19.1.0) + lodash: + specifier: ^4.17.21 + version: 4.17.21 lucide-react: specifier: 0.474.0 version: 0.474.0(react@19.1.0) @@ -340,6 +343,9 @@ importers: '@ianvs/prettier-plugin-sort-imports': specifier: ^4.4.1 version: 4.4.2(prettier@3.4.2) + '@types/lodash': + specifier: ^4.17.7 + version: 4.17.15 '@types/mdx': specifier: ^2.0.13 version: 2.0.13