Styling & Theming

Styling system, theme architecture, and customization in DesQTA

Styling System Overview

DesQTA uses TailwindCSS 4 with a custom theme system that supports light/dark modes, custom accent colors, and theme packs.

TailwindCSS Configuration

Base Configuration

DesQTA uses TailwindCSS 4 with custom configuration:

// tailwind.config.js
export default {
  theme: {
    extend: {
      colors: {
        accent: {
          50: 'var(--accent-50)',
          100: 'var(--accent-100)',
          // ... more shades
          500: 'var(--accent-500)',
          // ... more shades
          900: 'var(--accent-900)',
        }
      }
    }
  }
}

CSS Custom Properties

Themes use CSS custom properties for dynamic theming:

:root {
  --accent-50: #eff6ff;
  --accent-500: #3b82f6;
  --accent-900: #1e3a8a;
  
  --zinc-50: #fafafa;
  --zinc-900: #18181b;
}

.dark {
  --zinc-50: #18181b;
  --zinc-900: #fafafa;
}

Theme System Architecture

Theme Structure

Themes are organized in static/themes/:

static/themes/
├── default/
│   └── theme-manifest.json
├── midnight/
│   ├── theme-manifest.json
│   ├── preview.png
│   └── styles/
│       ├── global.css
│       ├── light.css
│       ├── dark.css
│       └── components.css
└── sunset/
    └── ...

Theme Manifest

Each theme has a theme-manifest.json:

{
  "name": "midnight",
  "displayName": "Midnight",
  "version": "1.0.0",
  "description": "A dark theme with blue accents",
  "author": "DesQTA Team",
  "license": "MIT",
  "category": "dark",
  "tags": ["dark", "blue", "modern"],
  "compatibility": {
    "minVersion": "1.0.0",
    "maxVersion": "2.0.0"
  },
  "preview": {
    "thumbnail": "/themes/midnight/preview.png",
    "screenshots": []
  },
  "settings": {
    "defaultAccentColor": "#6366f1",
    "defaultTheme": "dark",
    "supportsLightMode": true,
    "supportsDarkMode": true,
    "supportsSystemMode": true,
    "allowUserCustomization": true
  },
  "customProperties": {
    "--accent-500": "#6366f1",
    "--accent-ring": "#818cf8"
  },
  "fonts": {
    "primary": "Inter",
    "secondary": "Inter",
    "monospace": "JetBrains Mono"
  },
  "animations": {
    "duration": "200ms",
    "easing": "ease-in-out",
    "enableEnhanced": true
  },
  "features": {
    "customScrollbars": true,
    "glassmorphism": false,
    "gradients": true,
    "shadows": true
  }
}

Using Themes

Loading Themes

import { themeService } from '$lib/services/themeService';

// Load theme
await themeService.loadTheme('midnight');

// Get theme manifest
const manifest = await themeService.getThemeManifest('midnight');

// List available themes
const themes = await themeService.listThemes();

Applying Themes

import { loadAndApplyTheme } from '$lib/stores/theme';

// Load and apply theme
await loadAndApplyTheme('midnight');

Theme Preview

import { startThemePreview, cancelThemePreview, applyPreviewTheme } from '$lib/stores/theme';

// Start preview (doesn't save)
await startThemePreview('sunset');

// Cancel preview
await cancelThemePreview();

// Apply preview
await applyPreviewTheme();

Styling Components

Using Tailwind Classes

<div class="bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white">
  Content
</div>

Using Accent Colors

<button class="bg-accent-500 hover:bg-accent-600 text-white">
  Button
</button>

Using Theme Properties

<div style="--custom-color: var(--accent-500)">
  Content
</div>

Color System

Accent Colors

Accent colors are customizable and used throughout the UI:

<!-- Primary accent -->
<div class="bg-accent-500 text-white">Primary</div>

<!-- Accent ring for focus -->
<button class="focus:ring-2 focus:ring-accent-500">Button</button>

<!-- Accent background -->
<div class="bg-accent-100 dark:bg-accent-900/30">Background</div>

Semantic Colors

Semantic colors for states:

<!-- Success -->
<div class="bg-green-500 text-white">Success</div>

<!-- Error -->
<div class="bg-red-500 text-white">Error</div>

<!-- Warning -->
<div class="bg-yellow-500 text-white">Warning</div>

<!-- Info -->
<div class="bg-blue-500 text-white">Info</div>

Dark Mode

Automatic Dark Mode

Dark mode is handled automatically via the dark class:

<div class="bg-white dark:bg-zinc-900">
  <p class="text-zinc-900 dark:text-white">Text</p>
</div>

System Theme Detection

import { theme } from '$lib/stores/theme';

// Listen for system theme changes
if ($theme === 'system') {
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
  mediaQuery.addEventListener('change', (e) => {
    // Theme updates automatically
  });
}

Custom CSS Injection

Injecting Custom CSS

import { cssInjectionService } from '$lib/services/cssInjectionService';

// Inject custom CSS
cssInjectionService.injectCustomCSS(`
  .custom-class {
    color: var(--accent-500);
  }
`);

// Remove custom CSS
cssInjectionService.removeCustomCSS();

Component Styling Patterns

Consistent Button Styles

<button class="
  px-4 py-2 rounded-lg
  bg-accent-500 text-white
  hover:bg-accent-600
  focus:outline-none focus:ring-2 focus:ring-accent-500 focus:ring-offset-2
  transition-all duration-200 transform
  hover:scale-105 active:scale-95
  disabled:opacity-50 disabled:cursor-not-allowed
">
  Button
</button>

Card Styles

<div class="
  bg-white dark:bg-zinc-800
  border border-zinc-200 dark:border-zinc-700
  rounded-lg shadow-md
  p-4
  transition-all duration-200
  hover:shadow-lg hover:scale-[1.02]
">
  Card Content
</div>

Input Styles

<input class="
  w-full px-4 py-2
  bg-white dark:bg-zinc-800
  border border-zinc-200 dark:border-zinc-700
  rounded-lg
  text-zinc-900 dark:text-white
  focus:outline-none focus:ring-2 focus:ring-accent-500 focus:border-transparent
  transition-all duration-200
" />

Responsive Design

Breakpoints

<!-- Mobile first -->
<div class="
  text-sm          <!-- Base (mobile) -->
  sm:text-base     <!-- Small screens -->
  md:text-lg       <!-- Medium screens -->
  lg:text-xl       <!-- Large screens -->
  xl:text-2xl      <!-- Extra large -->
">
  Responsive Text
</div>

Common Patterns

<!-- Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  <!-- Items -->
</div>

<!-- Flex -->
<div class="flex flex-col md:flex-row gap-4">
  <!-- Items -->
</div>

<!-- Spacing -->
<div class="p-4 md:p-6 lg:p-8">
  <!-- Content -->
</div>

Animations

Transitions

<!-- Standard transition -->
<div class="transition-all duration-200">
  Content
</div>

<!-- Hover effects -->
<button class="
  transition-all duration-200 transform
  hover:scale-105 active:scale-95
">
  Button
</button>

<!-- Color transitions -->
<div class="transition-colors duration-200">
  Content
</div>

Custom Animations

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in {
  animation: fadeIn 0.3s ease-out;
}

Creating Custom Themes

Theme Structure

  1. Create theme directory:
static/themes/my-theme/
├── theme-manifest.json
├── preview.png
└── styles/
    ├── global.css
    ├── light.css
    ├── dark.css
    └── components.css
  1. Create theme-manifest.json:
{
  "name": "my-theme",
  "displayName": "My Theme",
  "version": "1.0.0",
  "description": "A custom theme",
  "author": "Your Name",
  "license": "MIT",
  "settings": {
    "defaultAccentColor": "#8b5cf6",
    "defaultTheme": "dark",
    "supportsLightMode": true,
    "supportsDarkMode": true,
    "supportsSystemMode": true
  },
  "customProperties": {
    "--accent-500": "#8b5cf6",
    "--accent-ring": "#a78bfa"
  }
}
  1. Create CSS files:
/* styles/global.css */
:root {
  --accent-500: #8b5cf6;
  --accent-ring: #a78bfa;
}

/* styles/dark.css */
.dark {
  --background: #0f0f0f;
  --foreground: #ffffff;
}

Register Theme

Themes are automatically discovered from static/themes/. No registration needed!

Best Practices

1. Use Semantic Colors

<!-- ✅ Good - Semantic -->
<div class="bg-success-500">Success</div>

<!-- ❌ Avoid - Hard-coded -->
<div class="bg-green-500">Success</div>

2. Support Dark Mode

<!-- ✅ Good - Dark mode support -->
<div class="bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white">
  Content
</div>

<!-- ❌ Avoid - No dark mode -->
<div class="bg-white text-black">
  Content
</div>

3. Use CSS Variables

<!-- ✅ Good - CSS variables -->
<div style="color: var(--accent-500)">
  Content
</div>

<!-- ❌ Avoid - Hard-coded -->
<div style="color: #3b82f6">
  Content
</div>

4. Consistent Spacing

<!-- ✅ Good - Consistent spacing -->
<div class="p-4 m-4 gap-4">
  Content
</div>

<!-- ❌ Avoid - Inconsistent -->
<div class="p-3 m-5 gap-2">
  Content
</div>

5. Responsive Design

<!-- ✅ Good - Responsive -->
<div class="text-sm md:text-base lg:text-lg">
  Text
</div>

<!-- ❌ Avoid - Fixed size -->
<div class="text-base">
  Text
</div>

Theme Customization

User Customization

Users can customize:

  • Accent Color: Choose from color picker
  • Theme Mode: Light, Dark, or System
  • Theme Pack: Select from available themes
  • Custom CSS: Inject custom styles

Programmatic Customization

import { updateAccentColor, updateTheme } from '$lib/stores/theme';

// Update accent color
await updateAccentColor('#8b5cf6');

// Update theme mode
await updateTheme('dark');

Next Steps