🔍 Skill: Design Drift Detector
Purpose
AI coding agents are precision-correct but context-blind. They generate #3B82F6 when they should generate var(--color-primary). They write margin: 16px when the token is var(--space-4). Over time, this silent drift disconnects the codebase from the design system — making future AI assistance increasingly inaccurate.
This skill detects that drift with surgical precision across 7 violation categories and 50+ pattern signatures.
Trigger Phrases
| Phrase |
Activation |
| "audit:drift" / "agentway audit:drift" |
✅ |
| "check hardcoded CSS" / "find hardcoded values" |
✅ |
| "token drift" / "design drift" |
✅ |
| "hardcoded colors" / "magic numbers" |
✅ |
| "CSS violations" / "token enforcement" |
✅ |
| "design system compliance" / "token coverage" |
✅ |
| "find non-token values" |
✅ |
Protocol: 3-Pass Drift Audit
PASS 1 — Critical Violations (Colors & Typography)
Scan for the highest-severity drift patterns that directly break visual consistency:
Color Violations:
- Hardcoded hex:
#[0-9a-fA-F]{3,6}
- Hardcoded RGB:
rgb([0-9]+,\s*[0-9]+,\s*[0-9]+)
- Hardcoded RGBA:
rgba([0-9]+,\s*[0-9]+,\s*[0-9]+,\s*[0-9.]+)
- Hardcoded HSL:
hsl([0-9]+,\s*[0-9]+%,\s*[0-9]+%)
- Named colors:
color: red, background: blue, border-color: black
Typography Violations:
- Literal font-size:
font-size:\s*[0-9]+(px|rem|em) (not using token)
- Literal font-weight:
font-weight:\s*(100|200|300|400|500|600|700|800|900) (not using token)
- Literal line-height:
line-height:\s*[0-9]+(px|em) (literal, not unitless token)
PASS 2 — High Violations (Spacing & Layout)
Spacing Violations:
- Literal margin:
margin(-top|-right|-bottom|-left)?:\s*[0-9]+(px|rem)
- Literal padding:
padding(-top|-right|-bottom|-left)?:\s*[0-9]+(px|rem)
- Literal gap:
gap:\s*[0-9]+(px|rem)
- Literal grid columns:
grid-template-columns:\s*repeat\([0-9]+,\s*[0-9]+(px|fr)
Dimension Violations:
- Hardcoded width/height with non-semantic values:
(width|height):\s*[0-9]+(px) (not 100%, auto, or a known breakpoint)
PASS 3 — Medium/Low Violations (Radius, Shadow, Z-Index, Duration)
Border Radius:
border-radius:\s*[0-9]+(px|rem|%) (not using var(--radius-*))
Box Shadow:
box-shadow:\s*[0-9]+(px) (hardcoded shadow, not using var(--shadow-*))
Z-Index:
z-index:\s*[0-9]+ (not using named var(--z-*) token)
- Anti-pattern:
z-index:\s*(9999|99999|999)
Transition/Duration:
transition(-duration)?:\s*[0-9]+(ms|s) (not using var(--duration-*))
animation-duration:\s*[0-9]+(ms|s)
Specificity Anti-Patterns:
!important usage (overrides token cascade)
style= inline styles in component templates
Severity Classification
| Level |
Score Impact |
Action Required |
| 🔴 Critical |
−20 pts per violation |
Fix before next AI session |
| 🟠 High |
−10 pts per violation |
Fix in current sprint |
| 🟡 Medium |
−5 pts per violation |
Fix in next sprint |
| 🟢 Low |
−2 pts per violation |
Fix in backlog cleanup |
Severity Matrix by Category
| Category |
Severity |
Why |
| Hardcoded colors |
🔴 Critical |
Breaks brand consistency, blocks dark mode |
| Hardcoded typography |
🟠 High |
Breaks type scale, disables responsive text |
| Hardcoded spacing |
🟠 High |
Breaks rhythm, causes layout inconsistency |
| Hardcoded radius |
🟡 Medium |
Visual inconsistency but non-breaking |
| Hardcoded shadow |
🟡 Medium |
Elevation inconsistency |
| Hardcoded z-index |
🟡 Medium |
Stacking context bugs |
| Hardcoded duration |
🟢 Low |
Motion inconsistency |
!important flags |
🟡 Medium |
Blocks token cascade override |
Inline style= |
🟠 High |
Unauditable, not token-resolved |
Drift Report Output Format
drift-report.md
# 🔍 Design Drift Report — [project-name]
Scanned: [timestamp] | Files: [N] | Total Violations: [N]
## Summary
| Severity | Count | Files Affected |
| Critical | 12 | 8 |
| High | 34 | 15 |
| Medium | 47 | 22 |
| Low | 18 | 9 |
## Critical Violations
### 🔴 Hardcoded Colors (12 violations)
| File | Line | Code | Fix |
| components/Button.css | 14 | `color: #3B82F6` | `color: var(--color-primary)` |
drift-report.json
{
"version": "1.6.0",
"scannedAt": "ISO8601",
"summary": {
"totalFiles": 47,
"totalViolations": 111,
"driftRate": "23.4%",
"byCategory": {
"hardcodedColors": { "count": 12, "severity": "critical" },
"hardcodedSpacing": { "count": 34, "severity": "high" },
"hardcodedTypography": { "count": 22, "severity": "high" }
}
},
"violations": [
{
"file": "components/Button.css",
"line": 14,
"category": "hardcodedColor",
"severity": "critical",
"found": "color: #3B82F6",
"fix": "color: var(--color-primary)"
}
]
}
Integration with project-health-diagnostics
The drift rate from this skill directly feeds Signal E in the TAI calculation:
drift_rate = (total_violations / (total_declarations × 100))
TAI_adjustment:
drift_rate < 5% → no penalty
drift_rate 5–15% → -5 from TAI
drift_rate 15–30% → -15 from TAI
drift_rate > 30% → -25 from TAI
Companion Skills
| Skill |
Relationship |
project-health-diagnostics |
Parent skill — runs drift-detector as Signal E |
design-tokens |
Provides the token system that violations should reference |
dark-mode-theming-system |
Color hardcoding blocks dark mode token switching |
ux-chaos-monkey |
Chaos injector validates fixes hold under stress |
1---2name: design-drift-detector3description: Scans a codebase for design token violations — components bypassing the design system with hardcoded colors, magic number spacings, literal font sizes, and other CSS anti-patterns. Produces a severity-sorted drift report with auto-fix recipes. Use when: audit:drift, hardcoded CSS, token drift, design drift, hardcoded colors, magic numbers, CSS violations, design system enforcement.4---56# 🔍 Skill: Design Drift Detector78## Purpose910AI coding agents are precision-correct but context-blind. They generate `#3B82F6` when they should generate `var(--color-primary)`. They write `margin: 16px` when the token is `var(--space-4)`. Over time, this silent drift disconnects the codebase from the design system — making future AI assistance increasingly inaccurate.1112This skill detects that drift with surgical precision across **7 violation categories** and **50+ pattern signatures**.1314---1516## Trigger Phrases1718| Phrase | Activation |19| :--- | :---: |20| "audit:drift" / "agentway audit:drift" | ✅ |21| "check hardcoded CSS" / "find hardcoded values" | ✅ |22| "token drift" / "design drift" | ✅ |23| "hardcoded colors" / "magic numbers" | ✅ |24| "CSS violations" / "token enforcement" | ✅ |25| "design system compliance" / "token coverage" | ✅ |26| "find non-token values" | ✅ |2728---2930## Protocol: 3-Pass Drift Audit3132### PASS 1 — Critical Violations (Colors & Typography)3334Scan for the highest-severity drift patterns that directly break visual consistency:3536**Color Violations:**37- Hardcoded hex: `#[0-9a-fA-F]{3,6}`38- Hardcoded RGB: `rgb([0-9]+,\s*[0-9]+,\s*[0-9]+)`39- Hardcoded RGBA: `rgba([0-9]+,\s*[0-9]+,\s*[0-9]+,\s*[0-9.]+)`40- Hardcoded HSL: `hsl([0-9]+,\s*[0-9]+%,\s*[0-9]+%)`41- Named colors: `color: red`, `background: blue`, `border-color: black`4243**Typography Violations:**44- Literal font-size: `font-size:\s*[0-9]+(px|rem|em)` (not using token)45- Literal font-weight: `font-weight:\s*(100|200|300|400|500|600|700|800|900)` (not using token)46- Literal line-height: `line-height:\s*[0-9]+(px|em)` (literal, not unitless token)4748### PASS 2 — High Violations (Spacing & Layout)4950**Spacing Violations:**51- Literal margin: `margin(-top|-right|-bottom|-left)?:\s*[0-9]+(px|rem)`52- Literal padding: `padding(-top|-right|-bottom|-left)?:\s*[0-9]+(px|rem)`53- Literal gap: `gap:\s*[0-9]+(px|rem)`54- Literal grid columns: `grid-template-columns:\s*repeat\([0-9]+,\s*[0-9]+(px|fr)`5556**Dimension Violations:**57- Hardcoded width/height with non-semantic values:58 `(width|height):\s*[0-9]+(px)` (not 100%, auto, or a known breakpoint)5960### PASS 3 — Medium/Low Violations (Radius, Shadow, Z-Index, Duration)6162**Border Radius:**63- `border-radius:\s*[0-9]+(px|rem|%)` (not using `var(--radius-*)`)6465**Box Shadow:**66- `box-shadow:\s*[0-9]+(px)` (hardcoded shadow, not using `var(--shadow-*)`)6768**Z-Index:**69- `z-index:\s*[0-9]+` (not using named `var(--z-*)` token)70- Anti-pattern: `z-index:\s*(9999|99999|999)`7172**Transition/Duration:**73- `transition(-duration)?:\s*[0-9]+(ms|s)` (not using `var(--duration-*)`)74- `animation-duration:\s*[0-9]+(ms|s)`7576**Specificity Anti-Patterns:**77- `!important` usage (overrides token cascade)78- `style=` inline styles in component templates7980---8182## Severity Classification8384| Level | Score Impact | Action Required |85| :--- | :---: | :--- |86| 🔴 **Critical** | −20 pts per violation | Fix before next AI session |87| 🟠 **High** | −10 pts per violation | Fix in current sprint |88| 🟡 **Medium** | −5 pts per violation | Fix in next sprint |89| 🟢 **Low** | −2 pts per violation | Fix in backlog cleanup |9091### Severity Matrix by Category92| Category | Severity | Why |93| :--- | :---: | :--- |94| Hardcoded colors | 🔴 Critical | Breaks brand consistency, blocks dark mode |95| Hardcoded typography | 🟠 High | Breaks type scale, disables responsive text |96| Hardcoded spacing | 🟠 High | Breaks rhythm, causes layout inconsistency |97| Hardcoded radius | 🟡 Medium | Visual inconsistency but non-breaking |98| Hardcoded shadow | 🟡 Medium | Elevation inconsistency |99| Hardcoded z-index | 🟡 Medium | Stacking context bugs |100| Hardcoded duration | 🟢 Low | Motion inconsistency |101| `!important` flags | 🟡 Medium | Blocks token cascade override |102| Inline `style=` | 🟠 High | Unauditable, not token-resolved |103104---105106## Drift Report Output Format107108### `drift-report.md`109```markdown110# 🔍 Design Drift Report — [project-name]111Scanned: [timestamp] | Files: [N] | Total Violations: [N]112113## Summary114| Severity | Count | Files Affected |115| Critical | 12 | 8 |116| High | 34 | 15 |117| Medium | 47 | 22 |118| Low | 18 | 9 |119120## Critical Violations121### 🔴 Hardcoded Colors (12 violations)122| File | Line | Code | Fix |123| components/Button.css | 14 | `color: #3B82F6` | `color: var(--color-primary)` |124```125126### `drift-report.json`127```json128{129 "version": "1.6.0",130 "scannedAt": "ISO8601",131 "summary": {132 "totalFiles": 47,133 "totalViolations": 111,134 "driftRate": "23.4%",135 "byCategory": {136 "hardcodedColors": { "count": 12, "severity": "critical" },137 "hardcodedSpacing": { "count": 34, "severity": "high" },138 "hardcodedTypography": { "count": 22, "severity": "high" }139 }140 },141 "violations": [142 {143 "file": "components/Button.css",144 "line": 14,145 "category": "hardcodedColor",146 "severity": "critical",147 "found": "color: #3B82F6",148 "fix": "color: var(--color-primary)"149 }150 ]151}152```153154---155156## Integration with project-health-diagnostics157158The drift rate from this skill directly feeds Signal E in the TAI calculation:159160```161drift_rate = (total_violations / (total_declarations × 100))162163TAI_adjustment:164 drift_rate < 5% → no penalty165 drift_rate 5–15% → -5 from TAI166 drift_rate 15–30% → -15 from TAI167 drift_rate > 30% → -25 from TAI168```169170---171172## Companion Skills173174| Skill | Relationship |175| :--- | :--- |176| `project-health-diagnostics` | Parent skill — runs drift-detector as Signal E |177| `design-tokens` | Provides the token system that violations should reference |178| `dark-mode-theming-system` | Color hardcoding blocks dark mode token switching |179| `ux-chaos-monkey` | Chaos injector validates fixes hold under stress |