Theming

Customize Suite.jl's visual appearance with built-in themes and fine-grained overrides.

How Themes Work

A theme is a named bundle of design tokens — accent color, border radius, font weight, shadow style, and more. Every Suite.jl component accepts a theme keyword argument.

When theme=:default (the default), there is zero overhead — the component renders its standard classes unchanged.

Pre-built Themes

Suite.jl ships with 5 pre-built themes:

ThemeAccentNeutralRadiusDescription
:defaultPurpleWarmrounded-mdClassic scholarly tones
:oceanBlueWarmrounded-lgCool professional
:minimalZincSlaterounded-noneSharp monospace-friendly
:natureEmeraldStonerounded-xlOrganic earthy tones
:islandsBlueWarmrounded-xlFloating glass panels, generous curves

Applying Themes

At render time

Pass the theme kwarg to any component:

julia
# Default theme (purple accent, warm neutrals, rounded-md)
Button("Default Theme")

# Ocean theme (blue accent, rounded-lg)
Button(theme=:ocean, "Ocean Theme")

# Minimal theme (zinc accent, no border radius)
Button(theme=:minimal, variant="outline", "Minimal Theme")

# Nature theme (emerald accent, rounded-xl)
Card(theme=:nature,
    CardHeader(CardTitle("Nature Theme")),
    CardContent("Emerald accents with stone neutrals")
)

# Islands theme (blue accent, glass panels, rounded-xl)
Card(theme=:islands,
    CardHeader(CardTitle("Islands Theme")),
    CardContent("Blue accents with glass-panel effects")
)

At extraction time

When extracting components, the theme is baked into the generated source code. The output file contains concrete Tailwind classes — no runtime theme lookup needed:

julia
# Extract with ocean theme
Suite.extract(:Button, "src/components/", theme=:ocean)
# → Button.jl uses bg-blue-600 instead of bg-accent-600

# Extract with nature theme
Suite.extract(:Card, "src/components/", theme=:nature)
# → Card.jl uses rounded-xl, stone-* neutrals, emerald-* accents
# (each theme substitutes its own color tokens)

Design Tokens

Each theme defines these tokens, which are substituted into component class strings:

TokenDefaultOceanDescription
accentpurple (accent-*)bluePrimary interactive color
accent_secondaryred (accent-secondary-*)roseDestructive/danger color
neutralwarmwarmBackground, border, text colors
radiusrounded-mdrounded-lgDefault border radius
ringring-accent-600ring-blue-600Focus ring color
font_weightfont-mediumfont-mediumDefault font weight
shadowshadow-smshadow-mdDefault shadow

Color Token Mapping

Suite.jl maps shadcn/ui's CSS variables to Tailwind utility classes:

shadcn VariableSuite.jl Token
--backgroundbg-warm-50 dark:bg-warm-950
--foregroundtext-warm-800 dark:text-warm-300
--primarybg-accent-600 / text-accent-600
--cardbg-warm-100 dark:bg-warm-900
--borderborder-warm-200 dark:border-warm-700
--destructivebg-accent-secondary-600 / text-accent-secondary-600
--ringring-accent-600

Dark Mode

Every Suite.jl component includes dark mode classes out of the box. Dark mode is toggled by adding the dark class to the <html> element.

Use the ThemeToggle component to add a dark mode toggle to your app:

julia
# In your Layout.jl navbar
ThemeToggle()  # Sun/moon toggle button

# Persists preference to localStorage
# Respects system prefers-color-scheme as default

Therapy.jl's App framework includes a FOUC-prevention script in <head> that applies the saved theme before first paint.

Warm Neutral Palette

The default theme uses a warm neutral palette shared across all GroupTherapyOrg packages:

50
100
200
300
400
500
600
700
800
900
950

Accent (Purple)

50
100
200
300
400
500
600
700
800
900
950