Overview

LocallyGrown's theming system is built on a foundation of standardized design tokens that ensure consistency across components while allowing for unique market personalities. This system bridges the gap between design and code, making themes both visually distinctive and technically maintainable.

🎨 How Themes Work

Every LocallyGrown theme follows a three-layer architecture:

  • Design Tokens - Core variables that all themes must implement
  • Theme Files - CSS files that define specific color palettes and styles
  • Component Styles - UI elements that reference theme variables

This approach means you can completely transform your market's appearance by changing just the theme file, while all components automatically adapt to the new design.

🔗 Design Token System: Our standardized variable naming convention ensures that themes are interchangeable and components remain consistent regardless of which theme is active.

Design Token Reference

Design tokens are the building blocks of our theming system. These CSS custom properties define colors, typography, spacing, and visual effects that components use throughout the application.

Required Theme Variables

All themes MUST implement these core variables for proper functionality:

Primary Brand Colors

--lg-primary

Main brand color used for primary actions and headers

--lg-primary-hover

Darker variant for hover states

--lg-primary-dark

Extra dark variant for pressed states and strong emphasis

--lg-primary-light

Semi-transparent version for backgrounds (rgba with 0.1 alpha)

--lg-primary-medium

Semi-transparent version for overlays (rgba with 0.2 alpha)

Secondary & Accent Colors

--lg-secondary

Supporting brand color

--lg-secondary-hover

Hover state for secondary elements

--lg-accent

Highlight color for special elements

--lg-accent-hover

Accent hover state

Standardized Accent Palette

These six accent colors provide consistent component styling across all themes:

--lg-accent-1

Lightest accent - used for subtle highlights

--lg-accent-2

Light accent - often vibrant/contrasting

--lg-accent-3

Medium-light accent - balanced tone

--lg-accent-4

Medium accent - matches primary theme tone

--lg-accent-5

Medium-dark accent - deeper variant

--lg-accent-6

Darkest accent - for maximum contrast

Neutral Gray Scale

Nine-step neutral scale (50-900) that adapts to your theme's color temperature:

--lg-gray-50
--lg-gray-100
--lg-gray-200
--lg-gray-300
--lg-gray-400
--lg-gray-500
--lg-gray-600
--lg-gray-700
--lg-gray-800
--lg-gray-900

Status Colors

--lg-success

Success states, confirmations

--lg-warning

Warnings, attention needed

--lg-error

Errors, critical states

--lg-info

Information, neutral alerts

Background Colors

--lg-bg-primary

Main page background

--lg-bg-secondary

Secondary surfaces, cards

--lg-bg-tertiary

Subtle surfaces, overlays

--lg-bg-accent

Accent backgrounds

Text Colors

--lg-text-primary

Main body text, headings

--lg-text-secondary

Secondary text, descriptions

--lg-text-muted

Muted text, placeholders

--lg-text-light

Light text, subtle elements

Visual Effects

--lg-gradient-primary

Main gradient for headers, hero sections

--lg-gradient-secondary

Secondary gradient for accents

--lg-gradient-accent

Subtle accent gradient

--lg-pattern-primary

Main pattern (typically dots)

--lg-pattern-secondary

Secondary pattern (typically grid)

--lg-shadow-primary

Main shadow for cards, buttons

--lg-shadow-secondary

Special effect shadow (often glow)

Optional Variables

These variables can be overridden but have sensible defaults from the design tokens:

  • Typography: Font families, sizes, weights, line heights
  • Spacing: Margins, paddings, gaps (--lg-space-* scale)
  • Border Radius: Corner rounding (--lg-radius-* scale)
  • Transitions: Animation timings and easing functions
  • Shadows: Traditional shadow scale (--lg-shadow-xs through --lg-shadow-2xl)

Theme Examples

Let's explore how different themes express their personality through the standardized variables:

🍂 Fall Theme

Warm autumn colors with rich browns and golden accents

Personality: Cozy, traditional, harvest-focused
Gradients: Sunset oranges to deep browns
Neutrals: Warm, earthy tones with cream highlights

🌊 Ocean Theme

Coastal blues with seafoam greens and sandy neutrals

Personality: Fresh, maritime, coastal community
Gradients: Ocean waves from seafoam to deep blue
Neutrals: Cool blue-grays with sandy background warmth

🌱 Spring Theme

Fresh greens with light, renewal-focused colors

Personality: Growing, optimistic, new beginnings
Gradients: Light greens to vibrant growth colors
Neutrals: Clean, fresh tones with subtle green warmth

Creating a Custom Theme

Follow this step-by-step guide to create your own market theme:

Step 1: Plan Your Color Palette

🎨 Color Selection Guidelines

  • Primary: Your main brand color - should be strong and recognizable
  • Secondary: Complements primary, often darker or more muted
  • Accent: Contrasts with primary/secondary, adds visual interest
  • Neutrals: Should have same color temperature as your brand colors
  • Accessibility: Ensure sufficient contrast for text readability

Step 2: Create Your Theme File

Create a new CSS file in the themes directory:

/* === Your Market Theme === */
/* Brief description of the theme's personality and inspiration */

:root {
    /* === Primary Brand Colors === */
    --lg-primary: #your-primary-color;
    --lg-primary-hover: #darker-primary;
    --lg-primary-dark: #darkest-primary;
    --lg-primary-light: rgba(your-primary-rgb, 0.1);
    --lg-primary-medium: rgba(your-primary-rgb, 0.2);

    --lg-secondary: #your-secondary-color;
    --lg-secondary-hover: #darker-secondary;
    --lg-secondary-light: rgba(your-secondary-rgb, 0.1);

    --lg-accent: #your-accent-color;
    --lg-accent-hover: #darker-accent;
    --lg-accent-light: rgba(your-accent-rgb, 0.05);
    --lg-accent-medium: rgba(your-accent-rgb, 0.1);
    --lg-accent-strong: rgba(your-accent-rgb, 0.2);

    /* === Standardized Accent Palette === */
    /* Choose 6 colors that work with your theme */
    --lg-accent-1: #lightest-accent;
    --lg-accent-2: #light-accent;
    --lg-accent-3: #medium-light-accent;
    --lg-accent-4: #medium-accent;
    --lg-accent-5: #medium-dark-accent;
    --lg-accent-6: #darkest-accent;

    /* Continue with all required variables... */
}

Step 3: Define Your Gray Scale

Create a neutral scale that matches your theme's color temperature:

/* === Neutral Scale === */
/* Adjust these to be warm/cool to match your brand */
--lg-gray-50: #your-lightest-neutral;   /* Almost white */
--lg-gray-100: #your-very-light-neutral; /* Very light */
--lg-gray-200: #your-light-neutral;     /* Light */
--lg-gray-300: #your-medium-light;      /* Medium-light */
--lg-gray-400: #your-medium;            /* Medium */
--lg-gray-500: #your-medium-dark;       /* Medium-dark */
--lg-gray-600: #your-dark;              /* Dark */
--lg-gray-700: #your-very-dark;         /* Very dark */
--lg-gray-800: #your-almost-black;      /* Almost black */
--lg-gray-900: #your-darkest;           /* Darkest text */

Step 4: Create Visual Effects

Design gradients, patterns, and shadows that reflect your theme's personality:

/* === Visual Effects === */
--lg-gradient-primary: linear-gradient(135deg, 
    var(--lg-primary) 0%, 
    var(--lg-secondary) 100%);

--lg-gradient-secondary: linear-gradient(180deg, 
    var(--lg-accent) 0%, 
    var(--lg-primary) 100%);

--lg-pattern-primary: radial-gradient(circle, 
    rgba(your-accent-rgb, 0.12) 1px, 
    transparent 1px);

--lg-shadow-primary: 0 4px 6px -1px rgba(your-primary-rgb, 0.15), 
                     0 2px 4px -1px rgba(your-primary-rgb, 0.08);

Step 5: Test Your Theme

⚠️ Testing Checklist:
  • Test on multiple screen sizes (desktop, tablet, mobile)
  • Verify text contrast meets WCAG AA standards
  • Check that all UI components look consistent
  • Test both light and dark system preferences
  • Ensure buttons, links, and interactive elements are clear
  • Validate that status colors (success, warning, error) are distinct

Live Theme Demonstration

See how theme variables affect real components:

Primary Button

Uses --lg-primary

Secondary Button

Uses --lg-secondary

Accent Elements

Fresh Today
Uses --lg-accent

Text Hierarchy

Primary Text Heading

Secondary descriptive text

Muted supporting text
💡 Live Theme Variables: The components above use the current theme's CSS variables, so they'll automatically update if you switch themes in your market settings.

Technical Implementation

Understanding how themes are loaded and applied in LocallyGrown:

Theme Loading Process

  1. Design Tokens: Base design-tokens.css loads first with defaults
  2. Market Assignment: Each market is assigned a theme in database
  3. Theme CSS: Specific theme file overrides design token variables
  4. Component Rendering: All components reference the CSS variables

CSS Custom Property Cascading

The system uses CSS custom property inheritance to ensure themes work consistently:

/* Design tokens set defaults */
:root {
    --lg-primary: #466d4d; /* Default green */
}

/* Theme overrides the default */
:root {
    --lg-primary: #715b31; /* Fall theme brown */
}

/* Components use the variable */
.button-primary {
    background-color: var(--lg-primary);
}

Market-Specific Theme Assignment

Themes are applied at the subdomain level:

  • Database Setting: Each market has a theme field
  • HTTP Request: Server identifies market from subdomain
  • CSS Loading: Appropriate theme CSS is served
  • Cache Headers: Themes are cached for performance

Component Integration

All modern UI components are designed to work with any theme:

/* Component always references theme variables */
.card {
    background-color: var(--lg-bg-secondary);
    border: 1px solid var(--lg-gray-300);
    box-shadow: var(--lg-shadow-primary);
    color: var(--lg-text-primary);
}

.card:hover {
    background-color: var(--lg-bg-tertiary);
    box-shadow: var(--lg-shadow-secondary);
}

Best Practices

Color Selection

  • Brand Consistency: Use colors that align with your market's existing brand
  • Community Reflection: Consider colors that represent your local area or season
  • Accessibility First: Ensure sufficient contrast ratios for all text
  • Cultural Sensitivity: Be mindful of color meanings in your community

Visual Hierarchy

  • Primary Color: Use for the most important actions and branding
  • Secondary Color: Support primary without competing
  • Accent Color: Add personality and draw attention to special elements
  • Neutrals: Create calm backgrounds that let content shine

Performance Considerations

  • CSS Variables: More efficient than class-based theming
  • Minimal Overrides: Only override necessary variables
  • Gradient Performance: Use simple gradients to avoid rendering issues
  • Shadow Complexity: Keep shadows subtle for better performance

Maintenance

  • Document Decisions: Comment your color choices and reasoning
  • Version Control: Track theme changes and test thoroughly
  • User Feedback: Monitor how your community responds to theme changes
  • Seasonal Updates: Consider if your theme works year-round

Advanced Techniques

Color Mathematics

Using OKLCH color space for better color manipulation:

/* OKLCH provides better color transitions */
--lg-primary: oklch(0.5263 0.1579 243.1579); /* Deep blue */
--lg-primary-hover: oklch(0.4421 0.1579 243.1579); /* Same hue, darker */
--lg-primary-dark: oklch(0.3579 0.1579 243.1579); /* Same hue, darkest */

/* Easy to create variations */
--lg-primary-light: oklch(0.7368 0.1579 243.1579); /* Same hue, lighter */

Semantic Color Naming

Using descriptive names for theme-specific colors:

/* Ocean theme semantic colors */
--ocean-deep: #1e6ba8;        /* Deep ocean blue */
--ocean-wave: #5b9bc6;        /* Wave blue */
--seafoam: #88c5cc;           /* Seafoam green */
--coral-accent: #ff7f7f;      /* Coral pink */
--kelp-green: #5a7a47;        /* Kelp green */
--sandy-beige: #f5e6d3;       /* Sandy background */

/* Map to standard variables */
--lg-primary: var(--ocean-deep);
--lg-secondary: var(--ocean-wave);
--lg-accent: var(--seafoam);

Responsive Theme Adjustments

Adapting themes for different screen sizes:

/* Adjust shadow intensity on mobile */
@media (max-width: 768px) {
    :root {
        --lg-shadow-primary: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
        --lg-shadow-secondary: 0 0 15px rgba(136, 197, 204, 0.2);
    }
}

/* Simplify patterns on small screens */
@media (max-width: 480px) {
    :root {
        --lg-pattern-primary: none;
        --lg-pattern-secondary: none;
    }
}

Ready to Create Your Custom Theme?

Start by exploring our existing themes to understand the system, then create your own unique market personality with custom colors and visual effects.