Skip to main content

Themes

EventCatalog comes with a selection of built-in themes and supports both light and dark modes out of the box.

Choosing a theme​

To set a theme, add the theme property to your eventcatalog.config.js file:

eventcatalog.config.js
export default {
// ... other config
theme: 'sapphire',
};

Available themes​

EventCatalog includes the following built-in themes:

ThemeDescription
defaultPurple accent - the original EventCatalog look
oceanTeal accent - calm and professional
sapphireBlue accent - premium enterprise feel
sunsetOrange accent - warm and energetic
forestDark green accent - natural and grounded

Light and dark mode​

EventCatalog supports both light and dark modes. Users can toggle between modes using the theme switcher in the header.

How it works​

  • The theme toggle appears in the header navigation
  • System preference by default: New visitors see light or dark mode based on their operating system preference
  • Remembers user choice: Once a user manually toggles the theme, their preference is saved and used on future visits
  • Syncs across tabs: Theme changes sync across browser tabs
  • Responds to system changes: If no manual preference is set, the theme automatically updates when the user changes their OS dark mode setting

Theme persistence​

When a user manually selects light or dark mode, their preference is stored in localStorage under the key eventcatalog-theme. This ensures their choice persists across page reloads and browser sessions.

If no preference is stored, EventCatalog automatically follows the user's system preference using the prefers-color-scheme media query.


Creating custom themes​

i
This feature is available on the Scale plan.

Custom themes allow you to fully brand EventCatalog with your organization's colors. You define your theme in eventcatalog.styles.css using CSS variables.

Step 1: Create your theme CSS​

Add your custom theme to eventcatalog.styles.css in your project root. Your theme needs to define CSS variables for both light and dark modes.

eventcatalog.styles.css
/**
* Custom "ruby" theme - Red accent colors
*/

/* Light Mode */
:root[data-catalog-theme="ruby"],
:root[data-catalog-theme="ruby"][data-theme="light"] {
/* Accent colors */
--ec-accent: 220 38 38; /* red-600 */
--ec-accent-hover: 185 28 28; /* red-700 */
--ec-accent-subtle: 254 226 226; /* red-100 */
--ec-accent-text: 153 27 27; /* red-800 */

/* Buttons */
--ec-button-bg: 185 28 28; /* red-700 */
--ec-button-bg-hover: 153 27 27; /* red-800 */
--ec-button-text: 255 255 255;

/* Sidebar */
--ec-sidebar-active-bg: 185 28 28;
--ec-sidebar-active-text: 255 255 255;
--ec-sidebar-hover-bg: 185 28 28;

/* You can override any CSS variable here */
}

/* Dark Mode */
:root[data-catalog-theme="ruby"][data-theme="dark"] {
/* Accent colors - use lighter shades for dark mode */
--ec-accent: 248 113 113; /* red-400 */
--ec-accent-hover: 239 68 68; /* red-500 */
--ec-accent-subtle: 127 29 29 / 0.3;
--ec-accent-text: 252 165 165; /* red-300 */

/* Buttons */
--ec-button-bg: 220 38 38; /* red-600 */
--ec-button-bg-hover: 239 68 68; /* red-500 */
--ec-button-text: 255 255 255;

/* Sidebar */
--ec-sidebar-active-bg: 220 38 38;
--ec-sidebar-active-text: 255 255 255;
}

Step 2: Set the theme in config​

Reference your custom theme name in eventcatalog.config.js:

eventcatalog.config.js
export default {
// ... other config
theme: 'ruby', // Matches data-catalog-theme="ruby" in your CSS
};

Step 3: Test both modes​

Start your catalog and test both light and dark modes to ensure all colors look correct:

npm run dev

Toggle between light and dark mode using the theme switcher in the header.

Tailwind Color Reference

Use Tailwind CSS colors as a reference for your RGB values. For example, red-600 is 220 38 38.

RGB Format Required

CSS variables must use space-separated RGB values (e.g., 220 38 38) without the rgb() wrapper. This allows EventCatalog to apply opacity modifiers like rgb(var(--ec-accent) / 0.5).


Full CSS variable reference​

Here are all available CSS variables you can customize:

Core colors​

VariableDescription
--ec-accentPrimary accent color for highlights and interactive elements
--ec-accent-hoverAccent color on hover
--ec-accent-subtleLight accent background (badges, highlights)
--ec-accent-textText color on accent backgrounds
--ec-accent-gradient-fromGradient start color
--ec-accent-gradient-toGradient end color
VariableDescription
--ec-header-bgHeader background
--ec-header-textHeader text color
--ec-header-borderHeader border color
VariableDescription
--ec-sidebar-bgSidebar background
--ec-sidebar-bg-gradientSidebar gradient end color
--ec-sidebar-borderSidebar border
--ec-sidebar-textSidebar text color
--ec-sidebar-active-bgActive item background
--ec-sidebar-active-textActive item text
--ec-sidebar-hover-bgHover item background

Content area​

VariableDescription
--ec-content-bgNested sidebar content background
--ec-content-textContent text
--ec-content-text-mutedMuted text
--ec-content-text-secondarySecondary text
--ec-content-borderContent borders
--ec-content-hoverHover background
--ec-content-activeActive item background

Page​

VariableDescription
--ec-page-bgMain page background
--ec-page-textPage text color
--ec-page-text-mutedMuted/secondary text
--ec-page-borderPage borders

Buttons​

VariableDescription
--ec-button-bgButton background
--ec-button-bg-hoverButton hover background
--ec-button-textButton text color

Form inputs​

VariableDescription
--ec-input-bgInput field background
--ec-input-borderInput field border
--ec-input-textInput field text
--ec-input-placeholderPlaceholder text color
VariableDescription
--ec-dropdown-bgDropdown background
--ec-dropdown-textDropdown text
--ec-dropdown-hoverDropdown hover background
--ec-dropdown-borderDropdown border

Icons​

VariableDescription
--ec-icon-colorDefault icon color
--ec-icon-hoverIcon hover color

Other​

VariableDescription
--ec-card-bgCard/elevated surface background
--ec-code-bgCode block background
--ec-group-icon-bgGroup header icon background
--ec-group-icon-textGroup header icon text

Dark mode prose overrides​

For custom themes, you may want to customize how markdown content (prose) appears in dark mode:

eventcatalog.styles.css
:root[data-catalog-theme="ruby"][data-theme="dark"] .prose {
--tw-prose-body: rgb(163 163 163);
--tw-prose-headings: rgb(245 245 245);
--tw-prose-links: rgb(248 113 113); /* Match your accent */
--tw-prose-bold: rgb(245 245 245);
--tw-prose-code: rgb(245 245 245);
--tw-prose-pre-bg: rgb(23 23 23);
}

:root[data-catalog-theme="ruby"][data-theme="dark"] .prose a {
color: rgb(248 113 113);
}

:root[data-catalog-theme="ruby"][data-theme="dark"] .prose a:hover {
color: rgb(252 165 165);
}

Example: Complete custom theme​

Here's a complete example of a custom "ruby" red theme you can use as a starting point:

View full ruby theme CSS
eventcatalog.styles.css
/**
* Ruby Theme - Custom Red Theme
*/

/* Ruby Light Mode */
:root[data-catalog-theme="ruby"],
:root[data-catalog-theme="ruby"][data-theme="light"] {
--ec-header-bg: 255 255 255;
--ec-header-text: 23 23 23;
--ec-header-border: 229 229 229;

--ec-primary: 220 38 38;
--ec-primary-hover: 185 28 28;

--ec-accent: 220 38 38;
--ec-accent-hover: 185 28 28;
--ec-accent-subtle: 254 226 226;
--ec-accent-text: 153 27 27;
--ec-accent-gradient-from: 239 68 68;
--ec-accent-gradient-to: 185 28 28;

--ec-button-bg: 185 28 28;
--ec-button-bg-hover: 153 27 27;
--ec-button-text: 255 255 255;

--ec-dropdown-bg: 255 255 255;
--ec-dropdown-text: 64 64 64;
--ec-dropdown-hover: 254 242 242;
--ec-dropdown-border: 229 229 229;

--ec-icon-color: 82 82 82;
--ec-icon-hover: 185 28 28;

--ec-sidebar-bg: 255 255 255;
--ec-sidebar-bg-gradient: 254 242 242;
--ec-sidebar-border: 229 229 229;
--ec-sidebar-text: 82 82 82;
--ec-sidebar-active-bg: 185 28 28;
--ec-sidebar-active-text: 255 255 255;
--ec-sidebar-hover-bg: 185 28 28;

--ec-content-bg: 255 255 255;
--ec-content-text: 23 23 23;
--ec-content-text-muted: 82 82 82;
--ec-content-text-secondary: 115 115 115;
--ec-content-border: 229 229 229;
--ec-content-hover: 250 250 250;
--ec-content-active: 254 226 226;

--ec-input-bg: 255 255 255;
--ec-input-border: 212 212 212;
--ec-input-text: 23 23 23;
--ec-input-placeholder: 163 163 163;

--ec-group-icon-bg: 254 226 226;
--ec-group-icon-text: 153 27 27;

--ec-page-bg: 255 255 255;
--ec-page-text: 23 23 23;
--ec-page-text-muted: 82 82 82;
--ec-page-border: 229 229 229;

--ec-card-bg: 255 255 255;
--ec-code-bg: 250 250 250;
}

/* Ruby Dark Mode */
:root[data-catalog-theme="ruby"][data-theme="dark"] {
--ec-header-bg: 23 23 23;
--ec-header-text: 245 245 245;
--ec-header-border: 38 38 38;

--ec-accent: 248 113 113;
--ec-accent-hover: 239 68 68;
--ec-accent-subtle: 127 29 29 / 0.3;
--ec-accent-text: 252 165 165;
--ec-accent-gradient-from: 248 113 113;
--ec-accent-gradient-to: 239 68 68;

--ec-button-bg: 220 38 38;
--ec-button-bg-hover: 239 68 68;
--ec-button-text: 255 255 255;

--ec-dropdown-bg: 23 23 23;
--ec-dropdown-text: 212 212 212;
--ec-dropdown-hover: 38 38 38;
--ec-dropdown-border: 64 64 64;

--ec-icon-color: 163 163 163;
--ec-icon-hover: 252 165 165;

--ec-sidebar-bg: 10 10 10;
--ec-sidebar-bg-gradient: 10 10 10;
--ec-sidebar-border: 38 38 38;
--ec-sidebar-text: 163 163 163;
--ec-sidebar-active-bg: 220 38 38;
--ec-sidebar-active-text: 255 255 255;
--ec-sidebar-hover-bg: 38 38 38;

--ec-content-bg: 10 10 10;
--ec-content-text: 245 245 245;
--ec-content-text-muted: 163 163 163;
--ec-content-text-secondary: 163 163 163;
--ec-content-border: 38 38 38;
--ec-content-hover: 23 23 23;
--ec-content-active: 38 38 38;

--ec-input-bg: 23 23 23;
--ec-input-border: 64 64 64;
--ec-input-text: 245 245 245;
--ec-input-placeholder: 115 115 115;

--ec-group-icon-bg: 38 38 38;
--ec-group-icon-text: 252 165 165;

--ec-page-bg: 10 10 10;
--ec-page-text: 245 245 245;
--ec-page-text-muted: 163 163 163;
--ec-page-border: 38 38 38;

--ec-card-bg: 10 10 10;
--ec-code-bg: 23 23 23;
}

/* Ruby theme prose overrides */
:root[data-catalog-theme="ruby"][data-theme="dark"] .prose {
--tw-prose-body: rgb(163 163 163);
--tw-prose-headings: rgb(245 245 245);
--tw-prose-links: rgb(248 113 113);
--tw-prose-bold: rgb(245 245 245);
}

:root[data-catalog-theme="ruby"][data-theme="dark"] .prose a {
color: rgb(248 113 113);
}

:root[data-catalog-theme="ruby"][data-theme="dark"] .prose a:hover {
color: rgb(252 165 165);
}