Skip to content

Docs :: Default Theme

File name Description Source
theme.default.css Default theme entry: imports the next two Github
theme.default.tokens.css Raw tokens: colors, type, spacing, etc. Github
theme.default.ui.css UI tokens: what elements and components use Github
theme.starter.css Use it as a start for your own theme Github
theme.wireframe.css Full swappable theme example Github

Every design value in mCSS (colors, fonts, spacing, component styling) lives in the default theme. Your own theme should be imported after it and just override what it needs.

Never edit the default theme files. Keep your design decisions in your own theme, so updating the framework is easy.

Activating a theme

Activate the default theme right after the framework, then (optionally) your own theme:

@import url(./framework/mcss.css);
@import url(./framework/mcss.components.css); /* optional */
@import url(./framework/theme.default.css);
@import url(./site/theme.starter.css); /* your theme */

Theme files are self-layered and your theme goes in the theme.user layer:

theme.starter.css
@layer theme.user {
/* […] */
}

mCSS is set up so that, regardless of how you load your theme (@import, <link>, or bundler), it always overrides the default theme.

Writing your own theme

Copy theme.starter.css and start overriding:

  • Tokens first. Most themes never need a selector: raw tokens for the palette and type, UI tokens for general UI changes, and component tokens for details.
  • Style rules only for what tokens can’t express: pseudo-elements, nth-child rhythm, font smoothing, text-wrap, etc. Your theme file is the one place where overriding framework classes and HTML elements from other files is ok.
  • Check tokens before writing a style rule. The page is already painted from --body-background-color, --text-color, and --text: set those instead of writing a body rule for background, color, or font.
  • No !important. It will break the layer system. And if you need !important, it’s a sign you’re doing something wrong.

Full themes

A theme can also be a complete, distributable style. mCSS ships with the theme.wireframe.css example. (Flip the switcher on the marketing template to see it live.)

A full theme is an entry that imports the default theme itself and overrides on top, so you activate it INSTEAD of the default:

@import url(./framework/mcss.css);
/* theme.default.css is swapped */
@import url(./framework/theme.wireframe.css);

The wireframe file is a good read if you’re planning a full theme. Token overrides do most of the work (grayscale palette, handwriting font stack, “paper cutout” shadows), a few style rules cover the rest (wavy underlines, tilted cards), and it’s deliberate about what it leaves alone: the focus ring stays crisp, and text stays high-contrast.

Tokens

Tokens are CSS custom properties, split in two files:

  • Raw tokens are named for what they are: raw values like colors, type sizes, spacing, radii, etc.
  • UI tokens are named for what they’re for: they map raw tokens to elements and components.

Because components read var(--ui-border-color) instead of a raw hex value, one override can have three levels of blast radius:

@layer theme.user {
:root {
/* Whole palette shifts */
--base-950: #1a1208;
/* Every bordered surface at once */
--ui-border-color: light-dark(var(--base-300), var(--base-600));
/* Single component override */
--bt-border-radius: 0;
}
}

That’s why small theme files can go far with a handful of token overrides.

How to use tokens

When you start a new project, put your design’s raw token values in your own theme: your base and primary colors, your font stacks, and whatever else your design calls for. The defaults are sensible and things like spacing might not need to change.

Then continue overriding UI tokens provided by mCSS as you go, and creating your own when needed. Do not add hard-coded “magic numbers” anywhere else but in your theme’s tokens.

UI tokens

UI tokens are named for what they’re for: semantic aliases (--ui-border-color), element defaults (--heading-font, --input-padding, etc.), and every component’s defaults (--badge-color, --card-spacing, etc.).

A UI token usually takes another token for value: a UI token when the meaning is shared (--input-border-color is --ui-border-color), or a raw token when the value should stay in sync with the rest of the design (--fieldset-padding is --sm3). Hard-coded values are for the few places where that sync would be wrong: content (separator strings, icon URLs), geometry tuned to one control (--toggle-width), and element-relative em measures.

For your own components, there’s no hard and fast rule about which kind of token to use. If the same style comes up in several places with the same meaning, a new UI token is probably the best option.

Raw tokens

Color

Check out tints.dev if you want to make your own palettes programmatically.

Base

Token Value Demo
base-0 #fff
base-50 #f6f7f9
base-100 #edeef1
base-200 #d6dbe1
base-300 #b2bbc7
base-400 #8897a8
base-500 #697a8e
base-600 #546375
base-700 #4a5666
base-800 #3c4550
base-900 #353c45
base-950 #23282e

Primary

Token Value Demo
primary-50 #f0f9ff
primary-100 #e0f2fe
primary-200 #bae6fd
primary-300 #7dd3fc
primary-400 #38bdf8
primary-500 #0ea5e9
primary-600 #0284c7
primary-700 #0369a1
primary-800 #075985
primary-900 #0c4a6e
primary-950 #082f49

Feedback

Token Value Demo
yes-100 #d5f6e8
yes-200 #afebd4
yes-300 #7adbbd
yes-400 #46c4a0
yes-500 #13886d
no-100 #ffe4e6
no-200 #fecdd3
no-300 #fda4af
no-400 #fb7185
no-500 #e11d48
maybe-100 #fff7d6
maybe-200 #fff0b3
maybe-300 #ffd64a
maybe-400 #ffc220
maybe-500 #f9a007

Highlight

The text marker color, consumed by the --marker-color UI token (what <mark> uses). Override --highlight-500 in a theme to restyle every highlight.

Token Value Demo
highlight-500 #ffee00

Dimension

Dimension tokens can be used anywhere you need to set margin, padding, width, height, etc.

Token Value Demo
xs1 4px
xs2 8px
xs3 12px
sm1 16px
sm2 20px
sm3 24px
md1 28px
md2 32px
md3 36px
lg1 40px
lg2 44px
lg3 48px
xl1 56px
xl2 64px
xl3 80px
xxl1 96px
xxl2 112px
xxl3 128px
mega1 160px
mega2 192px
mega3 224px
giga1 256px
giga2 288px
giga3 320px
tera1 384px
tera2 480px
tera3 520px

Aspect ratio

Token Value Demo
ar-square 1
ar-landscape 4/3
ar-portrait 3/4
ar-widescreen 16/9
ar-golden 1.618/1

Typography

Font stack

There are 3 font stacks set up by default for the font-family CSS property.

Token Value
text ui-sans-serif, system-ui, sans-serif
display Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, ui-sans-serif, sans-serif
mono Dank Mono, Inconsolata, Fira Mono, SF Mono, Monaco, Droid Sans Mono, Source Code Pro, Cascadia Code, Menlo, Consolas, DejaVu Sans Mono, ui-monospace, monospace

These stacks are optimized for fonts available on device, to maximize for speed and alleviate any layout shifts or flashes. You can find more stacks at Modern Font Stacks.

If you’d like to bring in your own fonts or Google fonts, you can override the display and text tokens inside your theme file.

Font size

Check out typescale.com if you need help creating your own sizes.

Token Value Demo
text-xs 0.694rem
Sample demo text
text-sm 0.833rem
Sample demo text
text-md 1rem
Sample demo text
text-lg 1.2rem
Sample demo text
text-xl 1.44rem
Sample demo text
display-sm 1.728rem
Sample demo text
display-md 2.074rem
Sample demo text
display-lg 2.488rem
Sample demo text
display-xl 2.986rem
Sample demo text
display-mega 3.583rem
Demo text
display-giga 4.299rem
Demo text

The heading font sizes (--heading-font-size-h1-h6) build on this scale but are UI tokens; they’re documented with the headings themselves.

Font weight

Token Value Demo
extra-light 200
Sample demo text
light 300
Sample demo text
book 400
Sample demo text
semi-bold 600
Sample demo text
bold 700
Sample demo text
black 900
Sample demo text

Letter spacing

Token Value Demo
tracking-sm -0.05em
Sample demo text
tracking-md 0.025em
Sample demo text
tracking-lg 0.05em
Sample demo text
tracking-xl 0.075em
Sample demo text
tracking-xxl 0.15em
Sample demo text

Line height

Token Value Demo
leading-xs 1
Sample demo text
leading-sm 1.15
Sample demo text
leading-md 1.375
Sample demo text
leading-lg 1.5
Sample demo text
leading-xl 1.75
Sample demo text
leading-xxl 2
Sample demo text

Borders

Border radius

Token Value Demo
radius-sm 3px
radius-md 5px
radius-lg 8px
radius-xl 12px
radius-xxl 16px
radius-round 1e5px

Border width

Token Value Demo
border-sm 1px
border-md 2px
border-lg 4px
border-xl 8px
border-xxl 12px

Drop Shadow

It wouldn’t be super useful to list the values here. You can look at them on Github if you’re curious.

Token Demo
shadow-sm
shadow-md
shadow-lg
shadow-xl
shadow-xxl

Opacity

Token Value Demo
o-0 0 Opacity level 0
o-1 0.2 Opacity level 1
o-2 0.4 Opacity level 2
o-3 0.6 Opacity level 3
o-4 0.8 Opacity level 4
o-5 1 Opacity level 5

Z-index

Token Value
z-bottom -1000000000
z-0 0
z-1 10
z-2 20
z-3 30
z-4 40
z-5 50
z-top 1000000000

Transition

Token Value
transition 220ms ease-in-out
transition-fast 100ms ease-in-out