From 85998de1453291054de4484eb4f06c0c7ba9469a Mon Sep 17 00:00:00 2001 From: keyur Chotaliya Date: Mon, 4 May 2026 00:01:55 +0530 Subject: [PATCH] feat: add dark/light mode toggle with persistence --- package-lock.json | 9 +- src/app/globals.css | 27 ++++-- src/components/marketing/Nav.tsx | 148 ++++++++++++++++++------------- tailwind.config.ts | 3 +- 4 files changed, 117 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53b5c67..e71b800 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { - "name": "securetrain", - "version": "0.1.0", + "name": "conply", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "securetrain", - "version": "0.1.0", + "name": "conply", + "version": "1.0.0", + "license": "MIT", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.96", "@anthropic-ai/sdk": "^0.27.0", diff --git a/src/app/globals.css b/src/app/globals.css index 57e6593..159c129 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -4,13 +4,30 @@ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap'); +/* global.css mein sabse upar ye change karo */ + :root { + /* --- LIGHT THEME (Default) --- */ + --bg: #ffffff; + --surface: #f8f9fa; + --border: #e2e8f0; + --brand: #5B54B8; + --brand-hover: #4a44a3; + --muted: #64748b; + --accent: #5B54B8; + --text: #0f172a; + --card: rgba(255,255,255,0.8); + --card-solid: #ffffff; + --card-border: rgba(0,0,0,0.1); +} + +.dark { + /* --- DARK THEME (Jo pehle root mein tha) --- */ --bg: #0e0c1e; --surface: #1a1730; --border: #2a2550; --brand: #5B54B8; --brand-hover: #7A74CC; - --brand-dark: #3F3A8A; --muted: #a9a5c4; --accent: #9d97e8; --text: #ffffff; @@ -57,12 +74,12 @@ body::after { /* Glassmorphism card */ .glass-card { - background: rgba(30,27,56,0.5); + background: var(--card); /* var use karo, hardcoded rgba nahi */ backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(91,84,184,0.15); - transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease; + border: 1px solid var(--card-border); + /* ... rest same */ } + .glass-card:hover { border-color: rgba(91,84,184,0.35); box-shadow: 0 0 30px -8px rgba(91,84,184,0.25); diff --git a/src/components/marketing/Nav.tsx b/src/components/marketing/Nav.tsx index 041d8c0..a6aede7 100644 --- a/src/components/marketing/Nav.tsx +++ b/src/components/marketing/Nav.tsx @@ -1,8 +1,8 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' import Link from 'next/link' import { usePathname } from 'next/navigation' -import { Menu, X, Sparkles, Crown, ChevronRight } from 'lucide-react' +import { Menu, X, Sparkles, Crown, ChevronRight, Moon, Sun } from 'lucide-react' import { ConplyLogo } from '@/components/ui/ConplyLogo' import { JurisdictionFlag } from '@/components/ui/JurisdictionFlag' import { BOOKING_URL } from '@/lib/constants' @@ -14,8 +14,8 @@ const LINKS = [ ] type Jurisdiction = { - slug: 'gibraltar' | 'luxembourg' - label: string + slug: 'gibraltar' | 'luxembourg' + label: string regulator: string } @@ -26,7 +26,7 @@ const JURISDICTIONS: Jurisdiction[] = [ const TIERS = [ { slug: 'pro', label: 'Pro', tag: 'Premium', desc: 'Team-wide compliance training', icon: Sparkles, color: '#a78bfa' }, - { slug: 'genius', label: 'Genius', tag: 'Platinum', desc: 'Personalised learning journeys per user', icon: Crown, color: '#fbbf24' }, + { slug: 'genius', label: 'Genius', tag: 'Platinum', desc: 'Personalised learning journeys per user', icon: Crown, color: '#fbbf24' }, ] export function Nav() { @@ -34,12 +34,38 @@ export function Nav() { const [open, setOpen] = useState(false) const [productsOpen, setProductsOpen] = useState(false) const [hoveredJx, setHoveredJx] = useState<'gibraltar' | 'luxembourg' | null>(null) + + // Dark theme state + const [theme, setTheme] = useState(null) + + // 1. Initial theme load (client-side only) + useEffect(() => { + const saved = localStorage.getItem("theme") || "light" + setTheme(saved) + }, []) + + // 2. Apply theme to HTML tag + useEffect(() => { + if (!theme) return + + if (theme === "dark") { + document.documentElement.classList.add("dark") + } else { + document.documentElement.classList.remove("dark") + } + localStorage.setItem("theme", theme) + }, [theme]) const isActive = (href: string) => href === pathname || pathname.startsWith(href + '/') const isProductsActive = pathname.startsWith('/products') + // Theme toggle function + const toggleTheme = () => { + setTheme(prev => (prev === "dark" ? "light" : "dark")) + } + return (