Skip to content

Token Naming Convention

Semanticus CSS uses a 4-tier token system. Each tier builds on the previous, giving you precise control over how broadly or narrowly a style change applies.

Four Token Tiers

Tier 1: System Tokens        --property[-state]              page-level defaults
Tier 2: Variant Tokens       --{variant}-property[-state]     variant definitions
Tier 3: Component Tokens     --{component}-property[-state]   component-scoped slots
Tier 4: Individual Tokens    --_{component}-property[-state]  per-instance overrides

The flow: System → Variant → Component → Individual (--_).

Tier 1: System Tokens

No scope prefix. These define the document-wide baseline and must match a CSS longhand property name whenever possible.

css
:root, :host {
  --background-color
  --color
  --font-family
  --font-size
  --typography-margin-block
  --border-color
  --border-radius
  --outline-width
  --opacity-disabled
  --transition

  /* Exceptions */
  --spacing
  --color-hover-shade
}

System Tokens affect the entire page. Setting --background-color on a modifier class changes the background of every component that reads it.

Tier 2: Variant Tokens

These provide the raw color values consumed by variant modifier classes. Users override these to define custom palettes.

--{variant}-{property}[-{state}]
css
:root, :host {
  --primary-color
  --primary-color-hover
  --primary-background-color
  --primary-background-color-hover
  --primary-outline-color

  --secondary-color
  --secondary-color-hover
  --secondary-background-color
  --secondary-background-color-hover
  --secondary-outline-color

  /* Also: contrast, success, info, warning, danger */
  /* (each with color, background-color, outline-color, and *-hover variants) */
}

Variant Tokens are referenced by variant classes but don't directly style elements — they feed into the tiers below.

Tier 3: Component Tokens

Scoped to a component type. Setting one of these changes every instance of that component (e.g., all buttons, all inputs, all dialogs).

--{component}[-{part}]-{property}[-{state}]
css
:root, :host {
  /* Building Blocks */
  --focus-ring-width
  --menu-box-shadow
  --selection-background-color
  --backdrop-background-color

  /* Buttons */
  --buttons-color / --buttons-color-hover
  --buttons-background-color / --buttons-background-color-hover
  --buttons-padding-block / --buttons-padding-inline

  /* Inputs */
  --inputs-background-color / --inputs-background-color-focus
  --inputs-border-color / --inputs-color
  --inputs-accent-color / --inputs-placeholder-color

  /* Dialog */
  --dialog-background-color / --dialog-border-color

  /* Details */
  --details-dropdown-background-color / --details-dropdown-color / --details-dropdown-border-color
  --details-menu-background-color / --details-menu-color

  /* Links, Headings, Lists, Code, Mark, Table, Navigation, Progress, Tooltip… */
}

Tier 4: Individual Component Tokens

Private tokens prefixed with --_. Defined in each component's CSS file and initialized from the Component Token tier. These are the values the component actually consumes for its own styling.

--_{component}[-{part}]-{property}[-{state}]
css
/* Inside _buttons.css */
button, [role="button"] {
  --_buttons-background-color: var(--buttons-background-color);
  --_buttons-color: var(--buttons-color);
  --_buttons-border-color: var(--_buttons-background-color);

  background-color: var(--_buttons-background-color);
  color: var(--_buttons-color);
  border-color: var(--_buttons-border-color);
}

/* Inside inputs/_common.css */
:where(input, select, textarea) {
  --_inputs-background-color: var(--inputs-background-color);
  --_inputs-border-color: var(--inputs-border-color);

  background-color: var(--_inputs-background-color);
  border-color: var(--_inputs-border-color);
}

/* Inside _dialog.css */
dialog {
  --_dialog-background-color: var(--dialog-background-color);
  --_dialog-border-color: var(--dialog-border-color);

  background: var(--_dialog-background-color);
  border-color: var(--_dialog-border-color);
}

How Modifier Classes Work Across Tiers

Modifier classes (.primary, .secondary, etc.) can target any tier to control the scope of their effect:

Override System Tokens → affects all children of the element

css
.primary {
  /* Affects all children */
  --background-color: var(--primary-background-color);
}

Override Component Tokens → affects all children, instances of a component

css
.primary {
  /* Affects all children that are a Card component */
  --card-background-color: var(--primary-background-color);
}

Override Individual Tokens → affects the specific element itself

css
.primary {
  /* Affects the element itself if it is a Card component */
  --_card-background-color: var(--primary-background-color);
}

The 4-tier cascade means no combinatorial explosion — .ghost works with any intent class without separate blocks for .ghost.primary, .ghost.secondary, etc.

Property Name Rules

Tokens at Tiers 1-3 must use CSS longhand property names:

✓ Do this✖ Not thisBecause
--background-color--backgroundbackground resets image, position, etc.
--border-color--borderborder resets width and style
--border-width--border-sizeCSS property is border-width
--outline-width--outline-sizeCSS property is outline-width

Genuine Exceptions

TokenReason
--spacingResponsive value used for margins and padding throughout the page
--color-hover-shadeInternal helper color mixed into base colors via color-mix() to derive hover-state variants — not a standalone property value

State Ordering

State always comes last:

css
--buttons-background-color-hover
--details-summary-color-open
--inputs-background-color-focus

Spacing Tokens

Use spacing as the property segment:

css
--spacing                       /* global density */
--typography-margin-block   /* block margins */
--inputs-padding-block       /* form padding */
--buttons-padding-block
--details-dropdown-padding-block

Cascade-Seed Tokens

Tokens on :root that propagate via inheritance use the CSS property name:

css
--font-size      /* seeds rem calculations */
--line-height    /* inherited by all text */
--font-weight    /* inherited baseline */
--text-underline-offset

Migration from v2.2.0 to v3.0.0

Old (v2.2.0)New (v3.0.0)Notes
--color-primary-fill--primary-background-colorfillbackground-color
--color-primary-text--primary-colortextcolor
--color-primary-focus-ring--primary-outline-colorProperty-mapped
--color-background--background-colorGlobal, no --color- wrapper
--color-text--colorGlobal text
--color-text-muted--color-mutedMuted variant
--color-border--border-colorGlobal border
--dialog-fill--dialog-background-colorComponent + property
--input-border-focus--inputs-border-color-focusState at end
--switch-thumb-glow--input-switch-thumb-box-shadowProperty name
--loading-spinner-opacityremovedUnused
--shadow--_buttons-box-shadow / --_inputs-box-shadowScoped private tokens
--button-*--buttons-*Pluralized
--input-*--inputs-*Pluralized
--h1-gap-top--h1-margin-topProperty-mapped
--dialog-section-*--dialog-marginals-*Renamed
--menu-*--details-menu-*Scoped under details
--pane-*--dialog-*Consolidated
--range-*--input-range-*Scoped under inputs
--switch-*--input-switch-*Scoped under inputs
--search-*--input-search-*Scoped under inputs
--checkbox-*--input-checkbox-*Scoped under inputs
--progress-background-color--progress-track-background-colorProperty-mapped