Multi-Theme System Guide
Tailkits Astro Pro includes a powerful multi-theme system with 6 professionally designed theme presets. Each theme offers a complete design system with its own colors, typography, border styles, and spacing.
Available Themes
| Theme | Personality | Best For |
|---|---|---|
| Sharp | Precise, modern, technical | SaaS, Developer tools, Fintech |
| Soft | Sophisticated, calm, refined | Consulting, Agencies, Portfolios |
| Rounded | Warm, friendly, approachable | Creative agencies, Education, Lifestyle |
| Minimal | Clean, focused, essential | Architecture, Luxury, Editorial |
| Bold | Energetic, confident, modern | Startups, Tech products, Events |
| Luxe | Premium, sophisticated, timeless | Luxury brands, Real estate, Hospitality |
Quick Start
Switching Themes
Users can switch themes in two ways:
- Via the Theme Switcher - Available in the header navigation
- Via the Themes page - Visit
/themesfor a visual gallery
Themes are persisted to localStorage and apply instantly across all pages.
Programmatic Theme Change
// Set a theme
document.documentElement.setAttribute('data-theme', 'bold');
localStorage.setItem('theme-preset', 'bold');
// Listen for theme changes
window.addEventListener('themechange', (e) => {
console.log('Theme changed to:', e.detail.theme);
});
Theme Architecture
File Structure
src/
├── styles/
│ ├── themes/
│ │ ├── sharp.css # Sharp theme CSS variables
│ │ ├── soft.css # Soft theme CSS variables
│ │ ├── rounded.css # Rounded theme CSS variables
│ │ ├── minimal.css # Minimal theme CSS variables
│ │ ├── bold.css # Bold theme CSS variables
│ │ └── luxe.css # Luxe theme CSS variables
│ └── global.css # Imports themes + base styles
├── utils/
│ └── theme-config.ts # TypeScript theme definitions
└── components/
└── ThemeSwitcher.astro # Theme switcher component
CSS Variable Naming Convention
Each theme defines CSS custom properties in a [data-theme="themename"] selector:
[data-theme="soft"] {
/* Colors */
--color-primary-50: #f0f9ff;
--color-primary-500: #0ea5e9;
--color-primary-600: #0284c7;
--color-accent-500: #14b8a6;
/* Typography */
--font-heading: 'Instrument Serif', serif;
--font-body: 'DM Sans', sans-serif;
--font-weight-heading: 400;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
/* Spacing */
--spacing-xs: 0.5rem;
--spacing-sm: 0.75rem;
--spacing-md: 1rem;
/* Shadows */
--shadow-sm: 0 1px 3px rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 12px rgb(0 0 0 / 0.08);
/* Components */
--button-border-width: 1px;
--card-border-width: 0px;
}
Using Theme Variables in Components
Reference theme variables using CSS var() with fallbacks:
<!-- Button example -->
<button class="
px-4 py-2
rounded-[var(--radius-theme-md,0.75rem)]
bg-[var(--color-primary-600)]
font-[var(--font-theme-body)]
">
Click me
</button>
Theme-Aware Utility Classes
The global CSS includes pre-built theme-aware component classes:
/* Available in global.css */
.btn-theme { /* Theme-aware button */ }
.btn-theme-primary { /* Primary colored button */ }
.btn-theme-secondary { /* Secondary/outline button */ }
.btn-theme-accent { /* Accent colored button */ }
.card-theme { /* Theme-aware card */ }
.input-theme { /* Theme-aware input */ }
.heading-theme { /* Uses theme heading font */ }
.body-theme { /* Uses theme body font */ }
.badge-theme { /* Theme-aware badge */ }
Customizing Themes
Modifying an Existing Theme
Edit the theme’s CSS file in src/styles/themes/:
/* src/styles/themes/soft.css */
[data-theme="soft"] {
/* Change the primary color */
--color-primary-500: #6366f1; /* Changed to indigo */
--color-primary-600: #4f46e5;
/* Adjust border radius */
--radius-md: 12px; /* More rounded */
}
Creating a New Theme
- Create the CSS file in
src/styles/themes/:
/* src/styles/themes/custom.css */
[data-theme="custom"] {
/* Primary Colors */
--color-primary-50: #fef2f2;
--color-primary-100: #fee2e2;
--color-primary-500: #ef4444;
--color-primary-600: #dc2626;
--color-primary-700: #b91c1c;
/* Accent Colors */
--color-accent-500: #22c55e;
--color-accent-600: #16a34a;
/* Typography */
--font-heading: 'Your Font', sans-serif;
--font-body: 'Your Font', sans-serif;
--font-weight-heading: 700;
--font-weight-body: 400;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 16px;
--radius-full: 9999px;
/* Spacing */
--spacing-xs: 0.5rem;
--spacing-sm: 0.75rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
/* Shadows */
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px rgb(0 0 0 / 0.1);
/* Components */
--button-border-width: 2px;
--card-border-width: 1px;
--input-border-width: 1px;
}
- Import in global.css:
/* src/styles/global.css */
@import "./themes/custom.css";
- Add to theme config (optional, for TypeScript support):
// src/utils/theme-config.ts
export const themes = {
// ... existing themes
custom: {
name: 'Custom',
description: 'Your custom theme',
// ... full theme configuration
}
}
export type ThemeName = 'sharp' | 'soft' | 'rounded' | 'minimal' | 'bold' | 'luxe' | 'custom';
- Add fonts (if using custom fonts):
<!-- src/layouts/BaseLayout.astro -->
<link href="https://fonts.googleapis.com/css2?family=Your+Font:wght@400;700&display=swap" rel="stylesheet" />
Best Practices
1. Always Use CSS Variables for Theme-Dependent Styles
<!-- ✅ Good -->
<div class="bg-[var(--color-primary-500)] rounded-[var(--radius-theme-md)]">
<!-- ❌ Bad - hardcoded values -->
<div class="bg-blue-500 rounded-lg">
2. Provide Fallbacks
/* Fallback ensures graceful degradation */
border-radius: var(--radius-theme-md, 0.75rem);
background: var(--color-primary-600, var(--color-brand-600));
3. Use Theme-Aware Component Classes
<!-- Use pre-built theme-aware classes when possible -->
<button class="btn-theme btn-theme-primary">
Submit
</button>
<div class="card-theme">
<h3 class="heading-theme">Title</h3>
<p class="body-theme">Content</p>
</div>
4. Test All Themes During Development
Visit /themes to quickly preview your changes across all themes.
5. Consider Dark Mode
Each theme CSS file includes dark mode overrides:
[data-theme="soft"].dark,
.dark [data-theme="soft"] {
/* Dark mode overrides */
--color-neutral-50: #020617;
--color-neutral-900: #f1f5f9;
}
Theme Variable Reference
Color Variables
| Variable | Description |
|---|---|
--color-primary-50 to --color-primary-950 | Primary color scale |
--color-accent-50 to --color-accent-950 | Accent color scale |
--color-neutral-50 to --color-neutral-950 | Neutral gray scale |
Typography Variables
| Variable | Description |
|---|---|
--font-heading | Heading font family |
--font-body | Body text font family |
--font-weight-heading | Heading font weight |
--font-weight-body | Body font weight |
--letter-spacing-heading | Heading letter spacing |
Layout Variables
| Variable | Description |
|---|---|
--radius-sm | Small border radius |
--radius-md | Medium border radius |
--radius-lg | Large border radius |
--radius-full | Full/pill border radius |
--spacing-xs to --spacing-xl | Spacing scale |
Shadow Variables
| Variable | Description |
|---|---|
--shadow-sm | Small shadow |
--shadow-md | Medium shadow |
--shadow-lg | Large shadow |
--shadow-xl | Extra large shadow |
Component Variables
| Variable | Description |
|---|---|
--button-border-width | Button border width |
--card-border-width | Card border width |
--input-border-width | Input border width |
--transition-fast | Fast transition duration |
--transition-base | Base transition duration |
Troubleshooting
Theme Not Applying
- Check that
data-themeattribute is on the<html>element - Verify the theme CSS file is imported in
global.css - Clear localStorage and refresh:
localStorage.removeItem('theme-preset')
Fonts Not Loading
- Check Google Fonts imports in
BaseLayout.astro - Verify font family name matches exactly in theme CSS
- Check browser DevTools Network tab for font loading errors
Styles Not Updating
- Hard refresh the page (Cmd/Ctrl + Shift + R)
- Restart the dev server
- Check for CSS specificity conflicts
Related Resources
- Theme Showcase - Visual theme gallery
- Component Library - Theme-aware components
- Design Tokens - Complete token reference