Add dark mode with CSS custom property theme system

Define 13 semantic color tokens (surface, text, border, hover) with
light/dark values in themes.css. Register with Tailwind via @theme inline.
Migrate all 335 Vue files from hardcoded gray/white classes to semantic
tokens. Add theme toggle (sun/moon/system) in user avatar dropdown.
Replace @tailwindcss/forms with custom form reset using theme vars.
Add status badge and alert tokens for dark mode. Theme-aware chart
grid/labels, skeleton placeholders, and editor. Inline script in
<head> prevents flash of wrong theme on load.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Darko Gjorgjijoski
2026-04-04 02:05:00 +02:00
parent 7fbe3d85a3
commit 88adfe0e50
221 changed files with 1265 additions and 982 deletions

View File

@@ -30,7 +30,7 @@
leave-to="opacity-0"
>
<DialogOverlay
class="fixed inset-0 transition-opacity bg-gray-500/75"
class="fixed inset-0 transition-opacity bg-surface-secondary0/75"
/>
</TransitionChild>
@@ -59,7 +59,7 @@
text-left
align-bottom
transition-all
bg-white
bg-surface
rounded-lg
shadow-xl
sm:my-8 sm:align-middle sm:w-full sm:p-6
@@ -76,35 +76,35 @@
w-12
h-12
mx-auto
bg-green-100
bg-alert-success-bg
rounded-full
"
:class="{
'bg-green-100': dialogStore.variant === 'primary',
'bg-red-100': dialogStore.variant === 'danger',
'bg-alert-success-bg': dialogStore.variant === 'primary',
'bg-alert-error-bg': dialogStore.variant === 'danger',
}"
>
<BaseIcon
v-if="dialogStore.variant === 'primary'"
name="CheckIcon"
class="w-6 h-6 text-green-600"
class="w-6 h-6 text-alert-success-text"
/>
<BaseIcon
v-else
name="ExclamationIcon"
class="w-6 h-6 text-red-600"
class="w-6 h-6 text-alert-error-text"
aria-hidden="true"
/>
</div>
<div class="mt-3 text-center sm:mt-5">
<DialogTitle
as="h3"
class="text-lg font-medium leading-6 text-gray-900"
class="text-lg font-medium leading-6 text-heading"
>
{{ dialogStore.title }}
</DialogTitle>
<div class="mt-2">
<p class="text-sm text-gray-500">
<p class="text-sm text-muted">
{{ dialogStore.message }}
</p>
</div>