diff --git a/web/src/app/globals.css b/web/src/app/globals.css
index 1baebcda..85d69a3f 100644
--- a/web/src/app/globals.css
+++ b/web/src/app/globals.css
@@ -64,7 +64,7 @@
}
:root {
- --radius: 0.3rem;
+ --radius: 0.75rem;
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
@@ -140,3 +140,21 @@
@apply bg-background text-foreground;
}
}
+
+@layer utilities {
+ .hover-lift {
+ @apply transition-transform duration-300 hover:-translate-y-1;
+ }
+
+ .soft-shadow {
+ @apply shadow-[0_8px_30px_rgba(0,0,0,0.06)];
+ }
+
+ .card-hover {
+ @apply transition-all duration-300 hover:shadow-md;
+ }
+
+ .glass-effect {
+ @apply backdrop-blur-sm;
+ }
+}
diff --git a/web/src/app/icons/components.tsx b/web/src/app/icons/components.tsx
index 19773e1f..4212afa1 100644
--- a/web/src/app/icons/components.tsx
+++ b/web/src/app/icons/components.tsx
@@ -46,11 +46,11 @@ export function IconSearch({ icons, initialQuery = "" }: IconSearchProps) {
return (
<>
-
+
handleSearch(e.target.value)}
/>
diff --git a/web/src/app/icons/components/icon-search.tsx b/web/src/app/icons/components/icon-search.tsx
index 3a20419d..c3722d67 100644
--- a/web/src/app/icons/components/icon-search.tsx
+++ b/web/src/app/icons/components/icon-search.tsx
@@ -109,11 +109,11 @@ export function IconSearch({ icons }: IconSearchProps) {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
-
+
handleSearch(e.target.value)}
/>
diff --git a/web/src/components/hero.tsx b/web/src/components/hero.tsx
index 4020f2da..b337d59c 100644
--- a/web/src/components/hero.tsx
+++ b/web/src/components/hero.tsx
@@ -16,7 +16,7 @@ interface IconCardProps {
function IconCard({ name, imageUrl }: IconCardProps) {
return (
-
+
@@ -202,7 +202,7 @@ export function HeroSection({ totalIcons }: { totalIcons: number }) {
-
+
setSearchQuery(e.target.value)}
/>
-
+
@@ -131,36 +131,36 @@ function RecentIconCard({ name, data, getIconVariant }: {
exit="exit"
variants={variants}
className="will-change-transform"
- >
-
-
+ >
+
+
-
-
-
-
- {name.replace(/-/g, " ")}
-
-
-
-
- {formatIconDate(data.update.timestamp)}
-
-
+
+
+
+
+ {name.replace(/-/g, " ")}
+
+
+
+
+ {formatIconDate(data.update.timestamp)}
+
+
-
-
-
-
-
+
+
+
+
+
);
}
diff --git a/web/src/components/theme-switcher.tsx b/web/src/components/theme-switcher.tsx
index 1ed793e6..3f1807a7 100644
--- a/web/src/components/theme-switcher.tsx
+++ b/web/src/components/theme-switcher.tsx
@@ -5,34 +5,46 @@ import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
+import { useState } from "react"
export function ThemeSwitcher() {
const { setTheme } = useTheme()
+ const [open, setOpen] = useState(false)
return (
-
-
-
-
-
- Toggle theme
-
-
-
- setTheme("light")} className="cursor-pointer">
- Light
-
- setTheme("dark")} className="cursor-pointer">
- Dark
-
- setTheme("system")} className="cursor-pointer">
- System
-
-
-
+
+
+
+
+
+
+
+
+ Toggle theme
+
+
+
+
+ Change theme
+
+
+
+ setTheme("light")} className="cursor-pointer">
+ Light
+
+ setTheme("dark")} className="cursor-pointer">
+ Dark
+
+ setTheme("system")} className="cursor-pointer">
+ System
+
+
+
+
)
}
diff --git a/web/src/components/ui/button.tsx b/web/src/components/ui/button.tsx
index a2df8dce..26db1314 100644
--- a/web/src/components/ui/button.tsx
+++ b/web/src/components/ui/button.tsx
@@ -5,27 +5,27 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all duration-300 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 [&_svg]:transition-all [&_svg]:duration-300 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive hover:scale-[1.02]",
{
variants: {
variant: {
default:
- "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
+ "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 hover:shadow-md",
destructive:
- "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ "bg-destructive text-white shadow-sm hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 hover:shadow-md",
outline:
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
+ "border bg-background shadow-sm hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 hover:shadow-md",
secondary:
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 hover:shadow-md",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
- icon: "size-9",
+ default: "h-10 px-5 py-2 has-[>svg]:px-3",
+ sm: "h-9 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
+ lg: "h-11 rounded-md px-6 has-[>svg]:px-4",
+ icon: "size-9 rounded-md",
},
},
defaultVariants: {
diff --git a/web/src/components/ui/card.tsx b/web/src/components/ui/card.tsx
index d05bbc6c..1700fee6 100644
--- a/web/src/components/ui/card.tsx
+++ b/web/src/components/ui/card.tsx
@@ -7,7 +7,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) {
) {
type={type}
data-slot="input"
className={cn(
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-10 w-full min-w-0 rounded-lg border bg-transparent px-4 py-2 text-base shadow-sm transition-all duration-300 outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:shadow-md",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className
)}