---
description: Creates a CSS custom property-based theme system for Vue 3 projects. Use when implementing dark/light mode, multi-theme support, or CSS variable theming in Vue 3 apps.
---

# Vue 3 Theme System Creator

Create a multi-theme system using CSS custom properties + Tailwind CSS for Vue 3 projects.

## Architecture

Theme system uses two layers:
1. **CSS Custom Properties** — Define all colors, shadows, and visual tokens per theme
2. **Tailwind CSS** — Handle layout, spacing, and responsive design

## Theme CSS Template

Create themes in `src/style.css` or `src/styles/themes.css`:

```css
/* ===== Midnight Theme (Default) ===== */
[data-theme="midnight"] {
  --bg:          #0F0F14;
  --surface:     #1A1A24;
  --surface-alt: #24243A;
  --text:        #E8E8F0;
  --text-muted:  #7A7A9A;
  --accent:      #6366F1;
  --accent-light:#818CF8;
  --danger:      #EF4444;
  --success:     #22C55E;
  --warning:     #F59E0B;
  --border:      #2A2A3E;
  --input-bg:    #14141E;
  --shadow-sm:   0 1px 3px rgba(0,0,0,0.4);
  --shadow-md:   0 4px 12px rgba(0,0,0,0.5);
  --shadow-lg:   0 8px 24px rgba(0,0,0,0.6);
}

/* ===== Daylight Theme ===== */
[data-theme="daylight"] {
  --bg:          #FAFAF5;
  --surface:     #FFFFFF;
  --surface-alt: #F0F0EB;
  --text:        #1A1A2E;
  --text-muted:  #8A8A9A;
  --accent:      #D97706;
  --accent-light:#F59E0B;
  --danger:      #DC2626;
  --success:     #16A34A;
  --warning:     #CA8A04;
  --border:      #E5E5DB;
  --input-bg:    #F5F5F0;
  --shadow-sm:   0 1px 3px rgba(0,0,0,0.08);
  --shadow-md:   0 4px 12px rgba(0,0,0,0.1);
  --shadow-lg:   0 8px 24px rgba(0,0,0,0.12);
}
```

## Rules

1. **Never use Tailwind color classes** for anything that should respond to theme changes
   - WRONG: `class="bg-gray-100 text-white"`
   - RIGHT: `style="background: var(--surface); color: var(--text);"`
2. **Tailwind handles**: layout (`flex`, `grid`), spacing (`p-4`, `gap-2`), sizing (`w-full`, `h-6`), responsive (`md:`, `lg:`), borders (`border`, `rounded-lg`), transitions (`transition-all duration-200`)
3. **CSS variables handle**: all colors, shadows, and visual appearance
4. **Theme switching**: Set `data-theme` attribute on `<html>` element

## Composable

Create `src/composables/useTheme.js`:

```js
import { ref, watch } from 'vue'

export const themes = [
  { key: 'midnight', color: '#6366F1', label: 'Midnight' },
  { key: 'daylight', color: '#D97706', label: 'Daylight' },
]

const current = ref(localStorage.getItem('app_theme') || 'midnight')

watch(current, (val) => {
  document.documentElement.setAttribute('data-theme', val)
  localStorage.setItem('app_theme', val)
}, { immediate: true })

export function useTheme() {
  const setTheme = (key) => { current.value = key }
  return { current, setTheme, themes }
}
```

## Component Usage

```vue
<template>
  <!-- Correct: Tailwind for layout, CSS vars for color -->
  <div class="flex items-center gap-3 p-4 rounded-xl transition-all duration-300"
       style="background: var(--surface); color: var(--text);
              border: 1px solid var(--border); box-shadow: var(--shadow-sm);">
    <span class="text-sm font-medium">{{ title }}</span>
  </div>

  <!-- Theme switcher -->
  <button v-for="t in themes" :key="t.key"
          class="w-6 h-6 rounded-full border-none cursor-pointer transition-all duration-200"
          :style="{
            background: current === t.key ? t.color : 'transparent',
            opacity: current === t.key ? 1 : 0.4,
          }"
          @click="setTheme(t.key)">
  </button>
</template>
```

## Required CSS Variables

Every theme MUST define all of these variables:

| Variable | Purpose |
|----------|---------|
| `--bg` | Page background |
| `--surface` | Card/panel background |
| `--surface-alt` | Alternative surface (hover, alternate rows) |
| `--text` | Primary text color |
| `--text-muted` | Secondary/muted text |
| `--accent` | Primary action color |
| `--accent-light` | Lighter accent (hover states) |
| `--danger` | Error/destructive color |
| `--success` | Success/positive color |
| `--warning` | Warning color |
| `--border` | Border color |
| `--input-bg` | Input field background |
| `--shadow-sm` | Subtle shadow |
| `--shadow-md` | Medium shadow |
| `--shadow-lg` | Large/elevated shadow |
