Theming
Acopl UI ships with dark mode as default and a complete light mode variant. Theme switching is controlled via the data-theme attribute on the <html> element.
How it works
Section titled “How it works”<!-- Dark mode (default) --><html data-theme="dark">
<!-- Light mode --><html data-theme="light">All components use semantic CSS Custom Properties (--ac-*) that automatically change value when the theme changes. You never need to update components individually.
Semantic token system
Section titled “Semantic token system”Components are written like this:
.ac-button--primary { background-color: var(--ac-action); /* changes per theme */ color: #fff;}The --ac-action token resolves to:
- dark:
#F97316(Safety Orange) - light:
#EA580C(Orange-600, higher contrast)
Available semantic tokens
Section titled “Available semantic tokens”| Token | Dark value | Light value | Purpose |
|---|---|---|---|
--ac-bg | #020617 | #F8FAFC | Page background |
--ac-surface | #0F172A | #FFFFFF | Cards, panels |
--ac-surface-2 | #1E293B | #F1F5F9 | Elevated surfaces |
--ac-text | #E2E8F0 | #1E293B | Primary text |
--ac-text-muted | #94A3B8 | #64748B | Secondary text |
--ac-text-subtle | #475569 | #94A3B8 | Disabled, placeholders |
--ac-border | rgba(255,255,255,0.1) | rgba(0,0,0,0.1) | Default borders |
--ac-border-strong | rgba(255,255,255,0.2) | rgba(0,0,0,0.2) | Hover borders |
--ac-primary | #2563EB | #2563EB | Blue — trust |
--ac-action | #F97316 | #EA580C | Orange — CTAs |
--ac-success | #10B981 | #059669 | Green — success |
--ac-danger | #EF4444 | #EF4444 | Red — errors |
ThemeManager API
Section titled “ThemeManager API”import { ThemeManager } from 'https://ui.acopl.ar/v2.0.0/acopl-ui.js';
// Initialize (reads localStorage → prefers-color-scheme → default)ThemeManager.init(); // call once on page loadThemeManager.init('light'); // force light as default
// ControlThemeManager.toggle(); // switch between dark/lightThemeManager.set('light'); // force a specific themeThemeManager.get(); // → 'dark' | 'light'
// HelpersThemeManager.isDark(); // → booleanThemeManager.isLight(); // → booleanThemeManager.clearOverride(); // remove manual override, follow system
// Subscribe to changesconst unsubscribe = ThemeManager.onChange((theme) => { console.log('Theme changed to:', theme);});unsubscribe(); // stop listeningAnti-FOUC (Flash of Unstyled Content)
Section titled “Anti-FOUC (Flash of Unstyled Content)”Without this inline script, the page flashes the wrong theme for ~100ms while the JS bundle loads. Add this before your CSS link:
<head> <script> (function(){ var t = localStorage.getItem('ac-theme') || (window.matchMedia('(prefers-color-scheme:light)').matches ? 'light' : 'dark'); document.documentElement.setAttribute('data-theme', t); })(); </script> <link rel="stylesheet" href="https://ui.acopl.ar/v2.0.0/acopl-ui.css"></head>Using tokens in your own CSS
Section titled “Using tokens in your own CSS”You can use the semantic tokens directly in your project’s CSS:
.my-panel { background: var(--ac-surface); border: 1px solid var(--ac-border); color: var(--ac-text);}
.my-panel:hover { border-color: var(--ac-border-strong);}
.my-cta { background: var(--ac-action); color: #fff;}These will automatically adapt to dark/light mode without any extra code.
Backwards compatibility (v1.x)
Section titled “Backwards compatibility (v1.x)”Projects still using --color-brand-* tokens from v1.x continue to work — they are aliased to the new semantic tokens:
/* These still work in v2 */var(--color-brand-base) → var(--ac-bg)var(--color-brand-surface) → var(--ac-surface)var(--color-brand-blue) → var(--ac-primary)var(--color-brand-orange) → var(--ac-action)var(--color-brand-green) → var(--ac-success)var(--color-brand-border) → var(--ac-border)
/* NEW in v2 — previously missing, now available */var(--color-text) → var(--ac-text)var(--color-text-secondary) → var(--ac-text-muted)var(--color-surface) → var(--ac-surface)var(--color-border) → var(--ac-border)var(--color-primary) → var(--ac-primary)