Theme Customization Guide
DayFlow Calendar’s appearance is controlled by a set of namespaced CSS custom properties (--df-color-*). All tokens are defined inside @layer df-theme, so host applications can override them without !important — regardless of whether they use Tailwind or plain CSS.
Table of Contents
- Custom Calendar Type Colors
- CSS Variable Reference
- Override Methods
- Tailwind v4 Integration
- Creating a Custom Theme
Custom Calendar Type Colors
Basic Custom Colors
Define unique colors for each calendar type with separate light and dark variants:
const calendar = useCalendarApp({
calendarTypes: [
{
id: 'personal',
name: 'Personal',
colors: {
lineColor: '#0891b2', // cyan-600
eventColor: '#cffafe', // cyan-100
eventSelectedColor: '#a5f3fc', // cyan-200
textColor: '#164e63', // cyan-900
},
darkColors: {
lineColor: '#22d3ee', // cyan-400
eventColor: '#164e63', // cyan-900
eventSelectedColor: '#083344', // cyan-950
textColor: '#cffafe', // cyan-100
},
},
],
});Color Properties Explained
- lineColor: Border and accent color (left bar on events)
- eventColor: Event background fill
- eventSelectedColor: Background fill when an event is selected
- textColor: Text color for event title and time
Brand Color Integration
{
id: 'brand',
name: 'Brand Events',
colors: {
lineColor: '#6366f1', // Brand indigo
eventColor: '#e0e7ff', // Indigo-100
eventSelectedColor: '#c7d2fe', // Indigo-200
textColor: '#312e81', // Indigo-900
},
darkColors: {
lineColor: '#a5b4fc', // Indigo-300
eventColor: '#312e81', // Indigo-900
eventSelectedColor: '#1e1b4b', // Indigo-950
textColor: '#e0e7ff', // Indigo-100
},
}Color Generation Helper
// utils/colorGenerator.ts
interface ColorSet {
lineColor: string;
eventColor: string;
eventSelectedColor: string;
textColor: string;
}
export function generateLightColors(baseColor: string): ColorSet {
return {
lineColor: baseColor,
eventColor: lighten(baseColor, 0.9),
eventSelectedColor: lighten(baseColor, 0.8),
textColor: darken(baseColor, 0.4),
};
}
export function generateDarkColors(baseColor: string): ColorSet {
return {
lineColor: lighten(baseColor, 0.3),
eventColor: darken(baseColor, 0.6),
eventSelectedColor: darken(baseColor, 0.7),
textColor: lighten(baseColor, 0.8),
};
}CSS Variable Reference
All DayFlow theme tokens use the --df-color- prefix to avoid collisions with any host application variables.
| Variable | Purpose |
|---|---|
--df-color-background | Calendar background |
--df-color-foreground | Primary text color |
--df-color-hover | Hover state background |
--df-color-border | Borders and dividers |
--df-color-card | Card / panel background |
--df-color-card-foreground | Card text color |
--df-color-muted | Subtle background areas |
--df-color-muted-foreground | Muted / secondary text |
--df-color-primary | Primary accent (buttons, selected states) |
--df-color-primary-foreground | Text on primary-colored backgrounds |
--df-color-secondary | Secondary accent |
--df-color-secondary-foreground | Text on secondary-colored backgrounds |
--df-color-destructive | Destructive actions |
--df-color-destructive-foreground | Text on destructive backgrounds |
Override Methods
Method 1 — Container-level override (works everywhere)
Set variables directly on .df-calendar-container. Because this rule is outside any @layer, it always wins over the library’s defaults regardless of Tailwind version or CSS setup.
/* styles/globals.css */
.df-calendar-container {
--df-color-primary: #6366f1;
--df-color-background: #f9fafb;
--df-color-border: #e0e7ff;
}
/* Dark mode — target the container when the .dark class is on an ancestor */
.dark .df-calendar-container {
--df-color-primary: #a5b4fc;
--df-color-background: #1e1e2e;
--df-color-border: #312e81;
}This is the recommended approach for most projects. The variables are scoped to the calendar and do not affect anything outside it.
Method 2 — Named layer ordering (Tailwind v4)
DayFlow’s defaults live inside @layer df-theme. You can declare a higher-priority layer before importing the library, then put your overrides in it:
/* app.css */
/* Declare df-theme first so your layer wins */
@layer df-theme, dayflow-overrides;
@import '@dayflow/core/dist/styles.css';
@import 'tailwindcss';
@layer dayflow-overrides {
:where(:root) {
--df-color-primary: #6366f1;
--df-color-background: #f9fafb;
}
:where(.dark) {
--df-color-primary: #a5b4fc;
--df-color-background: #1e1e2e;
}
}Method 3 — Wrap library in a layer (Tailwind v4 advanced)
Wrap the library import in a named layer so that Tailwind’s built-in @layer theme automatically outranks it, then use @theme to inject overrides:
/* app.css */
/* The layer declared first has the lowest priority */
@import '@dayflow/core/dist/styles.css' layer(dayflow);
@import 'tailwindcss';
/* @theme creates variables inside @layer theme, which outranks @layer dayflow */
@theme {
--df-color-primary: #6366f1;
--df-color-background: #f9fafb;
}Note: Use
@theme(not@theme inline) here.@theme inlineinlines values into utility classes at build time and does not produce a runtime CSS custom property, so the calendar’svar(--df-color-*)references would remain unaffected.
Tailwind v4 Integration
Tailwind v4 is configured entirely through CSS — there is no tailwind.config.js. The library’s CSS already includes the necessary @source directives to scan its own components.
Minimal setup
/* app.css */
@import '@dayflow/core/dist/styles.css';
@import 'tailwindcss';Dark mode
DayFlow respects the .dark class on any ancestor element (including <html>). Apply it with JavaScript:
document.documentElement.classList.toggle('dark', isDark);System-preference dark mode (no explicit class) is also supported automatically.
Applying overrides with @theme
@import '@dayflow/core/dist/styles.css' layer(dayflow);
@import 'tailwindcss';
@theme {
--df-color-primary: #6366f1;
--df-color-primary-foreground: #ffffff;
--df-color-secondary: #8b5cf6;
--df-color-secondary-foreground: #ffffff;
}Wrapping the calendar with Tailwind utilities
function ThemedCalendar({ calendar }) {
return (
<div className='rounded-2xl shadow-xl ring-1 ring-gray-200 dark:ring-gray-700'>
<DayFlowCalendar calendar={calendar} />
</div>
);
}Creating a Custom Theme
// themes/oceanTheme.ts
export const oceanTheme = {
mode: 'light' as const,
calendarTypes: [
{
id: 'deep-ocean',
name: 'Deep Ocean',
colors: {
lineColor: '#0369a1',
eventColor: '#e0f2fe',
eventSelectedColor: '#bae6fd',
textColor: '#0c4a6e',
},
darkColors: {
lineColor: '#7dd3fc',
eventColor: '#0c4a6e',
eventSelectedColor: '#083344',
textColor: '#e0f2fe',
},
},
{
id: 'coral-reef',
name: 'Coral Reef',
colors: {
lineColor: '#ea580c',
eventColor: '#ffedd5',
eventSelectedColor: '#fed7aa',
textColor: '#7c2d12',
},
darkColors: {
lineColor: '#fb923c',
eventColor: '#7c2d12',
eventSelectedColor: '#431407',
textColor: '#ffedd5',
},
},
],
};Pair it with CSS variable overrides for full visual consistency:
/* Ocean theme CSS tokens */
.df-calendar-container {
--df-color-primary: #0369a1;
--df-color-background: #f0f9ff;
--df-color-border: #bae6fd;
}
.dark .df-calendar-container {
--df-color-primary: #7dd3fc;
--df-color-background: #0c1220;
--df-color-border: #0c4a6e;
}Resources
Tools
- WebAIM Contrast Checker - Test color contrast
- Coolors - Generate color palettes
- Color Contrast Analyzer - Desktop tool
Libraries
- chroma-js - Color manipulation
- tinycolor2 - Color utilities
- color - Color conversion
Tailwind Resources
- Tailwind v4 Upgrade Guide - v3 → v4 migration
- Tailwind CSS Layers - Layer documentation
Related Documentation
- Dark Mode - Dark mode overview and API
- Calendar Types - Event categorization
- Use Calendar App - Core configuration