C CoolAdmin v3.3.0

Theming

CoolAdmin's two-stylesheet design system. css/theme.css carries the legacy token set under :root; css/app.css carries the modern overlay tokens under body.app. Six built-in accent presets. Dark mode hooks into Bootstrap's data-bs-theme attribute.

Last updated May 22, 2026

CoolAdmin ships two complete design systems side by side. Both are token-driven CSS — change a custom property, the cascade picks it up.

The two token surfaces

StylesheetActivated byToken prefixSource
css/theme.cssalways loaded--ca-*src/scss/_variables.scss
css/app.css<body class="app">--m-*src/scss/app/_variables.scss

Pages opt into the modern overlay by adding class="app" to <body>. Every demo page in the repo does this. Removing the class falls back to the legacy design — theme.css keeps working untouched.

Legacy tokens — --ca-* (theme.css)

Declared at the top of src/scss/_variables.scss, emitted to :root in theme.css:

:root {
    /* Brand */
    --ca-primary:       #4272d7;
    --ca-primary-rgb:   66, 114, 215;
    --ca-secondary:     #6c757d;
    --ca-success:       #28a745;
    --ca-warning:       #ffc107;
    --ca-danger:        #dc3545;
    --ca-info:          #17a2b8;

    /* Surfaces */
    --ca-body-bg:       #f8f9fa;
    --ca-card-bg:       #ffffff;
    --ca-sidebar-bg:    #2c3e50;
    --ca-topbar-bg:     #ffffff;

    /* Text */
    --ca-text:          #333333;
    --ca-text-muted:    #6c757d;
    --ca-text-on-dark:  #ffffff;

    /* Borders + dividers */
    --ca-border:        #e9ecef;
    --ca-divider:       #f1f3f5;

    /* Shadows */
    --ca-shadow-sm:     0 1px 3px rgba(0, 0, 0, 0.05);
    --ca-shadow:        0 4px 12px rgba(0, 0, 0, 0.08);
    --ca-shadow-lg:     0 12px 32px rgba(0, 0, 0, 0.12);

    /* Layout */
    --ca-sidebar-width: 240px;
    --ca-topbar-height: 70px;
    --ca-radius:        4px;
    --ca-transition:    150ms ease;
}

Sixteen tokens covering brand colors, semantic status, surfaces, text, borders, shadows, and layout dimensions. Change --ca-primary and the whole legacy design retones — buttons, links, focus rings, sidebar accents.

Dark mode (legacy)

The legacy theme has a dark-mode hook tied to Bootstrap 5’s data-bs-theme attribute:

<html data-bs-theme="dark">

That selector rebinds the same --ca-* tokens to dark-mode values:

[data-bs-theme="dark"] {
    --ca-body-bg:       #121417;
    --ca-card-bg:       #1c1f24;
    --ca-sidebar-bg:    #0f1115;
    --ca-text:          #e9ecef;
    /* ...rebinds every other --ca-* */
}

There’s no built-in toggle UI for this yet — set the attribute manually or wire your own toggle. The dark variants exist for every token, so once data-bs-theme="dark" is set the whole legacy design works in dark mode.

Modern overlay tokens — --m-* (app.css)

The modern overlay has its own, separate token set scoped under body.app:

body.app {
    /* Surfaces */
    --m-bg:           #f4f6fa;
    --m-surface:      #ffffff;
    --m-surface-2:    #f8fafc;
    --m-sidebar:      #1c2333;
    --m-sidebar-soft: #28304a;

    /* Borders + dividers */
    --m-border:       #e4e7ec;
    --m-border-soft:  #eef0f3;
    --m-divider:      #f1f3f5;

    /* Text */
    --m-text:         #1f2937;
    --m-text-muted:   #475569;
    --m-text-faint:   #94a3b8;
    --m-text-on-dark: #f1f5f9;

    /* Brand — anchored to the original CoolAdmin blue */
    --m-accent:        #4272d7;
    --m-accent-rgb:    66, 114, 215;
    --m-accent-hover:  #355cb8;
    --m-accent-soft:   #eaf0fc;

    /* KPI accents — used on the dashboard stat tiles */
    --m-c1: #4272d7;  /* blue (revenue) */
    --m-c2: #11998e;  /* teal (orders) */
    --m-c3: #f97316;  /* orange (users) */
    --m-c4: #ec4899;  /* pink (conversion) */

    /* Semantic */
    --m-success: #10b981;  --m-success-soft: #ecfdf5;
    --m-warning: #f59e0b;  --m-warning-soft: #fffbeb;
    --m-danger:  #ef4444;  --m-danger-soft:  #fef2f2;

    /* Effects */
    --m-shadow-xs: 0 1px 2px  rgba(15, 23, 42, 0.04);
    --m-shadow-sm: 0 1px 3px  rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
    --m-shadow-md: 0 4px 12px rgba(15, 23, 42, 0.06), 0 2px 4px rgba(15, 23, 42, 0.04);
    --m-shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.10);

    --m-radius-sm: 6px;
    --m-radius:    10px;
    --m-radius-lg: 14px;

    --m-font: "Inter", "Inter Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

The modern tokens are richer than the legacy set — multi-step shadows, three radii, four KPI accent colors, soft variants of every semantic color.

The six theme presets

src/scss/app/_theme-presets.scss extends the body class to redefine the brand token cascade:

body.app.theme-blue {
    --m-accent:        #4272d7;
    --m-accent-hover:  #355cb8;
    --m-accent-soft:   #eaf0fc;
}
body.app.theme-purple {
    --m-accent:        #7c3aed;
    --m-accent-hover:  #6b2fd0;
    --m-accent-soft:   #ede9fe;
}
body.app.theme-teal {
    --m-accent:        #0d9488;
    --m-accent-hover:  #0a7d72;
    --m-accent-soft:   #ccfbf1;
}
body.app.theme-rose {
    --m-accent:        #e11d48;
    --m-accent-hover:  #be1239;
    --m-accent-soft:   #ffe4e6;
}
body.app.theme-amber {
    --m-accent:        #d97706;
    --m-accent-hover:  #b86204;
    --m-accent-soft:   #fef3c7;
}
body.app.theme-graphite {
    --m-accent:        #334155;
    /* ... */
}

Apply by adding class="app theme-purple" to <body>. Every UI element that reads var(--m-accent) retones automatically — links, buttons, focus rings, badges, charts.

The floating theme switcher in the bottom-right of every page applies these by toggling the class at runtime — see Theme switcher for the runtime mechanics.

Customizing the brand color

Two paths depending on which design you’re using:

Legacy (body without .app): edit --ca-primary in src/scss/_variables.scss:

:root {
    --ca-primary:       #ff6b35;
    --ca-primary-rgb:   255, 107, 53;
}

Modern overlay (body.app): add a new preset to src/scss/app/_theme-presets.scss:

body.app.theme-coral {
    --m-accent:        #ff6b35;
    --m-accent-rgb:    255, 107, 53;
    --m-accent-hover:  #e85a28;
    --m-accent-soft:   #fff1e9;
}

Then register it in the theme switcher’s JS array in js/main-vanilla.js:

const THEMES = [
    { id: 'blue',     label: 'Blue',     color: '#4272d7' },
    { id: 'coral',    label: 'Coral',    color: '#ff6b35' },   // ← add here
    // ...
];

Rebuild (npm run build) — the switcher widget picks up the new preset on its next render.

Adding a new token

Both legacy and modern overlay accept new tokens with no machinery. Just add the declaration:

/* src/scss/app/_variables.scss */
body.app {
    --m-accent-purple: #7c3aed;
}

/* Use anywhere */
.my-component {
    background: var(--m-accent-purple);
}

Modern tokens use the --m-* prefix; legacy uses --ca-*. Don’t mix prefixes — they’re scoped to different stylesheets and only available in their respective contexts.

What “modern” gets you over “legacy”

Both stylesheets work. The modern overlay adds:

  • Inter typography with stylistic-set font features (cv11, ss01, ss03)
  • Multi-step shadows (--m-shadow-xs/sm/md/lg) tuned for thin layered cards
  • Three radii (--m-radius-sm: 6px, --m-radius: 10px, --m-radius-lg: 14px)
  • KPI accent colors for stat tiles (blue / teal / orange / pink)
  • Soft variants of every semantic color for chip / badge backgrounds
  • The six theme presets documented above
  • Component partials for the new patterns: kanban, inbox, data-table, invoice, wizard, command palette, theme switcher, toast, skeleton loaders, error pages

Legacy gets you the original CoolAdmin look. Modern is what every demo page ships with.

Conventions

  • CSS variables, never hex. If you find yourself writing #4272d7 in a partial, use var(--ca-primary) or var(--m-accent) instead.
  • State classes use is-is-open, is-active, is-dragging. Bootstrap’s show and active classes are used where they fit Bootstrap conventions; CoolAdmin’s own components use is-*.
  • data- attributes for JS hooksdata-bs-toggle (Bootstrap), data-sort (data-table), data-theme (presets), data-page (sidebar active state). Avoid ids for behavior.

See also