Visual redesign: lighter, cleaner, fully rounded modern UI
- Refreshed oklch palette: airier light mode, softer dark mode, gentler borders; soft/lift shadow tokens, selection tint, smooth scrolling - Buttons become pills (rounded-full) with subtle press scale and shadow - Cards rounded-3xl with soft shadows and hover lift on app/project cards - Badges become soft pills (primary/10 tint) - Header becomes a floating glass pill nav with active-page pill - Hero: soft gradient blobs, status chip, larger type scale - Uppercase section kickers on home and all subpages, softer separators Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Showing 13 changed files with +150 and −114
modified
app/apps/page.tsx
+2 −1
@@ -22,7 +22,8 @@ export default function AppsPage() { | ||
| 22 | 22 | return ( |
| 23 | 23 | <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6"> |
| 24 | 24 | <Reveal> |
| 25 | − <h1 className="text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 25 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Portfolio</p> | |
| 26 | + <h1 className="mt-2 text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 26 | 27 | Zyquo macOS Suite |
| 27 | 28 | </h1> |
| 28 | 29 | <p className="mt-3 max-w-2xl text-muted-foreground"> |
modified
app/cv/page.tsx
+2 −1
@@ -64,7 +64,8 @@ export default function CvPage() { | ||
| 64 | 64 | return ( |
| 65 | 65 | <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6"> |
| 66 | 66 | <Reveal> |
| 67 | − <h1 className="text-3xl font-bold tracking-tight sm:text-4xl">CV</h1> | |
| 67 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Curriculum Vitae</p> | |
| 68 | + <h1 className="mt-2 text-3xl font-bold tracking-tight sm:text-4xl">CV</h1> | |
| 68 | 69 | <p className="mt-3 max-w-2xl text-muted-foreground"> |
| 69 | 70 | Professor in the Department of Administrative Sciences at Université |
| 70 | 71 | du Québec en Outaouais (UQO). Research in financial econometrics, |
modified
app/globals.css
+41 −27
@@ -10,37 +10,37 @@ | ||
| 10 | 10 | @custom-variant dark (&:where(.dark, .dark *)); |
| 11 | 11 | |
| 12 | 12 | :root { |
| 13 | − --background: oklch(0.985 0.002 247.839); | |
| 14 | − --foreground: oklch(0.208 0.042 265.755); | |
| 13 | + --background: oklch(0.993 0.002 247.839); | |
| 14 | + --foreground: oklch(0.24 0.035 265.755); | |
| 15 | 15 | --card: oklch(1 0 0); |
| 16 | − --card-foreground: oklch(0.208 0.042 265.755); | |
| 17 | − --muted: oklch(0.968 0.007 247.896); | |
| 18 | − --muted-foreground: oklch(0.446 0.043 257.281); | |
| 19 | − --primary: oklch(0.488 0.243 264.376); | |
| 20 | − --primary-foreground: oklch(0.984 0.003 247.858); | |
| 21 | − --secondary: oklch(0.929 0.013 255.508); | |
| 22 | − --secondary-foreground: oklch(0.208 0.042 265.755); | |
| 23 | − --accent: oklch(0.929 0.013 255.508); | |
| 24 | − --accent-foreground: oklch(0.208 0.042 265.755); | |
| 25 | − --border: oklch(0.869 0.022 252.894); | |
| 26 | − --ring: oklch(0.488 0.243 264.376); | |
| 16 | + --card-foreground: oklch(0.24 0.035 265.755); | |
| 17 | + --muted: oklch(0.972 0.006 247.896); | |
| 18 | + --muted-foreground: oklch(0.5 0.035 257.281); | |
| 19 | + --primary: oklch(0.54 0.19 264.376); | |
| 20 | + --primary-foreground: oklch(0.99 0.003 247.858); | |
| 21 | + --secondary: oklch(0.955 0.01 255.508); | |
| 22 | + --secondary-foreground: oklch(0.3 0.04 265.755); | |
| 23 | + --accent: oklch(0.955 0.012 262); | |
| 24 | + --accent-foreground: oklch(0.3 0.04 265.755); | |
| 25 | + --border: oklch(0.915 0.012 252.894); | |
| 26 | + --ring: oklch(0.54 0.19 264.376); | |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | .dark { |
| 30 | − --background: oklch(0.179 0.025 265.755); | |
| 31 | − --foreground: oklch(0.929 0.013 255.508); | |
| 32 | − --card: oklch(0.218 0.028 265.755); | |
| 33 | − --card-foreground: oklch(0.929 0.013 255.508); | |
| 34 | − --muted: oklch(0.255 0.03 262.881); | |
| 35 | − --muted-foreground: oklch(0.704 0.04 256.788); | |
| 36 | − --primary: oklch(0.707 0.165 254.624); | |
| 37 | − --primary-foreground: oklch(0.179 0.025 265.755); | |
| 38 | − --secondary: oklch(0.279 0.041 260.031); | |
| 39 | − --secondary-foreground: oklch(0.929 0.013 255.508); | |
| 40 | − --accent: oklch(0.279 0.041 260.031); | |
| 41 | − --accent-foreground: oklch(0.929 0.013 255.508); | |
| 42 | − --border: oklch(0.323 0.038 262.881); | |
| 43 | − --ring: oklch(0.707 0.165 254.624); | |
| 30 | + --background: oklch(0.165 0.02 265.755); | |
| 31 | + --foreground: oklch(0.93 0.01 255.508); | |
| 32 | + --card: oklch(0.205 0.024 265.755); | |
| 33 | + --card-foreground: oklch(0.93 0.01 255.508); | |
| 34 | + --muted: oklch(0.245 0.026 262.881); | |
| 35 | + --muted-foreground: oklch(0.71 0.035 256.788); | |
| 36 | + --primary: oklch(0.72 0.15 258); | |
| 37 | + --primary-foreground: oklch(0.165 0.02 265.755); | |
| 38 | + --secondary: oklch(0.26 0.033 260.031); | |
| 39 | + --secondary-foreground: oklch(0.93 0.01 255.508); | |
| 40 | + --accent: oklch(0.27 0.035 260.031); | |
| 41 | + --accent-foreground: oklch(0.93 0.01 255.508); | |
| 42 | + --border: oklch(0.29 0.03 262.881); | |
| 43 | + --ring: oklch(0.72 0.15 258); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | @theme inline { |
@@ -59,12 +59,26 @@ | ||
| 59 | 59 | --color-border: var(--border); |
| 60 | 60 | --color-ring: var(--ring); |
| 61 | 61 | --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif; |
| 62 | + --shadow-soft: 0 1px 2px oklch(0.24 0.035 265.755 / 4%), | |
| 63 | + 0 8px 24px -8px oklch(0.24 0.035 265.755 / 8%); | |
| 64 | + --shadow-lift: 0 2px 4px oklch(0.24 0.035 265.755 / 5%), | |
| 65 | + 0 16px 40px -12px oklch(0.24 0.035 265.755 / 14%); | |
| 66 | +} | |
| 67 | + | |
| 68 | +html { | |
| 69 | + scroll-behavior: smooth; | |
| 62 | 70 | } |
| 63 | 71 | |
| 64 | 72 | body { |
| 65 | 73 | background-color: var(--background); |
| 66 | 74 | color: var(--foreground); |
| 67 | 75 | font-family: var(--font-sans); |
| 76 | + -webkit-font-smoothing: antialiased; | |
| 77 | + text-rendering: optimizeLegibility; | |
| 78 | +} | |
| 79 | + | |
| 80 | +::selection { | |
| 81 | + background: oklch(0.54 0.19 264.376 / 18%); | |
| 68 | 82 | } |
| 69 | 83 | |
| 70 | 84 | /* Framer Motion reveals bake opacity:0 into SSR inline styles; guarantee |
modified
app/page.tsx
+27 −12
@@ -113,15 +113,26 @@ export default function HomePage() { | ||
| 113 | 113 | return ( |
| 114 | 114 | <div className="mx-auto max-w-5xl px-4 sm:px-6"> |
| 115 | 115 | {/* Hero */} |
| 116 | − <section className="py-16 sm:py-24"> | |
| 116 | + <section className="relative py-20 sm:py-28"> | |
| 117 | + <div | |
| 118 | + aria-hidden="true" | |
| 119 | + className="pointer-events-none absolute inset-0 -z-10 overflow-visible" | |
| 120 | + > | |
| 121 | + <div className="absolute -top-24 right-0 h-72 w-72 rounded-full bg-primary/10 blur-3xl" /> | |
| 122 | + <div className="absolute top-20 -left-20 h-64 w-64 rounded-full bg-accent blur-3xl dark:bg-primary/5" /> | |
| 123 | + </div> | |
| 117 | 124 | <Reveal> |
| 118 | − <p className="text-sm font-medium text-primary"> | |
| 125 | + <p className="inline-flex items-center gap-2 rounded-full border border-border/70 bg-card/70 px-4 py-1.5 text-sm font-medium text-primary shadow-[var(--shadow-soft)]"> | |
| 126 | + <span | |
| 127 | + aria-hidden="true" | |
| 128 | + className="h-1.5 w-1.5 rounded-full bg-primary" | |
| 129 | + /> | |
| 119 | 130 | Professor — Department of Administrative Sciences |
| 120 | 131 | </p> |
| 121 | − <h1 className="mt-3 text-4xl font-bold tracking-tight sm:text-5xl"> | |
| 132 | + <h1 className="mt-6 text-4xl font-bold tracking-tight sm:text-6xl"> | |
| 122 | 133 | Simon-Pierre Boucher |
| 123 | 134 | </h1> |
| 124 | − <p className="mt-4 max-w-2xl text-lg text-muted-foreground"> | |
| 135 | + <p className="mt-5 max-w-2xl text-lg text-muted-foreground sm:text-xl"> | |
| 125 | 136 | Financial econometrics researcher and macOS/AI developer. |
| 126 | 137 | </p> |
| 127 | 138 | <p className="mt-2 text-sm text-muted-foreground"> |
@@ -169,9 +180,10 @@ export default function HomePage() { | ||
| 169 | 180 | </section> |
| 170 | 181 | |
| 171 | 182 | {/* About */} |
| 172 | − <section className="border-t border-border py-16"> | |
| 183 | + <section className="border-t border-border/50 py-16 sm:py-20"> | |
| 173 | 184 | <Reveal> |
| 174 | − <h2 className="text-2xl font-semibold tracking-tight">About</h2> | |
| 185 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Profile</p> | |
| 186 | + <h2 className="mt-2 text-2xl font-semibold tracking-tight sm:text-3xl">About</h2> | |
| 175 | 187 | <p className="mt-4 max-w-3xl leading-relaxed text-muted-foreground"> |
| 176 | 188 | Simon-Pierre Boucher is a Professor in the Department of |
| 177 | 189 | Administrative Sciences at Université du Québec en Outaouais (UQO). |
@@ -188,9 +200,10 @@ export default function HomePage() { | ||
| 188 | 200 | </section> |
| 189 | 201 | |
| 190 | 202 | {/* Education */} |
| 191 | − <section className="border-t border-border py-16"> | |
| 203 | + <section className="border-t border-border/50 py-16 sm:py-20"> | |
| 192 | 204 | <Reveal> |
| 193 | − <h2 className="text-2xl font-semibold tracking-tight">Education</h2> | |
| 205 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Background</p> | |
| 206 | + <h2 className="mt-2 text-2xl font-semibold tracking-tight sm:text-3xl">Education</h2> | |
| 194 | 207 | </Reveal> |
| 195 | 208 | <div className="mt-6 grid gap-4 sm:grid-cols-3"> |
| 196 | 209 | {education.map((item, i) => ( |
@@ -222,9 +235,10 @@ export default function HomePage() { | ||
| 222 | 235 | </section> |
| 223 | 236 | |
| 224 | 237 | {/* Research highlight */} |
| 225 | − <section className="border-t border-border py-16"> | |
| 238 | + <section className="border-t border-border/50 py-16 sm:py-20"> | |
| 226 | 239 | <Reveal> |
| 227 | − <h2 className="text-2xl font-semibold tracking-tight"> | |
| 240 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Latest</p> | |
| 241 | + <h2 className="mt-2 text-2xl font-semibold tracking-tight sm:text-3xl"> | |
| 228 | 242 | Research Highlight |
| 229 | 243 | </h2> |
| 230 | 244 | <Card className="mt-6"> |
@@ -253,9 +267,10 @@ export default function HomePage() { | ||
| 253 | 267 | </section> |
| 254 | 268 | |
| 255 | 269 | {/* Skills */} |
| 256 | − <section className="border-t border-border py-16"> | |
| 270 | + <section className="border-t border-border/50 py-16 sm:py-20"> | |
| 257 | 271 | <Reveal> |
| 258 | − <h2 className="text-2xl font-semibold tracking-tight"> | |
| 272 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Toolbox</p> | |
| 273 | + <h2 className="mt-2 text-2xl font-semibold tracking-tight sm:text-3xl"> | |
| 259 | 274 | Technical Skills |
| 260 | 275 | </h2> |
| 261 | 276 | </Reveal> |
modified
app/research/page.tsx
+2 −1
@@ -62,7 +62,8 @@ export default function ResearchPage() { | ||
| 62 | 62 | return ( |
| 63 | 63 | <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6"> |
| 64 | 64 | <Reveal> |
| 65 | − <h1 className="text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 65 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Publications & Papers</p> | |
| 66 | + <h1 className="mt-2 text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 66 | 67 | Research |
| 67 | 68 | </h1> |
| 68 | 69 | <p className="mt-3 max-w-2xl text-muted-foreground"> |
modified
app/teaching/page.tsx
+2 −1
@@ -61,7 +61,8 @@ export default function TeachingPage() { | ||
| 61 | 61 | return ( |
| 62 | 62 | <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6"> |
| 63 | 63 | <Reveal> |
| 64 | − <h1 className="text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 64 | + <p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary">Courses</p> | |
| 65 | + <h1 className="mt-2 text-3xl font-bold tracking-tight sm:text-4xl"> | |
| 65 | 66 | Teaching |
| 66 | 67 | </h1> |
| 67 | 68 | <p className="mt-3 max-w-2xl text-muted-foreground"> |
modified
components/app-card.tsx
+1 −1
@@ -22,7 +22,7 @@ import { cn } from "@/lib/utils"; | ||
| 22 | 22 | |
| 23 | 23 | export function AppCard({ app }: { app: ZyquoApp }) { |
| 24 | 24 | return ( |
| 25 | − <Card className="flex h-full flex-col transition-shadow hover:shadow-md"> | |
| 25 | + <Card className="flex h-full flex-col hover:-translate-y-1 hover:shadow-[var(--shadow-lift)]"> | |
| 26 | 26 | <CardHeader className="flex-row items-center gap-4 space-y-0"> |
| 27 | 27 | <Image |
| 28 | 28 | src={app.icon} |
modified
components/project-card.tsx
+1 −1
@@ -21,7 +21,7 @@ import { cn } from "@/lib/utils"; | ||
| 21 | 21 | |
| 22 | 22 | export function ProjectCard({ project }: { project: OpenSourceProject }) { |
| 23 | 23 | return ( |
| 24 | − <Card className="flex h-full flex-col transition-shadow hover:shadow-md"> | |
| 24 | + <Card className="flex h-full flex-col hover:-translate-y-1 hover:shadow-[var(--shadow-lift)]"> | |
| 25 | 25 | <CardHeader className="flex-row items-center gap-4 space-y-0"> |
| 26 | 26 | <div |
| 27 | 27 | aria-hidden="true" |
modified
components/site-footer.tsx
+2 −2
@@ -9,8 +9,8 @@ import Link from "next/link"; | ||
| 9 | 9 | |
| 10 | 10 | export function SiteFooter() { |
| 11 | 11 | return ( |
| 12 | − <footer className="border-t border-border"> | |
| 13 | − <div className="mx-auto flex max-w-5xl flex-col items-center justify-between gap-4 px-4 py-8 text-sm text-muted-foreground sm:flex-row sm:px-6"> | |
| 12 | + <footer className="border-t border-border/50"> | |
| 13 | + <div className="mx-auto flex max-w-5xl flex-col items-center justify-between gap-4 px-4 py-10 text-sm text-muted-foreground sm:flex-row sm:px-6"> | |
| 14 | 14 | <p> |
| 15 | 15 | © {new Date().getFullYear()} Simon-Pierre Boucher — Université du |
| 16 | 16 | Québec en Outaouais (UQO) |
modified
components/site-header.tsx
+57 −55
@@ -29,66 +29,68 @@ export function SiteHeader() { | ||
| 29 | 29 | const [open, setOpen] = React.useState(false); |
| 30 | 30 | |
| 31 | 31 | return ( |
| 32 | − <header className="sticky top-0 z-50 w-full border-b border-border bg-background/80 backdrop-blur"> | |
| 33 | − <div className="mx-auto flex h-14 max-w-5xl items-center justify-between px-4 sm:px-6"> | |
| 34 | − <Link href="/" className="font-semibold tracking-tight"> | |
| 35 | − Simon-Pierre Boucher | |
| 36 | − </Link> | |
| 32 | + <header className="sticky top-0 z-50 w-full px-4 pt-3 sm:px-6"> | |
| 33 | + <div className="mx-auto max-w-5xl rounded-3xl border border-border/60 bg-background/70 shadow-[var(--shadow-soft)] backdrop-blur-xl"> | |
| 34 | + <div className="flex h-14 items-center justify-between pl-5 pr-3"> | |
| 35 | + <Link href="/" className="font-semibold tracking-tight"> | |
| 36 | + Simon-Pierre Boucher | |
| 37 | + </Link> | |
| 37 | 38 | |
| 38 | − <nav className="hidden items-center gap-1 md:flex" aria-label="Main"> | |
| 39 | − {navItems.map((item) => ( | |
| 40 | − <Link | |
| 41 | − key={item.href} | |
| 42 | − href={item.href} | |
| 43 | − className={cn( | |
| 44 | − "rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground", | |
| 45 | − pathname === item.href | |
| 46 | − ? "text-foreground" | |
| 47 | − : "text-muted-foreground" | |
| 48 | − )} | |
| 39 | + <nav className="hidden items-center gap-1 md:flex" aria-label="Main"> | |
| 40 | + {navItems.map((item) => ( | |
| 41 | + <Link | |
| 42 | + key={item.href} | |
| 43 | + href={item.href} | |
| 44 | + className={cn( | |
| 45 | + "rounded-full px-4 py-2 text-sm font-medium transition-colors", | |
| 46 | + pathname === item.href | |
| 47 | + ? "bg-secondary text-foreground" | |
| 48 | + : "text-muted-foreground hover:bg-accent hover:text-accent-foreground" | |
| 49 | + )} | |
| 50 | + > | |
| 51 | + {item.label} | |
| 52 | + </Link> | |
| 53 | + ))} | |
| 54 | + <ThemeToggle /> | |
| 55 | + </nav> | |
| 56 | + | |
| 57 | + <div className="flex items-center gap-1 md:hidden"> | |
| 58 | + <ThemeToggle /> | |
| 59 | + <Button | |
| 60 | + variant="ghost" | |
| 61 | + size="icon" | |
| 62 | + aria-label={open ? "Close menu" : "Open menu"} | |
| 63 | + aria-expanded={open} | |
| 64 | + onClick={() => setOpen(!open)} | |
| 49 | 65 | > |
| 50 | − {item.label} | |
| 51 | − </Link> | |
| 52 | − ))} | |
| 53 | − <ThemeToggle /> | |
| 54 | − </nav> | |
| 66 | + {open ? <X /> : <Menu />} | |
| 67 | + </Button> | |
| 68 | + </div> | |
| 69 | + </div> | |
| 55 | 70 | |
| 56 | − <div className="flex items-center gap-1 md:hidden"> | |
| 57 | − <ThemeToggle /> | |
| 58 | − <Button | |
| 59 | − variant="ghost" | |
| 60 | − size="icon" | |
| 61 | − aria-label={open ? "Close menu" : "Open menu"} | |
| 62 | − aria-expanded={open} | |
| 63 | − onClick={() => setOpen(!open)} | |
| 71 | + {open && ( | |
| 72 | + <nav | |
| 73 | + className="border-t border-border/60 px-4 pb-4 pt-2 md:hidden" | |
| 74 | + aria-label="Mobile" | |
| 64 | 75 | > |
| 65 | − {open ? <X /> : <Menu />} | |
| 66 | − </Button> | |
| 67 | − </div> | |
| 76 | + {navItems.map((item) => ( | |
| 77 | + <Link | |
| 78 | + key={item.href} | |
| 79 | + href={item.href} | |
| 80 | + onClick={() => setOpen(false)} | |
| 81 | + className={cn( | |
| 82 | + "block rounded-full px-4 py-2 text-sm font-medium transition-colors", | |
| 83 | + pathname === item.href | |
| 84 | + ? "bg-secondary text-foreground" | |
| 85 | + : "text-muted-foreground hover:bg-accent hover:text-accent-foreground" | |
| 86 | + )} | |
| 87 | + > | |
| 88 | + {item.label} | |
| 89 | + </Link> | |
| 90 | + ))} | |
| 91 | + </nav> | |
| 92 | + )} | |
| 68 | 93 | </div> |
| 69 | − | |
| 70 | − {open && ( | |
| 71 | − <nav | |
| 72 | − className="border-t border-border px-4 pb-4 pt-2 md:hidden" | |
| 73 | − aria-label="Mobile" | |
| 74 | − > | |
| 75 | − {navItems.map((item) => ( | |
| 76 | − <Link | |
| 77 | − key={item.href} | |
| 78 | − href={item.href} | |
| 79 | − onClick={() => setOpen(false)} | |
| 80 | − className={cn( | |
| 81 | − "block rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground", | |
| 82 | − pathname === item.href | |
| 83 | − ? "text-foreground" | |
| 84 | − : "text-muted-foreground" | |
| 85 | − )} | |
| 86 | − > | |
| 87 | − {item.label} | |
| 88 | − </Link> | |
| 89 | − ))} | |
| 90 | − </nav> | |
| 91 | − )} | |
| 92 | 94 | </header> |
| 93 | 95 | ); |
| 94 | 96 | } |
modified
components/ui/badge.tsx
+3 −3
@@ -11,13 +11,13 @@ import { cva, type VariantProps } from "class-variance-authority"; | ||
| 11 | 11 | import { cn } from "@/lib/utils"; |
| 12 | 12 | |
| 13 | 13 | const badgeVariants = cva( |
| 14 | − "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-medium transition-colors", | |
| 14 | + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors", | |
| 15 | 15 | { |
| 16 | 16 | variants: { |
| 17 | 17 | variant: { |
| 18 | − default: "border-transparent bg-primary text-primary-foreground", | |
| 18 | + default: "border-transparent bg-primary/10 text-primary", | |
| 19 | 19 | secondary: "border-transparent bg-secondary text-secondary-foreground", |
| 20 | − outline: "border-border text-foreground", | |
| 20 | + outline: "border-border text-muted-foreground", | |
| 21 | 21 | }, |
| 22 | 22 | }, |
| 23 | 23 | defaultVariants: { |
modified
components/ui/button.tsx
+9 −8
@@ -11,23 +11,24 @@ import { cva, type VariantProps } from "class-variance-authority"; | ||
| 11 | 11 | import { cn } from "@/lib/utils"; |
| 12 | 12 | |
| 13 | 13 | const buttonVariants = cva( |
| 14 | − "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0", | |
| 14 | + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98] [&_svg]:size-4 [&_svg]:shrink-0", | |
| 15 | 15 | { |
| 16 | 16 | variants: { |
| 17 | 17 | variant: { |
| 18 | − default: "bg-primary text-primary-foreground hover:bg-primary/90", | |
| 18 | + default: | |
| 19 | + "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 hover:shadow-md", | |
| 19 | 20 | secondary: |
| 20 | − "bg-secondary text-secondary-foreground hover:bg-secondary/80", | |
| 21 | + "bg-secondary text-secondary-foreground hover:bg-secondary/70", | |
| 21 | 22 | outline: |
| 22 | − "border border-border bg-transparent hover:bg-accent hover:text-accent-foreground", | |
| 23 | + "border border-border bg-card/60 hover:border-primary/30 hover:bg-accent hover:text-accent-foreground", | |
| 23 | 24 | ghost: "hover:bg-accent hover:text-accent-foreground", |
| 24 | 25 | link: "text-primary underline-offset-4 hover:underline", |
| 25 | 26 | }, |
| 26 | 27 | size: { |
| 27 | − default: "h-9 px-4 py-2", | |
| 28 | − sm: "h-8 rounded-md px-3 text-xs", | |
| 29 | − lg: "h-10 rounded-md px-8", | |
| 30 | − icon: "h-9 w-9", | |
| 28 | + default: "h-10 px-5 py-2", | |
| 29 | + sm: "h-8 px-3.5 text-xs", | |
| 30 | + lg: "h-11 px-8", | |
| 31 | + icon: "h-10 w-10", | |
| 31 | 32 | }, |
| 32 | 33 | }, |
| 33 | 34 | defaultVariants: { |
modified
components/ui/card.tsx
+1 −1
@@ -14,7 +14,7 @@ const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElemen | ||
| 14 | 14 | <div |
| 15 | 15 | ref={ref} |
| 16 | 16 | className={cn( |
| 17 | − "rounded-xl border border-border bg-card text-card-foreground shadow-sm", | |
| 17 | + "rounded-3xl border border-border/70 bg-card text-card-foreground shadow-[var(--shadow-soft)] transition-all duration-300", | |
| 18 | 18 | className |
| 19 | 19 | )} |
| 20 | 20 | {...props} |
| 21 | 21 | |