add color theme with dark and light mode!

This commit is contained in:
padreug 2025-02-02 18:44:05 +01:00
parent 08b505c145
commit 23081d8685
5 changed files with 184 additions and 127 deletions

View file

@ -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 ... */

View 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>

View file

@ -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>

View file

@ -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

View file

@ -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",
}, },
}, },
}, },