From a9d5ddf43df5d9d4ab1c7febcba6299515815611 Mon Sep 17 00:00:00 2001 From: dvelo <52332868+DeveloLongScript@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:31:59 -0600 Subject: [PATCH] feat: progress (2/19) & clerk themes and extra theming --- apps/www/package.json | 2 + apps/www/postcss.config.mjs | 2 +- apps/www/src/app/(main)/layout.tsx | 62 +++--- apps/www/src/app/globals.css | 172 ++++++++++++++++- apps/www/src/app/layout.tsx | 14 +- apps/www/src/components/feat/embeds/embed.tsx | 4 +- .../feat/settings/browser-settings.tsx | 70 ++++++- .../src/components/feat/settings/setting.tsx | 78 ++++++++ .../src/components/feat/settings/settings.tsx | 6 +- apps/www/src/components/ui/button.tsx | 26 +-- apps/www/src/components/ui/checkbox.tsx | 2 +- apps/www/src/components/ui/context-menu.tsx | 10 +- apps/www/src/components/ui/dialog.tsx | 4 +- apps/www/src/components/ui/dropdown-menu.tsx | 12 +- apps/www/src/components/ui/input.tsx | 6 +- apps/www/src/components/ui/material.tsx | 4 +- apps/www/src/components/ui/radio-group.tsx | 2 +- apps/www/src/components/ui/select.tsx | 8 +- apps/www/src/components/ui/sheet.tsx | 2 +- apps/www/src/components/ui/sidebar.tsx | 44 ++--- apps/www/src/components/ui/switch.tsx | 6 +- apps/www/src/components/ui/tabs.tsx | 4 +- apps/www/src/components/ui/text-area.tsx | 2 +- .../src/components/util/clerk-provider.tsx | 25 +++ .../www/src/components/util/font-boundary.tsx | 47 +++++ apps/www/src/components/util/link.tsx | 1 + apps/www/src/components/util/mode-toggle.tsx | 16 +- .../src/components/util/theme-provider.tsx | 20 +- apps/www/src/lib/hooks/use-settings-store.tsx | 38 ++++ .../www/src/pages/api/v0/account-sl/change.ts | 71 +++---- apps/www/tailwind.config.ts | 153 --------------- yarn.lock | 180 +++++++++++++++++- 32 files changed, 768 insertions(+), 325 deletions(-) create mode 100644 apps/www/src/components/feat/settings/setting.tsx create mode 100644 apps/www/src/components/util/clerk-provider.tsx create mode 100644 apps/www/src/components/util/font-boundary.tsx create mode 100644 apps/www/src/lib/hooks/use-settings-store.tsx delete mode 100644 apps/www/tailwind.config.ts diff --git a/apps/www/package.json b/apps/www/package.json index 8df5147..3bc82a9 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -71,6 +71,7 @@ "sonner": "^1.7.0", "stripe-gradient": "^1.0.1", "tailwind-merge": "^2.3.0", + "tailwindcss": "^4.0.7", "tailwindcss-animate": "^1.0.7", "tailwindcss-patch": "^4.0.0", "turbo": "^2.4.0", @@ -92,6 +93,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.3", + "@tailwindcss/postcss": "^4.0.7", "@tailwindcss/typography": "^0.5.13", "@types/canvas-confetti": "^1.6.4", "@types/node": "^20", diff --git a/apps/www/postcss.config.mjs b/apps/www/postcss.config.mjs index d6a28d6..898209d 100644 --- a/apps/www/postcss.config.mjs +++ b/apps/www/postcss.config.mjs @@ -31,7 +31,7 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - tailwindcss: {}, + '@tailwindcss/postcss': {}, }, }; diff --git a/apps/www/src/app/(main)/layout.tsx b/apps/www/src/app/(main)/layout.tsx index 2eff33f..55c5b88 100644 --- a/apps/www/src/app/(main)/layout.tsx +++ b/apps/www/src/app/(main)/layout.tsx @@ -31,18 +31,16 @@ "use client"; import "../globals.css"; import { useSearchParams } from "next/navigation"; -import { Inter } from "next/font/google"; import { Placeholder } from "@/components/ui/placeholder"; import { X } from "lucide-react"; import { IsScript } from "@/components/util/is-script"; import { Button } from "@/components/ui/button"; -import { ClerkProvider } from "@clerk/nextjs"; import Link from "next/link"; import { NavBar } from "@/components/feat/navbar/navbar"; import { TooltipProvider } from "@/components/ui/tooltip"; import { ThemeProvider } from "@/components/util/theme-provider"; - -const inter = Inter({ subsets: ["latin"] }); +import { FontBoundary } from "@/components/util/font-boundary"; +import { ClerkProvider } from "@/components/util/clerk-provider"; export default function RootLayout({ children, @@ -53,37 +51,37 @@ export default function RootLayout({ const search = searchParams?.get("theme") || "light"; return ( - - - + + + + - - - + +
{children}
-
-
+
+ - - - + + + ); } diff --git a/apps/www/src/app/globals.css b/apps/www/src/app/globals.css index 0fddd1b..9eeab6b 100644 --- a/apps/www/src/app/globals.css +++ b/apps/www/src/app/globals.css @@ -1,9 +1,142 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; -body { - font-family: Arial, Helvetica, sans-serif; +@plugin 'tailwindcss-animate'; + +@custom-variant dark (&:is(.dark *)); + +@theme { + --animate-spin: spin 1s linear infinite; + --animate-scale-in: scaleIn 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); + + --color-border: hsl(var(--border)); + --color-input: hsl(var(--input)); + --color-ring: hsl(var(--ring)); + --color-background: hsl(var(--background)); + --color-foreground: hsl(var(--foreground)); + + --color-shadcn-primary: hsl(var(--primary)); + --color-shadcn-primary-foreground: hsl(var(--primary-foreground)); + + --color-secondary: hsl(var(--secondary)); + --color-secondary-foreground: hsl(var(--secondary-foreground)); + + --color-destructive: hsl(var(--destructive)); + --color-destructive-foreground: hsl(var(--destructive-foreground)); + + --color-muted: hsl(var(--muted)); + --color-muted-foreground: hsl(var(--muted-foreground)); + + --color-accent: hsl(var(--accent)); + --color-accent-foreground: hsl(var(--accent-foreground)); + + --color-popover: hsl(var(--popover)); + --color-popover-foreground: hsl(var(--popover-foreground)); + + --color-card: hsl(var(--card)); + --color-card-foreground: hsl(var(--card-foreground)); + + --color-slate-25: rgb(var(--c-s-25, 252 253 254)); + --color-slate-50: rgb(var(--c-s-50, 248 250 252)); + --color-slate-100: rgb(var(--c-s-100, 241 245 249)); + --color-slate-200: rgb(var(--c-s-200, 226 232 240)); + --color-slate-300: rgb(var(--c-s-300, 203 213 225)); + --color-slate-400: rgb(var(--c-s-400, 148 163 184)); + --color-slate-500: rgb(var(--c-s-500, 100 116 139)); + --color-slate-600: rgb(var(--c-s-600, 71 85 105)); + --color-slate-700: rgb(var(--c-s-700, 51 65 85)); + --color-slate-800: rgb(var(--c-s-800, 30 41 59)); + --color-slate-900: rgb(var(--c-s-900, 15 23 42)); + --color-slate-950: rgb(var(--c-s-950, 2 6 23)); + + --color-zinc-50: rgb(var(--c-z-50, 249 250 251)); + --color-zinc-100: rgb(var(--c-z-100, 243 244 246)); + --color-zinc-200: rgb(var(--c-z-200, 229 231 235)); + --color-zinc-300: rgb(var(--c-z-300, 209 213 219)); + --color-zinc-400: rgb(var(--c-z-400, 156 163 175)); + --color-zinc-500: rgb(var(--c-z-500, 107 114 128)); + --color-zinc-600: rgb(var(--c-z-600, 75 85 99)); + --color-zinc-700: rgb(var(--c-z-700, 50 60 76)); + --color-zinc-800: rgb(var(--c-z-800, 22 31 45)); + --color-zinc-900: rgb(var(--c-z-900, 17 24 39)); + --color-zinc-925: rgb(var(--c-z-925, 8 12 25)); + --color-zinc-950: rgb(var(--c-z-950, 5 9 16)); + + --color-primary-100: rgb(var(--c-p-100, 241 245 249)); + --color-primary-900: rgb(var(--c-p-900, 15 23 42)); + + --color-black: rgb(var(--c-o-black, 0 0 0)); + --color-white: rgb(var(--c-o-white, 255 255 255)); + + --color-sidebar: hsl(var(--sidebar-background)); + --color-sidebar-foreground: hsl(var(--sidebar-foreground)); + --color-sidebar-primary: hsl(var(--sidebar-primary)); + --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground)); + --color-sidebar-accent: hsl(var(--sidebar-accent)); + --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground)); + --color-sidebar-border: hsl(var(--sidebar-border)); + --color-sidebar-ring: hsl(var(--sidebar-ring)); + + --radius-lg: var(--radius); + --radius-md: calc(var(--radius) - 2px); + --radius-sm: calc(var(--radius) - 4px); + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + @keyframes scaleIn { + 0% { + transform: scale(0.95); + opacity: 0; + } + 100% { + transform: scale(1); + opacity: 1; + } + } +} + +/* + The default border color has changed to `currentColor` in Tailwind CSS v4, + so we've added these compatibility styles to make sure everything still + looks the same as it did with Tailwind CSS v3. + + If we ever want to remove these styles, we need to add an explicit border + color utility to any element that depends on these defaults. +*/ +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentColor); + } +} + +@layer utilities { + body { + font-family: Arial, Helvetica, sans-serif; + } +} + +.system-ui-font--font-boundary { + font-family: + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; } @layer base { @@ -93,8 +226,10 @@ body { } } -body { - @apply bg-slate-50 text-slate-900 dark:bg-zinc-950 dark:text-zinc-100 accent-slate-950 dark:accent-zinc-50; +@layer utilities { + body { + @apply bg-slate-50 text-slate-900 dark:bg-zinc-950 dark:text-zinc-100 accent-slate-950 dark:accent-zinc-50; + } } @layer base { @@ -106,6 +241,29 @@ body { } } +.cl-headerTitle { + @apply bg-linear-to-r from-[#3b82f6] to-[#ef4444] bg-clip-text text-transparent; +} + +.cl-socialButtonsBlockButtonText__discord { + @apply text-[#5865f2]; +} + +.cl-socialButtonsBlockButtonText__github { + @apply text-black dark:text-white; +} + +.cl-footer { + background: white !important; + &:is(.dark *) { + background: #1e1e24 !important; + } +} + +.cl-card { + box-shadow: none !important; +} + @layer base { ::view-transition-old(root), ::view-transition-new(root) { diff --git a/apps/www/src/app/layout.tsx b/apps/www/src/app/layout.tsx index 0cb2762..b0d6958 100644 --- a/apps/www/src/app/layout.tsx +++ b/apps/www/src/app/layout.tsx @@ -31,6 +31,8 @@ "use client"; import "./globals.css"; import { useSearchParams } from "next/navigation"; +import { ThemeProvider } from "@/components/util/theme-provider"; +import { ClerkProvider } from "@/components/util/clerk-provider"; import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"] }); @@ -45,7 +47,17 @@ export default function RootLayout({ return ( - {children} + + + + {children} + + ); } diff --git a/apps/www/src/components/feat/embeds/embed.tsx b/apps/www/src/components/feat/embeds/embed.tsx index 3b9e552..89b97d8 100644 --- a/apps/www/src/components/feat/embeds/embed.tsx +++ b/apps/www/src/components/feat/embeds/embed.tsx @@ -90,9 +90,9 @@ export default function Embed({ params }: { params: { server: string } }) { > - + Powered by MHSF diff --git a/apps/www/src/components/feat/settings/browser-settings.tsx b/apps/www/src/components/feat/settings/browser-settings.tsx index 6201b43..60de69a 100644 --- a/apps/www/src/components/feat/settings/browser-settings.tsx +++ b/apps/www/src/components/feat/settings/browser-settings.tsx @@ -1,5 +1,73 @@ import { Material } from "@/components/ui/material"; +import { + Setting, + SettingContent, + SettingDescription, + SettingMeta, + SettingTitle, +} from "./setting"; +import { ModeToggle } from "@/components/util/mode-toggle"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { useEffect, useState } from "react"; +import { useSettingsStore } from "@/lib/hooks/use-settings-store"; export function BrowserSettings() { - return ; + const settingsStore = useSettingsStore(); + const [fontFamily, setFontFamily] = useState("inter"); + + useEffect(() => { + setFontFamily((settingsStore.get("font-family") ?? "inter") as string); + }, [settingsStore]); + + return ( + +

Appearance

+ + + + Color Scheme + + Change the MHSF color scheme + + + + + + + + + Font + + Change the default font used in the interface. + + + + + +
+ ); } diff --git a/apps/www/src/components/feat/settings/setting.tsx b/apps/www/src/components/feat/settings/setting.tsx new file mode 100644 index 0000000..2570d8d --- /dev/null +++ b/apps/www/src/components/feat/settings/setting.tsx @@ -0,0 +1,78 @@ +import { cn } from "@/lib/utils"; +import type { ReactNode } from "react"; + +export function Setting({ + className, + children, +}: { + className?: string; + children: ReactNode | ReactNode[] | undefined; +}) { + return ( +
+ {children} +
+ ); +} + +export function SettingContent({ + className, + children, +}: { + className?: string; + children: ReactNode | ReactNode[] | undefined; +}) { + return ( +
+ {children} +
+ ); +} + +export function SettingMeta({ + className, + children, +}: { + className?: string; + children: ReactNode | ReactNode[] | undefined; +}) { + return ( +
+ {children} +
+ ); +} + +export function SettingTitle({ + className, + children, +}: { + className?: string; + children: ReactNode | ReactNode[] | undefined; +}) { + return

{children}

; +} + +export function SettingDescription({ + className, + children, +}: { + className?: string; + children: ReactNode | ReactNode[] | undefined; +}) { + return ( +

+ {children} +

+ ); +} diff --git a/apps/www/src/components/feat/settings/settings.tsx b/apps/www/src/components/feat/settings/settings.tsx index 89c178e..13fdbac 100644 --- a/apps/www/src/components/feat/settings/settings.tsx +++ b/apps/www/src/components/feat/settings/settings.tsx @@ -16,7 +16,7 @@ export function Settings() {

Settings

- + - +

diff --git a/apps/www/src/components/ui/button.tsx b/apps/www/src/components/ui/button.tsx index f848e61..873c407 100644 --- a/apps/www/src/components/ui/button.tsx +++ b/apps/www/src/components/ui/button.tsx @@ -13,35 +13,35 @@ const buttonVariants = cva( variant: { default: `border border-transparent bg-primary-900 text-white dark:bg-primary-100 dark:text-black hover:brightness-125 dark:hover:brightness-90 active:brightness-90 - active:dark:brightness-75`, + dark:active:brightness-75`, secondary: `border border-slate-200 border-b-slate-300 dark:border-zinc-800 dark:border-t-zinc-700/50 bg-white dark:bg-zinc-900 - hover:bg-slate-100 hover:dark:bg-zinc-800 hover:dark:border-zinc-700 hover:dark:border-zinc-700 active:dark:bg-zinc-900 active:bg-slate-200`, + hover:bg-slate-100 dark:hover:bg-zinc-800 dark:hover:border-zinc-700 dark:hover:border-zinc-700 dark:active:bg-zinc-900 active:bg-slate-200`, tertiary: - "border border-transparent bg-transparent hover:bg-slate-100 hover:dark:bg-zinc-700/30 dark:text-zinc-200", + "border border-transparent bg-transparent hover:bg-slate-100 dark:hover:bg-zinc-700/30 dark:text-zinc-200", danger: "border border-red-500 bg-red-500 hover:text-red-500 hover:bg-transparent text-white", - "danger-subtle": "text-red-500 hover:bg-red-500 hover:!text-inherit", + "danger-subtle": "text-red-500 hover:bg-red-500 hover:text-inherit!", "success-subtle": - "text-green-500 hover:bg-green-500 hover:!text-inherit", + "text-green-500 hover:bg-green-500 hover:text-inherit!", "warning-subtle": - "text-yellow-500 hover:bg-yellow-500 hover:!text-inherit", + "text-yellow-500 hover:bg-yellow-500 hover:text-inherit!", ghost: `border border-slate-200 dark:border-zinc-800 bg-transparent - hover:bg-slate-100 hover:dark:bg-zinc-800 hover:dark:border-zinc-700 dark:text-zinc-400 hover:text-inherit - hover:dark:text-inherit`, + hover:bg-slate-100 dark:hover:bg-zinc-800 dark:hover:border-zinc-700 dark:text-zinc-400 hover:text-inherit + dark:hover:text-inherit`, elevated: `bg-slate-100 dark:bg-zinc-800 border border-slate-200 - dark:border-zinc-700 hover:bg-zinc-200 hover:dark:bg-zinc-700 hover:border-slate-300 - hover:dark:border-zinc-600`, + dark:border-zinc-700 hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:border-slate-300 + dark:hover:border-zinc-600`, elevatedLow: `bg-slate-100 dark:bg-zinc-900 border border-slate-200 - dark:border-zinc-800 hover:bg-slate-200 hover:dark:bg-zinc-800 hover:border-slate-300 - hover:dark:border-zinc-700`, + dark:border-zinc-800 hover:bg-slate-200 dark:hover:bg-zinc-800 hover:border-slate-300 + dark:hover:border-zinc-700`, none: "", }, @@ -63,7 +63,7 @@ const buttonVariants = cva( right: "justify-end text-right origin-right", }, shadow: { - sm: "shadow-sm", + sm: "shadow-xs", none: "shadow-none", }, rounding: { diff --git a/apps/www/src/components/ui/checkbox.tsx b/apps/www/src/components/ui/checkbox.tsx index f678b95..9d31e01 100644 --- a/apps/www/src/components/ui/checkbox.tsx +++ b/apps/www/src/components/ui/checkbox.tsx @@ -13,7 +13,7 @@ const Checkbox = React.forwardRef<
{props.children}
-
+
)); DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; diff --git a/apps/www/src/components/ui/input.tsx b/apps/www/src/components/ui/input.tsx index 3cf7698..93975ab 100644 --- a/apps/www/src/components/ui/input.tsx +++ b/apps/www/src/components/ui/input.tsx @@ -14,7 +14,7 @@ const sizeClass = { }; const shadowClass = { - sm: "shadow-sm", + sm: "shadow-xs", none: "shadow-none", }; @@ -63,7 +63,7 @@ const Input: React.FC = ({ )}
{prefix && (
= ({ disabled={disabled} value={value} onChange={onChange} - className={`${sizeClass[size]} bg-white dark:bg-zinc-950 focus:outline-none rounded-lg text-sm w-full disabled:bg-slate-100 disabled:cursor-not-allowed invalid:!border-red-500 peer invalid:text-red-500 z-10 ${className}`} + className={`${sizeClass[size]} bg-white dark:bg-zinc-950 focus:outline-hidden rounded-lg text-sm w-full disabled:bg-slate-100 disabled:cursor-not-allowed invalid:border-red-500! peer invalid:text-red-500 z-10 ${className}`} /> {suffix && (
- + Close diff --git a/apps/www/src/components/ui/sidebar.tsx b/apps/www/src/components/ui/sidebar.tsx index 5e9f37b..0c7a091 100644 --- a/apps/www/src/components/ui/sidebar.tsx +++ b/apps/www/src/components/ui/sidebar.tsx @@ -141,7 +141,7 @@ const SidebarProvider = React.forwardRef< } as React.CSSProperties } className={cn( - "group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar", + "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className )} ref={ref} @@ -181,7 +181,7 @@ const Sidebar = React.forwardRef< return (
{restProps.children} diff --git a/apps/www/src/components/util/clerk-provider.tsx b/apps/www/src/components/util/clerk-provider.tsx new file mode 100644 index 0000000..0b9b67a --- /dev/null +++ b/apps/www/src/components/util/clerk-provider.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { ClerkProvider as ImportedClerkProvider } from "@clerk/nextjs"; +import { dark } from "@clerk/themes"; +import { useTheme } from "next-themes"; +import { MultisessionAppSupport } from "@clerk/nextjs/internal"; + +export const ClerkProvider = ({ children }: { children: React.ReactNode }) => { + const { resolvedTheme } = useTheme(); + if (resolvedTheme === "dark") { + console.log(resolvedTheme); + return ( + + {children} + + ); + } + console.log("a"); + + return ( + + {children} + + ); +}; diff --git a/apps/www/src/components/util/font-boundary.tsx b/apps/www/src/components/util/font-boundary.tsx new file mode 100644 index 0000000..265a7de --- /dev/null +++ b/apps/www/src/components/util/font-boundary.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useSettingsStore } from "@/lib/hooks/use-settings-store"; +import { Inter, Roboto } from "next/font/google"; +import { useEffect, useState, type ReactNode } from "react"; +import { GeistSans } from "geist/font/sans"; + +const inter = Inter({ subsets: ["latin"] }); +const roboto = Roboto({ + subsets: ["latin"], + weight: ["100", "300", "400", "500", "700", "900"], +}); + +export function FontBoundary({ + children, +}: { + children?: ReactNode | ReactNode[]; +}) { + const settingsStore = useSettingsStore(); + const [fontFamily, setFontFamily] = useState("inter"); + + useEffect(() => { + setFontFamily((settingsStore.get("font-family") ?? "inter") as string); + window.addEventListener("font-family-change", () => { + setFontFamily((settingsStore.get("font-family") ?? "inter") as string); + }); + }, [settingsStore]); + + return ( + { + switch (fontFamily) { + case "geist-sans": + return GeistSans.className; + case "roboto": + return roboto.className; + case "inter": + return inter.className; + default: + return "system-ui-font--font-boundary"; + } + })()}`} + > + {children} + + ); +} diff --git a/apps/www/src/components/util/link.tsx b/apps/www/src/components/util/link.tsx index 6e8721c..bf0ebf3 100644 --- a/apps/www/src/components/util/link.tsx +++ b/apps/www/src/components/util/link.tsx @@ -4,6 +4,7 @@ import { Book, ExternalLink, NotebookText } from "lucide-react"; export function Link( props: LinkProps & { children?: React.ReactNode; + className?: string; } ) { const href = props.href as string; diff --git a/apps/www/src/components/util/mode-toggle.tsx b/apps/www/src/components/util/mode-toggle.tsx index c7eee35..7629521 100644 --- a/apps/www/src/components/util/mode-toggle.tsx +++ b/apps/www/src/components/util/mode-toggle.tsx @@ -11,19 +11,17 @@ import { } from "../ui/dropdown-menu"; export function ModeToggle() { - const { setTheme } = useTheme(); + const { setTheme, resolvedTheme } = useTheme(); return ( - diff --git a/apps/www/src/components/util/theme-provider.tsx b/apps/www/src/components/util/theme-provider.tsx index 8bf430b..f3ce3bf 100644 --- a/apps/www/src/components/util/theme-provider.tsx +++ b/apps/www/src/components/util/theme-provider.tsx @@ -1,11 +1,17 @@ "use client"; -import type * as React from "react"; -import { ThemeProvider as NextThemesProvider } from "next-themes"; +import * as React from "react"; +import { ThemeProvider as NextThemeProvider } from "next-themes"; +import type { ThemeProviderProps } from "next-themes"; -export function ThemeProvider({ - children, - ...props -}: React.ComponentProps) { - return {children}; +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + const [mounted, setMounted] = React.useState(false); + + React.useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return null; + + return {children}; } diff --git a/apps/www/src/lib/hooks/use-settings-store.tsx b/apps/www/src/lib/hooks/use-settings-store.tsx new file mode 100644 index 0000000..b4df1af --- /dev/null +++ b/apps/www/src/lib/hooks/use-settings-store.tsx @@ -0,0 +1,38 @@ +import { useUser } from "@clerk/nextjs"; + +export function useSettingsStore() { + const { isSignedIn, user } = useUser(); + + /* Get: (key: string) => + check if the user is signed in, if so, check user storage & grab entry + if not or if the entry couldn't be found, check browser storage + Set: (key: string, value: string, userEntry: boolean) => + if user signed in & userEntry === true, send to user storage + if user signed out & userEntry === true, do nothing + if userEntry === false, send to browser + */ + + return { + get: (key: string) => { + if (isSignedIn) { + const value = user.publicMetadata[key] as string | boolean; + + if (value === undefined) return localStorage.getItem(key); + return value; + } + return localStorage.getItem(key); + }, + set: async (key: string, value: string, userEntry: boolean) => { + if (isSignedIn && userEntry === true) { + await fetch("/api/v0/account-sl/change", { + body: JSON.stringify({ [key]: value }), + }); + } + if (!isSignedIn && userEntry) + throw new Error("How is this even possible?!?!"); + if (userEntry === false) { + localStorage.setItem(key, value); + } + }, + }; +} diff --git a/apps/www/src/pages/api/v0/account-sl/change.ts b/apps/www/src/pages/api/v0/account-sl/change.ts index 9a2611f..c37e5b8 100644 --- a/apps/www/src/pages/api/v0/account-sl/change.ts +++ b/apps/www/src/pages/api/v0/account-sl/change.ts @@ -30,52 +30,41 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { clerkClient, getAuth } from "@clerk/nextjs/server"; +import z from "zod"; + +const obj = z.object({ + // Use padding on the sides of only the servers, not the whole server list + srv: z.boolean(), + // Items per row (4-6 rows) + ipr: z.number().min(4).max(6), + // Padding of server list (0-120px) + pad: z.number().min(0).max(120), +}); export default async function handler( - req: NextApiRequest, - res: NextApiResponse + req: NextApiRequest, + res: NextApiResponse, ) { - const { userId } = getAuth(req); + const { userId } = getAuth(req); - if (!userId) { - return res.status(401).json({ error: "Unauthorized" }); - } - const { data } = req.body; + if (!userId) { + return res.status(401).json({ error: "Unauthorized" }); + } + const { data } = req.body; - if (data === undefined) { - res.status(400).send({ message: "Couldn't find data" }); - return; - } - const { type } = req.body; + if (data === undefined) { + res.status(400).send({ message: "Couldn't find data" }); + return; + } - if (type === undefined) { - res.status(400).send({ message: "Couldn't find data" }); - return; - } - if (data === null) { - await ( - await clerkClient() - ).users.updateUserMetadata(userId, { - publicMetadata: { [type]: null }, - }); - res.status(200).send({ message: "Success" }); - } - if (type !== "srv" && type !== "ipr" && type !== "pad") - return res.status(400).send({ message: "Couldn't find data" }); + const v = obj.parse(data); + for (const [key, value] of Object.entries(v)) { + (await clerkClient()).users.updateUserMetadata(userId, { + publicMetadata: { + [key]: typeof value === "number" ? value.toString() : value, + }, + }); + } - if (type === "srv" && typeof data !== "boolean") - return res.status(400).send({ message: "Couldn't find data" }); - - if (type === "ipr" && typeof data !== "number") - return res.status(400).send({ message: "Couldn't find data" }); - - if (type === "pad" && typeof data !== "number") - return res.status(400).send({ message: "Couldn't find data" }); - - (await clerkClient()).users.updateUserMetadata(userId, { - publicMetadata: { - [type]: typeof data === "number" ? data.toString() : data, - }, - }); - res.status(200).send({ message: "Success" }); + res.status(200).send({ message: "Success" }); } diff --git a/apps/www/tailwind.config.ts b/apps/www/tailwind.config.ts deleted file mode 100644 index e73e5e7..0000000 --- a/apps/www/tailwind.config.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * MHSF, Minehut Server List - * All external content is rather licensed under the ECA Agreement - * located here: https://mhsf.app/docs/legal/external-content-agreement - * - * All code under MHSF is licensed under the MIT License - * by open source contributors - * - * Copyright (c) 2025 dvelo - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -import type { Config } from "tailwindcss"; - -export default { - darkMode: ["class"], - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - keyframes: { - spin: { - "0%": { - transform: "rotate(0deg)", - }, - "100%": { - transform: "rotate(360deg)", - }, - }, - scaleIn: { - "0%": { - transform: "scale(0.95)", - opacity: "0", - }, - "100%": { - transform: "scale(1)", - opacity: "1", - }, - }, - }, - animation: { - spin: "spin 1s linear infinite", - "scale-in": "scaleIn 0.2s cubic-bezier(0.34, 1.56, 0.64, 1)", - }, - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - "shadcn-primary": { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - slate: { - "25": "rgb(var(--c-s-25,252 253 254) / )", - "50": "rgb(var(--c-s-50,248 250 252) / )", - "100": "rgb(var(--c-s-100,241 245 249) / )", - "200": "rgb(var(--c-s-200,226 232 240) / )", - "300": "rgb(var(--c-s-300,203 213 225) / )", - "400": "rgb(var(--c-s-400,148 163 184) / )", - "500": "rgb(var(--c-s-500,100 116 139) / )", - "600": "rgb(var(--c-s-600,71 85 105) / )", - "700": "rgb(var(--c-s-700,51 65 85) / )", - "800": "rgb(var(--c-s-800,30 41 59) / )", - "900": "rgb(var(--c-s-900,15 23 42) / )", - "950": "rgb(var(--c-s-950,2 6 23) / )", - }, - zinc: { - "50": "rgb(var(--c-z-50,249 250 251) / )", - "100": "rgb(var(--c-z-100,243 244 246) / )", - "200": "rgb(var(--c-z-200,229 231 235) / )", - "300": "rgb(var(--c-z-300,209 213 219) / )", - "400": "rgb(var(--c-z-400,156 163 175) / )", - "500": "rgb(var(--c-z-500,107 114 128) / )", - "600": "rgb(var(--c-z-600,75 85 99) / )", - "700": "rgb(var(--c-z-700,50 60 76) / )", - "800": "rgb(var(--c-z-800,22 31 45) / )", - "900": "rgb(var(--c-z-900,17 24 39) / )", - "925": "rgb(var(--c-z-925,8 12 25) / )", - "950": "rgb(var(--c-z-950,5 9 16) / )", - }, - primary: { - "100": "rgb(var(--c-p-100,241 245 249) / )", - "900": "rgb(var(--c-p-900,15 23 42) / )", - }, - black: "rgb(var(--c-o-black,0 0 0) / )", - white: "rgb(var(--c-o-white,255 255 255) / )", - sidebar: { - DEFAULT: "hsl(var(--sidebar-background))", - foreground: "hsl(var(--sidebar-foreground))", - primary: "hsl(var(--sidebar-primary))", - "primary-foreground": "hsl(var(--sidebar-primary-foreground))", - accent: "hsl(var(--sidebar-accent))", - "accent-foreground": "hsl(var(--sidebar-accent-foreground))", - border: "hsl(var(--sidebar-border))", - ring: "hsl(var(--sidebar-ring))", - }, - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - }, - }, - plugins: [require("tailwindcss-animate")], -} satisfies Config; diff --git a/yarn.lock b/yarn.lock index 500da7c..818e31f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2588,6 +2588,99 @@ resolved "https://registry.yarnpkg.com/@tailwindcss-mangle/shared/-/shared-3.0.0.tgz#8a60fa4168da0069c62fba75f212864ac796c54b" integrity sha512-h1ateiRm/o0JvRsD5755dyS4H1RPE5sgeyEAOorLGVkGvNawkACtM+0MsiD/ZFNgrfQ7aYDD+DF/dV/8LN5Lmw== +"@tailwindcss/node@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/node/-/node-4.0.7.tgz#11211457bbe83ff3656c74bf0276e27e9ce87410" + integrity sha512-dkFXufkbRB2mu3FPsW5xLAUWJyexpJA+/VtQj18k3SUiJVLdpgzBd1v1gRRcIpEJj7K5KpxBKfOXlZxT3ZZRuA== + dependencies: + enhanced-resolve "^5.18.1" + jiti "^2.4.2" + tailwindcss "4.0.7" + +"@tailwindcss/oxide-android-arm64@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.7.tgz#a0864f4831a4eca1a92207fd5ae726343fbb0554" + integrity sha512-5iQXXcAeOHBZy8ASfHFm1k0O/9wR2E3tKh6+P+ilZZbQiMgu+qrnfpBWYPc3FPuQdWiWb73069WT5D+CAfx/tg== + +"@tailwindcss/oxide-darwin-arm64@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.7.tgz#a25e3831cfb0a9ab5b77ada620b8c714e0f41eab" + integrity sha512-7yGZtEc5IgVYylqK/2B0yVqoofk4UAbkn1ygNpIJZyrOhbymsfr8uUFCueTu2fUxmAYIfMZ8waWo2dLg/NgLgg== + +"@tailwindcss/oxide-darwin-x64@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.7.tgz#1dae8648aa03c9783cd01cfd1249c781aaa49dd1" + integrity sha512-tPQDV20fBjb26yWbPqT1ZSoDChomMCiXTKn4jupMSoMCFyU7+OJvIY1ryjqBuY622dEBJ8LnCDDWsnj1lX9nNQ== + +"@tailwindcss/oxide-freebsd-x64@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.7.tgz#904aaa135e5a2500faf729290b12133f15273500" + integrity sha512-sZqJpTyTZiknU9LLHuByg5GKTW+u3FqM7q7myequAXxKOpAFiOfXpY710FuMY+gjzSapyRbDXJlsTQtCyiTo5w== + +"@tailwindcss/oxide-linux-arm-gnueabihf@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.7.tgz#27b6483303218f545a971ec68f468417cab1f6be" + integrity sha512-PBgvULgeSswjd8cbZ91gdIcIDMdc3TUHV5XemEpxlqt9M8KoydJzkuB/Dt910jYdofOIaTWRL6adG9nJICvU4A== + +"@tailwindcss/oxide-linux-arm64-gnu@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.7.tgz#98126af54ff0262756e9a4f730a8b6f6585e13c2" + integrity sha512-By/a2yeh+e9b+C67F88ndSwVJl2A3tcUDb29FbedDi+DZ4Mr07Oqw9Y1DrDrtHIDhIZ3bmmiL1dkH2YxrtV+zw== + +"@tailwindcss/oxide-linux-arm64-musl@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.7.tgz#55f0183a8521473cab1ca0414b57079efc145952" + integrity sha512-WHYs3cpPEJb/ccyT20NOzopYQkl7JKncNBUbb77YFlwlXMVJLLV3nrXQKhr7DmZxz2ZXqjyUwsj2rdzd9stYdw== + +"@tailwindcss/oxide-linux-x64-gnu@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.7.tgz#053b019201892b339c0d975092bfc8024be54226" + integrity sha512-7bP1UyuX9kFxbOwkeIJhBZNevKYPXB6xZI37v09fqi6rqRJR8elybwjMUHm54GVP+UTtJ14ueB1K54Dy1tIO6w== + +"@tailwindcss/oxide-linux-x64-musl@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.7.tgz#c4d753acf3d6ef617e91b53880b7c1b966677ca6" + integrity sha512-gBQIV8nL/LuhARNGeroqzXymMzzW5wQzqlteVqOVoqwEfpHOP3GMird5pGFbnpY+NP0fOlsZGrxxOPQ4W/84bQ== + +"@tailwindcss/oxide-win32-arm64-msvc@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.7.tgz#cceea5857939092d5149e6afc8da1b8d3a7464b2" + integrity sha512-aH530NFfx0kpQpvYMfWoeG03zGnRCMVlQG8do/5XeahYydz+6SIBxA1tl/cyITSJyWZHyVt6GVNkXeAD30v0Xg== + +"@tailwindcss/oxide-win32-x64-msvc@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.7.tgz#500cf333326a45078ca5b0fd68b56b1f0b434bfa" + integrity sha512-8Cva6bbJN7ZJx320k7vxGGdU0ewmpfS5A4PudyzUuofdi8MgeINuiiWiPQ0VZCda/GX88K6qp+6UpDZNVr8HMQ== + +"@tailwindcss/oxide@4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide/-/oxide-4.0.7.tgz#b53573fc01b8b61af195ad36957d05c78278761d" + integrity sha512-yr6w5YMgjy+B+zkJiJtIYGXW+HNYOPfRPtSs+aqLnKwdEzNrGv4ZuJh9hYJ3mcA+HMq/K1rtFV+KsEr65S558g== + optionalDependencies: + "@tailwindcss/oxide-android-arm64" "4.0.7" + "@tailwindcss/oxide-darwin-arm64" "4.0.7" + "@tailwindcss/oxide-darwin-x64" "4.0.7" + "@tailwindcss/oxide-freebsd-x64" "4.0.7" + "@tailwindcss/oxide-linux-arm-gnueabihf" "4.0.7" + "@tailwindcss/oxide-linux-arm64-gnu" "4.0.7" + "@tailwindcss/oxide-linux-arm64-musl" "4.0.7" + "@tailwindcss/oxide-linux-x64-gnu" "4.0.7" + "@tailwindcss/oxide-linux-x64-musl" "4.0.7" + "@tailwindcss/oxide-win32-arm64-msvc" "4.0.7" + "@tailwindcss/oxide-win32-x64-msvc" "4.0.7" + +"@tailwindcss/postcss@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/postcss/-/postcss-4.0.7.tgz#b8bc02b5e23248ac7cbac1970ed807850e03261c" + integrity sha512-zXcKs1uGssVDlnsQ+iwrkul5GPKvsXPynGCuk/eXLx3DVhHlQKMpA6tXN2oO28x2ki1xRBTfadKiHy2taVvp7g== + dependencies: + "@alloc/quick-lru" "^5.2.0" + "@tailwindcss/node" "4.0.7" + "@tailwindcss/oxide" "4.0.7" + lightningcss "^1.29.1" + postcss "^8.4.41" + tailwindcss "4.0.7" + "@tailwindcss/typography@^0.5.13": version "0.5.16" resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.16.tgz#a926c8f44d5c439b2915e231cad80058850047c6" @@ -4130,6 +4223,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + detect-libc@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" @@ -4326,7 +4424,7 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.15.0: +enhanced-resolve@^5.15.0, enhanced-resolve@^5.18.1: version "5.18.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== @@ -6119,6 +6217,11 @@ jiti@^1.18.2, jiti@^1.21.6: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== +jiti@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560" + integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== + js-cookie@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" @@ -6275,6 +6378,74 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lightningcss-darwin-arm64@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz#dce17349c7b9f968f396ec240503de14e7b4870b" + integrity sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw== + +lightningcss-darwin-x64@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz#e79c984180c57d00ee114210ceced83473d72dfc" + integrity sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA== + +lightningcss-freebsd-x64@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz#4b3aec9620684a60c45266d50fd843869320f42f" + integrity sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ== + +lightningcss-linux-arm-gnueabihf@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz#b80e9c4dd75652bec451ffd4d5779492a01791ff" + integrity sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg== + +lightningcss-linux-arm64-gnu@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz#7825eb119ddf580a4a4f011c6f384a3f9c992060" + integrity sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ== + +lightningcss-linux-arm64-musl@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz#389efccf80088dce2bb00e28bd7d1cfe36a71669" + integrity sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw== + +lightningcss-linux-x64-gnu@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz#98fc5df5e39ac8ddc51e51f785849eb21131f789" + integrity sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw== + +lightningcss-linux-x64-musl@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz#fb4f80895ba7dfa8048ee32e9716a1684fefd6b2" + integrity sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw== + +lightningcss-win32-arm64-msvc@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz#fd4409fd1505d89d0ff66511c36df5a1379eb7cd" + integrity sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog== + +lightningcss-win32-x64-msvc@1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz#54dcd52884f6cbf205a53d49239559603f194927" + integrity sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q== + +lightningcss@^1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.29.1.tgz#1d4d62332fc5ba4b6c28e04a8c5638c76019702b" + integrity sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q== + dependencies: + detect-libc "^1.0.3" + optionalDependencies: + lightningcss-darwin-arm64 "1.29.1" + lightningcss-darwin-x64 "1.29.1" + lightningcss-freebsd-x64 "1.29.1" + lightningcss-linux-arm-gnueabihf "1.29.1" + lightningcss-linux-arm64-gnu "1.29.1" + lightningcss-linux-arm64-musl "1.29.1" + lightningcss-linux-x64-gnu "1.29.1" + lightningcss-linux-x64-musl "1.29.1" + lightningcss-win32-arm64-msvc "1.29.1" + lightningcss-win32-x64-msvc "1.29.1" + lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -8056,7 +8227,7 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8, postcss@^8.4.23, postcss@^8.4.38, postcss@^8.4.39, postcss@^8.4.40, postcss@^8.4.47: +postcss@^8, postcss@^8.4.23, postcss@^8.4.38, postcss@^8.4.39, postcss@^8.4.40, postcss@^8.4.41, postcss@^8.4.47: version "8.5.2" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.2.tgz#e7b99cb9d2ec3e8dd424002e7c16517cb2b846bd" integrity sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA== @@ -9240,6 +9411,11 @@ tailwindcss@3.3.2: resolve "^1.22.2" sucrase "^3.32.0" +tailwindcss@4.0.7, tailwindcss@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.0.7.tgz#b3e26a5dda77651808a873f1b535cc8c39fcb0ae" + integrity sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA== + tailwindcss@^3.4.1: version "3.4.17" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.17.tgz#ae8406c0f96696a631c790768ff319d46d5e5a63"