feat: Refactor theme management and add multiple themes
Some checks failed
GBCI / build (push) Failing after 1m48s
Some checks failed
GBCI / build (push) Failing after 1m48s
- Updated the layout to integrate a new ThemeProvider component. - Removed the old ModeToggle component and integrated theme selection directly into the ThemeProvider. - Deleted unused SVG files (tauri.svg, vite.svg) and the old mode-toggle and theme-provider components. - Added a comprehensive ThemeProvider that supports multiple themes with corresponding CSS files. - Created new theme CSS files for various themes including RetroWave, CyberPunk, and more. - Updated tsconfig.json to include new component paths for better type checking. - Ensured the application loads the saved theme from localStorage on startup.
This commit is contained in:
parent
22452abf36
commit
70a369ad04
27 changed files with 962 additions and 224 deletions
|
@ -212,7 +212,10 @@ const ChatPage = () => {
|
|||
<div className="p-4 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
|
||||
<div className="flex items-center gap-3 p-3 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-700/50 cursor-pointer transition-colors duration-200">
|
||||
<User className="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||
<span className="font-medium text-gray-700 dark:text-gray-300">Account</span>
|
||||
<User className="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||
<User className="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||
<User className="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||
<User className="w-5 h-5 text-gray-600 dark:text-gray-400" />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
"use client";
|
||||
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { Button } from '../src/components/ui/button';
|
||||
import Image from 'next/image';
|
||||
import { useRef, useEffect } from 'react';
|
||||
import { useRef, useEffect, useState } from 'react';
|
||||
import { useTheme } from './theme-provider';
|
||||
|
||||
const examples = [
|
||||
{ name: "Chat", href: "/chat" },
|
||||
{ name: "Dashboard", href: "/dashboard" },
|
||||
{ name: "Mail", href: "/mail" },
|
||||
{ name: "Tree", href: "/tree" },
|
||||
{ name: "Editor", href: "/editor" },
|
||||
{ name: "Tables", href: "/table" },
|
||||
{ name: "Meet", href: "/meet" },
|
||||
{ name: "Videos", href: "/videos" },
|
||||
{ name: "Music", href: "/music" },
|
||||
{ name: "Templates", href: "/templates" },
|
||||
{ name: "Settings", href: "/settings" },
|
||||
{ name: "Chat", href: "/chat", color: "#25D366" }, // WhatsApp green
|
||||
{ name: "Dashboard", href: "/dashboard", color: "#6366F1" }, // Indigo
|
||||
{ name: "Mail", href: "/mail", color: "#FFD700" }, // Outlook yellow
|
||||
{ name: "Tree", href: "/tree", color: "#10B981" }, // Emerald green
|
||||
{ name: "Editor", href: "/editor", color: "#2563EB" }, // Word blue
|
||||
{ name: "Tables", href: "/table", color: "#8B5CF6" }, // Purple
|
||||
{ name: "Meet", href: "/meet", color: "#059669" }, // Google Meet green
|
||||
{ name: "Videos", href: "/videos", color: "#DC2626" }, // YouTube red
|
||||
{ name: "Music", href: "/music", color: "#1DB954" }, // Spotify green
|
||||
{ name: "Templates", href: "/templates", color: "#F59E0B" }, // Amber
|
||||
{ name: "Settings", href: "/settings", color: "#6B7280" }, // Gray
|
||||
];
|
||||
|
||||
export function Nav() {
|
||||
|
@ -24,87 +24,94 @@ export function Nav() {
|
|||
const router = useRouter();
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
const navItemsRefs = useRef<(HTMLButtonElement | null)[]>([]);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [showLoginMenu, setShowLoginMenu] = useState(false);
|
||||
const [showScrollButtons, setShowScrollButtons] = useState(false);
|
||||
const loginMenuRef = useRef<HTMLDivElement>(null);
|
||||
const [showThemeMenu, setShowThemeMenu] = useState(false);
|
||||
const themeMenuRef = useRef<HTMLDivElement>(null);
|
||||
const { theme, setTheme, themes } = useTheme();
|
||||
|
||||
// Enhanced URL matching to handle sub-routes
|
||||
const isActive = (href: string) => {
|
||||
if (href === '/') return pathname === href;
|
||||
return pathname.startsWith(href);
|
||||
};
|
||||
|
||||
const handleLogin = () => {
|
||||
setIsLoggedIn(true);
|
||||
setShowLoginMenu(false);
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
setIsLoggedIn(false);
|
||||
setShowLoginMenu(false);
|
||||
};
|
||||
|
||||
const checkScrollNeeded = () => {
|
||||
if (scrollContainerRef.current) {
|
||||
const container = scrollContainerRef.current;
|
||||
const isScrollable = container.scrollWidth > container.clientWidth;
|
||||
setShowScrollButtons(isScrollable);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (loginMenuRef.current && !loginMenuRef.current.contains(event.target as Node)) {
|
||||
setShowLoginMenu(false);
|
||||
}
|
||||
if (themeMenuRef.current && !themeMenuRef.current.contains(event.target as Node)) {
|
||||
setShowThemeMenu(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
checkScrollNeeded();
|
||||
window.addEventListener('resize', checkScrollNeeded);
|
||||
return () => window.removeEventListener('resize', checkScrollNeeded);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Load GSAP from CDN
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js';
|
||||
script.onload = () => {
|
||||
const gsap = window.gsap;
|
||||
|
||||
// Animate navigation items on mount
|
||||
gsap.fromTo('.nav-item',
|
||||
{
|
||||
opacity: 0,
|
||||
y: -10,
|
||||
scale: 0.9
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
scale: 1,
|
||||
duration: 0.6,
|
||||
stagger: 0.1,
|
||||
ease: "back.out(1.7)"
|
||||
}
|
||||
{ opacity: 0, y: -10, scale: 0.9 },
|
||||
{ opacity: 1, y: 0, scale: 1, duration: 0.6, stagger: 0.1, ease: "back.out(1.7)" }
|
||||
);
|
||||
|
||||
// Add hover animations
|
||||
navItemsRefs.current.forEach((item, index) => {
|
||||
navItemsRefs.current.forEach((item) => {
|
||||
if (item) {
|
||||
item.addEventListener('mouseenter', () => {
|
||||
gsap.to(item, {
|
||||
scale: 1.05,
|
||||
duration: 0.3,
|
||||
ease: "power2.out"
|
||||
});
|
||||
gsap.to(item, { scale: 1.05, duration: 0.3, ease: "power2.out" });
|
||||
});
|
||||
|
||||
item.addEventListener('mouseleave', () => {
|
||||
gsap.to(item, {
|
||||
scale: 1,
|
||||
duration: 0.3,
|
||||
ease: "power2.out"
|
||||
});
|
||||
gsap.to(item, { scale: 1, duration: 0.3, ease: "power2.out" });
|
||||
});
|
||||
|
||||
item.addEventListener('click', () => {
|
||||
gsap.to(item, {
|
||||
scale: 0.95,
|
||||
duration: 0.1,
|
||||
yoyo: true,
|
||||
repeat: 1,
|
||||
ease: "power2.inOut"
|
||||
});
|
||||
gsap.to(item, { scale: 0.95, duration: 0.1, yoyo: true, repeat: 1, ease: "power2.inOut" });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Animate logo
|
||||
gsap.fromTo('.logo',
|
||||
{
|
||||
opacity: 0,
|
||||
x: -20,
|
||||
rotate: -10
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
rotate: 0,
|
||||
duration: 0.8,
|
||||
ease: "elastic.out(1, 0.5)"
|
||||
}
|
||||
gsap.fromTo('.theme-toggle',
|
||||
{ opacity: 0, x: 20, scale: 0.8 },
|
||||
{ opacity: 1, x: 0, scale: 1, duration: 0.8, delay: 0.3, ease: "elastic.out(1, 0.5)" }
|
||||
);
|
||||
|
||||
gsap.fromTo('.login-button',
|
||||
{ opacity: 0, x: 20, scale: 0.8 },
|
||||
{ opacity: 1, x: 0, scale: 1, duration: 0.8, delay: 0.4, ease: "elastic.out(1, 0.5)" }
|
||||
);
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
|
||||
return () => {
|
||||
if (document.head.contains(script)) {
|
||||
document.head.removeChild(script);
|
||||
|
@ -112,22 +119,32 @@ export function Nav() {
|
|||
};
|
||||
}, []);
|
||||
|
||||
// Smooth scroll functions for mobile
|
||||
const scrollLeft = () => {
|
||||
if (scrollContainerRef.current) {
|
||||
scrollContainerRef.current.scrollBy({
|
||||
left: -150,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
scrollContainerRef.current?.scrollBy({ left: -150, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
const scrollRight = () => {
|
||||
if (scrollContainerRef.current) {
|
||||
scrollContainerRef.current.scrollBy({
|
||||
left: 150,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
scrollContainerRef.current?.scrollBy({ left: 150, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
const getThemeIcon = () => {
|
||||
switch(theme.name) {
|
||||
case 'retrowave': return '🌌';
|
||||
case 'vapordream': return '🌀';
|
||||
case 'y2kglow': return '💿';
|
||||
case 'mellowgold': return '☮️';
|
||||
case 'arcadeflash': return '🕹️';
|
||||
case 'polaroidmemories': return '📸';
|
||||
case 'midcenturymod': return '🪑';
|
||||
case 'grungeera': return '🎸';
|
||||
case 'discofever': return '🪩';
|
||||
case 'saturdaycartoons': return '📺';
|
||||
case 'oldhollywood': return '🎬';
|
||||
case 'cyberpunk': return '🤖';
|
||||
case 'seasidepostcard': return '🏖️';
|
||||
case 'typewriter': return '⌨️';
|
||||
case 'jazzage': return '🎷';
|
||||
default: return '🎨';
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -142,18 +159,16 @@ export function Nav() {
|
|||
alt="Logo"
|
||||
width={64}
|
||||
height={24}
|
||||
className="logo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button className="scroll-btn scroll-left" onClick={scrollLeft} aria-label="Scroll left">
|
||||
‹
|
||||
</button>
|
||||
{showScrollButtons && (
|
||||
<button className="scroll-btn scroll-left" onClick={scrollLeft} aria-label="Scroll left">
|
||||
‹
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
className="nav-scroll"
|
||||
>
|
||||
<div ref={scrollContainerRef} className="nav-scroll">
|
||||
<div className="nav-items">
|
||||
{examples.map((example, index) => {
|
||||
const active = isActive(example.href);
|
||||
|
@ -163,6 +178,7 @@ export function Nav() {
|
|||
ref={el => navItemsRefs.current[index] = el}
|
||||
onClick={() => router.push(example.href)}
|
||||
className={`nav-item ${active ? 'active' : ''}`}
|
||||
style={{'--neon-color': example.color} as React.CSSProperties}
|
||||
>
|
||||
{example.name}
|
||||
<div className="neon-glow"></div>
|
||||
|
@ -172,9 +188,66 @@ export function Nav() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<button className="scroll-btn scroll-right" onClick={scrollRight} aria-label="Scroll right">
|
||||
›
|
||||
</button>
|
||||
{showScrollButtons && (
|
||||
<button className="scroll-btn scroll-right" onClick={scrollRight} aria-label="Scroll right">
|
||||
›
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div className="auth-controls">
|
||||
<div className="login-container" ref={loginMenuRef}>
|
||||
<button
|
||||
onClick={() => setShowLoginMenu(!showLoginMenu)}
|
||||
className="login-button"
|
||||
aria-label={isLoggedIn ? "User menu" : "Login"}
|
||||
>
|
||||
{isLoggedIn ? '👤' : '🔐'}
|
||||
</button>
|
||||
|
||||
{showLoginMenu && (
|
||||
<div className="login-menu">
|
||||
{!isLoggedIn ? (
|
||||
<button onClick={handleLogin} className="menu-item">
|
||||
Login
|
||||
</button>
|
||||
) : (
|
||||
<button onClick={handleLogout} className="menu-item">
|
||||
Logout
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="theme-container" ref={themeMenuRef}>
|
||||
<button
|
||||
onClick={() => setShowThemeMenu(!showThemeMenu)}
|
||||
className="theme-toggle"
|
||||
aria-label="Change theme"
|
||||
>
|
||||
{getThemeIcon()}
|
||||
</button>
|
||||
|
||||
{showThemeMenu && (
|
||||
<div className="theme-menu">
|
||||
{themes.map((t) => (
|
||||
<button
|
||||
key={t.name}
|
||||
onClick={() => {
|
||||
setTheme(t.name);
|
||||
setShowThemeMenu(false);
|
||||
}}
|
||||
className={`theme-menu-item ${
|
||||
theme.name === t.name ? 'active-theme' : ''
|
||||
}`}
|
||||
>
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -188,10 +261,10 @@ export function Nav() {
|
|||
left: 0;
|
||||
right: 0;
|
||||
z-index: 50;
|
||||
background: linear-gradient(135deg, #0a0a0a 0%, #1a1a2e 50%, #16213e 100%);
|
||||
border-bottom: 1px solid #333;
|
||||
background: hsl(var(--background));
|
||||
height: 40px;
|
||||
box-shadow: 0 2px 20px rgba(0, 255, 255, 0.1);
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
|
@ -208,25 +281,86 @@ export function Nav() {
|
|||
gap: 8px;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
.auth-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
padding: 4px;
|
||||
border-radius: 6px;
|
||||
background: rgba(0, 255, 255, 0.1);
|
||||
box-shadow: 0 0 10px rgba(0, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 20px;
|
||||
width: auto;
|
||||
filter: drop-shadow(0 0 5px rgba(0, 255, 255, 0.5));
|
||||
|
||||
.login-container,
|
||||
.theme-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.login-button,
|
||||
.theme-toggle {
|
||||
background: hsl(var(--accent));
|
||||
border: 1px solid hsl(var(--border));
|
||||
color: hsl(var(--accent-foreground));
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.login-button:hover,
|
||||
.theme-toggle:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 0 10px hsla(var(--primary), 0.5);
|
||||
}
|
||||
|
||||
.login-menu,
|
||||
.theme-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 8px);
|
||||
right: 0;
|
||||
background: hsl(var(--popover));
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: 6px;
|
||||
min-width: 120px;
|
||||
z-index: 100;
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.menu-item,
|
||||
.theme-menu-item {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: hsl(var(--foreground));
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-align: left;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.menu-item:hover,
|
||||
.theme-menu-item:hover {
|
||||
background: hsl(var(--accent));
|
||||
color: hsl(var(--accent-foreground));
|
||||
}
|
||||
|
||||
.active-theme {
|
||||
background: hsl(var(--primary));
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
|
||||
.scroll-btn {
|
||||
display: none;
|
||||
background: rgba(0, 255, 255, 0.2);
|
||||
border: 1px solid rgba(0, 255, 255, 0.3);
|
||||
color: #00ffff;
|
||||
background: hsl(var(--accent));
|
||||
border: 1px solid hsl(var(--border));
|
||||
color: hsl(var(--accent-foreground));
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
|
@ -236,12 +370,14 @@ export function Nav() {
|
|||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.scroll-btn:hover {
|
||||
background: rgba(0, 255, 255, 0.3);
|
||||
box-shadow: 0 0 15px rgba(0, 255, 255, 0.5);
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 0 10px hsla(var(--primary), 0.5);
|
||||
}
|
||||
|
||||
.scroll-btn:active {
|
||||
|
@ -274,9 +410,9 @@ export function Nav() {
|
|||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(0, 255, 255, 0.2);
|
||||
color: #e0e0e0;
|
||||
background: hsl(var(--card));
|
||||
border: 1px solid hsl(var(--border));
|
||||
color: hsl(var(--foreground));
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
padding: 6px 14px;
|
||||
|
@ -289,8 +425,8 @@ export function Nav() {
|
|||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
overflow: hidden;
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.nav-item::before {
|
||||
|
@ -300,7 +436,7 @@ export function Nav() {
|
|||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 255, 255, 0.2), transparent);
|
||||
background: linear-gradient(90deg, transparent, rgba(var(--neon-color-rgb, 0, 255, 255), 0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
|
@ -309,28 +445,21 @@ export function Nav() {
|
|||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: rgba(0, 255, 255, 0.1);
|
||||
border-color: rgba(0, 255, 255, 0.4);
|
||||
color: #00ffff;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 255, 0.3);
|
||||
text-shadow: 0 0 8px rgba(0, 255, 255, 0.6);
|
||||
border-color: var(--neon-color, hsl(var(--primary)));
|
||||
color: var(--neon-color, hsl(var(--primary)));
|
||||
box-shadow: 0 0 15px rgba(var(--neon-color-rgb, 0, 255, 255), 0.3);
|
||||
text-shadow: 0 0 6px rgba(var(--neon-color-rgb, 0, 255, 255), 0.4);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: linear-gradient(135deg, rgba(0, 255, 255, 0.2), rgba(0, 200, 255, 0.3));
|
||||
border-color: #00ffff;
|
||||
color: #ffffff;
|
||||
box-shadow:
|
||||
0 0 20px rgba(0, 255, 255, 0.4),
|
||||
inset 0 0 10px rgba(0, 255, 255, 0.1);
|
||||
text-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
|
||||
border-color: var(--neon-color, hsl(var(--primary)));
|
||||
color: var(--neon-color, hsl(var(--primary)));
|
||||
box-shadow: 0 0 20px rgba(var(--neon-color-rgb, 0, 255, 255), 0.4);
|
||||
text-shadow: 0 0 8px rgba(var(--neon-color-rgb, 0, 255, 255), 0.6);
|
||||
}
|
||||
|
||||
.nav-item.active:hover {
|
||||
background: linear-gradient(135deg, rgba(0, 255, 255, 0.3), rgba(0, 200, 255, 0.4));
|
||||
box-shadow:
|
||||
0 0 25px rgba(0, 255, 255, 0.6),
|
||||
inset 0 0 15px rgba(0, 255, 255, 0.2);
|
||||
box-shadow: 0 0 25px rgba(var(--neon-color-rgb, 0, 255, 255), 0.6);
|
||||
}
|
||||
|
||||
.neon-glow {
|
||||
|
@ -339,7 +468,7 @@ export function Nav() {
|
|||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
background: linear-gradient(45deg, transparent, rgba(0, 255, 255, 0.3), transparent);
|
||||
background: linear-gradient(45deg, transparent, rgba(var(--neon-color-rgb, 0, 255, 255), 0.3), transparent);
|
||||
border-radius: 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
|
@ -354,14 +483,95 @@ export function Nav() {
|
|||
.nav-spacer {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* Set CSS custom properties for each neon color */
|
||||
.nav-item[style*="--neon-color: #25D366"] {
|
||||
--neon-color-rgb: 37, 211, 102;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #6366F1"] {
|
||||
--neon-color-rgb: 99, 102, 241;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #FFD700"] {
|
||||
--neon-color-rgb: 255, 215, 0;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #10B981"] {
|
||||
--neon-color-rgb: 16, 185, 129;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #2563EB"] {
|
||||
--neon-color-rgb: 37, 99, 235;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #8B5CF6"] {
|
||||
--neon-color-rgb: 139, 92, 246;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #059669"] {
|
||||
--neon-color-rgb: 5, 150, 105;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #DC2626"] {
|
||||
--neon-color-rgb: 220, 38, 38;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #1DB954"] {
|
||||
--neon-color-rgb: 29, 185, 84;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #F59E0B"] {
|
||||
--neon-color-rgb: 245, 158, 11;
|
||||
}
|
||||
.nav-item[style*="--neon-color: #6B7280"] {
|
||||
--neon-color-rgb: 107, 114, 128;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-container {
|
||||
height: 36px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.nav-spacer {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.nav-content {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.scroll-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.theme-toggle, .login-button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 13px;
|
||||
padding: 8px 16px;
|
||||
height: 36px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.nav-items {
|
||||
gap: 6px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.auth-controls {
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.nav-container {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.nav-spacer {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
|
@ -373,34 +583,35 @@ export function Nav() {
|
|||
}
|
||||
|
||||
.scroll-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 16px;
|
||||
.theme-toggle, .login-button {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 12px;
|
||||
padding: 4px 12px;
|
||||
height: 28px;
|
||||
padding: 10px 14px;
|
||||
height: 34px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.nav-items {
|
||||
gap: 4px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.auth-controls {
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.nav-container {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.nav-spacer {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 320px) {
|
||||
.nav-inner {
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
@ -409,20 +620,27 @@ export function Nav() {
|
|||
gap: 4px;
|
||||
}
|
||||
|
||||
.scroll-btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding: 8px 12px;
|
||||
height: 32px;
|
||||
font-size: 11px;
|
||||
padding: 3px 10px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.nav-items {
|
||||
gap: 3px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.theme-toggle, .login-button {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.scroll-btn {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
|
||||
import { ThemeProvider } from '@/components/ui/theme-provider';
|
||||
|
||||
import { Nav } from './client-nav';
|
||||
import './globals.css';
|
||||
|
||||
import './globals.css' // This path is correct if the file is in your src/app directory
|
||||
import { ReactNode } from 'react'
|
||||
import ModeToggle from '@/components/ui/mode-toggle';
|
||||
import { ThemeProvider } from './theme-provider';
|
||||
|
||||
|
||||
export default function RootLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className='flex flex-col min-h-screen'>
|
||||
<Nav />
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<ModeToggle />
|
||||
<Nav />
|
||||
{children}
|
||||
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
|
|
94
app/theme-provider.tsx
Normal file
94
app/theme-provider.tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
// themes/theme-provider.tsx
|
||||
'use client'
|
||||
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react'
|
||||
|
||||
type Theme = {
|
||||
name: string
|
||||
label: string
|
||||
cssFile: string
|
||||
}
|
||||
|
||||
const themes: Theme[] = [
|
||||
{ name: 'retrowave', label: 'RetroWave', cssFile: '/themes/retrowave.css' },
|
||||
{ name: '3dbevel', label: '3dbevel', cssFile: '/themes/3dbevel.css' },
|
||||
{ name: 'arcadeflash', label: 'Arcadeflash', cssFile: '/themes/arcadeflash.css' },
|
||||
{ name: 'cyberpunk', label: 'Cyberpunk', cssFile: '/themes/cyberpunk.css' },
|
||||
{ name: 'discofever', label: 'Discofever', cssFile: '/themes/discofever.css' },
|
||||
{ name: 'grungeera', label: 'Grungeera', cssFile: '/themes/grungeera.css' },
|
||||
{ name: 'jazzage', label: 'Jazzage', cssFile: '/themes/jazzage.css' },
|
||||
{ name: 'mellowgold', label: 'Mellowgold', cssFile: '/themes/mellowgold.css' },
|
||||
{ name: 'midcenturymod', label: 'Midcenturymod', cssFile: '/themes/midcenturymod.css' },
|
||||
{ name: 'oldhollywood', label: 'Oldhollywood', cssFile: '/themes/oldhollywood.css' },
|
||||
{ name: 'polaroidmemories', label: 'Polaroidmemories', cssFile: '/themes/polaroidmemories.css' },
|
||||
{ name: 'retrowave', label: 'Retrowave', cssFile: '/themes/retrowave.css' },
|
||||
{ name: 'saturdaycartoons', label: 'Saturdaycartoons', cssFile: '/themes/saturdaycartoons.css' },
|
||||
{ name: 'seasidepostcard', label: 'Seasidepostcard', cssFile: '/themes/seasidepostcard.css' },
|
||||
{ name: 'typewriter', label: 'Typewriter', cssFile: '/themes/typewriter.css' },
|
||||
{ name: 'vapordream', label: 'Vapordream', cssFile: '/themes/vapordream.css' },
|
||||
{ name: 'xeroxui', label: 'Xeroxui', cssFile: '/themes/xeroxui.css' },
|
||||
{ name: 'y2kglow', label: 'Y2kglow', cssFile: '/themes/y2kglow.css' }
|
||||
|
||||
]
|
||||
|
||||
type ThemeContextType = {
|
||||
theme: Theme
|
||||
setTheme: (themeName: string) => void
|
||||
themes: Theme[]
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [currentTheme, setCurrentTheme] = useState<Theme>(themes[0])
|
||||
const [isLoaded, setIsLoaded] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
// Load saved theme from localStorage
|
||||
const savedThemeName = localStorage.getItem('theme') || themes[0].name
|
||||
const savedTheme = themes.find(t => t.name === savedThemeName) || themes[0]
|
||||
setTheme(savedTheme.name)
|
||||
setIsLoaded(true)
|
||||
}, [])
|
||||
|
||||
const setTheme = (themeName: string) => {
|
||||
const theme = themes.find(t => t.name === themeName)
|
||||
if (!theme) return
|
||||
|
||||
// Remove any existing theme link
|
||||
const existingLink = document.getElementById('theme-stylesheet')
|
||||
if (existingLink) {
|
||||
document.head.removeChild(existingLink)
|
||||
}
|
||||
|
||||
// Create new link element
|
||||
const link = document.createElement('link')
|
||||
link.id = 'theme-stylesheet'
|
||||
link.rel = 'stylesheet'
|
||||
link.href = theme.cssFile
|
||||
link.onload = () => {
|
||||
setCurrentTheme(theme)
|
||||
localStorage.setItem('theme', theme.name)
|
||||
}
|
||||
|
||||
document.head.appendChild(link)
|
||||
}
|
||||
|
||||
if (!isLoaded) {
|
||||
return null // or loading spinner
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme: currentTheme, setTheme, themes }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useTheme() {
|
||||
const context = useContext(ThemeContext)
|
||||
if (!context) {
|
||||
throw new Error('useTheme must be used within a ThemeProvider')
|
||||
}
|
||||
return context
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
|
||||
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.5 KiB |
28
public/themes/3dbevel.css
Normal file
28
public/themes/3dbevel.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* 3DBevel Theme */
|
||||
--background: 0 0% 80%;
|
||||
--foreground: 0 0% 10%;
|
||||
--card: 0 0% 75%;
|
||||
--card-foreground: 0 0% 10%;
|
||||
--popover: 0 0% 80%;
|
||||
--popover-foreground: 0 0% 10%;
|
||||
--primary: 210 80% 40%;
|
||||
--primary-foreground: 0 0% 80%;
|
||||
--secondary: 0 0% 70%;
|
||||
--secondary-foreground: 0 0% 10%;
|
||||
--muted: 0 0% 65%;
|
||||
--muted-foreground: 0 0% 30%;
|
||||
--accent: 30 80% 40%;
|
||||
--accent-foreground: 0 0% 80%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 70%;
|
||||
--input: 0 0% 70%;
|
||||
--ring: 210 80% 40%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 210 80% 40%;
|
||||
--chart-2: 30 80% 40%;
|
||||
--chart-3: 120 80% 40%;
|
||||
--chart-4: 300 80% 40%;
|
||||
--chart-5: 240 80% 40%;
|
||||
}
|
28
public/themes/arcadeflash.css
Normal file
28
public/themes/arcadeflash.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* ArcadeFlash Theme */
|
||||
--background: 0 0% 5%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 0 0% 8%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 5%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 120 100% 50%;
|
||||
--primary-foreground: 0 0% 5%;
|
||||
--secondary: 0 0% 15%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 0 0% 10%;
|
||||
--muted-foreground: 0 0% 60%;
|
||||
--accent: 240 100% 50%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 100% 50%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 15%;
|
||||
--input: 0 0% 15%;
|
||||
--ring: 120 100% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 120 100% 50%;
|
||||
--chart-2: 240 100% 50%;
|
||||
--chart-3: 60 100% 50%;
|
||||
--chart-4: 0 100% 50%;
|
||||
--chart-5: 300 100% 50%;
|
||||
}
|
28
public/themes/cyberpunk.css
Normal file
28
public/themes/cyberpunk.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* CyberPunk Theme */
|
||||
--background: 240 30% 5%;
|
||||
--foreground: 60 100% 80%;
|
||||
--card: 240 30% 8%;
|
||||
--card-foreground: 60 100% 80%;
|
||||
--popover: 240 30% 5%;
|
||||
--popover-foreground: 60 100% 80%;
|
||||
--primary: 330 100% 60%;
|
||||
--primary-foreground: 240 30% 5%;
|
||||
--secondary: 240 30% 15%;
|
||||
--secondary-foreground: 60 100% 80%;
|
||||
--muted: 240 30% 10%;
|
||||
--muted-foreground: 60 100% 60%;
|
||||
--accent: 180 100% 60%;
|
||||
--accent-foreground: 240 30% 5%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 30% 15%;
|
||||
--input: 240 30% 15%;
|
||||
--ring: 330 100% 60%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 330 100% 60%;
|
||||
--chart-2: 180 100% 60%;
|
||||
--chart-3: 60 100% 60%;
|
||||
--chart-4: 0 100% 60%;
|
||||
--chart-5: 270 100% 60%;
|
||||
}
|
28
public/themes/discofever.css
Normal file
28
public/themes/discofever.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* DiscoFever Theme */
|
||||
--background: 270 20% 10%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 270 20% 15%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 270 20% 10%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 330 100% 60%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 270 20% 20%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 270 20% 25%;
|
||||
--muted-foreground: 270 10% 60%;
|
||||
--accent: 60 100% 60%;
|
||||
--accent-foreground: 270 20% 10%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 270 20% 20%;
|
||||
--input: 270 20% 20%;
|
||||
--ring: 330 100% 60%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 330 100% 60%;
|
||||
--chart-2: 60 100% 60%;
|
||||
--chart-3: 120 100% 60%;
|
||||
--chart-4: 240 100% 60%;
|
||||
--chart-5: 0 100% 60%;
|
||||
}
|
28
public/themes/grungeera.css
Normal file
28
public/themes/grungeera.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* GrungeEra Theme */
|
||||
--background: 30 10% 10%;
|
||||
--foreground: 30 30% 80%;
|
||||
--card: 30 10% 15%;
|
||||
--card-foreground: 30 30% 80%;
|
||||
--popover: 30 10% 10%;
|
||||
--popover-foreground: 30 30% 80%;
|
||||
--primary: 10 70% 50%;
|
||||
--primary-foreground: 30 30% 80%;
|
||||
--secondary: 30 10% 20%;
|
||||
--secondary-foreground: 30 30% 80%;
|
||||
--muted: 30 10% 25%;
|
||||
--muted-foreground: 30 30% 60%;
|
||||
--accent: 200 70% 50%;
|
||||
--accent-foreground: 30 30% 80%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 30 10% 20%;
|
||||
--input: 30 10% 20%;
|
||||
--ring: 10 70% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 10 70% 50%;
|
||||
--chart-2: 200 70% 50%;
|
||||
--chart-3: 90 70% 50%;
|
||||
--chart-4: 300 70% 50%;
|
||||
--chart-5: 30 70% 50%;
|
||||
}
|
28
public/themes/jazzage.css
Normal file
28
public/themes/jazzage.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* JazzAge Theme */
|
||||
--background: 30 20% 10%;
|
||||
--foreground: 40 30% 85%;
|
||||
--card: 30 20% 15%;
|
||||
--card-foreground: 40 30% 85%;
|
||||
--popover: 30 20% 10%;
|
||||
--popover-foreground: 40 30% 85%;
|
||||
--primary: 20 80% 50%;
|
||||
--primary-foreground: 40 30% 85%;
|
||||
--secondary: 30 20% 20%;
|
||||
--secondary-foreground: 40 30% 85%;
|
||||
--muted: 30 20% 25%;
|
||||
--muted-foreground: 40 30% 60%;
|
||||
--accent: 200 80% 50%;
|
||||
--accent-foreground: 40 30% 85%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 30 20% 20%;
|
||||
--input: 30 20% 20%;
|
||||
--ring: 20 80% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 20 80% 50%;
|
||||
--chart-2: 200 80% 50%;
|
||||
--chart-3: 350 80% 50%;
|
||||
--chart-4: 140 80% 50%;
|
||||
--chart-5: 260 80% 50%;
|
||||
}
|
28
public/themes/mellowgold.css
Normal file
28
public/themes/mellowgold.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* MellowGold Theme */
|
||||
--background: 45 30% 90%;
|
||||
--foreground: 30 20% 20%;
|
||||
--card: 45 30% 85%;
|
||||
--card-foreground: 30 20% 20%;
|
||||
--popover: 45 30% 90%;
|
||||
--popover-foreground: 30 20% 20%;
|
||||
--primary: 35 80% 50%;
|
||||
--primary-foreground: 45 30% 90%;
|
||||
--secondary: 45 30% 80%;
|
||||
--secondary-foreground: 30 20% 20%;
|
||||
--muted: 45 30% 75%;
|
||||
--muted-foreground: 30 20% 40%;
|
||||
--accent: 25 80% 50%;
|
||||
--accent-foreground: 45 30% 90%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 45 30% 80%;
|
||||
--input: 45 30% 80%;
|
||||
--ring: 35 80% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 35 80% 50%;
|
||||
--chart-2: 25 80% 50%;
|
||||
--chart-3: 15 80% 50%;
|
||||
--chart-4: 5 80% 50%;
|
||||
--chart-5: 55 80% 50%;
|
||||
}
|
28
public/themes/midcenturymod.css
Normal file
28
public/themes/midcenturymod.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* MidCenturyMod Theme */
|
||||
--background: 40 30% 95%;
|
||||
--foreground: 30 20% 20%;
|
||||
--card: 40 30% 90%;
|
||||
--card-foreground: 30 20% 20%;
|
||||
--popover: 40 30% 95%;
|
||||
--popover-foreground: 30 20% 20%;
|
||||
--primary: 180 60% 40%;
|
||||
--primary-foreground: 40 30% 95%;
|
||||
--secondary: 40 30% 85%;
|
||||
--secondary-foreground: 30 20% 20%;
|
||||
--muted: 40 30% 80%;
|
||||
--muted-foreground: 30 20% 40%;
|
||||
--accent: 350 60% 40%;
|
||||
--accent-foreground: 40 30% 95%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 40 30% 85%;
|
||||
--input: 40 30% 85%;
|
||||
--ring: 180 60% 40%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 180 60% 40%;
|
||||
--chart-2: 350 60% 40%;
|
||||
--chart-3: 40 60% 40%;
|
||||
--chart-4: 220 60% 40%;
|
||||
--chart-5: 300 60% 40%;
|
||||
}
|
28
public/themes/oldhollywood.css
Normal file
28
public/themes/oldhollywood.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* OldHollywood Theme */
|
||||
--background: 30 20% 10%;
|
||||
--foreground: 30 30% 85%;
|
||||
--card: 30 20% 15%;
|
||||
--card-foreground: 30 30% 85%;
|
||||
--popover: 30 20% 10%;
|
||||
--popover-foreground: 30 30% 85%;
|
||||
--primary: 10 70% 50%;
|
||||
--primary-foreground: 30 30% 85%;
|
||||
--secondary: 30 20% 20%;
|
||||
--secondary-foreground: 30 30% 85%;
|
||||
--muted: 30 20% 25%;
|
||||
--muted-foreground: 30 30% 60%;
|
||||
--accent: 40 70% 50%;
|
||||
--accent-foreground: 30 30% 85%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 30 20% 20%;
|
||||
--input: 30 20% 20%;
|
||||
--ring: 10 70% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 10 70% 50%;
|
||||
--chart-2: 40 70% 50%;
|
||||
--chart-3: 350 70% 50%;
|
||||
--chart-4: 200 70% 50%;
|
||||
--chart-5: 280 70% 50%;
|
||||
}
|
28
public/themes/polaroidmemories.css
Normal file
28
public/themes/polaroidmemories.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* PolaroidMemories Theme */
|
||||
--background: 50 30% 95%;
|
||||
--foreground: 30 20% 20%;
|
||||
--card: 50 30% 90%;
|
||||
--card-foreground: 30 20% 20%;
|
||||
--popover: 50 30% 95%;
|
||||
--popover-foreground: 30 20% 20%;
|
||||
--primary: 200 80% 50%;
|
||||
--primary-foreground: 50 30% 95%;
|
||||
--secondary: 50 30% 85%;
|
||||
--secondary-foreground: 30 20% 20%;
|
||||
--muted: 50 30% 80%;
|
||||
--muted-foreground: 30 20% 40%;
|
||||
--accent: 350 80% 50%;
|
||||
--accent-foreground: 50 30% 95%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 50 30% 85%;
|
||||
--input: 50 30% 85%;
|
||||
--ring: 200 80% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 200 80% 50%;
|
||||
--chart-2: 350 80% 50%;
|
||||
--chart-3: 50 80% 50%;
|
||||
--chart-4: 140 80% 50%;
|
||||
--chart-5: 260 80% 50%;
|
||||
}
|
28
public/themes/retrowave.css
Normal file
28
public/themes/retrowave.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* RetroWave Theme */
|
||||
--background: 240 21% 15%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 21% 18%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 21% 15%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 334 89% 62%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 240 21% 25%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 21% 20%;
|
||||
--muted-foreground: 240 5% 65%;
|
||||
--accent: 41 99% 60%;
|
||||
--accent-foreground: 240 21% 15%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 21% 25%;
|
||||
--input: 240 21% 25%;
|
||||
--ring: 334 89% 62%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 334 89% 62%;
|
||||
--chart-2: 41 99% 60%;
|
||||
--chart-3: 190 90% 50%;
|
||||
--chart-4: 280 89% 65%;
|
||||
--chart-5: 80 75% 55%;
|
||||
}
|
28
public/themes/saturdaycartoons.css
Normal file
28
public/themes/saturdaycartoons.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* SaturdayCartoons Theme */
|
||||
--background: 220 50% 95%;
|
||||
--foreground: 220 50% 20%;
|
||||
--card: 220 50% 90%;
|
||||
--card-foreground: 220 50% 20%;
|
||||
--popover: 220 50% 95%;
|
||||
--popover-foreground: 220 50% 20%;
|
||||
--primary: 30 100% 55%;
|
||||
--primary-foreground: 220 50% 95%;
|
||||
--secondary: 220 50% 85%;
|
||||
--secondary-foreground: 220 50% 20%;
|
||||
--muted: 220 50% 80%;
|
||||
--muted-foreground: 220 50% 40%;
|
||||
--accent: 120 100% 55%;
|
||||
--accent-foreground: 220 50% 95%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 220 50% 85%;
|
||||
--input: 220 50% 85%;
|
||||
--ring: 30 100% 55%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 30 100% 55%;
|
||||
--chart-2: 120 100% 55%;
|
||||
--chart-3: 240 100% 55%;
|
||||
--chart-4: 330 100% 55%;
|
||||
--chart-5: 60 100% 55%;
|
||||
}
|
28
public/themes/seasidepostcard.css
Normal file
28
public/themes/seasidepostcard.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* SeasidePostcard Theme */
|
||||
--background: 200 50% 95%;
|
||||
--foreground: 200 50% 20%;
|
||||
--card: 200 50% 90%;
|
||||
--card-foreground: 200 50% 20%;
|
||||
--popover: 200 50% 95%;
|
||||
--popover-foreground: 200 50% 20%;
|
||||
--primary: 30 100% 55%;
|
||||
--primary-foreground: 200 50% 95%;
|
||||
--secondary: 200 50% 85%;
|
||||
--secondary-foreground: 200 50% 20%;
|
||||
--muted: 200 50% 80%;
|
||||
--muted-foreground: 200 50% 40%;
|
||||
--accent: 350 100% 55%;
|
||||
--accent-foreground: 200 50% 95%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 200 50% 85%;
|
||||
--input: 200 50% 85%;
|
||||
--ring: 30 100% 55%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 30 100% 55%;
|
||||
--chart-2: 350 100% 55%;
|
||||
--chart-3: 200 100% 55%;
|
||||
--chart-4: 140 100% 55%;
|
||||
--chart-5: 260 100% 55%;
|
||||
}
|
28
public/themes/typewriter.css
Normal file
28
public/themes/typewriter.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* Typewriter Theme */
|
||||
--background: 0 0% 95%;
|
||||
--foreground: 0 0% 10%;
|
||||
--card: 0 0% 90%;
|
||||
--card-foreground: 0 0% 10%;
|
||||
--popover: 0 0% 95%;
|
||||
--popover-foreground: 0 0% 10%;
|
||||
--primary: 0 0% 20%;
|
||||
--primary-foreground: 0 0% 95%;
|
||||
--secondary: 0 0% 85%;
|
||||
--secondary-foreground: 0 0% 10%;
|
||||
--muted: 0 0% 80%;
|
||||
--muted-foreground: 0 0% 40%;
|
||||
--accent: 0 0% 70%;
|
||||
--accent-foreground: 0 0% 10%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 85%;
|
||||
--input: 0 0% 85%;
|
||||
--ring: 0 0% 20%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 0 0% 20%;
|
||||
--chart-2: 0 0% 40%;
|
||||
--chart-3: 0 0% 60%;
|
||||
--chart-4: 0 0% 30%;
|
||||
--chart-5: 0 0% 50%;
|
||||
}
|
28
public/themes/vapordream.css
Normal file
28
public/themes/vapordream.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* VaporDream Theme */
|
||||
--background: 260 20% 10%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 260 20% 13%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 260 20% 10%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 300 100% 70%;
|
||||
--primary-foreground: 260 20% 10%;
|
||||
--secondary: 260 20% 20%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 260 20% 15%;
|
||||
--muted-foreground: 260 10% 60%;
|
||||
--accent: 200 100% 70%;
|
||||
--accent-foreground: 260 20% 10%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 260 20% 20%;
|
||||
--input: 260 20% 20%;
|
||||
--ring: 300 100% 70%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 300 100% 70%;
|
||||
--chart-2: 200 100% 70%;
|
||||
--chart-3: 50 100% 60%;
|
||||
--chart-4: 330 100% 70%;
|
||||
--chart-5: 150 100% 60%;
|
||||
}
|
28
public/themes/xeroxui.css
Normal file
28
public/themes/xeroxui.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* XeroxUI Theme */
|
||||
--background: 0 0% 90%;
|
||||
--foreground: 240 10% 10%;
|
||||
--card: 0 0% 85%;
|
||||
--card-foreground: 240 10% 10%;
|
||||
--popover: 0 0% 90%;
|
||||
--popover-foreground: 240 10% 10%;
|
||||
--primary: 240 80% 40%;
|
||||
--primary-foreground: 0 0% 90%;
|
||||
--secondary: 0 0% 80%;
|
||||
--secondary-foreground: 240 10% 10%;
|
||||
--muted: 0 0% 75%;
|
||||
--muted-foreground: 240 10% 30%;
|
||||
--accent: 120 80% 40%;
|
||||
--accent-foreground: 0 0% 90%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 80%;
|
||||
--input: 0 0% 80%;
|
||||
--ring: 240 80% 40%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 240 80% 40%;
|
||||
--chart-2: 120 80% 40%;
|
||||
--chart-3: 60 80% 40%;
|
||||
--chart-4: 0 80% 40%;
|
||||
--chart-5: 300 80% 40%;
|
||||
}
|
28
public/themes/y2kglow.css
Normal file
28
public/themes/y2kglow.css
Normal file
|
@ -0,0 +1,28 @@
|
|||
:root {
|
||||
/* Y2KGlow Theme */
|
||||
--background: 240 10% 10%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 13%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 10%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 190 90% 50%;
|
||||
--primary-foreground: 240 10% 10%;
|
||||
--secondary: 240 10% 20%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 10% 15%;
|
||||
--muted-foreground: 240 5% 60%;
|
||||
--accent: 280 89% 65%;
|
||||
--accent-foreground: 240 10% 10%;
|
||||
--destructive: 0 85% 60%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 240 10% 20%;
|
||||
--input: 240 10% 20%;
|
||||
--ring: 190 90% 50%;
|
||||
--radius: 0.5rem;
|
||||
--chart-1: 190 90% 50%;
|
||||
--chart-2: 280 89% 65%;
|
||||
--chart-3: 80 75% 55%;
|
||||
--chart-4: 334 89% 62%;
|
||||
--chart-5: 41 99% 60%;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1,40 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react"
|
||||
import { Moon, Sun } from "lucide-react"
|
||||
import { useTheme } from "next-themes"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
|
||||
export default function ModeToggle() {
|
||||
const { setTheme } = useTheme()
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon">
|
||||
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
||||
Light
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
||||
Dark
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
||||
System
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
||||
import { type ThemeProviderProps } from "next-themes";
|
||||
|
||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
||||
}
|
|
@ -38,9 +38,10 @@
|
|||
},
|
||||
"include": [
|
||||
"src",
|
||||
|
||||
".next/types/**/*.ts"
|
||||
, "app", "components/user-auth-form.tsx" ],
|
||||
".next/types/**/*.ts",
|
||||
"app",
|
||||
"components/**/*.tsx",
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
|
@ -50,4 +51,4 @@
|
|||
"node_modules",
|
||||
"src-rust"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue