mirror of
https://github.com/dyzulk/dyzulk.github.io.git
synced 2026-01-26 05:45:28 +07:00
Implement Dark Glassmorphism Theme (Navbar, Cards, Fonts)
This commit is contained in:
20
package-lock.json
generated
20
package-lock.json
generated
@@ -8,6 +8,8 @@
|
||||
"name": "dyzulk.github.io",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@fontsource/geist-mono": "^5.2.7",
|
||||
"@fontsource/geist-sans": "^5.2.5",
|
||||
"@supabase/supabase-js": "^2.90.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -932,6 +934,24 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource/geist-mono": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/geist-mono/-/geist-mono-5.2.7.tgz",
|
||||
"integrity": "sha512-xVPVFISJg/K0VVd+aQN0Y7X/sw9hUcJPyDWFJ5GpyU3bHELhoRsJkPSRSHXW32mOi0xZCUQDOaPj1sqIFJ1FGg==",
|
||||
"license": "OFL-1.1",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ayuhito"
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource/geist-sans": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/geist-sans/-/geist-sans-5.2.5.tgz",
|
||||
"integrity": "sha512-anllOHyJbElRs9fV15TeDRqAeb1IKm4bSknPl6ZMoyPTx1BBy7logudcUwpNjmQLkzn4Q0JGQLRCUKJYoyST6A==",
|
||||
"license": "OFL-1.1",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ayuhito"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/geist-mono": "^5.2.7",
|
||||
"@fontsource/geist-sans": "^5.2.5",
|
||||
"@supabase/supabase-js": "^2.90.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
@@ -11,27 +11,36 @@ export default function Navbar() {
|
||||
]
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 w-full border-b border-slate-200 dark:border-slate-800 bg-white/80 dark:bg-slate-950/80 backdrop-blur-md">
|
||||
<div className="container mx-auto px-4 h-16 flex items-center justify-between">
|
||||
<Link to="/" className="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-cyan-500">
|
||||
Dyzulk.
|
||||
<div className="fixed top-6 left-0 right-0 z-50 flex justify-center px-4">
|
||||
<nav className="flex items-center gap-1 p-1 rounded-full border border-white/10 bg-black/50 backdrop-blur-xl shadow-lg ring-1 ring-white/5">
|
||||
<Link
|
||||
to="/"
|
||||
className="ml-2 mr-4 flex items-center gap-2 font-bold text-white tracking-tight"
|
||||
>
|
||||
<img src="/logo.svg" alt="Dyzulk" className="w-6 h-6" />
|
||||
<span>Dyzulk.</span>
|
||||
</Link>
|
||||
|
||||
<nav className="flex gap-6">
|
||||
{links.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
to={link.href}
|
||||
className={cn(
|
||||
"text-sm font-medium transition-colors hover:text-blue-600",
|
||||
location.pathname === link.href ? "text-blue-600" : "text-slate-600 dark:text-slate-400"
|
||||
)}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex items-center gap-1 pr-1">
|
||||
{links.map((link) => {
|
||||
const isActive = location.pathname === link.href
|
||||
return (
|
||||
<Link
|
||||
key={link.href}
|
||||
to={link.href}
|
||||
className={cn(
|
||||
"px-4 py-2 rounded-full text-sm font-medium transition-all duration-300",
|
||||
isActive
|
||||
? "bg-white text-black shadow-sm"
|
||||
: "text-zinc-400 hover:text-white hover:bg-white/5"
|
||||
)}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ import Navbar from './Navbar'
|
||||
|
||||
export default function PublicLayout() {
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen bg-white dark:bg-slate-950 text-slate-900 dark:text-slate-50">
|
||||
<div className="flex flex-col min-h-screen bg-background text-foreground selection:bg-white/20">
|
||||
<Navbar />
|
||||
<main className="flex-1">
|
||||
<main className="flex-1 pt-24 pb-12">
|
||||
<Outlet />
|
||||
</main>
|
||||
<footer className="py-8 border-t border-slate-100 dark:border-slate-900 text-center text-slate-500 text-sm">
|
||||
<p>© {new Date().getFullYear()} Dyzulk. Built with React & Supabase.</p>
|
||||
<footer className="py-8 border-t border-white/5 text-center text-muted-foreground text-sm">
|
||||
<p>© {new Date().getFullYear()} DyzulkDev. Built with React & Supabase.</p>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -6,9 +6,9 @@ interface ProjectCardProps {
|
||||
|
||||
export function ProjectCard({ project }: ProjectCardProps) {
|
||||
return (
|
||||
<div className="group relative bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl overflow-hidden hover:shadow-xl transition-all duration-300 flex flex-col h-full">
|
||||
<div className="group relative glass-card h-full flex flex-col overflow-hidden">
|
||||
{/* Image */}
|
||||
<div className="aspect-video w-full overflow-hidden bg-slate-100 dark:bg-slate-800">
|
||||
<div className="aspect-video w-full overflow-hidden bg-white/5 border-b border-white/5">
|
||||
{project.cover_image ? (
|
||||
<img
|
||||
src={project.cover_image}
|
||||
@@ -16,7 +16,7 @@ export function ProjectCard({ project }: ProjectCardProps) {
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-slate-400">
|
||||
<div className="w-full h-full flex items-center justify-center text-muted-foreground">
|
||||
No Image
|
||||
</div>
|
||||
)}
|
||||
@@ -24,30 +24,30 @@ export function ProjectCard({ project }: ProjectCardProps) {
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-5 flex flex-col flex-1">
|
||||
<h3 className="text-xl font-bold mb-2 group-hover:text-blue-500 transition-colors">
|
||||
<h3 className="text-xl font-bold mb-2 group-hover:text-primary transition-colors tracking-tight">
|
||||
{project.title}
|
||||
</h3>
|
||||
<p className="text-slate-600 dark:text-slate-400 text-sm mb-4 line-clamp-3 flex-1">
|
||||
<p className="text-muted-foreground text-sm mb-4 line-clamp-3 flex-1 leading-relaxed">
|
||||
{project.description}
|
||||
</p>
|
||||
|
||||
{/* Tech Stack */}
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
<div className="flex flex-wrap gap-2 mb-6">
|
||||
{project.tech_stack?.map((tech: string) => (
|
||||
<span key={tech} className="px-2 py-1 text-xs bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 rounded-md">
|
||||
<span key={tech} className="px-2.5 py-1 text-[10px] font-medium bg-white/5 border border-white/5 text-muted-foreground rounded-full">
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Links */}
|
||||
<div className="flex items-center gap-4 mt-auto pt-4 border-t border-slate-100 dark:border-slate-800">
|
||||
<div className="flex items-center gap-4 mt-auto pt-4 border-t border-white/5">
|
||||
{project.demo_url && (
|
||||
<a
|
||||
href={project.demo_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1 text-sm font-medium text-blue-600 hover:underline"
|
||||
className="flex items-center gap-2 text-xs font-semibold text-white hover:text-blue-400 transition-colors"
|
||||
>
|
||||
<ExternalLink size={14} /> Live Demo
|
||||
</a>
|
||||
@@ -57,7 +57,7 @@ export function ProjectCard({ project }: ProjectCardProps) {
|
||||
href={project.repo_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1 text-sm font-medium text-slate-600 hover:text-black dark:text-slate-400 dark:hover:text-white"
|
||||
className="flex items-center gap-2 text-xs font-semibold text-muted-foreground hover:text-white transition-colors"
|
||||
>
|
||||
<Github size={14} /> Code
|
||||
</a>
|
||||
|
||||
113
src/index.css
113
src/index.css
@@ -4,58 +4,59 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 12 76% 61%;
|
||||
--chart-2: 173 58% 39%;
|
||||
--chart-3: 197 37% 24%;
|
||||
--chart-4: 43 74% 66%;
|
||||
--chart-5: 27 87% 67%;
|
||||
/* Deep Graphite / Black Theme Base */
|
||||
--background: 0 0% 4%; /* #0a0a0a */
|
||||
--foreground: 0 0% 98%;
|
||||
|
||||
--card: 0 0% 4%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
||||
--popover: 0 0% 4%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
|
||||
--radius: 0.75rem; /* More rounded */
|
||||
}
|
||||
|
||||
/* Force Dark Mode Default */
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--background: 0 0% 4%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 0 0% 4%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 4%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
--chart-1: 220 70% 50%;
|
||||
--chart-2: 160 60% 45%;
|
||||
--chart-3: 30 80% 55%;
|
||||
--chart-4: 280 65% 60%;
|
||||
--chart-5: 340 75% 55%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +65,20 @@
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
@apply bg-background text-foreground antialiased selection:bg-white/20 selection:text-white;
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Glassmorphism Utilities */
|
||||
@layer utilities {
|
||||
.glass {
|
||||
@apply bg-white/5 backdrop-blur-md border border-white/10 shadow-lg;
|
||||
}
|
||||
.glass-hover {
|
||||
@apply hover:bg-white/10 hover:border-white/20 transition-all duration-300;
|
||||
}
|
||||
.glass-card {
|
||||
@apply glass glass-hover rounded-xl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import '@fontsource/geist-sans'
|
||||
import '@fontsource/geist-mono'
|
||||
import './index.css'
|
||||
import App from './App.tsx'
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ export default {
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Geist Sans', 'sans-serif'],
|
||||
mono: ['Geist Mono', 'monospace'],
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
|
||||
Reference in New Issue
Block a user