BuddyX

Design Tokens

Free theme

The CSS custom-property contract BuddyX exposes for theme CSS, child themes, and plugin integrations. Reference these --bx-* variables instead of hard-coded colors, radii, or spacing so your styles inherit the customizer, the active style variation, and light/dark mode automatically.


What tokens are

BuddyX emits a single block of CSS custom properties into an inline stylesheet on every front-end render. inc/Tokens/Component.php reads customizer theme_mod values, merges them with framework defaults, and prints a :root { … } rule (plus a dark override rule). Every stylesheet in the theme, and everything you write in a child theme, should consume the token names rather than raw values:

.my-card {
  background: var(--bx-color-bg-elevated);
  color: var(--bx-color-fg);
  border: 1px solid var(--bx-color-border);
  border-radius: var(--bx-radius-card);
  padding: var(--bx-space-card);
  box-shadow: var(--bx-shadow-card-md);
}

Because the value lives in one variable, a brand change in the customizer, a style-variation swap, or a dark-mode toggle repaints your CSS with no further work.

Naming convention

--bx-{kind}-{role}-{state?}
Segment Values
kind color, radius, space, shadow, duration, easing, z
role semantic identifier (accent, fg, bg, link, button, header, card, …)
state optional suffix (-hover, -active, -bg, -fg, -strong, -muted)

Reference tokens by name only. Never copy the resolved hex or px value into your CSS. That is the one rule that keeps mode swaps and rebrands to a single variable change.


The 3-layer model

The final value of any token is resolved through three layers that build_token_css() prints in cascade order. Later layers win.

Layer Source Emitted Purpose
1. Framework defaults $framework_tokens in inc/Tokens/Component.php Always, regardless of settings Guarantees every token is present (neutrals, spacing, shadows, motion, z-index) so consumer CSS never hits an undefined variable.
2. Customizer values theme_mods mapped in $simple_color_tokens, $typography_color_tokens, $dimension_tokens When site_custom_colors is enabled and the customer saved a non-default value The site owner's colors, radii, and typography colors override the framework baseline.
3. Mode + variation overlay $dark_defaults and the active style variation Dark set via :root[data-bx-mode="dark"]; a dark style variation routes its palette into the same block Repaints tokens for dark mode / the selected preset without touching consumer CSS.

A fourth, non-authoritative surface rides alongside these: legacy aliases (see below) that point old variable names at the canonical --bx-* tokens for backward compatibility.

Data flow:

theme_mod  ->  Tokens::collect_mods()  ->  build_token_css()  ->  <style>:root { --bx-… : …; }
                                                              ->  <style>:root[data-bx-mode="dark"] { --bx-… : …; }

Framework tokens emit even when the site_custom_colors master toggle is off, so neutrals, spacing, shadows, and motion are always available.


Token families

Color - brand and buttons

Token Customizer setting Purpose
--bx-color-accent site_primary_color Primary brand color
--bx-color-button-bg site_buttons_background_color Button surface
--bx-color-button-bg-hover site_buttons_background_hover_color Button hover surface
--bx-color-button-fg site_buttons_text_color Button text
--bx-color-button-fg-hover site_buttons_text_hover_color Button hover text
--bx-color-button-border site_buttons_border_color Button border (defaults to button bg)
--bx-color-button-border-hover site_buttons_border_hover_color Button hover border
--bx-color-accent-secondary framework default Variation accent slot (teal)
--bx-color-accent-tertiary framework default Variation accent slot (yellow)

Brand-driven bases (--bx-color-accent, --bx-color-button-bg, --bx-color-link, --bx-color-bg, --bx-color-bg-elevated, --bx-color-header-bg) also emit derived -rgb / -hover / -active / -focus / -bg / -border / -disabled / -inverse variants, so hover and focus states follow a rebrand automatically.

Color - surfaces

Token Source Purpose
--bx-color-bg body_background_color Page background
--bx-color-bg-page content_background_color Centered content frame
--bx-color-bg-elevated box_background_color Cards / boxes
--bx-color-bg-muted secondary_background_color Quiet panels
--bx-color-bg-subtle framework default Very-light surface tint
--bx-color-bg-overlay framework default Modal / mobile-menu scrim

Color - text and links

Token Source Purpose
--bx-color-fg typography_option[color] Body text
--bx-color-fg-muted framework default Mid-tone / meta text (WCAG AA on white)
--bx-color-fg-subtle framework default Placeholder / subtle text
--bx-color-fg-inverse framework default Text on a color surface
--bx-color-link site_links_color Hyperlink default
--bx-color-link-hover site_links_focus_hover_color Hyperlink hover
--bx-color-h1--bx-color-h6 h1-h6_typography_option[color] Heading colors

Color - header, menu, footer

Token Source Purpose
--bx-color-header-bg site_header_bg_color Site header surface
--bx-color-site-title site_title_typography_option[color] Site title text
--bx-color-site-title-hover site_title_hover_color Site title hover
--bx-color-site-tagline site_tagline_typography_option[color] Tagline
--bx-color-menu-fg menu_typography_option[color] Menu link
--bx-color-menu-hover menu_hover_color Menu hover
--bx-color-menu-active menu_active_color Menu active
--bx-color-subheader-fg site_sub_header_typography[color] Sub-header text
--bx-color-loader-bg site_loader_bg Page loader background
--bx-color-footer-title site_footer_title_color Footer titles
--bx-color-footer-fg site_footer_content_color Footer body text
--bx-color-footer-link site_footer_links_color Footer link
--bx-color-footer-link-hover site_footer_links_hover_color Footer link hover
--bx-color-copyright-bg site_copyright_background_color Copyright surface
--bx-color-copyright-border site_copyright_border_color Copyright divider
--bx-color-copyright-fg site_copyright_content_color Copyright text
--bx-color-copyright-link site_copyright_links_color Copyright link
--bx-color-copyright-link-hover site_copyright_links_hover_color Copyright link hover

Color - structural, state, forms

These have no customizer field. They are framework-supplied neutrals introduced to remove hard-coded hex values from the stylesheets, and each has a dark counterpart.

Group Tokens
Structural --bx-color-border, --bx-color-border-strong, --bx-color-divider, --bx-color-shadow, --bx-color-shadow-strong
State --bx-color-success / -bg, --bx-color-warning / -bg, --bx-color-error / -bg, --bx-color-info / -bg
Community / presence --bx-color-presence-online, --bx-color-presence-away, --bx-color-presence-busy, --bx-color-presence-offline, --bx-color-bp-friend, --bx-color-bp-favorite
Forms --bx-color-input-bg, --bx-color-input-border, --bx-color-input-focus-border, --bx-color-input-fg, --bx-color-input-placeholder

Radius

Token Source Default
--bx-radius-global site_global_border_radius Global UI radius
--bx-radius-button site_button_border_radius Button radius
--bx-radius-form site_form_border_radius Form input radius
--bx-radius-card framework default 12px
--bx-radius-pill framework default 999px

Spacing

Token Default Purpose
--bx-space-section clamp(40px, 8vw, 80px) Vertical rhythm between sections
--bx-space-card 24px Card / panel padding
--bx-space-stack 12px Vertical gap between siblings
--bx-space-inline 8px Inline gap (icon + text)

Shadows

Token Default
--bx-shadow-card-sm 0 1px 2px 0 var(--bx-color-shadow)
--bx-shadow-card-md 0 4px 12px -2px var(--bx-color-shadow)
--bx-shadow-card-lg 0 12px 32px -4px var(--bx-color-shadow-strong)

The shadow ladder references the --bx-color-shadow* color tokens, so shadows deepen automatically in dark mode.

Motion

Token Default
--bx-duration-fast 120ms
--bx-duration-base 200ms
--bx-duration-slow 400ms
--bx-easing-base cubic-bezier(0.4, 0, 0.2, 1)
--bx-easing-bounce cubic-bezier(0.68, -0.55, 0.265, 1.55)

Z-index

Token Default Layer
--bx-z-base 1 Baseline
--bx-z-dropdown 100 Dropdowns
--bx-z-sticky-header 999 Sticky header
--bx-z-overlay 9999 Overlays / modals
--bx-z-loader 999991 Page loader
--bx-z-toast 999999 Toasts / notices

Light and dark mode

The same token names power both modes. build_token_css() prints the light values into :root { … } and the dark values into :root[data-bx-mode="dark"] { … } from $dark_defaults. Because your CSS references only the token name, a mode swap is a single variable change, never a stylesheet swap.

:root                        { --bx-color-bg: #f7f7f9; --bx-color-fg: #505050; }
:root[data-bx-mode="dark"]   { --bx-color-bg: #0a0a0a; --bx-color-fg: #f5f5f5; }

How the mode is chosen:

  • The customizer field site_color_mode sets the site default (light or dark). The auto / system option was retired in 5.1.4; a legacy saved auto resolves to light.
  • An inline bootstrap script (emit_mode_script(), printed at wp_head priority 1) stamps data-bx-mode on <html> before first paint, reading the visitor's saved choice from localStorage['bx-color-mode'] and falling back to the site default. This prevents a flash of the wrong mode.
  • A dark style variation forces the dark default; a visitor can still toggle to light.

If you add custom colors, define both modes so your UI does not break under the dark cascade:

:root {
  --my-plugin-panel-bg: var(--bx-color-bg-elevated);
  --my-plugin-panel-fg: var(--bx-color-fg);
}
/* No override needed - the referenced tokens already flip in dark mode. */

Only hard-code a dark override when your value does not map to an existing token:

:root[data-bx-mode="dark"] {
  --my-plugin-custom-glow: rgba(255, 107, 107, 0.25);
}

Overriding tokens in a child theme

Tokens are plain CSS custom properties, so a child theme overrides them with ordinary CSS specificity. Because the theme prints its token block as an inline style attached to the buddyx-global stylesheet, enqueue your child stylesheet as a dependent of that handle so your :root rule loads afterward and wins.

functions.php in your child theme:

add_action( 'wp_enqueue_scripts', function () {
    wp_enqueue_style(
        'buddyx-child',
        get_stylesheet_directory_uri() . '/style.css',
        array( 'buddyx-global' ), // Load after BuddyX tokens.
        wp_get_theme()->get( 'Version' )
    );
}, 20 );

style.css in your child theme:

:root {
  --bx-color-accent: #6d28d9;         /* Brand purple */
  --bx-color-link: #6d28d9;
  --bx-radius-card: 20px;
  --bx-space-card: 32px;
}

/* Keep dark mode intentional - override there too when the value is fixed. */
:root[data-bx-mode="dark"] {
  --bx-color-accent: #a78bfa;
}

Guidance:

  • Prefer the customizer for anything a site owner should control (colors, radii, typography colors). Reach for a child-theme :root override only for values with no customizer field, or to lock a brand value regardless of customizer state.
  • Override at :root, not on individual elements, so every consumer that references the token inherits your value.
  • To override a color for dark mode only, target :root[data-bx-mode="dark"].
  • Template overrides work the standard WordPress way. BuddyX loads its parts with get_template_part(), so copying a template-part file into your child theme at the same relative path replaces it. Tokens are unaffected by template overrides.

Legacy aliases

Through the 5.2.x line, every canonical token also emits a legacy alias (for example --color-theme-primary, --global-border-radius, --color-footer-link) so pre-token stylesheets and third-party CSS keep working. Aliases are printed as --legacy: var(--bx-token);, so they flip light/dark through the canonical token automatically.

:root {
  --bx-color-accent: #ef5455;         /* Canonical - use this. */
  --color-theme-primary: var(--bx-color-accent); /* Legacy alias. */
}

The alias maps live in $simple_color_tokens, $typography_color_tokens, $dimension_tokens, and $legacy_aliases in inc/Tokens/Component.php. Aliases are deprecated and slated for removal in 5.3.0. Migrate any consumers to the --bx-* names before then.


Reading tokens in PHP

Usually CSS is the right consumer. When you need the underlying value in PHP, read the customizer setting directly:

$accent = get_theme_mod( 'site_primary_color', '#ef5455' );

Or iterate the token map:

$tokens = \BuddyX\Buddyx\Tokens\Component::get_simple_color_tokens();
foreach ( $tokens as $mod_key => $cfg ) {
    echo $cfg['token'];        // e.g. '--bx-color-accent'
    echo $cfg['aliases'][0];   // e.g. '--color-theme-primary'
}

You can force the dark-scheme decision for a custom style variation with the buddyx_variation_is_dark_scheme filter (receives the variation slug as its second argument).


Related