Base color stops have been standardized to a 12-stop scale. Includes migration tools for stop renames and upgrading to semantic color tokens.
var(--dt-color-purple-350).Six of the base color ramps (purple, blue, magenta, gold, green, red) previously used irregular stop numbers (250, 350, 425, etc.). This was previously necessary as part of mid-2025's Dialpad Rebrand. Some colors like black already used a 12-stop scale and remain unchanged.
All colors now follow a consistent 12-stop scale:
50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950 | 1000
Only names changed. They've just moved to new positions in the scale. For example, the color for purple-350 is now purple-500.
.foo {
color: var(--dt-color-purple-350);
background: var(--dt-color-red-450);
}
.foo {
color: var(--dt-color-purple-500);
background: var(--dt-color-red-600);
}
<div class="d-bgc-purple-350 d-fc-blue-425">
...
</div>
<div class="d-bgc-purple-500 d-fc-blue-500">
...
</div>
Stops not listed (e.g. 50, 100, 200, 1000) are unchanged for all colors. Blue, gold, green, and red also keep 300 unchanged. Colors not listed here already use a 12-stop scale and remain unchanged.
| Old Stop | New Stop |
|---|---|
250 | 300 |
300 | 400 |
350 | 500 |
400 | 600 |
450 | 700 |
500 | 800 |
550 | 900 |
600 | 950 |
| Old Stop | New Stop |
|---|---|
425 | 500 |
450 | 600 |
475 | 700 |
500 | 800 |
600 | 900 |
900 | 950 |
| Old Stop | New Stop |
|---|---|
250 | 300 |
300 | 400 |
400 | 500 |
425 | 600 |
475 | 700 |
500 | 800 |
600 | 900 |
900 | 950 |
| Old Stop | New Stop |
|---|---|
350 | 400 |
400 | 500 |
450 | 600 |
500 | 700 |
600 | 800 |
700 | 900 |
900 | 950 |
| Old Stop | New Stop |
|---|---|
350 | 400 |
400 | 500 |
425 | 600 |
475 | 700 |
500 | 800 |
600 | 900 |
900 | 950 |
| Old Stop | New Stop |
|---|---|
350 | 400 |
400 | 500 |
450 | 600 |
500 | 700 |
600 | 800 |
700 | 900 |
900 | 950 |
dialtone-migration-helper scans your files for old color stop references and renames them to the new standard scale. It's included with @dialpad/dialtone-css.
The tool migrates:
var(--dt-color-{color}-{oldStop}) → var(--dt-color-{color}-{newStop})d-bgc-{color}-{oldStop}, d-fc-*, d-bc-*, d-bgg-from-*, d-bgg-to-*-h, -s, -l, -hslnpx dialtone-migration-helper --cwd ./src
# Select "color stops" from the config list
npx dialtone-migration-helper --cwd ./src --force
# Select "color stops" from the config list
After renaming stops, many base color usages have a direct semantic equivalent. For example, d-fc-red-600 is the same color as d-fc-critical. The semantic version is theme-aware, adapting automatically to dark mode, high contrast, and brand variants.
The base-to-semantic migration tool auto-replaces only where the mapping is unambiguous. It uses context to determine the correct semantic category:
d-fc-* → foreground, d-bgc-* → surface, d-bc-* → bordercolor: → foreground, background[-color]: → surface, border[-*][-color]: → border<p class="d-fc-red-600">Error message</p>
<div class="d-bgc-black-100">Card</div>
<div class="d-bc-green-700">Success</div>
<p class="d-fc-critical">Error message</p>
<div class="d-bgc-secondary">Card</div>
<div class="d-bc-positive">Success</div>
.alert {
color: var(--dt-color-red-600);
background-color: var(--dt-color-red-100);
border-color: var(--dt-color-red-600);
}
.alert {
color: var(--dt-color-foreground-critical);
background-color: var(--dt-color-surface-critical);
border-color: var(--dt-color-border-critical);
}
.foo {
border: var(--dt-size-border-100) solid
var(--dt-color-red-600);
}
.foo {
border: var(--dt-size-border-100) solid
var(--dt-color-border-critical);
}
Notice that the same base color red-600 maps to different semantics depending on which CSS property it's used in: foreground-critical for text, surface-critical-strong for backgrounds, and border-critical for borders.
npx dialtone-migration-helper --cwd ./src
# Select "base to semantic" from the config list
d-fc-*, d-bgc-*, d-bc-*, d-divide-* with mapped base colorscolor:, background[-color]:, border[-side][-color]: with mapped base color varsbackground:, border:)border-top-color, border-block-start, border-inline-end-color, etc.)The tool leaves unmapped base colors unchanged. Dialtone's ESLint rule (deprecated-base-color-classes) and Stylelint rule (no-base-color-tokens) will flag these for manual review:
--my-var: var(--dt-color-*))fill, stroke)var(--dt-color-red-600-h))| Base Color | Semantic Class | Semantic Token |
|---|---|---|
black-600 | d-fc-tertiary | var(--dt-color-foreground-tertiary) |
black-700 | d-fc-secondary | var(--dt-color-foreground-secondary) |
black-900 | d-fc-primary | var(--dt-color-foreground-primary) |
red-600 | d-fc-critical | var(--dt-color-foreground-critical) |
red-700 | d-fc-critical-strong | var(--dt-color-foreground-critical-strong) |
green-800 | d-fc-positive | var(--dt-color-foreground-positive) |
green-900 | d-fc-positive-strong | var(--dt-color-foreground-positive-strong) |
gold-800 | d-fc-warning | var(--dt-color-foreground-warning) |
| Base Color | Semantic Class | Semantic Token |
|---|---|---|
black-50 | d-bgc-primary | var(--dt-color-surface-primary) |
black-100 | d-bgc-secondary | var(--dt-color-surface-secondary) |
black-200 | d-bgc-moderate | var(--dt-color-surface-moderate) |
black-300 | d-bgc-bold | var(--dt-color-surface-bold) |
black-600 | d-bgc-strong | var(--dt-color-surface-strong) |
black-800 | d-bgc-contrast | var(--dt-color-surface-contrast) |
red-50 | d-bgc-critical-subtle | var(--dt-color-surface-critical-subtle) |
red-100 | d-bgc-critical | var(--dt-color-surface-critical) |
red-600 | d-bgc-critical-strong | var(--dt-color-surface-critical-strong) |
gold-50 | d-bgc-warning-subtle | var(--dt-color-surface-warning-subtle) |
gold-100 | d-bgc-warning | var(--dt-color-surface-warning) |
gold-400 | d-bgc-warning-strong | var(--dt-color-surface-warning-strong) |
green-50 | d-bgc-positive-subtle | var(--dt-color-surface-positive-subtle) |
green-100 | d-bgc-positive | var(--dt-color-surface-positive) |
green-800 | d-bgc-positive-strong | var(--dt-color-surface-positive-strong) |
blue-50 | d-bgc-info-subtle | var(--dt-color-surface-info-subtle) |
blue-100 | d-bgc-info | var(--dt-color-surface-info) |
blue-800 | d-bgc-info-strong | var(--dt-color-surface-info-strong) |
purple-50 | d-bgc-brand-subtle | var(--dt-color-surface-brand-subtle) |
purple-100 | d-bgc-brand | var(--dt-color-surface-brand) |
purple-600 | d-bgc-brand-strong | var(--dt-color-surface-brand-strong) |
| Base Color | Semantic Class | Semantic Token |
|---|---|---|
red-300 | d-bc-critical-subtle | var(--dt-color-border-critical-subtle) |
red-600 | d-bc-critical | var(--dt-color-border-critical) |
red-800 | d-bc-critical-strong | var(--dt-color-border-critical-strong) |
green-300 | d-bc-positive-subtle | var(--dt-color-border-positive-subtle) |
green-700 | d-bc-positive | var(--dt-color-border-positive) |
green-900 | d-bc-positive-strong | var(--dt-color-border-positive-strong) |
gold-300 | d-bc-warning-subtle | var(--dt-color-border-warning-subtle) |
gold-500 | d-bc-warning | var(--dt-color-border-warning) |
gold-700 | d-bc-warning-strong | var(--dt-color-border-warning-strong) |
purple-300 | d-bc-brand-subtle | var(--dt-color-border-brand-subtle) |
purple-600 | d-bc-brand | var(--dt-color-border-brand) |
purple-800 | d-bc-brand-strong | var(--dt-color-border-brand-strong) |
blue-500 | d-bc-focus | var(--dt-color-border-focus) |
Migrating Base Color Stops documentation last updated Friday, September 4, 2026
fix/popover-modal-zindex-scope