VAT
Your cart

Your cart is empty.

Dark mode and color palettes

Addofy's dark mode switches CSS variables. Use them and your own screens follow the theme automatically. On top of that, you can add a complete color palette.

Dark mode for your screens

body.adba .myplugin-panel {
	background: var(--adba-surface);
	color: var(--adba-text);
	border: 1px solid var(--adba-border);
	border-radius: var(--adba-radius);
}

For colors that need their own dark value, use body.adba.adba-theme-dark and, for the automatic theme, @media (prefers-color-scheme: dark) { body.adba.adba-theme-auto ... }.

Queue that stylesheet through enqueue_external() with the dependency adba-module-darkmode-css. A screen of yours that uses WooCommerce admin components can join the WooCommerce dark styles through adba_darkmode_wc_fragments.

The tokens you can use are listed on the CSS tokens page.

Color palettes (since 2.12.0)

The colors of dark and light mode come from a palette: five base colors for one scheme. Since 2.25.0 palettes come in families of a dark and a light variant. Addofy ships three families:

  • classic: the default. Dark classic (the gray and blue dark mode of before 2.12.0) and light default.
  • vibrant: gray with orange, purple and yellow. Dark vibrant and light vibrant-light.
  • graphite: calm, orange only. Dark graphite and light graphite-light.

The site administrator picks one family under Addofy > Preferences. Users only choose light, dark or auto; their theme picks the variant, and with auto it follows the operating system without a reload.

Register your own palette

A plugin or theme adds its own family with one call. Addofy derives every color token from the five base colors and moves text and border colors until they reach WCAG AA: 4.5:1 for text, 3:1 for borders and focus. The settings show which tokens were moved.

// Registers acme (dark) and acme-light, at any moment before the first admin screen.
adba_register_palette( 'acme', array(
	'label' => __( 'Acme', 'acme' ),
	'dark'  => array(
		'colors' => array(
			'background' => '#14161f',
			'text'       => '#f5f5f5',
			'accent'     => '#00c2a8', // links, focus, toggles, counters
			'accent_2'   => '#3d5afe', // primary button, current menu item; '' for none
			'hover'      => '#ffd166', // hover of links, icon buttons, tabs and the primary button
		),
		// Optional: set single color tokens yourself (allowlist below).
		'tokens' => array( '--adba-sidebar-bg' => '#0e1017' ),
	),
	'light' => array(
		'colors' => array(
			'background' => '#fafafa',
			'text'       => '#14161f',
			'accent'     => '#007a6a',
			'accent_2'   => '#3d5afe',
			'hover'      => '#3d5afe',
		),
		// Optional: a hover fill of the primary button that differs from the link hover.
		'tokens' => array( '--adba-hover-fill' => '#ffd166' ),
	),
) );

// The same through the action, one palette at a time; family pairs them.
add_action( 'adba_register_palettes', function ( \AddoBack\Design\PaletteRegistry $palettes ) {
	$palettes->add( 'acme', array( 'label' => 'Acme', 'scheme' => 'dark', 'colors' => array( /* ... */ ) ) );
	$palettes->add( 'acme-day', array( 'label' => 'Acme', 'scheme' => 'light', 'family' => 'acme', 'colors' => array( /* ... */ ) ) );
} );

Leave out light and Addofy derives it: background and text swap places, the accents stay and the dark hover color stays the hover fill of the primary button. The card then says "Light automatically". When the dark text color is gray, or the derivation has to move the text color or more than two base colors, the family uses Classic light instead and the card says "Dark only". The older form with scheme keeps working.

What each base color becomes

Base colorBecomes
background--adba-gray-50 (page), the gray scale mixed towards text, surfaces just lighter (dark) or white (light).
text--adba-gray-900 and the text on light or dark fills.
accent--adba-accent, --adba-ring, --adba-accent-text (lightened or darkened for 4.5:1 on a tint), --adba-on-accent.
accent_2--adba-primary, --adba-accent-2, the current sidebar item (dark), the pressed segment, the selected row tint. Empty: the text color fills the primary button and the current item gets an accent stripe.
hover--adba-hover (links, icons) and, unless the palette sets --adba-hover-fill, the hover fill of the primary button. --adba-on-hover is the text on that fill.

Token overrides

Token overrides accept only color tokens, with a #rgb, #rrggbb, strict rgb() or rgba(), or transparent value. Anything else is dropped, and logged when WP_DEBUG is on. The allowed tokens are:

  • the gray scale --adba-gray-25 to --adba-gray-900
  • --adba-bg, --adba-surface, --adba-surface-muted, --adba-surface-hover, --adba-segmented-on
  • --adba-border, --adba-border-input, --adba-text, --adba-text-muted, --adba-badge-neutral
  • --adba-accent, --adba-accent-text, --adba-ring, --adba-on-accent
  • --adba-accent-2, --adba-accent-2-text, --adba-on-accent-2
  • --adba-hover, --adba-hover-fill, --adba-on-hover, --adba-row-selected
  • --adba-primary, --adba-primary-text
  • --adba-success, --adba-warning, --adba-danger, --adba-info, the four --adba-*-text status colors, --adba-on-danger, --adba-on-warning
  • --adba-knob, the --adba-toast-*, --adba-sidebar-* and --adba-topbar-* colors
  • --adba-overlay, --adba-shadow-color and --adba-shadow-strong

Which palette is active

Per scheme, the order is:

  1. Constant or environment variable ADBA_PALETTE_DARK or ADBA_PALETTE_LIGHT (a palette id).
  2. Constant or environment variable ADBA_PALETTE (a family).
  3. A stored palette for that scheme (palette.dark or palette.light), written by older versions and by wp adba palette set <family> --scheme=....
  4. The family setting palette.family. On multisite: network enforced, site, network default.
  5. classic.

A palette id stands for its family; an unknown id falls back to the default. The filter adba_active_palette decides last, per scheme, role or site. adba_palette_tokens adjusts the derived tokens right before output. Updating from before 2.25.0 turns the stored dark palette into the family; a light choice other than default stays as an override.

Cost and output

The built-in default and classic live in the stylesheet and cost nothing. Any other palette, the light variants of vibrant and graphite included, adds one inline rule set with only the tokens that differ, a solid focus ring and its hover fill. It comes after the core stylesheet (light, dark, auto and the Customizer) and is cached in the object cache when there is one. A light variant with a primary fill of its own also sets the WordPress accent (--wp-admin-theme-color, --wp-components-color-accent).

The body gets adba-palette-{id} for the active light and dark palette and adba-palette-family-{family}, so your CSS can target either. TinyMCE and the block editor canvas take their dark colors from the active palette; in light, TinyMCE links take the accent of a light palette other than Classic. The theme-color meta and the menu icons follow both variants.

Check both variants of a family from the command line:

wp adba palette check <family>

Plugin colors: the automatic scan (since 2.31.5)

Plugins that never heard of Addofy still have fixed colors: a white panel, gray text, a light border. The experimental module Plugin colors fixes most of that without hand work. Switch it on under Addofy > Settings > Modules > Experimental.

  • When it scans: in the background (Action Scheduler, or WP-Cron without it), never during a page request. Every active plugin once when the module is switched on, a plugin when it is activated or updated, and again when its main file changes.
  • What it does: it reads the plugin's stylesheets (not its front-end, right-to-left or own dark stylesheets) and writes one override per stylesheet to uploads/addofy-colors/. Fixed backgrounds, text and border colors become Addofy tokens (--adba-surface, --adba-text, --adba-border, the gray scale and the status colors), so they follow light, dark, auto and the palette.
  • What it leaves alone: dark fills such as tooltips, white text on colored buttons, colored fills and brand colors, document and e-mail previews, and selectors Addofy styles itself. Plugin files never change.
  • Where it loads: an override only loads next to the plugin stylesheet it belongs to, behind body.adba. Excluded screens, safe mode and the screens of a compatibility adapter stay as they are.

Tools > Plugin colors lists every plugin with its status. Turn a plugin off there when its screens look better without the scan, or scan it again. The same from the command line: wp adba colors scan|list|enable|disable|clear.

Your plugin already uses Addofy's tokens? Keep it out of the scan:

add_filter( 'adba_colorscan_plugins', function ( array $plugins ) {
	unset( $plugins['myplugin'] );
	return $plugins;
} );

adba_colorscan_token decides per color (return null to keep it), adba_colorscan_css changes the generated CSS and adba_colorscan_done fires after each scan.

Ready to connect your AI to real tools?

Start free trial