# Default Theme

> Part of mCSS (mcss.dev). Rendered page: https://mcss.dev/docs/default-theme

<div class="docs_oversizedTable">

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

</div>

[srcDefault]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.default.css
[src]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.default.tokens.css
[srcUi]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.default.ui.css
[srcStarter]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.starter.css
[srcWireframe]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.wireframe.css

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:

```css
@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:

```css
/* 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`][srcStarter] 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`][srcWireframe] example. (Flip the switcher on the [marketing template](/templates/marketing) 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:

```css
@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:

```css
@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](https://www.tints.dev) if you want to make your own palettes programmatically.

<div class="grid" col="1" col-lg="2">
  <div class="grid_item">
  #### Base

| Token      | Value   | Demo                                      |
| ---------- | ------- | ----------------------------------------- |
| `base-0`   | #fff    | <div class="docs_box bgc-base-0"></div>   |
| `base-50`  | #f6f7f9 | <div class="docs_box bgc-base-50"></div>  |
| `base-100` | #edeef1 | <div class="docs_box bgc-base-100"></div> |
| `base-200` | #d6dbe1 | <div class="docs_box bgc-base-200"></div> |
| `base-300` | #b2bbc7 | <div class="docs_box bgc-base-300"></div> |
| `base-400` | #8897a8 | <div class="docs_box bgc-base-400"></div> |
| `base-500` | #697a8e | <div class="docs_box bgc-base-500"></div> |
| `base-600` | #546375 | <div class="docs_box bgc-base-600"></div> |
| `base-700` | #4a5666 | <div class="docs_box bgc-base-700"></div> |
| `base-800` | #3c4550 | <div class="docs_box bgc-base-800"></div> |
| `base-900` | #353c45 | <div class="docs_box bgc-base-900"></div> |
| `base-950` | #23282e | <div class="docs_box bgc-base-950"></div> |

  </div>
  <div class="grid_item">
  #### Primary

| Token         | Value   | Demo                                         |
| ------------- | ------- | -------------------------------------------- |
| `primary-50`  | #f0f9ff | <div class="docs_box bgc-primary-50"></div>  |
| `primary-100` | #e0f2fe | <div class="docs_box bgc-primary-100"></div> |
| `primary-200` | #bae6fd | <div class="docs_box bgc-primary-200"></div> |
| `primary-300` | #7dd3fc | <div class="docs_box bgc-primary-300"></div> |
| `primary-400` | #38bdf8 | <div class="docs_box bgc-primary-400"></div> |
| `primary-500` | #0ea5e9 | <div class="docs_box bgc-primary-500"></div> |
| `primary-600` | #0284c7 | <div class="docs_box bgc-primary-600"></div> |
| `primary-700` | #0369a1 | <div class="docs_box bgc-primary-700"></div> |
| `primary-800` | #075985 | <div class="docs_box bgc-primary-800"></div> |
| `primary-900` | #0c4a6e | <div class="docs_box bgc-primary-900"></div> |
| `primary-950` | #082f49 | <div class="docs_box bgc-primary-950"></div> |

  </div>
  <div class="grid_item">
  #### Feedback

| Token       | Value   | Demo                                       |
| ----------- | ------- | ------------------------------------------ |
| `yes-100`   | #d5f6e8 | <div class="docs_box bgc-yes-100"></div>   |
| `yes-200`   | #afebd4 | <div class="docs_box bgc-yes-200"></div>   |
| `yes-300`   | #7adbbd | <div class="docs_box bgc-yes-300"></div>   |
| `yes-400`   | #46c4a0 | <div class="docs_box bgc-yes-400"></div>   |
| `yes-500`   | #13886d | <div class="docs_box bgc-yes-500"></div>   |
| `no-100`    | #ffe4e6 | <div class="docs_box bgc-no-100"></div>    |
| `no-200`    | #fecdd3 | <div class="docs_box bgc-no-200"></div>    |
| `no-300`    | #fda4af | <div class="docs_box bgc-no-300"></div>    |
| `no-400`    | #fb7185 | <div class="docs_box bgc-no-400"></div>    |
| `no-500`    | #e11d48 | <div class="docs_box bgc-no-500"></div>    |
| `maybe-100` | #fff7d6 | <div class="docs_box bgc-maybe-100"></div> |
| `maybe-200` | #fff0b3 | <div class="docs_box bgc-maybe-200"></div> |
| `maybe-300` | #ffd64a | <div class="docs_box bgc-maybe-300"></div> |
| `maybe-400` | #ffc220 | <div class="docs_box bgc-maybe-400"></div> |
| `maybe-500` | #f9a007 | <div class="docs_box bgc-maybe-500"></div> |

#### 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 | <div class="docs_box" style="background-color: var(--highlight-500)"></div> |

  </div>
</div>

### Dimension

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

<div class="docs_oversizedTable">

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

</div>

### Aspect ratio

| Token           | Value   | Demo                                       |
| --------------- | ------- | ------------------------------------------ |
| `ar-square`     | 1       | <div class="docs_box ar-square"></div>     |
| `ar-landscape`  | 4/3     | <div class="docs_box ar-landscape"></div>  |
| `ar-portrait`   | 3/4     | <div class="docs_box ar-portrait"></div>   |
| `ar-widescreen` | 16/9    | <div class="docs_box ar-widescreen"></div> |
| `ar-golden`     | 1.618/1 | <div class="docs_box ar-golden"></div>     |

### 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](https://modernfontstacks.com).

If you'd like to bring in your own fonts or [Google fonts](https://fonts.google.com), you can override the `display` and `text` tokens inside your theme file.

<Notice type="info" title="Note" class="mb-sm3">
  In case you're curious, `ui-sans-serif` is the system's sans-serif UI font,
  `system-ui` is the system's UI font whether serif or sans-serif, and
  `sans-serif` is the browser default.
</Notice>

#### Font size

Check out [typescale.com](https://typescale.com) if you need help creating your own sizes.

<div class="docs_oversizedTable">

| Token          | Value    | Demo                                           |
| -------------- | -------- | ---------------------------------------------- |
| `text-xs`      | 0.694rem | <div class="text-xs">Sample demo text</div>    |
| `text-sm`      | 0.833rem | <div class="text-sm">Sample demo text</div>    |
| `text-md`      | 1rem     | <div class="text-md">Sample demo text</div>    |
| `text-lg`      | 1.2rem   | <div class="text-lg">Sample demo text</div>    |
| `text-xl`      | 1.44rem  | <div class="text-xl">Sample demo text</div>    |
| `display-sm`   | 1.728rem | <div class="display-sm">Sample demo text</div> |
| `display-md`   | 2.074rem | <div class="display-md">Sample demo text</div> |
| `display-lg`   | 2.488rem | <div class="display-lg">Sample demo text</div> |
| `display-xl`   | 2.986rem | <div class="display-xl">Sample demo text</div> |
| `display-mega` | 3.583rem | <div class="display-mega">Demo text</div>      |
| `display-giga` | 4.299rem | <div class="display-giga">Demo text</div>      |

</div>

The heading font sizes (`--heading-font-size-h1`…`-h6`) build on this scale but are [UI tokens](#ui-tokens); they're documented with [the headings themselves](/docs/default-html#headings).

#### Font weight

| Token         | Value | Demo                                                 |
| ------------- | ----- | ---------------------------------------------------- |
| `extra-light` | 200   | <div class="font-extra-light">Sample demo text</div> |
| `light`       | 300   | <div class="font-light">Sample demo text</div>       |
| `book`        | 400   | <div class="font-book">Sample demo text</div>        |
| `semi-bold`   | 600   | <div class="font-semi-bold">Sample demo text</div>   |
| `bold`        | 700   | <div class="font-bold">Sample demo text</div>        |
| `black`       | 900   | <div class="font-black">Sample demo text</div>       |

#### Letter spacing

| Token          | Value   | Demo                                             |
| -------------- | ------- | ------------------------------------------------ |
| `tracking-sm`  | -0.05em | <div class="tracking-sm">Sample demo text</div>  |
| `tracking-md`  | 0.025em | <div class="tracking-md">Sample demo text</div>  |
| `tracking-lg`  | 0.05em  | <div class="tracking-lg">Sample demo text</div>  |
| `tracking-xl`  | 0.075em | <div class="tracking-xl">Sample demo text</div>  |
| `tracking-xxl` | 0.15em  | <div class="tracking-xxl">Sample demo text</div> |

#### Line height

| Token         | Value | Demo                                                                |
| ------------- | ----- | ------------------------------------------------------------------- |
| `leading-xs`  | 1     | <div class="docs_lineHeightDemo leading-xs">Sample demo text</div>  |
| `leading-sm`  | 1.15  | <div class="docs_lineHeightDemo leading-sm">Sample demo text</div>  |
| `leading-md`  | 1.375 | <div class="docs_lineHeightDemo leading-md">Sample demo text</div>  |
| `leading-lg`  | 1.5   | <div class="docs_lineHeightDemo leading-lg">Sample demo text</div>  |
| `leading-xl`  | 1.75  | <div class="docs_lineHeightDemo leading-xl">Sample demo text</div>  |
| `leading-xxl` | 2     | <div class="docs_lineHeightDemo leading-xxl">Sample demo text</div> |

### Borders

  <div class="grid" col="1" col-lg="2">
    <div class="grid_item docs_radius">

#### Border radius

| Token          | Value | Demo        |
| -------------- | ----- | ----------- |
| `radius-sm`    | 3px   | <div></div> |
| `radius-md`    | 5px   | <div></div> |
| `radius-lg`    | 8px   | <div></div> |
| `radius-xl`    | 12px  | <div></div> |
| `radius-xxl`   | 16px  | <div></div> |
| `radius-round` | 1e5px | <div></div> |

</div>
<div class="grid_item docs_border">

#### Border width

| Token        | Value | Demo        |
| ------------ | ----- | ----------- |
| `border-sm`  | 1px   | <div></div> |
| `border-md`  | 2px   | <div></div> |
| `border-lg`  | 4px   | <div></div> |
| `border-xl`  | 8px   | <div></div> |
| `border-xxl` | 12px  | <div></div> |

    </div>

  </div>

### Drop Shadow

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

[githubShadows]: https://github.com/minimaldesign/mCSS/blob/main/src/styles/framework/theme.default.tokens.css#L217

  <div class="docs_shadow">

| Token        | Demo        |
| ------------ | ----------- |
| `shadow-sm`  | <div></div> |
| `shadow-md`  | <div></div> |
| `shadow-lg`  | <div></div> |
| `shadow-xl`  | <div></div> |
| `shadow-xxl` | <div></div> |

  </div>

### Opacity

| Token | Value | Demo                                     |
| ----- | ----- | ---------------------------------------- |
| `o-0` | 0     | <span class="o-0">Opacity level 0</span> |
| `o-1` | 0.2   | <span class="o-1">Opacity level 1</span> |
| `o-2` | 0.4   | <span class="o-2">Opacity level 2</span> |
| `o-3` | 0.6   | <span class="o-3">Opacity level 3</span> |
| `o-4` | 0.8   | <span class="o-4">Opacity level 4</span> |
| `o-5` | 1     | <span class="o-5">Opacity level 5</span> |

### 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 |
