inmake DOCS
Docs / CRM & Studio / Site CSS & tokens

Site CSS & tokens

What design.css provides, the token list, cascade order, the minimal site stylesheet, moving an old stylesheet onto tokens.

A project's styling starts from its design system. Committing it generates design.css: the tokens as CSS variables, plus a few base rules. Every other piece of CSS (element, template, shell, headTags stylesheet) should be small and should read the tokens instead of repeating values. Then a change on the Design page restyles the whole site.

What design.css already gives you#

Every published page links /store/{sid}/css/design.css?v={hash} as its first stylesheet. It contains:

  • :root tokens (the full list is below).

  • Base rules, so you don't repeat them:

    *, *::before, *::after { box-sizing: border-box; }
    body { margin: 0; font-family: var(--font-body); font-size: var(--text-body);
           line-height: var(--leading-body); color: var(--color-text); background: var(--color-surface); }
    h1,h2,h3,h4 { font-family: var(--font-heading); margin: 0 0 var(--space-4); }
    a { color: var(--color-primary-strong); }
    mark { color: inherit; }

    (A project still on tokens v1 gets the same rules on the original names: var(--text), var(--surface), var(--space-2).)

  • :root[data-theme="light"|"dark"] blocks. Only the console's design preview uses them. Published pages never set data-theme, so they always render the design's default scheme.

A project with no committed design system (the Design page is empty) has no design.css. Then every var(--…) falls through to its fallback, or to nothing.

The tokens#

New projects are on tokens v2. A project created before it keeps tokens v1 until someone switches it on the Design page (Tokens v2 migration). The sheet tells you which: a v2 sheet has --space-unit.

Tokens v2#

Group Variables
Color ramps --color-{role}-50 … -900 for all eight roles primary, secondary, neutral, accent, success, warning, error, info — the same in both schemes
Acting colors --color-{role} (buttons, links, icons; per scheme), -hover, -on (ink on it), -container / -on-container, -soft / -strong (chips, callouts)
Surfaces and text --color-surface, -surface-alt, -surface-card, -surface-inverse, --color-text, -text-muted, -text-on-inverse, -text-on-primary, --color-border, --color-scheme
Type scale --text-xs, -sm, -base (fixed), --text-lg … -5xl (fluid clamp()); --font-heading, -body, -button; --font-weight-body, -heading, -bold; --leading-tight, -normal, -display, -ui; --tracking-normal, -tight, -display
Type roles --text-{role}, --leading-{role}, --weight-{role}, --tracking-{role} for display-lg, display, headline, title, subtitle, body, label — references into the scale
Space --space-unit (the brand's grid, 4 px by default) and --space-{0,1,2,3,4,5,6,8,10,12,16,20,24,32} = N × the unit; --section-space
Shape and depth --radius-sm, -md, -lg, -xl, -full, -panel; --shadow-sm, -md, -lg; --border-width
Motion --motion-duration, -duration-slow, --motion-easing, --ease-out-expo, -out-quart, --ease-spring, --reveal-duration, -duration-slow, -distance, -stagger, -stagger-group, -stagger-line, -trigger
Layout --container-max, --grid-columns
Brand --brand-logo, --brand-mark, --brand-wordmark as url() per scheme, when the Brand tab holds files
Custom your own tokens from Properties › Custom tokens, grouped (slot for component slots)

Write every geometric value as a multiple of the unit: padding: var(--space-6), never padding: 18px. Font sizes follow the type scale instead. Color text through the surface and text set, never a raw ramp stop, so it stays correct in both schemes. Pair ink with its background: --color-primary-on on --color-primary, --color-success-strong on --color-success-soft.

Tokens v1#

Group Variables
Color ramps --color-{role}-50 … -900 for the roles the design defines
Color pairs --color-{role}-on, -container / -on-container, -soft / -strong
Surfaces --surface, --surface-card, --surface-muted, --text, --text-muted, --border-subtle
Type --font-heading, --font-body; per role --text-{role}, --leading-{role} (px), --weight-{role}, --tracking-{role}
Space --space-0 … --space-7, an index into unit × density (4, 8, 12, 16, 24, 32, 48, 64 px at unit 8, regular density)
Shape --radius-sm, --radius-md, --radius-lg, --radius-pill, --elevation-0 … -3
Layout --container-max, --grid-columns, --density

A migrated project keeps a few v1 names as aliases (--surface, --text-muted, --radius-pill, --elevation-* …) until nothing uses them. Don't write them in new CSS.

Custom tokens#

Brand values with no derived token (a gradient, a section's theme color, a component slot) become custom tokens on the Design page. A name is lowercase a-z0-9-. It must not shadow a generated variable. On tokens v2 the names space-unit, section-space, container-max, grid-columns, border-width and anything starting with color-, text-, leading-, tracking-, weight-, font-, space-, radius-, shadow-, motion-, ease-, reveal- or brand- are refused. On tokens v1 the list is surface, text, density, container-max, grid-columns and the prefixes color-, text-, leading-, weight-, tracking-, space-, radius-, elevation-, font-, surface-, border-. Name brand tokens by what they are: heading-ink, outline-tint, hero-gradient, theme-laser.

Where CSS goes, in cascade order#

Later stylesheets win at equal specificity:

  1. design.css: the tokens and base rules.
  2. Element-library asset stylesheets (kit CSS files).
  3. The shell (header and footer) CSS.
  4. Element and fragment CSS.
  5. The page template's CSS.
  6. The headTags from Website › Web. They come after all generated stylesheets, so a <link> there overrides template CSS.
  7. The platform cookie bar, last.

The minimal site stylesheet#

Most sites need no global stylesheet at all: each template and element carries its own scoped CSS. When you do add one (a store file linked from headTags), keep it to what is truly site-wide:

/* site.css: additions on top of the design system, not a theme */
.site-wrap { max-width: var(--container-max); margin: 0 auto; padding: 0 var(--space-4); }

.site-btn {
  background: var(--color-primary);
  color: var(--color-primary-on);
  border-radius: var(--radius-full);
  padding: var(--space-3) var(--space-6);
  font: var(--font-weight-bold) var(--text-sm)/var(--leading-ui) var(--font-button);
  transition: background var(--motion-duration) var(--motion-easing);
}
.site-btn:hover { background: var(--color-primary-hover); }

On a project still on tokens v1, the same button reads var(--color-primary-500), var(--radius-pill), var(--space-2) var(--space-4) and the label role, with var(--color-primary-600) on hover.

Rules:

  • Read tokens, don't restate them. Write background: var(--color-primary), not #ea560d. A literal never changes when the design does.
  • Don't style html or body. design.css owns them.
  • Prefix your classes (.site-…, or a page's own root class) and never use bare generic selectors (.container, .btn, h2). Template CSS follows the same rule: one unique root class per template, and every selector under it.
  • Mobile-first. Base styles for a phone, then @media (min-width: …) steps up.
  • Fonts: add them in Design system › Properties › Typography › Fonts (uploaded files, a self-hosted or linked Google family, an Adobe Fonts kit or any font stylesheet) and name the family in the type settings, so --font-heading / --font-body carry it. The platform writes the @font-face rules into design.css and the <link>s into headTags — no @font-face in your own stylesheet.

Moving an existing stylesheet onto tokens#

A site imported from elsewhere often arrives as one big stylesheet in headTags. It renders, but design edits change nothing. To move it onto the tokens without changing how the site looks:

  1. Commit a design system derived from that stylesheet first: its colors as the color roles, its fonts, its radii. Values that have no derived token become custom tokens.
  2. Replace a literal only where it exactly equals a token's value, and keep the literal as the fallback: #ea560d → var(--color-primary-500,#ea560d).
  3. Never define a variable through a token of the same name (.site { --x: var(--x, …) }). That is a cycle, and the variable becomes invalid. Delete the site's copy and let the token inherit.
  4. Leave font-family stacks alone unless they match the token's stack exactly. A different fallback list changes how any glyph missing from the web font renders.
  5. Write the result as a new file, repoint the headTags link to it, and keep the old file. Pointing the link back is the rollback.
  6. Compare pages before and after at desktop and phone widths. Then change a token and confirm the page follows it.

Font sizes, spacing and other values that are near a token but not equal to it stay literal. Moving them onto the scale changes the site visibly, so it is a design decision, not a migration step.