add color theme with dark and light mode!
This commit is contained in:
parent
08b505c145
commit
23081d8685
5 changed files with 184 additions and 127 deletions
|
|
@ -1,76 +1,100 @@
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
/* @layer base { */
|
@layer base {
|
||||||
/* :root { */
|
:root {
|
||||||
/* --background: 0 0% 100%; */
|
--color-background: hsl(32 92% 87%); /* bg0 */
|
||||||
/* --foreground: 222.2 84% 4.9%; */
|
--color-foreground: hsl(40 13% 23%); /* fg */
|
||||||
/**/
|
|
||||||
/* --muted: 210 40% 96.1%; */
|
--color-card: hsl(39 59% 88%); /* bg1 */
|
||||||
/* --muted-foreground: 215.4 16.3% 46.9%; */
|
--color-card-foreground: hsl(40 13% 23%); /* fg */
|
||||||
/**/
|
|
||||||
/* --popover: 0 0% 100%; */
|
--color-popover: hsl(39 59% 88%); /* bg1 */
|
||||||
/* --popover-foreground: 222.2 84% 4.9%; */
|
--color-popover-foreground: hsl(40 13% 23%); /* fg */
|
||||||
/**/
|
|
||||||
/* --card: 0 0% 100%; */
|
--color-primary: hsl(0 100% 31%); /* red */
|
||||||
/* --card-foreground: 222.2 84% 4.9%; */
|
--color-primary-foreground: hsl(40 92% 88%); /* bg */
|
||||||
/**/
|
|
||||||
/* --border: 214.3 31.8% 91.4%; */
|
--color-secondary: hsl(39 46% 81%); /* bg2 */
|
||||||
/* --input: 214.3 31.8% 91.4%; */
|
--color-secondary-foreground: hsl(40 13% 23%); /* fg */
|
||||||
/**/
|
|
||||||
/* --primary: 222.2 47.4% 11.2%; */
|
--color-muted: hsl(37 29% 73%); /* bg3 */
|
||||||
/* --primary-foreground: 210 40% 98%; */
|
--color-muted-foreground: hsl(40 4% 36%); /* gray */
|
||||||
/**/
|
|
||||||
/* --secondary: 210 40% 96.1%; */
|
--color-accent: hsl(40 71% 49%); /* yellow */
|
||||||
/* --secondary-foreground: 222.2 47.4% 11.2%; */
|
--color-accent-foreground: hsl(0 0% 16%);
|
||||||
/**/
|
|
||||||
/* --accent: 210 40% 96.1%; */
|
--color-destructive: hsl(0 76% 46%); /* bright_red */
|
||||||
/* --accent-foreground: 222.2 47.4% 11.2%; */
|
--color-destructive-foreground: hsl(40 92% 88%); /* bg */
|
||||||
/**/
|
|
||||||
/* --destructive: 0 84.2% 60.2%; */
|
--color-border: hsl(33 14% 59%); /* fg4 */
|
||||||
/* --destructive-foreground: 210 40% 98%; */
|
--color-input: hsl(33 14% 59%); /* fg4 */
|
||||||
/**/
|
--color-ring: hsl(0 100% 31%); /* red */
|
||||||
/* --ring: 222.2 84% 4.9%; */
|
|
||||||
/**/
|
--radius: 0.5rem;
|
||||||
/* --radius: 0.5rem; */
|
}
|
||||||
/* } */
|
|
||||||
/**/
|
.dark {
|
||||||
/* .dark { */
|
--color-background: hsl(0 0% 16%); /* bg0 */
|
||||||
/* --background: 222.2 84% 4.9%; */
|
--color-foreground: hsl(40 92% 88%); /* fg */
|
||||||
/* --foreground: 210 40% 98%; */
|
|
||||||
/**/
|
--color-card: hsl(0 7% 23%); /* bg1 */
|
||||||
/* --muted: 217.2 32.6% 17.5%; */
|
--color-card-foreground: hsl(40 92% 88%); /* fg */
|
||||||
/* --muted-foreground: 215 20.2% 65.1%; */
|
|
||||||
/**/
|
--color-popover: hsl(0 7% 23%); /* bg1 */
|
||||||
/* --popover: 222.2 84% 4.9%; */
|
--color-popover-foreground: hsl(40 92% 88%); /* fg */
|
||||||
/* --popover-foreground: 210 40% 98%; */
|
|
||||||
/**/
|
--color-primary: hsl(6 93% 59%); /* red */
|
||||||
/* --card: 222.2 84% 4.9%; */
|
--color-primary-foreground: hsl(0 0% 16%); /* bg */
|
||||||
/* --card-foreground: 210 40% 98%; */
|
|
||||||
/**/
|
--color-secondary: hsl(0 5% 29%); /* bg2 */
|
||||||
/* --border: 217.2 32.6% 17.5%; */
|
--color-secondary-foreground: hsl(40 92% 88%); /* fg */
|
||||||
/* --input: 217.2 32.6% 17.5%; */
|
|
||||||
/**/
|
--color-muted: hsl(20 6% 36%); /* bg3 */
|
||||||
/* --primary: 210 40% 98%; */
|
--color-muted-foreground: hsl(33 14% 59%); /* gray */
|
||||||
/* --primary-foreground: 222.2 47.4% 11.2%; */
|
|
||||||
/**/
|
--color-accent: hsl(42 95% 58%); /* yellow */
|
||||||
/* --secondary: 217.2 32.6% 17.5%; */
|
--color-accent-foreground: hsl(0 0% 16%);
|
||||||
/* --secondary-foreground: 210 40% 98%; */
|
|
||||||
/**/
|
--color-destructive: hsl(6 93% 59%); /* bright_red */
|
||||||
/* --accent: 217.2 32.6% 17.5%; */
|
--color-destructive-foreground: hsl(40 92% 88%); /* bg */
|
||||||
/* --accent-foreground: 210 40% 98%; */
|
|
||||||
/**/
|
--color-border: hsl(24 10% 51%); /* fg4 */
|
||||||
/* --destructive: 0 62.8% 30.6%; */
|
--color-input: hsl(24 10% 51%); /* fg4 */
|
||||||
/* --destructive-foreground: 210 40% 98%; */
|
--color-ring: hsl(6 93% 59%); /* red */
|
||||||
/**/
|
}
|
||||||
/* --ring: 212.7 26.8% 83.9%; */
|
|
||||||
/* } */
|
* {
|
||||||
/* } */
|
@apply box-border;
|
||||||
/**/
|
}
|
||||||
/* @layer base { */
|
|
||||||
/* * { */
|
body {
|
||||||
/* @apply border-border; */
|
@apply bg-background text-foreground;
|
||||||
/* } */
|
}
|
||||||
/* body { */
|
}
|
||||||
/* @apply bg-background text-foreground; */
|
|
||||||
/* } */
|
@utility bg-background {
|
||||||
/* } */
|
background-color: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility text-foreground {
|
||||||
|
color: var(--color-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add other utility classes for colors */
|
||||||
|
@utility bg-card {
|
||||||
|
background-color: var(--color-card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility text-card-foreground {
|
||||||
|
color: var(--color-card-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility bg-primary {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@utility text-primary-foreground {
|
||||||
|
color: var(--color-primary-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... add other utility classes as needed ... */
|
||||||
|
|
|
||||||
38
src/components/ThemeToggle.vue
Normal file
38
src/components/ThemeToggle.vue
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { Moon, Sun } from 'lucide-vue-next'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const isDark = ref(false)
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
isDark.value = !isDark.value
|
||||||
|
updateTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateTheme = () => {
|
||||||
|
if (isDark.value) {
|
||||||
|
document.documentElement.classList.add('dark')
|
||||||
|
localStorage.setItem('theme', 'dark')
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark')
|
||||||
|
localStorage.setItem('theme', 'light')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const savedTheme = localStorage.getItem('theme')
|
||||||
|
isDark.value =
|
||||||
|
savedTheme === 'dark' ||
|
||||||
|
(!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
updateTheme()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button variant="ghost" size="icon" @click="toggleTheme">
|
||||||
|
<Sun v-if="isDark" class="h-5 w-5" />
|
||||||
|
<Moon v-else class="h-5 w-5" />
|
||||||
|
<span class="sr-only">Toggle theme</span>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
@ -3,9 +3,9 @@ const currentYear = new Date().getFullYear()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<footer class="border-t mt-auto">
|
<footer class="bg-card border-t border-border">
|
||||||
<div class="container mx-auto px-4 py-6">
|
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex flex-col sm:flex-row items-center justify-between gap-4">
|
<div class="flex h-16 items-center justify-between">
|
||||||
<!-- Powered by section -->
|
<!-- Powered by section -->
|
||||||
<div class="flex items-center space-x-2 text-sm text-muted-foreground">
|
<div class="flex items-center space-x-2 text-sm text-muted-foreground">
|
||||||
<span>Powered by</span>
|
<span>Powered by</span>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { Menu, X } from 'lucide-vue-next'
|
import { Menu, X } from 'lucide-vue-next'
|
||||||
|
import ThemeToggle from '@/components/ThemeToggle.vue'
|
||||||
|
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
|
|
||||||
|
|
@ -16,14 +17,14 @@ const toggleMenu = () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav class="bg-white shadow-sm">
|
<nav class="bg-card border-b border-border">
|
||||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex h-16 justify-between">
|
<div class="flex h-16 justify-between">
|
||||||
<!-- Logo and Desktop Navigation -->
|
<!-- Logo and Desktop Navigation -->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex flex-shrink-0 items-center">
|
<div class="flex flex-shrink-0 items-center">
|
||||||
<!-- Replace with your logo -->
|
<!-- Replace with your logo -->
|
||||||
<router-link to="/" class="text-xl font-bold">
|
<router-link to="/" class="text-xl font-bold text-card-foreground">
|
||||||
⚡️ Lightning Directory
|
⚡️ Lightning Directory
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -37,8 +38,8 @@ const toggleMenu = () => {
|
||||||
class="inline-flex items-center px-1 pt-1 text-sm font-medium"
|
class="inline-flex items-center px-1 pt-1 text-sm font-medium"
|
||||||
:class="[
|
:class="[
|
||||||
$route.path === item.href
|
$route.path === item.href
|
||||||
? 'border-b-2 border-primary text-gray-900'
|
? 'border-b-2 border-primary text-card-foreground'
|
||||||
: 'text-gray-500 hover:border-b-2 hover:border-gray-300 hover:text-gray-700'
|
: 'text-muted-foreground hover:border-b-2 hover:border-muted hover:text-card-foreground'
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
|
@ -46,6 +47,11 @@ const toggleMenu = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Theme Toggle -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<ThemeToggle />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Mobile menu button -->
|
<!-- Mobile menu button -->
|
||||||
<div class="flex items-center sm:hidden">
|
<div class="flex items-center sm:hidden">
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -23,69 +23,58 @@ module.exports = {
|
||||||
},
|
},
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
border: "hsl(var(--border))",
|
background: 'var(--color-background)',
|
||||||
input: "hsl(var(--input))",
|
foreground: 'var(--color-foreground)',
|
||||||
ring: "hsl(var(--ring))",
|
card: {
|
||||||
background: "hsl(var(--background))",
|
DEFAULT: 'var(--color-card)',
|
||||||
foreground: "hsl(var(--foreground))",
|
foreground: 'var(--color-card-foreground)',
|
||||||
primary: {
|
|
||||||
DEFAULT: "hsl(var(--primary))",
|
|
||||||
foreground: "hsl(var(--primary-foreground))",
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
DEFAULT: "hsl(var(--secondary))",
|
|
||||||
foreground: "hsl(var(--secondary-foreground))",
|
|
||||||
},
|
|
||||||
destructive: {
|
|
||||||
DEFAULT: "hsl(var(--destructive))",
|
|
||||||
foreground: "hsl(var(--destructive-foreground))",
|
|
||||||
},
|
|
||||||
muted: {
|
|
||||||
DEFAULT: "hsl(var(--muted))",
|
|
||||||
foreground: "hsl(var(--muted-foreground))",
|
|
||||||
},
|
|
||||||
accent: {
|
|
||||||
DEFAULT: "hsl(var(--accent))",
|
|
||||||
foreground: "hsl(var(--accent-foreground))",
|
|
||||||
},
|
},
|
||||||
popover: {
|
popover: {
|
||||||
DEFAULT: "hsl(var(--popover))",
|
DEFAULT: 'var(--color-popover)',
|
||||||
foreground: "hsl(var(--popover-foreground))",
|
foreground: 'var(--color-popover-foreground)',
|
||||||
},
|
},
|
||||||
card: {
|
primary: {
|
||||||
DEFAULT: "hsl(var(--card))",
|
DEFAULT: 'var(--color-primary)',
|
||||||
foreground: "hsl(var(--card-foreground))",
|
foreground: 'var(--color-primary-foreground)',
|
||||||
},
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: 'var(--color-secondary)',
|
||||||
|
foreground: 'var(--color-secondary-foreground)',
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: 'var(--color-muted)',
|
||||||
|
foreground: 'var(--color-muted-foreground)',
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: 'var(--color-accent)',
|
||||||
|
foreground: 'var(--color-accent-foreground)',
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: 'var(--color-destructive)',
|
||||||
|
foreground: 'var(--color-destructive-foreground)',
|
||||||
|
},
|
||||||
|
border: 'var(--color-border)',
|
||||||
|
input: 'var(--color-input)',
|
||||||
|
ring: 'var(--color-ring)',
|
||||||
},
|
},
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
xl: "calc(var(--radius) + 4px)",
|
lg: 'var(--radius)',
|
||||||
lg: "var(--radius)",
|
md: 'calc(var(--radius) - 2px)',
|
||||||
md: "calc(var(--radius) - 2px)",
|
sm: 'calc(var(--radius) - 4px)',
|
||||||
sm: "calc(var(--radius) - 4px)",
|
|
||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
"accordion-down": {
|
"accordion-down": {
|
||||||
from: { height: 0 },
|
from: { height: "0" },
|
||||||
to: { height: "var(--radix-accordion-content-height)" },
|
to: { height: "var(--radix-accordion-content-height)" },
|
||||||
},
|
},
|
||||||
"accordion-up": {
|
"accordion-up": {
|
||||||
from: { height: "var(--radix-accordion-content-height)" },
|
from: { height: "var(--radix-accordion-content-height)" },
|
||||||
to: { height: 0 },
|
to: { height: "0" },
|
||||||
},
|
|
||||||
"collapsible-down": {
|
|
||||||
from: { height: 0 },
|
|
||||||
to: { height: 'var(--radix-collapsible-content-height)' },
|
|
||||||
},
|
|
||||||
"collapsible-up": {
|
|
||||||
from: { height: 'var(--radix-collapsible-content-height)' },
|
|
||||||
to: { height: 0 },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
"accordion-down": "accordion-down 0.2s ease-out",
|
"accordion-down": "accordion-down 0.2s ease-out",
|
||||||
"accordion-up": "accordion-up 0.2s ease-out",
|
"accordion-up": "accordion-up 0.2s ease-out",
|
||||||
"collapsible-down": "collapsible-down 0.2s ease-in-out",
|
|
||||||
"collapsible-up": "collapsible-up 0.2s ease-in-out",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue