Namespace your theme using the
bq-theme attribute (e.g., bq-theme="my-custom-theme") or a matching CSS class (e.g., .my-custom-theme).Step-by-step guide
Define base theme variables
Create a CSS file for your custom theme (e.g.,
custom-theme.css) and set the base design tokens:[bq-theme="my-custom-theme"],
.my-custom-theme {
/* Override font family */
--bq-font-family: 'Inter', sans-serif;
/* Define brand colors using any primitive color from the palette */
--bq-brand-light: var(--bq-blue-100);
--bq-brand: var(--bq-blue-600);
--bq-brand-dark: var(--bq-blue-1000);
/* Define accent colors */
--bq-accent-light: var(--bq-purple-100);
--bq-accent: var(--bq-purple-600);
--bq-accent-dark: var(--bq-purple-1000);
/* Override neutral scale if needed */
--bq-neutral-50: var(--bq-grey-50);
--bq-neutral-100: var(--bq-grey-100);
/* ... continue with other neutrals ... */
/* Define semantic colors */
--bq-success: var(--bq-teal-600);
--bq-danger: var(--bq-red-600);
--bq-warning: var(--bq-gold-600);
--bq-info: var(--bq-blue-600);
--bq-focus: var(--bq-blue-600);
/* Interactive state overlays */
--bq-state--hover: rgba(0, 0, 0, 0.08); /* Subtle hover overlay (light mode) */
--bq-state--active: rgba(0, 0, 0, 0.12); /* Pressed state overlay (light mode) */
}
Override
--bq-state--hover and --bq-state--active for each mode. In dark mode, use light
overlays (e.g. rgba(255, 255, 255, 0.1)) instead of dark ones.Define light mode theme
Define the declarative color tokens for the light mode:
[bq-theme="my-custom-theme"]:not([bq-mode]), /* Default — no mode specified */
[bq-theme="my-custom-theme"][bq-mode="light"], /* Explicit light mode (via attributes) */
.my-custom-theme:not([bq-mode]), /* Default — no mode (via CSS class) */
.my-custom-theme.light { /* Explicit light mode (via CSS classes) */
/* Background colors */
--bq-background--primary: var(--bq-white);
--bq-background--secondary: var(--bq-neutral-100);
--bq-background--tertiary: var(--bq-neutral-200);
--bq-background--alt: var(--bq-neutral-300);
--bq-background--inverse: var(--bq-neutral-900);
--bq-background--brand: var(--bq-brand);
--bq-background--overlay: var(--bq-neutral-900);
/* Icon colors */
--bq-icon--primary: var(--bq-neutral-800);
--bq-icon--secondary: var(--bq-neutral-600);
--bq-icon--inverse: var(--bq-neutral-50);
--bq-icon--brand: var(--bq-brand);
--bq-icon--alt: var(--bq-white);
--bq-icon--info: var(--bq-info);
--bq-icon--success: var(--bq-success);
--bq-icon--warning: var(--bq-warning);
--bq-icon--danger: var(--bq-danger);
/* Stroke colors */
--bq-stroke--primary: var(--bq-neutral-200);
--bq-stroke--secondary: var(--bq-neutral-600);
--bq-stroke--tertiary: var(--bq-neutral-900);
--bq-stroke--inverse: var(--bq-white);
--bq-stroke--brand: var(--bq-brand);
--bq-stroke--alt: var(--bq-neutral-50);
--bq-stroke--success: var(--bq-success);
--bq-stroke--warning: var(--bq-warning);
--bq-stroke--danger: var(--bq-danger);
/* Text colors */
--bq-text--primary: var(--bq-neutral-800);
--bq-text--secondary: var(--bq-neutral-600);
--bq-text--inverse: var(--bq-neutral-50);
--bq-text--brand: var(--bq-brand);
--bq-text--alt: var(--bq-white);
--bq-text--info: var(--bq-info);
--bq-text--success: var(--bq-success);
--bq-text--warning: var(--bq-warning);
--bq-text--danger: var(--bq-danger);
/* UI colors */
--bq-ui--primary: var(--bq-white);
--bq-ui--secondary: var(--bq-neutral-100);
--bq-ui--tertiary: var(--bq-neutral-500);
--bq-ui--inverse: var(--bq-neutral-900);
--bq-ui--brand: var(--bq-brand);
--bq-ui--brand-alt: var(--bq-brand-light);
--bq-ui--alt: var(--bq-neutral-50);
--bq-ui--success: var(--bq-success);
--bq-ui--success-alt: var(--bq-success-light);
--bq-ui--warning: var(--bq-warning);
--bq-ui--warning-alt: var(--bq-warning-light);
--bq-ui--danger: var(--bq-danger);
--bq-ui--danger-alt: var(--bq-danger-light);
}
Define dark mode theme
Define the declarative color tokens for the dark mode:
[bq-theme="my-custom-theme"][bq-mode="dark"], /* Explicit dark mode (via attributes) */
.my-custom-theme.dark { /* Explicit dark mode (via CSS classes) */
/* Background colors */
--bq-background--primary: var(--bq-neutral-1000);
--bq-background--secondary: var(--bq-neutral-950);
--bq-background--tertiary: var(--bq-neutral-800);
--bq-background--alt: var(--bq-neutral-700);
--bq-background--inverse: var(--bq-neutral-600);
--bq-background--brand: var(--bq-brand);
--bq-background--overlay: var(--bq-neutral-900);
/* Icon colors */
--bq-icon--primary: var(--bq-neutral-100);
--bq-icon--secondary: var(--bq-neutral-400);
--bq-icon--inverse: var(--bq-neutral-800);
--bq-icon--brand: var(--bq-brand);
--bq-icon--alt: var(--bq-white);
--bq-icon--info: var(--bq-info);
--bq-icon--success: var(--bq-success);
--bq-icon--warning: var(--bq-warning);
--bq-icon--danger: var(--bq-danger);
/* Stroke colors */
--bq-stroke--primary: var(--bq-neutral-900);
--bq-stroke--secondary: var(--bq-neutral-700);
--bq-stroke--tertiary: var(--bq-neutral-400);
--bq-stroke--inverse: var(--bq-neutral-950);
--bq-stroke--brand: var(--bq-brand);
--bq-stroke--alt: var(--bq-neutral-1000);
--bq-stroke--success: var(--bq-success);
--bq-stroke--warning: var(--bq-warning);
--bq-stroke--danger: var(--bq-danger);
/* Text colors */
--bq-text--primary: var(--bq-neutral-100);
--bq-text--secondary: var(--bq-neutral-400);
--bq-text--inverse: var(--bq-neutral-800);
--bq-text--brand: var(--bq-brand);
--bq-text--alt: var(--bq-white);
--bq-text--info: var(--bq-info);
--bq-text--success: var(--bq-success);
--bq-text--warning: var(--bq-warning);
--bq-text--danger: var(--bq-danger);
/* UI colors */
--bq-ui--primary: var(--bq-neutral-900);
--bq-ui--secondary: var(--bq-neutral-950);
--bq-ui--tertiary: var(--bq-neutral-700);
--bq-ui--inverse: var(--bq-neutral-100);
--bq-ui--brand: var(--bq-brand);
--bq-ui--brand-alt: var(--bq-brand-dark);
--bq-ui--alt: var(--bq-neutral-950);
--bq-ui--success: var(--bq-success);
--bq-ui--success-alt: var(--bq-success-dark);
--bq-ui--warning: var(--bq-warning);
--bq-ui--warning-alt: var(--bq-warning-dark);
--bq-ui--danger: var(--bq-danger);
--bq-ui--danger-alt: var(--bq-danger-dark);
}
Apply your custom theme
Include your custom theme CSS file in your project and set the To switch to dark mode, change the You can also use CSS classes instead of HTML attributes:
bq-theme and bq-mode attributes on the <html> element:Always load
beeq.css before your custom theme CSS so that your variables correctly override the defaults.<!DOCTYPE html>
<html lang="en" bq-theme="my-custom-theme" bq-mode="light">
<head>
<link rel="stylesheet" href="path/to/beeq.css">
<link rel="stylesheet" href="path/to/custom-theme.css">
</head>
<body>
<!-- Your components will automatically use the custom theme -->
<bq-button>Click me</bq-button>
</body>
</html>
bq-mode attribute:<html lang="en" bq-theme="my-custom-theme" bq-mode="dark">
<body class="my-custom-theme light"> ... </body>
<!-- or -->
<body class="my-custom-theme dark"> ... </body>