Theming

For individual design tokens, see the design system documentations as well.

Overview

All of Camome's design tokens (colors, fonts, radii, etc.) are exported as CSS Custom Properties so that you can easily customize the appearance for your brand.

Dark theme is supported by default.

Default Theme

The default theme file can be imported from @camome/system/theme.css, @camome/system.theme.min.css, or unpkg.com. If you don't need to customize it, use it directly.

Configuration File (Optional)

Create a camome.config.js file in the project root.

camome.config.js
import { defineConfig } from "@camome/system";
export default defineConfig({
themes: {
light: {
color: {
primary: {
0: "#faf5ff",
1: "#f3e8ff",
2: "#e9d5ff",
3: "#d8b4fe",
4: "#c084fc",
5: "#a855f7",
6: "#9333ea",
7: "#7e22ce",
8: "#6b21a8",
9: "#581c87",
},
},
Switch: {
bgOn: (get) => get("color.success.emphasis"),
bgOff: (get) => get("color.danger.emphasis"),
fontOff: (get) => get("color.font.onEmphasis"),
},
},
},
});

In this example, the primary color is changed to purple, so custom accent colors are applied to all components such as buttons and checkboxes at once.

Switch properties are an example of component-level tokens. Many components use generic tokens such as color.<color-scheme>.<variant>..., so there is no need to set them individually, but complex components have their own tokens.

For example, <Button colorScheme="danger" variant="solid" /> uses color.danger.solid.bg and so on, and these are also shared with <Tag colorScheme="danger" variant="solid" /> . Currently, it is not possible to change these individually for each component (mainly to keep the size of global CSS small).

Get another token in theme config

Like the above Switch example, if you want to refer to another token in theme config, pass a callback function that accepts get(path: string) as the first parameter.

camome.config.js
import { alpha } from "./color-utils";
/** @type { import("@camome/system").Config;} */
export default {
themes: {
light: {
color: {
primary: {
subtle: (get) => alpha(get("color.primary.5"), 0.5),
},
},
},
},
};

In this example, semi-transparent version of color.primary.5 is passed to color.primary.subtle. Even if color.primary.subtle is referencing to another token, get function is invoked recursively until it resolves to an actual value.

Be careful with circular reference.

Because some of the tokens in the default theme are referencing, changes to color shades (like primary.color.5) cascade down other tokens.

Camome CLI

You can use Camome CLI to generate a custom theme with the definition of the configuration file.

npx camome theme

The following options are available:

  • --output: Path of CSS generation destination (defaults to theme.css)
  • --config: Path of configuration file (defaults to camome.config.js)

--watch Mode and integration with bundlers are under consideration. Currently, please run the command each time you change the theme.

Overriding Components

At the top of Camome's theme.css, priority of CSS Cascade Layers is declared as follows:

@layer cmm.reset, cmm.theme, cmm.base, cmm.components;

Thanks to this line, CSS styles declared after theme.css will always win regardless of specificity or order (as long as they are not inside the layers mentioned above). You can create a layer like cmm.custom but it is completely optional.

globals.css
/* Override styles of Button
(Outside of @layer always wins over inside) */
.Button {
border-radius: 999px;
}
/* Optional */
@layer cmm.custom {...}

Dark theme

Camome supports both light and dark themes, which can be specified by the data-theme attribute.

index.html
<!DOCTYPE html>
<html data-theme="<light or dark>">
<!-- Content -->
</html>

Tokens for each theme is defined as follows in theme.css:

theme.css
@layer cmm.theme {
:root[data-theme="light"] {
--cmm-color-primary-font: var(--cmm-color-primary-7);
--cmm-color-primary-emphasis: var(--cmm-color-primary-6);
{...}
}
/* And dark theme as well... */
}

To style according to each theme in your own CSS:

:root[data-theme="dark"] .your-class {
/* Your styles for dark theme... */
}

light and dark can be customized independently. Please refer to the configuration file section.

Font

While OS's system fonts are specified in default themes, demos in this docs are using Inter for latin characters. For changing fonts, see Typography.