Skip to content

Instantly share code, notes, and snippets.

@jamigibbs
Last active June 22, 2026 20:58
Show Gist options
  • Select an option

  • Save jamigibbs/8039cef4d04861a5ce9b3fa54a373ecf to your computer and use it in GitHub Desktop.

Select an option

Save jamigibbs/8039cef4d04861a5ce9b3fa54a373ecf to your computer and use it in GitHub Desktop.
token-migration.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Token Migration Analysis: Component Library Web Components</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bitter:wght@400;600;700&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f8f9fa;
--surface: #ffffff;
--border: #e2e8f0;
--text: #1a202c;
--text-muted: #718096;
--red: #c53030;
--red-bg: #fff5f5;
--red-border: #feb2b2;
--orange: #c05621;
--orange-bg: #fffaf0;
--orange-border: #fbd38d;
--yellow: #744210;
--yellow-bg: #fffff0;
--yellow-border: #f6e05e;
--blue: #2b6cb0;
--blue-bg: #ebf8ff;
--blue-border: #bee3f8;
--green: #276749;
--green-bg: #f0fff4;
--green-border: #9ae6b4;
--purple: #553c9a;
--purple-bg: #faf5ff;
--purple-border: #d6bcfa;
}
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); font-size: 16px; line-height: 1.5; }
a { color: #005ea2; }
a:hover, a:active { color: #0b4778; }
.page { max-width: 1100px; margin: 0 auto; padding: 2rem 1.5rem; }
h1, h2, h3, h4, h5, h6 { font-family: Bitter, Georgia, Cambria, "Times New Roman", Times, serif; line-height: 1.3; margin-bottom: .5em; }
h1 { font-size: 2.75rem; }
h3 { font-size: 1rem; }
h4 { font-size: 0.85rem; }
h5, h6 { font-size: 0.75rem; }
.subtitle { color: var(--text-muted); margin-bottom: 2rem; font-size: 0.875rem; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; margin-bottom: 2.5rem; }
.stat { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; text-align: center; }
.stat-num { font-size: 2rem; font-weight: 800; line-height: 1; }
.stat-label { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem; }
.stat.red .stat-num { color: var(--red); }
.stat.orange .stat-num { color: var(--orange); }
.stat.yellow .stat-num { color: var(--yellow); }
.stat.green .stat-num { color: var(--green); }
.stat.blue .stat-num { color: var(--blue); }
section { margin-bottom: 2.5rem; }
h2 { font-size: 1.6rem; font-weight: 700; margin-bottom: 0.75rem; display: flex; align-items: center; gap: 0.5rem; }
.badge { font-size: 0.7rem; font-weight: 600; padding: 0.15rem 0.5rem; border-radius: 100px; }
.badge.red { background: var(--red-bg); color: var(--red); border: 1px solid var(--red-border); }
.badge.orange { background: var(--orange-bg); color: var(--orange); border: 1px solid var(--orange-border); }
.badge.yellow { background: var(--yellow-bg); color: var(--yellow); border: 1px solid var(--yellow-border); }
.badge.blue { background: var(--blue-bg); color: var(--blue); border: 1px solid var(--blue-border); }
.badge.green { background: var(--green-bg); color: var(--green); border: 1px solid var(--green-border); }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.alert { border-radius: 8px; padding: 0.75rem 1rem; margin-bottom: 1rem; font-size: 0.875rem; border-left: 4px solid; }
.alert.red { background: var(--red-bg); border-color: var(--red); color: var(--red); }
.alert.yellow { background: var(--yellow-bg); border-color: #d69e2e; color: var(--yellow); }
.alert.blue { background: var(--blue-bg); border-color: var(--blue); color: var(--blue); }
.alert strong { font-weight: 700; }
table { width: 100%; border-collapse: collapse; }
th { background: #f7fafc; padding: 0.6rem 0.75rem; text-align: left; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); border-bottom: 1px solid var(--border); }
td { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); vertical-align: top; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: #f7fafc; }
code { font-family: 'SF Mono', 'Fira Code', Consolas, monospace; font-size: 0.82rem; background: #edf2f7; padding: 0.1em 0.3em; border-radius: 3px; }
.val-old { color: var(--red); }
.val-new { color: var(--green); }
.swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; border: 1px solid rgba(0,0,0,0.15); vertical-align: middle; margin-right: 4px; flex-shrink: 0; }
.group-header td { background: #f0f4f8; font-weight: 700; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); padding: 0.4rem 0.75rem; }
.tag { display: inline-block; font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 3px; margin-left: 0.25rem; font-weight: 600; }
.tag.invalid { background: #fed7d7; color: #c53030; }
.tag.placeholder { background: #fbd38d; color: #7b341e; }
.tag.changed { background: #bee3f8; color: #2b6cb0; }
details { margin-bottom: 0.5rem; }
summary { cursor: pointer; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); font-weight: 600; font-size: 0.875rem; list-style: none; display: flex; align-items: center; gap: 0.5rem; justify-content: flex-start; }
summary::-webkit-details-marker { display: none; }
summary::after { content: '▶'; font-size: 0.7rem; color: var(--text-muted); margin-left: auto; }
details[open] summary::after { content: '▼'; }
details[open] summary { background: #f7fafc; }
.col-narrow { width: 30%; }
.col-wide { width: 70%; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 700px) { .two-col { grid-template-columns: 1fr; } }
.overflow-x { overflow-x: auto; }
.note { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.5rem; }
</style>
</head>
<body>
<div class="page">
<h1>CSS Token Migration Analysis: Component Library</h1>
<p class="subtitle">css-library/dist/tokens/css/variables.css &rarr; va-design-system-resources/packages/tokens/dist/css/variables.css</p>
<h2>Index</h2>
<nav style="margin-bottom:2rem;padding:0.75rem 1rem;background:#f7fafc;border:1px solid var(--border);border-radius:8px;font-size:0.875rem;display:flex;flex-wrap:wrap;gap:0.5rem 1.25rem;">
<a href="#migration-plan">Migration Plan</a>
<a href="#complications">Complications &amp; Blockers</a>
<a href="#general-differences">General Differences</a>
<a href="#value-changes">Value Changes</a>
<a href="#placeholders">Placeholder Values</a>
<a href="#breakpoints">Breakpoints</a>
<a href="#font-sizes">Font Sizes</a>
<a href="#line-length">Line Length</a>
<a href="#removed-tokens">Removed Tokens</a>
<a href="#new-tokens">New Token Categories</a>
<a href="#storybook">Storybook Package</a>
<a href="#summary">Token Summary</a>
</nav>
<!-- MIGRATION PLAN -->
<section id="migration-plan">
<h2>Migration Plan: <code>packages/web-components/src</code></h2>
<p class="note" style="margin-bottom:1rem">Based on an audit of 172 files, 68 use CSS variables. 106 unique variables are referenced. The plan is organized into four phases by risk level.</p>
<details>
<summary><span class="badge blue">Pre-flight</span> Phase 0: Add new package import (34 token values change immediately)</summary>
<div class="overflow-x">
<p style="padding:0.75rem;font-size:0.875rem;">Adding the new package import to <code>main.scss</code> is the trigger for the entire migration. Before any component token references are updated, <a href="#value-changes">34 tokens</a> that share the same name in both files will immediately resolve to their new values because the new file loads second and wins the cascade. No code changes are required for these tokens, but visual regressions are possible. Run a Chromatic snapshot after adding the import and resolve any unexpected changes before proceeding to Phase 1.</p>
<div class="alert blue" style="margin:0 0.75rem 1rem;">
<strong>This change ships to vets-website on the next release.</strong> Once the new package import is added to <code>main.scss</code> and merged, the next component library release will publish it and vets-website will pick it up. The <a href="#value-changes">34 token values that change</a> as a result will take effect in vets-website too, not just in this repo. Coordinate the Phase 0 Chromatic review and release timing with that downstream impact in mind.
</div>
<table>
<thead><tr><th>Action</th><th>File</th><th>Risk</th></tr></thead>
<tbody>
<tr>
<td>Add <code>@use '~@department-of-veterans-affairs/va-design-system-tokens/dist/css/variables.css' as *;</code> after the existing css-library import</td>
<td><code>src/global/main.scss</code></td>
<td>34 token values change globally and immediately. Run Chromatic before continuing.</td>
</tr>
</tbody>
</table>
</div>
</details>
<details>
<summary><span class="badge green">Low risk</span> Phase 1: Mechanical renames (safe, values unchanged)</summary>
<div class="overflow-x">
<table>
<thead><tr><th>Old token</th><th>New token</th><th>Files affected</th></tr></thead>
<tbody>
<tr class="group-header"><td colspan="3">Hub colors (va-sidenav-item.scss)</td></tr>
<tr><td><code>--vads-color-hub-burials</code> (and 10 others)</td><td><code>--vads-hub-color-burials</code> etc.</td><td>va-sidenav-item.scss</td></tr>
<tr class="group-header"><td colspan="3">Line length namespace</td></tr>
<tr><td><code>--vads-size-line-length-4</code>, <code>-5</code></td><td><code>--vads-font-line-length-4</code>, <code>-5</code></td><td>~2 files</td></tr>
<tr class="group-header"><td colspan="3">Font weight / style</td></tr>
<tr><td><code>--font-weight-normal</code></td><td><code>--vads-font-weight-normal</code></td><td>~5 files</td></tr>
<tr><td><code>--font-weight-bold</code></td><td><code>--vads-font-weight-bold</code></td><td>~8 files</td></tr>
<tr><td><code>--font-style-italic</code></td><td>Remove token, use <code>italic</code> directly (no equivalent exists)</td><td>~1 file</td></tr>
<tr class="group-header"><td colspan="3">Breakpoint</td></tr>
<tr><td><code>--mobile-lg</code></td><td><code>--vads-breakpoint-mobile-lg</code></td><td>va-telephone-input.scss</td></tr>
<tr class="group-header"><td colspan="3">Units → spacing (equivalent values at 16px root)</td></tr>
<tr><td><code>--units-0p5</code></td><td><code>--vads-spacing-0p5</code></td><td>~3 files</td></tr>
<tr><td><code>--units-1</code></td><td><code>--vads-spacing-1</code></td><td>~3 files</td></tr>
<tr><td><code>--units-1p5</code></td><td><code>--vads-spacing-1p5</code></td><td>~1 file</td></tr>
<tr><td><code>--units-2</code></td><td><code>--vads-spacing-2</code></td><td>~4 files</td></tr>
<tr><td><code>--units-3</code></td><td><code>--vads-spacing-3</code></td><td>~2 files</td></tr>
<tr><td><code>--units-5</code></td><td><code>--vads-spacing-5</code></td><td>~1 file</td></tr>
<tr class="group-header"><td colspan="3">Input tokens (name change, same value)</td></tr>
<tr><td><code>--vads-input-background-color-on-light</code></td><td><code>--vads-input-color-background-light</code></td><td>input-related scss</td></tr>
<tr><td><code>--vads-input-border-color-on-light</code></td><td><code>--vads-input-color-border-light</code></td><td>input-related scss</td></tr>
<tr class="group-header"><td colspan="3">Link / focus (name change, same value)</td></tr>
<tr><td><code>--vads-color-link</code></td><td><code>--vads-link-color-light</code></td><td>~18 files (highest priority)</td></tr>
<tr><td><code>--vads-color-link-visited</code></td><td><code>--vads-link-color-visited-light</code></td><td>~2 files</td></tr>
<tr><td><code>--vads-color-action-focus-on-light</code></td><td><code>--vads-focus-color-background-light</code></td><td>~14 files (high priority)</td></tr>
<tr><td><code>--vads-color-primary</code></td><td><code>--vads-color-primary-light</code></td><td>~10 files</td></tr>
<tr class="group-header"><td colspan="3">Font family (name change; see font stack note in Phase 3)</td></tr>
<tr><td><code>--font-serif</code>, <code>--font-family-serif</code></td><td><code>--vads-font-family-serif</code></td><td>~15 files</td></tr>
<tr class="group-header"><td colspan="3">Font sizes (heading tokens renamed; see Font Sizes section for full reference)</td></tr>
<tr><td><code>--font-size-h1</code></td><td><code>--vads-font-size-2xl</code></td><td>2.5rem &rarr; 2.5rem (exact)</td></tr>
<tr><td><code>--font-size-h2</code></td><td><code>--vads-font-size-xl</code></td><td>2rem &rarr; 2rem (exact)</td></tr>
<tr><td><code>--font-size-h4</code></td><td><code>--vads-font-size-md</code></td><td>1.063rem &rarr; 1.0625rem (essentially exact)</td></tr>
<tr><td><code>--font-size-h5</code>, <code>--font-size-h6</code></td><td><code>--vads-font-size-xs</code></td><td>0.938rem &rarr; 0.9375rem (essentially exact)</td></tr>
</tbody>
</table>
</div>
</details>
<details>
<summary><span class="badge orange">Medium risk</span> Phase 2: Renames with value changes (verify rendering after each)</summary>
<div class="overflow-x">
<table>
<thead><tr><th>Old token</th><th>Old value</th><th>Replacement</th><th>New value</th><th>Notes</th></tr></thead>
<tbody>
<tr class="group-header"><td colspan="5">Base / text colors</td></tr>
<tr>
<td><code>--vads-color-base</code></td>
<td>#1b1b1b</td>
<td><code>--vads-text-color-light</code></td>
<td>#1c1d1f</td>
<td>~19 files. 1-step darker; verify text contrast.</td>
</tr>
<tr>
<td><code>--vads-color-base-dark</code></td>
<td>#565c65</td>
<td><code>--vads-color-base-strong-light</code></td>
<td>#565c65</td>
<td>Same value but renamed; confirms alignment.</td>
</tr>
<tr>
<td><code>--vads-color-base-lighter</code></td>
<td>#dfe1e2</td>
<td><code>--vads-color-base-weaker-light</code></td>
<td>#dfe1e2</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-base-lightest</code></td>
<td>#f0f0f0</td>
<td><code>--vads-color-base-weakest-light</code></td>
<td>#f0f0f0</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-base-darker</code></td>
<td>#3d4551</td>
<td><code>--vads-color-base-stronger-light</code></td>
<td>#3d4551</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-base-darkest</code></td>
<td>#1b1b1b</td>
<td><code>--vads-color-base-strongest-light</code></td>
<td>#1c1d1f</td>
<td>Slight value shift; verify.</td>
</tr>
<tr>
<td><code>--vads-color-base-light</code></td>
<td>#a9aeb1</td>
<td><code>--vads-color-base-weak-light</code></td>
<td>#a9aeb1</td>
<td>Same value, renamed.</td>
</tr>
<tr class="group-header"><td colspan="5">Link</td></tr>
<tr>
<td><code>--vads-color-link-active</code></td>
<td>#0b4778</td>
<td><code>--vads-link-color-active-light</code></td>
<td>#1a4480</td>
<td>Value shifted slightly. Verify hover/active states.</td>
</tr>
<tr class="group-header"><td colspan="5">Status / feedback colors (success, info, warning)</td></tr>
<tr>
<td><code>--vads-color-success</code></td>
<td>#00a91c</td>
<td><code>--vads-color-success-light</code></td>
<td>#00a91c</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-success-dark</code></td>
<td>#008817</td>
<td><code>--vads-color-success-strong-light</code></td>
<td>#008817</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-success-lighter</code></td>
<td>#ecf3ec</td>
<td><code>--vads-color-success-weakest-light</code></td>
<td>#ecf3ec</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-warning</code></td>
<td>#ffbe2e</td>
<td><code>--vads-color-warning-light</code></td>
<td>#ffbe2e</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-info</code></td>
<td>#00bde3</td>
<td><code>--vads-color-info-light</code></td>
<td>#00bde3</td>
<td>Same value, renamed.</td>
</tr>
<tr>
<td><code>--vads-color-info-darker</code></td>
<td>#2e6276</td>
<td><code>--vads-color-info-weak-light</code></td>
<td>#99deea</td>
<td>Value is different. Evaluate per usage.</td>
</tr>
<tr>
<td><code>--vads-color-info-lighter</code></td>
<td>#e7f6f8</td>
<td><code>--vads-color-info-weaker-light</code></td>
<td>#e7f6f8</td>
<td>Same value, renamed.</td>
</tr>
<tr class="group-header"><td colspan="5">Component-scoped alert tokens (removed, replace with semantic equivalents)</td></tr>
<tr>
<td><code>--vads-alert-color-background-info-on-light</code></td>
<td>#e7f6f8</td>
<td><code>--vads-color-info-weaker-light</code></td>
<td>#e7f6f8</td>
<td>Same value.</td>
</tr>
<tr>
<td><code>--vads-alert-color-background-success-on-light</code></td>
<td>#ecf3ec</td>
<td><code>--vads-color-success-weakest-light</code></td>
<td>#ecf3ec</td>
<td>Same value.</td>
</tr>
<tr>
<td><code>--vads-alert-color-background-warning-on-light</code></td>
<td>#faf3d1</td>
<td><code>--vads-color-warning-weakest-light</code></td>
<td>#faf3d1</td>
<td>Same value.</td>
</tr>
<tr>
<td><code>--vads-alert-color-background-error-on-light</code></td>
<td>#f4e3db</td>
<td><code>--vads-color-critical-weaker-light</code></td>
<td>#f4e3db</td>
<td>Same value; note error → critical rename.</td>
</tr>
<tr class="group-header"><td colspan="5">Font sizes (value shift)</td></tr>
<tr>
<td><code>--font-size-h3</code></td>
<td>1.25rem</td>
<td><code>--vads-font-size-lg</code></td>
<td>1.375rem</td>
<td>Closest match but 0.125rem larger; verify heading size visually.</td>
</tr>
<tr class="group-header"><td colspan="5">Sass variable conversions: convert $ syntax to CSS custom property and rename</td></tr>
<tr>
<td><code>$vads-color-error-dark</code></td>
<td>#b21d38</td>
<td><code>var(--vads-color-critical-strong-light)</code></td>
<td>verify in new file</td>
<td>1 file: va-file-input.scss. Sass form of <code>--vads-color-error-dark</code>; convert syntax and apply error → critical rename in the same pass.</td>
</tr>
<tr>
<td><code>$vads-font-size-source-sans-normalized</code></td>
<td>1.06rem</td>
<td><code>var(--vads-font-size-md)</code></td>
<td>1.063rem</td>
<td>1 file: va-button-segmented.scss. Slight value shift; verify rendered text size.</td>
</tr>
</tbody>
</table>
</div>
</details>
<details>
<summary><span class="badge red">High risk</span> Phase 3: Design decisions required (no clean mapping)</summary>
<div class="overflow-x">
<table>
<thead><tr><th>Token(s)</th><th>Issue</th><th>Recommended action</th><th>Files affected</th></tr></thead>
<tbody>
<tr>
<td><code>--font-source-sans</code></td>
<td>The new token stack uses <code>'Source Sans'</code>, but the existing <code>@font-face</code> in <code>core.css</code> registers the font as <code>"Source Sans Pro Web"</code>. No <code>@font-face</code> registers <code>"Source Sans"</code>, so renaming the token will cause the browser to skip the web font entirely and fall through to <code>Helvetica Neue</code>.</td>
<td>Before renaming: confirm whether the new package ships <code>@font-face</code> declarations under <code>"Source Sans"</code>. If not, add them manually pointing to the same woff2 files. Rename only after font loading is validated.</td>
<td><strong>17</strong></td>
</tr>
<tr>
<td>Button component tokens: <code>--vads-button-color-*</code></td>
<td>All removed. No button-scoped tokens exist in new file.</td>
<td>Replace with semantic tokens: primary button bg → <code>--vads-color-primary-light</code>, disabled bg → <code>--vads-color-disabled-light</code>, etc.</td>
<td><strong>8</strong><br><small>buttons.css, va-button.scss, va-button-icon.scss, va-button-segmented.scss, va-radio-option.scss, va-checkbox.scss, va-header-minimal.scss, va-crisis-line-modal.scss</small></td>
</tr>
<tr>
<td><code>$small-screen</code> (Sass)</td>
<td>No equivalent exists in the new file. Closest option is <code>$mobile-lg</code> at 480px, which is 1px off from the current 481px value.</td>
<td>Decide whether the 1px difference is acceptable and remap to <code>$mobile-lg</code>, or request a dedicated <code>$small-screen</code> token in the new package's SCSS output.</td>
<td><strong>3</strong><br><small>va-breadcrumbs-slot, va-header-minimal, va-statement-of-truth</small></td>
</tr>
<tr>
<td><code>--vads-color-error</code>, <code>-dark</code>, <code>-light</code>, <code>-darker</code>, <code>-lighter</code></td>
<td>Entire error token family removed. Replaced by a <code>--vads-color-critical-*</code> family with different shade naming.</td>
<td>Map each usage to the closest <code>--vads-color-critical-*</code> token by value. Core error color <code>#d54309</code> maps to <code>--vads-color-critical-light</code>.</td>
<td><strong>2</strong><br><small>va-alert.scss, va-tag-status.scss</small></td>
</tr>
<tr>
<td><code>--vads-color-secondary-dark</code>, <code>-darkest</code>, <code>-lightest</code></td>
<td>Old secondary was red. New secondary is cyan. No shade mapping is safe.</td>
<td>Audit each usage to determine whether the intent was "destructive/error" (use critical tokens) or a brand accent. Replace with the appropriate family after design review.</td>
<td><strong>9</strong><br><small>form-field-error.scss, va-file-input.scss, va-button-icon.scss, va-modal.scss, va-crisis-line-modal.scss, va-maintenance-banner.scss, va-card-status.scss, va-notification.scss, va-date.scss</small></td>
</tr>
<tr>
<td><code>$vads-color-secondary-dark</code>, <code>$vads-color-secondary-darkest</code> (Sass)</td>
<td>Sass variable form of old red secondary tokens. Same semantic mismatch as the CSS counterparts above.</td>
<td>Same design review as CSS token counterparts. After the design decision, convert Sass $ syntax to <code>var()</code> using the chosen replacement token.</td>
<td><strong>4 + 1</strong><br><small>$secondary-dark (4): uswds-error-border, va-file-input-multiple, va-file-input, va-crisis-line-modal. $secondary-darkest (1): va-crisis-line-modal</small></td>
</tr>
<tr>
<td><code>--vads-input-tile-background-active-on-light</code>, <code>--vads-input-tile-border-on-light</code></td>
<td>Both value and name changed. Old used rgba transparency; new uses solid colors. Visual rendering will differ.</td>
<td>New equivalents are <code>--vads-input-tile-color-background-active-light</code> (#ecf1f7) and <code>--vads-input-tile-color-border-light</code> (#a9aeb1). Review visually against design specs before shipping.</td>
<td><strong>2</strong><br><small>va-radio-option.scss, va-checkbox.scss</small></td>
</tr>
</tbody>
</table>
</div>
</details>
<details>
<summary><span class="badge yellow">Blocked</span> Phase 4: Blocked on new package completing placeholder values</summary>
<div class="overflow-x">
<table>
<thead><tr><th>Blocked area</th><th>Placeholder tokens involved</th></tr></thead>
<tbody>
<tr>
<td>Dark mode focus styles</td>
<td><code>--vads-focus-color-background-dark</code>, <code>--vads-focus-color-outline-dark</code></td>
</tr>
<tr>
<td>Dark mode link states</td>
<td><code>--vads-link-color-active-dark</code>, <code>--vads-link-color-hover-dark</code>, <code>--vads-link-color-visited-dark</code></td>
</tr>
<tr>
<td>Link hover (light mode)</td>
<td><code>--vads-link-color-hover-light</code></td>
</tr>
<tr>
<td>Dark mode inputs</td>
<td><code>--vads-input-color-background-dark</code>, <code>--vads-input-color-border-dark</code></td>
</tr>
<tr>
<td>Dark mode icons</td>
<td><code>--vads-icon-color-dark</code>, <code>--vads-icon-color-weak-dark</code></td>
</tr>
<tr>
<td>Dark mode modal overlay</td>
<td><code>--vads-modal-overlay-color-dark</code></td>
</tr>
<tr>
<td>Several semantic color scale endpoints</td>
<td><code>--vads-color-*-strongest-light</code>, <code>--vads-color-*-weaker-light</code> (14 tokens total)</td>
</tr>
</tbody>
</table>
<p class="note" style="padding:0.75rem">Do not migrate any component that consumes these tokens until the new package ships corrected values. Migration of light-mode-only components can proceed independently.</p>
</div>
</details>
<div style="margin-top:1rem;padding:0.75rem 1rem;background:#f7fafc;border:1px solid var(--border);border-radius:8px;font-size:0.875rem;">
<strong>Suggested PR structure:</strong>
<ol style="margin-top:0.5rem;padding-left:1.25rem;display:flex;flex-direction:column;gap:0.35rem;">
<li><strong>Phase 0 PR:</strong> Add the new package import to <code>main.scss</code>. Run Chromatic and resolve any regressions from the 34 automatic value changes before merging. Consider cutting a component library release at this point so the 34 automatic changes can be reviewed in vets-website before continuing.</li>
<li><strong>Phase 1 + Phase 2 PR:</strong> Update all token references across components. Do not remove the old import — Phase 3 components still reference tokens that only exist in the old file (<code>--font-source-sans</code>, <code>--font-size-h*</code>, <code>--vads-button-color-*</code>, <code>--vads-color-error</code> family). Verify with Chromatic.</li>
<li><strong>Phase 3 PRs:</strong> Group similar components together for review. Each group requires explicit design sign-off before merging.</li>
<li><strong>Cleanup PR:</strong> Remove the old css-library import from <code>main.scss</code> once all Phase 3 components are updated and no references to old-only tokens remain.</li>
<li><strong>Phase 4:</strong> Hard dependency on the new package shipping corrected placeholder values; track as a blocker.</li>
</ol>
</div>
</section>
<!-- COMPLICATIONS / BLOCKERS -->
<section id="complications">
<h2>Complications &amp; Blockers</h2>
<div class="alert red">
<strong>Importing both files simultaneously causes silent value conflicts.</strong> Both variable files define the same <a href="#value-changes">34 token names</a> in <code>:root</code> but with different values. CSS gives all <code>:root</code> declarations equal specificity, so whichever file is imported last wins, and the other silently loses. If both files are loaded at the same time during migration, those 34 tokens will resolve to the last file in the cascade regardless of which package a given component expects, causing unintended visual changes across components not yet migrated. The transition should be treated as atomic rather than gradual. If an overlap period is unavoidable, load the old file last to keep components that have not yet been migrated visually stable.
</div>
<div class="alert red">
<strong>Font family stack trimmed: web font will break.</strong> The current <code>@font-face</code> declarations in <code>css-library/dist/stylesheets/core.css</code> register the font under <code>"Source Sans Pro Web"</code>. The new token stack drops that name entirely, using only <code>'Source Sans'</code>, which has no matching <code>@font-face</code> registration. The browser will skip the web font and fall through to <code>Helvetica Neue</code>. Before renaming <code>--font-source-sans</code> to <code>--vads-font-family-sans</code>, either confirm the new package ships its own <code>@font-face</code> declarations under <code>"Source Sans"</code>, or add them manually pointing to the same woff2 files.
</div>
<div class="alert red">
<strong>New package ships no SCSS output: breakpoint Sass variables must be preserved.</strong> CSS custom properties cannot be used inside <code>@media</code> queries, as media conditions are evaluated before the cascade, making <code>var()</code> invalid there. Sass variables are the only viable option for token-driven breakpoints, as they are resolved at compile time.
<div class="overflow-x" style="margin-top:0.75rem">
<table>
<thead><tr><th>Sass variable</th><th>Type</th><th>Resolution</th><th>Files</th><th>File names</th></tr></thead>
<tbody>
<tr class="group-header"><td colspan="5">Breakpoints: must remain as Sass variables (CSS custom properties cannot be used in @media queries)</td></tr>
<tr><td><code>$medium-screen</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>13</strong></td><td><small>va-notification, va-on-this-page, va-tab-item, va-breadcrumbs, va-link-action, va-promo-banner, va-service-list-item, va-official-gov-banner, va-back-to-top, va-critical-action, va-table-row, va-table-slot, va-table-inner</small></td></tr>
<tr><td><code>$mobile-lg</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>9</strong></td><td><small>va-memorable-date, va-telephone-input, va-button-pair, va-breadcrumbs, va-file-input, va-search-input, va-modal, va-crisis-line-modal, va-table-inner</small></td></tr>
<tr><td><code>$desktop</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>8</strong></td><td><small>uswds-error-border, form-field-error, va-alert, va-file-input-multiple, va-alert-sign-in, va-file-input, va-header-minimal, va-crisis-line-modal</small></td></tr>
<tr><td><code>$tablet</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>4</strong></td><td><small>uswds-input-width, va-modal, va-button-segmented, va-select</small></td></tr>
<tr><td><code>$small-screen</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>3</strong></td><td><small>va-breadcrumbs-slot, va-header-minimal, va-statement-of-truth</small></td></tr>
<tr><td><code>$xsmall-screen</code></td><td>Breakpoint</td><td>New package must ship Sass variable equivalent</td><td><strong>2</strong></td><td><small>va-file-input, va-tab-item</small></td></tr>
</tbody>
</table>
</div>
<p style="margin-top:0.75rem"><strong>Required action:</strong> Request that the new package ship a SCSS file containing at minimum the 6 breakpoint variables.</p>
</div>
<div class="alert red">
<strong>Invalid CSS in old file.</strong> <code>--color-link-default-hover: rgba(#000000, 0.05)</code> uses an invalid syntax (rgba does not accept hex strings). This variable silently fails in browsers. It has no equivalent in the new file. <strong>Fix:</strong> replace with <code>--color-link-default-hover: rgba(0, 0, 0, 0.05)</code>.
</div>
<div class="alert yellow">
<strong>26 placeholder values</strong> in the new file use <code>#00ff00</code> or <code>#ff00ff</code> as obvious stand-ins for unfinished tokens. These are not production-ready and will render incorrectly if consumed. See the <a href="#placeholders">Placeholders section below</a>.
</div>
<div class="alert yellow">
<strong>Secondary color meaning changed entirely.</strong> Old <code>--vads-color-secondary</code> was red (#d83933). New <code>--vads-color-secondary-light</code> is cyan (#00bde3). Any component using secondary tokens will render a completely different hue without a corresponding design decision.
</div>
<div class="alert blue">
<strong>Hub color prefix changed.</strong> <code>--vads-color-hub-*</code> &rarr; <code>--vads-hub-color-*</code>. Values are identical but all 11 references must be updated.
</div>
<div class="alert blue">
<strong>Input tile border tokens changed both name and value.</strong> <code>--vads-input-tile-background-active-on-light: rgba(0, 94, 162, 0.1)</code> is now a flat solid <code>#ecf1f7</code>. <code>--vads-input-tile-border-on-light: rgba(27, 27, 27, 0.03)</code> is now <code>#a9aeb1</code>. Visible rendering change.
</div>
<div class="alert blue">
<strong>Line-length none value changed.</strong> <code>--vads-size-line-length-none: inherit</code> &rarr; <code>--vads-font-line-length-none: none</code>. <code>inherit</code> and <code>none</code> have different cascade behavior on <code>max-width</code>.
</div>
</section>
<!-- GENERAL DIFFERENCES -->
<section id="general-differences">
<h2>General Differences to Note</h2>
<div class="card overflow-x">
<table>
<thead><tr><th>Difference</th><th>Detail</th></tr></thead>
<tbody>
<tr>
<td><strong>Spacing units: px &rarr; rem</strong></td>
<td>All <code>--vads-spacing-*</code> values switched (e.g. <code>8px</code> &rarr; <code>0.5rem</code>). Functionally equivalent at the default 16px root. Not expected to cause visual changes in practice.</td>
</tr>
<tr>
<td><strong>Elevation shadow format</strong></td>
<td><code>rgba(0, 0, 0, 0.1)</code> &rarr; <code>#0000001a</code>. Identical computed value, different notation.</td>
</tr>
<tr>
<td><strong>New token categories</strong></td>
<td>The new file adds border radius/width tokens, a full USWDS system color palette (~460 tokens), opacity scale, clinical chart colors, and named spacing aliases. These are additive and do not affect existing usage.</td>
</tr>
<tr>
<td><strong>Multiple <code>:root</code> blocks</strong></td>
<td>The new file organizes tokens into separate <code>:root</code> blocks by category (border, breakpoint, color, elevation, font, opacity, spacing) rather than one flat block. This is valid CSS and has no functional impact.</td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- VALUE CHANGES -->
<section id="value-changes">
<h2>Same Name, Value Changed <span class="badge orange">34</span></h2>
<div class="card overflow-x">
<table>
<thead><tr><th>Token</th><th>Old value</th><th>New value</th><th>Notes</th></tr></thead>
<tbody>
<tr class="group-header"><td colspan="4">Color: semantic tokens (meaning shifted)</td></tr>
<tr>
<td><code>--vads-color-base-dark</code></td>
<td class="val-old">#565c65</td>
<td class="val-new">#71767a</td>
<td>Lighter gray</td>
</tr>
<tr>
<td><code>--vads-color-base-light</code></td>
<td class="val-old">#a9aeb1</td>
<td class="val-new">#71767a</td>
<td>Now darker; both -dark and -light resolve to same value</td>
</tr>
<tr>
<td><code>--vads-color-emergency-dark</code></td>
<td class="val-old">#332d29 (dark brown)</td>
<td class="val-new">#d83933 (bright red)</td>
<td>Completely different hue; dark/light semantics inverted</td>
</tr>
<tr>
<td><code>--vads-color-info-dark</code></td>
<td class="val-old">#009ec1</td>
<td class="val-new">#0d7ea2</td>
<td>Darker cyan</td>
</tr>
<tr>
<td><code>--vads-color-info-light</code></td>
<td class="val-old">#99deea (pale cyan)</td>
<td class="val-new">#00bde3 (vivid cyan)</td>
<td>Now the primary info color, not a tint</td>
</tr>
<tr>
<td><code>--vads-color-primary-dark</code></td>
<td class="val-old">#1a4480 (dark blue)</td>
<td class="val-new">#58b4ff (light blue)</td>
<td>Dark mode primary; semantics are now on-dark vs on-light, not shade</td>
</tr>
<tr>
<td><code>--vads-color-primary-light</code></td>
<td class="val-old">#73b3e7 (light blue)</td>
<td class="val-new">#005ea2 (VA blue)</td>
<td>Now the core brand blue on light backgrounds</td>
</tr>
<tr>
<td><code>--vads-color-secondary-dark</code></td>
<td class="val-old">#b50909 (dark red)</td>
<td class="val-new">#0081a1 (teal)</td>
<td>Secondary color completely rebranded</td>
</tr>
<tr>
<td><code>--vads-color-secondary-light</code></td>
<td class="val-old">#f2938c (pink/red tint)</td>
<td class="val-new">#00bde3 (cyan)</td>
<td>Secondary color completely rebranded</td>
</tr>
<tr>
<td><code>--vads-color-success-dark</code></td>
<td class="val-old">#008817</td>
<td class="val-new">#21c834</td>
<td>Dark mode success; much lighter/brighter</td>
</tr>
<tr>
<td><code>--vads-color-success-light</code></td>
<td class="val-old">#70e17b (pale green)</td>
<td class="val-new">#00a91c (vivid green)</td>
<td>Now the primary success green</td>
</tr>
<tr>
<td><code>--vads-color-warning-dark</code></td>
<td class="val-old">#e5a000</td>
<td class="val-new">#947100</td>
<td>Much darker gold</td>
</tr>
<tr>
<td><code>--vads-color-warning-light</code></td>
<td class="val-old">#fee685 (pale yellow)</td>
<td class="val-new">#ffbe2e (vivid gold)</td>
<td>Now the primary warning color</td>
</tr>
<tr class="group-header"><td colspan="4">Elevation shadows (equivalent values, format only)</td></tr>
<tr>
<td><code>--vads-elevation-shadow-1</code> through <code>-5</code></td>
<td class="val-old"><code>rgba(0, 0, 0, 0.1)</code></td>
<td class="val-new"><code>#0000001a</code></td>
<td>Functionally identical; hex shorthand for the same rgba</td>
</tr>
<tr class="group-header"><td colspan="4">Font</td></tr>
<tr>
<td><code>--vads-font-line-height-heading</code></td>
<td class="val-old">1.2</td>
<td class="val-new">1.15</td>
<td>Tighter heading line height</td>
</tr>
<tr class="group-header"><td colspan="4">Spacing (px &rarr; rem, functionally equivalent at 16px root)</td></tr>
<tr>
<td><code>--vads-spacing-1</code> through <code>-15</code></td>
<td class="val-old">e.g. <code>8px</code></td>
<td class="val-new">e.g. <code>0.5rem</code></td>
<td>Same computed size at default root. calc() with mixed units may break.</td>
</tr>
<tr>
<td><code>--vads-spacing-0</code></td>
<td class="val-old"><code>0</code></td>
<td class="val-new"><code>0rem</code></td>
<td>Functionally identical</td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- PLACEHOLDER VALUES -->
<section id="placeholders">
<h2 id="placeholders">Placeholder Values in New File <span class="badge yellow">26</span></h2>
<p class="note" style="margin-bottom:0.75rem">These tokens contain #00ff00 or #ff00ff as stand-in values, indicating the design work is incomplete. Do not ship these.</p>
<div class="card overflow-x">
<table>
<thead><tr><th>Token</th><th>Placeholder</th></tr></thead>
<tbody>
<tr><td><code>--vads-color-success-strong-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-focus-color-background-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-focus-color-outline-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-icon-color-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-icon-color-weak-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-input-color-background-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-input-color-border-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-link-color-active-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-link-color-background-hover-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-link-color-hover-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-link-color-visited-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-modal-overlay-color-dark</code></td><td><code>#00ff00</code></td></tr>
<tr><td><code>--vads-link-color-hover-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-critical-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-critical-weakest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-disabled-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-disabled-weakest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-info-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-info-weakest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-primary-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-secondary-stronger-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-secondary-weaker-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-success-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-success-weaker-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-warning-strongest-light</code></td><td><code>#ff00ff</code></td></tr>
<tr><td><code>--vads-color-warning-weaker-light</code></td><td><code>#ff00ff</code></td></tr>
</tbody>
</table>
</div>
</section>
<!-- BREAKPOINTS -->
<section id="breakpoints">
<h2>Breakpoints (unprefixed legacy names) <span class="badge red">12</span></h2>
<p class="note" style="margin-bottom:0.75rem">All 12 unprefixed breakpoint tokens are removed from the old file. Most have renamed equivalents in the new file under the <code>--vads-breakpoint-*</code> prefix.</p>
<div class="card overflow-x">
<table>
<thead><tr><th>Removed token</th><th>Old value</th><th>Conceptual equivalent in new</th></tr></thead>
<tbody>
<tr><td><code>--xsmall-screen</code></td><td>320px</td><td><code>--vads-breakpoint-mobile</code></td></tr>
<tr><td><code>--small-screen</code></td><td>481px</td><td>None (new mobile-lg is 480px)</td></tr>
<tr><td><code>--tablet</code></td><td>640px</td><td><code>--vads-breakpoint-tablet</code></td></tr>
<tr><td><code>--medium-screen</code></td><td>768px</td><td><code>--vads-breakpoint-medium-screen</code></td></tr>
<tr><td><code>--tablet-lg</code></td><td>880px</td><td><code>--vads-breakpoint-tablet-lg</code></td></tr>
<tr><td><code>--small-desktop-screen</code></td><td>1024px</td><td><code>--vads-breakpoint-desktop</code></td></tr>
<tr><td><code>--large-screen</code></td><td>1201px</td><td><code>--vads-breakpoint-desktop-lg</code> (1200px, 1px diff)</td></tr>
<tr><td><code>--mobile</code></td><td>320px</td><td><code>--vads-breakpoint-mobile</code></td></tr>
<tr><td><code>--mobile-lg</code></td><td>480px</td><td><code>--vads-breakpoint-mobile-lg</code></td></tr>
<tr><td><code>--desktop</code></td><td>1024px</td><td><code>--vads-breakpoint-desktop</code></td></tr>
<tr><td><code>--desktop-lg</code></td><td>1201px</td><td><code>--vads-breakpoint-desktop-lg</code> (1200px, 1px diff)</td></tr>
<tr><td><code>--widescreen</code></td><td>1400px</td><td><code>--vads-breakpoint-widescreen</code></td></tr>
</tbody>
</table>
</div>
</section>
<!-- FONT SIZES -->
<section id="font-sizes">
<h2>Font Size Tokens <span class="badge orange">9 new</span></h2>
<p class="note" style="margin-bottom:0.75rem">The new file replaces heading-specific size tokens with a numeric scale. h1, h2, h4, h5, and h6 map directly; h3 has a slight value difference.</p>
<div class="card overflow-x">
<table>
<thead><tr><th>Old token</th><th>Old value</th><th>New token</th><th>New value</th><th>Match</th></tr></thead>
<tbody>
<tr><td><code>--font-size-h1</code></td><td>2.5rem</td><td><code>--vads-font-size-2xl</code></td><td>2.5rem</td><td>Exact</td></tr>
<tr><td><code>--font-size-h2</code></td><td>2rem</td><td><code>--vads-font-size-xl</code></td><td>2rem</td><td>Exact</td></tr>
<tr><td><code>--font-size-h3</code></td><td>1.25rem</td><td><code>--vads-font-size-lg</code></td><td>1.375rem</td><td>Off by 0.125rem — verify</td></tr>
<tr><td><code>--font-size-h4</code></td><td>1.063rem</td><td><code>--vads-font-size-md</code></td><td>1.0625rem</td><td>Essentially exact</td></tr>
<tr><td><code>--font-size-h5</code>, <code>--font-size-h6</code></td><td>0.938rem</td><td><code>--vads-font-size-xs</code></td><td>0.9375rem</td><td>Essentially exact</td></tr>
<tr class="group-header"><td colspan="5">New scale tokens with no heading equivalent</td></tr>
<tr><td colspan="2">—</td><td><code>--vads-font-size-3xs</code></td><td>0.8125rem</td><td>New</td></tr>
<tr><td colspan="2">—</td><td><code>--vads-font-size-2xs</code></td><td>0.875rem</td><td>New</td></tr>
<tr><td colspan="2">—</td><td><code>--vads-font-size-3xl</code></td><td>3rem</td><td>New</td></tr>
</tbody>
</table>
</div>
</section>
<!-- LINE LENGTH -->
<section id="line-length">
<h2>Line Length Tokens <span class="badge orange">7</span></h2>
<p class="note" style="margin-bottom:0.75rem">All 7 line length tokens are renamed from the <code>vads-size-*</code> namespace to <code>vads-font-*</code>. Values are unchanged except for <code>-none</code>, which has a functional difference.</p>
<div class="card overflow-x">
<table>
<thead><tr><th>Old token</th><th>New token</th><th>Value change</th></tr></thead>
<tbody>
<tr><td><code>--vads-size-line-length-1</code></td><td><code>--vads-font-line-length-1</code></td><td>44ex &rarr; 44ex</td></tr>
<tr><td><code>--vads-size-line-length-2</code></td><td><code>--vads-font-line-length-2</code></td><td>60ex &rarr; 60ex</td></tr>
<tr><td><code>--vads-size-line-length-3</code></td><td><code>--vads-font-line-length-3</code></td><td>64ex &rarr; 64ex</td></tr>
<tr><td><code>--vads-size-line-length-4</code></td><td><code>--vads-font-line-length-4</code></td><td>68ex &rarr; 68ex</td></tr>
<tr><td><code>--vads-size-line-length-5</code></td><td><code>--vads-font-line-length-5</code></td><td>72ex &rarr; 72ex</td></tr>
<tr><td><code>--vads-size-line-length-6</code></td><td><code>--vads-font-line-length-6</code></td><td>88ex &rarr; 88ex</td></tr>
<tr><td><code>--vads-size-line-length-none</code></td><td><code>--vads-font-line-length-none</code></td><td><strong class="val-old">inherit &rarr; none</strong> (functional change on max-width)</td></tr>
</tbody>
</table>
</div>
</section>
<!-- REMOVED TOKENS by category -->
<section id="removed-tokens">
<h2>Removed Tokens (in old, no equivalent in new) <span class="badge red">221</span></h2>
<p class="note" style="margin-bottom:0.75rem">Some have conceptual equivalents under a different name; those are noted in the Renamed section below.</p>
<div class="card">
<details>
<summary>Component-scoped tokens (button, alert, input, label, process list) <span class="badge red">19</span></summary>
<div class="overflow-x">
<table>
<thead><tr><th>Removed token</th><th>Old value</th></tr></thead>
<tbody>
<tr><td><code>--vads-button-color-background-primary-on-light</code></td><td>#005ea2</td></tr>
<tr><td><code>--vads-button-color-background-primary-alt-active-on-light</code></td><td>#154c21</td></tr>
<tr><td><code>--vads-button-color-background-secondary-on-light</code></td><td>#ffffff</td></tr>
<tr><td><code>--vads-button-color-background-disabled-on-light</code></td><td>#c9c9c9</td></tr>
<tr><td><code>--vads-button-color-text-primary-alt-on-light</code></td><td>#ffffff</td></tr>
<tr><td><code>--vads-button-color-text-primary-on-light</code></td><td>#ffffff</td></tr>
<tr><td><code>--vads-alert-color-background-info-on-light</code></td><td>#e7f6f8</td></tr>
<tr><td><code>--vads-alert-color-background-success-on-light</code></td><td>#ecf3ec</td></tr>
<tr><td><code>--vads-alert-color-background-warning-on-light</code></td><td>#faf3d1</td></tr>
<tr><td><code>--vads-alert-color-background-error-on-light</code></td><td>#f4e3db</td></tr>
<tr><td><code>--vads-input-background-color-on-light</code></td><td>#ffffff</td></tr>
<tr><td><code>--vads-input-border-color-on-light</code></td><td>#565c65</td></tr>
<tr><td><code>--vads-input-prefix-color-fill-on-light</code></td><td>#757575</td></tr>
<tr><td><code>--vads-input-prefix-color-text-on-light</code></td><td>#757575</td></tr>
<tr><td><code>--vads-input-suffix-color-text-on-light</code></td><td>#757575</td></tr>
<tr><td><code>--vads-input-tile-background-active-on-light</code></td><td>rgba(0, 94, 162, 0.1)</td></tr>
<tr><td><code>--vads-input-tile-border-active-on-light</code></td><td>#005ea2</td></tr>
<tr><td><code>--vads-input-tile-border-on-light</code></td><td>rgba(27, 27, 27, 0.03)</td></tr>
<tr><td><code>--vads-label-hint-text-color-on-light</code></td><td>#757575</td></tr>
<tr><td><code>--vads-process-list-color-text-pending-on-light</code></td><td>#757575</td></tr>
</tbody>
</table>
</div>
</details>
<details>
<summary>Semantic color aliases (error, action, feedback, forms, hub, misc) <span class="badge red">~60</span></summary>
<div class="overflow-x">
<table>
<thead><tr><th>Removed token</th><th>Old value</th><th>Note</th></tr></thead>
<tbody>
<tr><td><code>--vads-color-error</code></td><td>#d54309</td><td>Now <code>--vads-color-critical-*</code> family</td></tr>
<tr><td><code>--vads-color-error-dark</code></td><td>#b21d38</td><td></td></tr>
<tr><td><code>--vads-color-error-darker</code></td><td>#6f3331</td><td></td></tr>
<tr><td><code>--vads-color-error-light</code></td><td>#f39268</td><td></td></tr>
<tr><td><code>--vads-color-error-lighter</code></td><td>#f4e3db</td><td></td></tr>
<tr><td><code>--vads-color-emergency</code></td><td>#9c3d10</td><td></td></tr>
<tr><td><code>--vads-color-action-focus-on-light</code></td><td>#face00</td><td>Now <code>--vads-focus-color-background-light</code></td></tr>
<tr><td><code>--vads-color-action-surface-default-on-dark</code></td><td>#58b4ff</td><td></td></tr>
<tr><td><code>--vads-color-action-surface-destructive-on-dark</code></td><td>#fb5a47</td><td></td></tr>
<tr><td><code>--vads-color-action-border-base-active-on-light</code></td><td>#2e2e2e</td><td></td></tr>
<tr><td><code>--vads-color-action-border-base-active-on-dark</code></td><td>#adadad</td><td></td></tr>
<tr><td><code>--vads-color-feedback-foreground-success-on-dark</code></td><td>#21c834</td><td></td></tr>
<tr><td><code>--vads-color-feedback-foreground-success-on-light</code></td><td>#008817</td><td></td></tr>
<tr><td><code>--vads-color-feedback-foreground-warning-on-dark</code></td><td>#e5a000</td><td></td></tr>
<tr><td><code>--vads-color-feedback-foreground-warning-on-light</code></td><td>#c2850c</td><td></td></tr>
<tr><td><code>--vads-color-feedback-surface-info-on-dark</code></td><td>#112f4e</td><td></td></tr>
<tr><td><code>--vads-color-feedback-surface-success-on-dark</code></td><td>#19311e</td><td></td></tr>
<tr><td><code>--vads-color-feedback-surface-warning-on-dark</code></td><td>#422d19</td><td></td></tr>
<tr><td><code>--vads-color-feedback-surface-error-on-dark</code></td><td>#5c1111</td><td></td></tr>
<tr><td><code>--vads-color-feedback-border-warning-on-dark</code></td><td>#face00</td><td></td></tr>
<tr><td><code>--vads-color-forms-surface-active-on-light</code></td><td>#ecf1f7</td><td></td></tr>
<tr><td><code>--vads-color-forms-surface-active-on-dark</code></td><td>#252f3e</td><td></td></tr>
<tr><td><code>--vads-color-background-default-on-dark</code></td><td>#171716</td><td>Now <code>--vads-color-background-dark</code></td></tr>
<tr><td><code>--vads-color-base</code></td><td>#1b1b1b</td><td></td></tr>
<tr><td><code>--vads-color-base-darker</code></td><td>#3d4551</td><td></td></tr>
<tr><td><code>--vads-color-base-darkest</code></td><td>#1b1b1b</td><td></td></tr>
<tr><td><code>--vads-color-base-lighter</code></td><td>#dfe1e2</td><td></td></tr>
<tr><td><code>--vads-color-base-lightest</code></td><td>#f0f0f0</td><td></td></tr>
<tr><td><code>--vads-color-gray-medium</code></td><td>#757575</td><td></td></tr>
<tr><td><code>--vads-color-gray-light-alt</code></td><td>#edeff0</td><td></td></tr>
<tr><td><code>--vads-color-gray-warm-light</code></td><td>#e6e6e2</td><td></td></tr>
<tr><td><code>--vads-color-gray-warm-dark</code></td><td>#454540</td><td></td></tr>
<tr><td><code>--vads-color-gray-cool-light</code></td><td>#e1e7f1</td><td></td></tr>
<tr><td><code>--vads-color-gibill-accent</code></td><td>#fef0c8</td><td></td></tr>
<tr><td><code>--vads-color-gold-lighter</code></td><td>#ffe396</td><td></td></tr>
<tr><td><code>--vads-color-gold-lightest</code></td><td>#fef0c8</td><td></td></tr>
<tr><td><code>--vads-color-green-light</code></td><td>#5e9f69</td><td></td></tr>
<tr><td><code>--vads-color-green-lighter</code></td><td>#b4d0b9</td><td></td></tr>
<tr><td><code>--vads-color-blue-cool</code></td><td>#345d96</td><td></td></tr>
<tr><td><code>--vads-color-blue-cool-light</code></td><td>#4a77b4</td><td></td></tr>
<tr><td><code>--vads-color-blue-cool-lightest</code></td><td>#98afd2</td><td></td></tr>
<tr><td><code>--vads-color-ink</code></td><td>#1b1b1b</td><td></td></tr>
<tr><td><code>--vads-color-inset-bg</code></td><td>#e7f6f8</td><td></td></tr>
<tr><td><code>--vads-color-orange</code></td><td>#dd7533</td><td></td></tr>
<tr><td><code>--vads-color-va-accent</code></td><td>#8a7237</td><td></td></tr>
<tr><td><code>--vads-color-hub-*</code> (11 tokens)</td><td>various</td><td>Renamed to <code>--vads-hub-color-*</code>, same values</td></tr>
<tr><td><code>--vads-color-link</code></td><td>#005ea2</td><td>Renamed to <code>--vads-link-color-light</code></td></tr>
<tr><td><code>--vads-color-link-active</code></td><td>#0b4778</td><td>Renamed to <code>--vads-link-color-active-light</code> (#1a4480, different value)</td></tr>
<tr><td><code>--vads-color-link-visited</code></td><td>#54278f</td><td>Renamed to <code>--vads-link-color-visited-light</code></td></tr>
<tr><td><code>--vads-color-primary</code></td><td>#005ea2</td><td>Renamed to <code>--vads-color-primary-light</code></td></tr>
<tr><td><code>--vads-color-primary-alt</code> (5 tokens)</td><td>various cyans</td><td>Now <code>--vads-color-secondary-*</code> family</td></tr>
<tr><td><code>--vads-color-secondary</code> (4 tokens)</td><td>various reds</td><td>No equivalent; secondary now means cyan</td></tr>
<tr><td><code>--vads-color-success</code></td><td>#00a91c</td><td>Renamed to <code>--vads-color-success-light</code></td></tr>
<tr><td><code>--vads-color-warning</code></td><td>#ffbe2e</td><td>Renamed to <code>--vads-color-warning-light</code></td></tr>
<tr><td><code>--color-link-default-hover</code> <span class="tag invalid">invalid CSS</span></td><td>rgba(#000000, 0.05)</td><td>Invalid syntax; browser ignores it. Do not migrate.</td></tr>
</tbody>
</table>
</div>
</details>
<details>
<summary>Font tokens (unprefixed and pixel-based sizes) <span class="badge red">~30</span></summary>
<div class="overflow-x">
<table>
<thead><tr><th>Removed token</th><th>Old value</th><th>Conceptual equivalent in new</th></tr></thead>
<tbody>
<tr><td><code>--font-family-sans</code></td><td>Source Sans Pro Web…</td><td><code>--vads-font-family-sans</code> (stack trimmed)</td></tr>
<tr><td><code>--font-family-serif</code></td><td>Bitter…</td><td><code>--vads-font-family-serif</code></td></tr>
<tr><td><code>--font-family-mono</code></td><td>Roboto Mono Web…</td><td><code>--vads-font-family-mono</code> (stack trimmed)</td></tr>
<tr><td><code>--font-serif</code></td><td>Bitter…</td><td>Alias removed</td></tr>
<tr><td><code>--font-source-sans</code></td><td>Source Sans Pro Web…</td><td>Alias removed</td></tr>
<tr><td><code>--font-mono</code></td><td>Roboto Mono Web…</td><td>Alias removed</td></tr>
<tr><td><code>--font-weight-normal</code></td><td>400</td><td><code>--vads-font-weight-normal</code></td></tr>
<tr><td><code>--font-weight-bold</code></td><td>700</td><td><code>--vads-font-weight-bold</code></td></tr>
<tr><td><code>--font-style-normal</code></td><td>normal</td><td>Removed entirely</td></tr>
<tr><td><code>--font-style-italic</code></td><td>italic</td><td>Removed entirely</td></tr>
<tr><td><code>--font-size-sm</code></td><td>0.938rem</td><td><code>--vads-font-size-xs: 0.9375rem</code></td></tr>
<tr><td><code>--font-size-root</code></td><td>1rem</td><td><code>--vads-font-size-sm: 1rem</code></td></tr>
<tr><td><code>--font-size-md</code></td><td>1.063rem</td><td><code>--vads-font-size-md: 1.0625rem</code></td></tr>
<tr><td><code>--font-size-lg</code></td><td>1.25rem</td><td>None (new --vads-font-size-lg is 1.375rem, different value)</td></tr>
<tr><td><code>--font-size-xl</code></td><td>2rem</td><td><code>--vads-font-size-xl: 2rem</code></td></tr>
<tr><td><code>--font-size-2xl</code></td><td>2.5rem</td><td><code>--vads-font-size-2xl: 2.5rem</code></td></tr>
<tr><td><code>--font-size-h1</code> through <code>h6</code></td><td>various</td><td>Removed; use heading-level-* tokens instead (also removed)</td></tr>
<tr><td><code>--v3-font-base-size</code></td><td>16px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-body-large</code></td><td>20px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-body-lead</code></td><td>20px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-body-medium</code></td><td>17px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-body-small</code></td><td>15px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-eyebrow</code></td><td>17px</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-heading-level-1</code> through <code>-6</code></td><td>various</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-root</code></td><td>1rem</td><td>Removed</td></tr>
<tr><td><code>--vads-font-size-source-sans-normalized</code></td><td>1.06rem</td><td>Removed</td></tr>
<tr><td><code>--vads-font-line-height-body-lead</code></td><td>1.75</td><td>Removed</td></tr>
<tr><td><code>--vads-font-line-height-mono</code></td><td>1.7</td><td>Removed</td></tr>
<tr><td><code>--vads-font-line-height-serif</code></td><td>1.9</td><td>Removed</td></tr>
</tbody>
</table>
</div>
</details>
<details>
<summary>Units tokens (all removed, spacing-* is the replacement) <span class="badge red">37</span></summary>
<p style="padding:0.75rem;font-size:0.875rem;color:var(--text-muted)">All <code>--units-*</code> and <code>--units-neg-*</code> tokens are gone. The <code>--vads-spacing-*</code> series covers positive values (now in rem). Negative spacing tokens are fully removed with no replacement.</p>
</details>
<details>
<summary>Spacing (negative and composite tokens removed) <span class="badge red">~20</span></summary>
<div class="overflow-x">
<table>
<thead><tr><th>Removed token</th><th>Old value</th><th>Note</th></tr></thead>
<tbody>
<tr><td><code>--vads-spacing-1px</code></td><td>1px</td><td>Now <code>--vads-spacing-0p125-px</code></td></tr>
<tr><td><code>--vads-spacing-2px</code></td><td>2px</td><td>Now <code>--vads-spacing-0p25-px</code></td></tr>
<tr><td><code>--vads-spacing-neg-1px</code> through <code>neg-15</code></td><td>negative px</td><td>No replacement</td></tr>
<tr><td><code>--vads-spacing-inset-l</code></td><td>32px</td><td>No replacement</td></tr>
<tr><td><code>--vads-spacing-inset-m</code></td><td>24px</td><td>No replacement</td></tr>
<tr><td><code>--vads-spacing-inset-s</code></td><td>16px</td><td>No replacement</td></tr>
<tr><td><code>--vads-spacing-vertical-stack-l/m/s/default</code></td><td>32/24/16/16px</td><td>No replacement</td></tr>
<tr><td><code>--vads-forms-spacing-vertical-stack-default</code></td><td>32px</td><td>No replacement</td></tr>
<tr><td><code>--vads-site-margins-mobile-width</code></td><td>16px</td><td>No replacement</td></tr>
<tr><td><code>--vads-site-margins-width</code></td><td>32px</td><td>No replacement</td></tr>
<tr><td><code>--vads-site-margins-breakpoint</code></td><td>1024px</td><td>No replacement</td></tr>
<tr><td><code>--vads-grid-container-max-width</code></td><td>1024px</td><td>No replacement</td></tr>
</tbody>
</table>
</div>
</details>
</div>
</section>
<!-- NEW IN NEW FILE -->
<section id="new-tokens">
<h2>New Token Categories in New File <span class="badge green">710 added</span></h2>
<div class="card overflow-x">
<table>
<thead><tr><th>Category</th><th>Example tokens</th><th>Count (approx)</th></tr></thead>
<tbody>
<tr><td>Border radius &amp; width</td><td><code>--vads-border-radius-sm/md/lg</code>, <code>--vads-border-width-sm/md/lg</code></td><td>6</td></tr>
<tr><td>USWDS system colors</td><td><code>--uswds-system-color-blue-*</code>, <code>--uswds-system-color-red-*</code>, etc.</td><td>~460</td></tr>
<tr><td>Clinical charts colors</td><td><code>--vads-clinical-charts-color-muted-*</code>, <code>--vads-clinical-charts-color-vibrant-*</code></td><td>18</td></tr>
<tr><td>Opacity scale</td><td><code>--vads-opacity-0</code> through <code>--vads-opacity-100</code></td><td>12</td></tr>
<tr><td>Focus colors</td><td><code>--vads-focus-color-background-light/dark</code>, <code>--vads-focus-color-outline-light/dark</code></td><td>4</td></tr>
<tr><td>Link colors</td><td><code>--vads-link-color-light/dark</code>, <code>--vads-link-color-visited-light/dark</code></td><td>~10</td></tr>
<tr><td>Icon colors</td><td><code>--vads-icon-color-light/dark</code>, error variants</td><td>5</td></tr>
<tr><td>Text colors</td><td><code>--vads-text-color-light/dark</code>, error, inverse, weak variants</td><td>~8</td></tr>
<tr><td>Modal overlay</td><td><code>--vads-modal-overlay-color-light/dark</code></td><td>2</td></tr>
<tr><td>Named spacing aliases</td><td><code>--vads-spacing-2xs/xs/sm/md/lg</code></td><td>5</td></tr>
<tr><td>Font letter spacing</td><td><code>--vads-font-letter-spacing-tight/loose</code> etc.</td><td>5</td></tr>
<tr><td>Extended font sizes</td><td><code>--vads-font-size-3xs/2xs</code>, <code>--vads-font-size-3xl</code></td><td>3</td></tr>
<tr><td>Semantic color families (light/dark)</td><td><code>--vads-color-primary-strong-light</code>, <code>--vads-color-warning-weak-dark</code> etc.</td><td>~70</td></tr>
</tbody>
</table>
</div>
</section>
<!-- STORYBOOK -->
<section id="storybook">
<h2>Storybook Package <code>packages/storybook</code></h2>
<p class="note" style="margin-bottom:1rem">7 unique CSS variables used across 6 files. Significantly smaller scope than web-components, but the shared SCSS import in <code>.storybook/style.scss</code> is the primary migration dependency.</p>
<div class="alert yellow" style="margin-bottom:1rem">
<strong>Import path must be updated.</strong> <code>.storybook/style.scss</code> imports tokens via <code>@use '@department-of-veterans-affairs/css-library/dist/tokens/scss/variables.scss'</code>. This path will need to point to the new package once the token source changes.
</div>
<div class="card overflow-x" style="margin-bottom:1.5rem">
<table>
<thead><tr><th>Variable</th><th>File</th><th>Status in new package</th><th>Action</th></tr></thead>
<tbody>
<tr>
<td><code>--vads-color-primary</code></td>
<td>va-link.stories.tsx</td>
<td>Removed, rename only</td>
<td>Replace with <code>--vads-color-primary-light</code></td>
</tr>
<tr>
<td><code>--vads-color-base</code></td>
<td>stories/styles/va-icon.scss</td>
<td>Removed</td>
<td>Replace with <code>--vads-text-color-light</code></td>
</tr>
<tr>
<td><code>--vads-color-secondary</code></td>
<td>va-alert-sign-in.stories.tsx</td>
<td>Removed; secondary color changed to cyan</td>
<td>Determine intent: if red/destructive, use <code>--vads-color-critical-light</code>; requires design review</td>
</tr>
<tr>
<td><code>--vads-color-primary-dark</code></td>
<td>va-link.stories.tsx</td>
<td>Value changed (#1a4480 &rarr; #58b4ff, now dark-mode blue)</td>
<td>Verify usage context; if light-mode, use <code>--vads-color-primary-strong-light</code> (#1a4480) instead</td>
</tr>
<tr>
<td><code>--vads-color-primary-darker</code></td>
<td>va-link.stories.tsx, va-back-to-top.stories.tsx</td>
<td>Removed, no direct equivalent</td>
<td>Replace with <code>--vads-color-primary-stronger-light</code> (#162e51)</td>
</tr>
<tr>
<td><code>--vads-color-gray-light-alt</code></td>
<td>va-icon-uswds.stories.tsx</td>
<td>Removed, no direct equivalent</td>
<td>Replace with <code>--uswds-system-color-gray-cool-5</code> (#edeff0, same value)</td>
</tr>
<tr>
<td><code>--color-link-default</code></td>
<td>.storybook/style.scss</td>
<td>Not in either token file; appears to be a local USWDS token</td>
<td>Investigate source; likely safe to leave or replace with <code>--vads-link-color-light</code></td>
</tr>
</tbody>
</table>
</div>
<div class="card overflow-x">
<table>
<thead><tr><th>Import in .storybook/style.scss</th><th>Notes</th></tr></thead>
<tbody>
<tr>
<td><code>@use '@department-of-veterans-affairs/css-library/dist/tokens/scss/variables.scss' as *</code></td>
<td>Primary token import; path changes with new package</td>
</tr>
<tr>
<td><code>@use '.../formation-overrides/_variables.scss' as fo-vars</code></td>
<td>Formation overrides; verify still needed after token migration</td>
</tr>
<tr>
<td><code>@use '.../stylesheets/_mixins.scss' as *</code></td>
<td>Mixins; verify compatibility with new token names</td>
</tr>
<tr>
<td><code>preview.js</code>: 23 CSS stylesheet imports</td>
<td>Broad stylesheet dependencies; audit for any that reference old token variable names directly</td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="summary">
<h2>Token Summary</h2>
<div class="stats">
<div class="stat"><div class="stat-num">265</div><div class="stat-label">Old tokens</div></div>
<div class="stat"><div class="stat-num">754</div><div class="stat-label">New tokens</div></div>
<div class="stat red"><div class="stat-num">221</div><div class="stat-label">Removed</div></div>
<div class="stat blue"><div class="stat-num">710</div><div class="stat-label">Added</div></div>
<div class="stat orange"><div class="stat-num">34</div><div class="stat-label">Value changes</div></div>
<div class="stat yellow"><div class="stat-num">26</div><div class="stat-label">Placeholders in new</div></div>
</div>
</section>
</div>
<script>
(function () {
const HEX = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})\b/g;
const SKIP_TAGS = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT']);
function injectSwatches(root) {
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
const hits = [];
let node;
while ((node = walker.nextNode())) {
if (SKIP_TAGS.has(node.parentElement.tagName)) continue;
if (node.parentElement.classList.contains('swatch')) continue;
if (HEX.test(node.textContent)) hits.push(node);
}
hits.forEach(text => {
const frag = document.createDocumentFragment();
let last = 0;
HEX.lastIndex = 0;
let m;
while ((m = HEX.exec(text.textContent)) !== null) {
if (m.index > last) frag.appendChild(document.createTextNode(text.textContent.slice(last, m.index)));
const swatch = document.createElement('span');
swatch.className = 'swatch';
swatch.style.cssText = `background:${m[0]};display:inline-block;width:12px;height:12px;border-radius:2px;border:1px solid rgba(0,0,0,0.15);vertical-align:middle;margin-right:3px;flex-shrink:0;`;
frag.appendChild(swatch);
frag.appendChild(document.createTextNode(m[0]));
last = m.index + m[0].length;
}
if (last < text.textContent.length) frag.appendChild(document.createTextNode(text.textContent.slice(last)));
text.parentNode.replaceChild(frag, text);
});
}
document.addEventListener('DOMContentLoaded', () => injectSwatches(document.body));
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment