Replace remaining hardcoded border-radius and color values across 22 CSS files with design system tokens. Add .live-status-bar, .live-scene, and .live-panel-* classes to layout.css for the grid-based live view shell. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
260 lines
7.9 KiB
Python
260 lines
7.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Replace hard-coded hex colors in CSS files with design system tokens."""
|
|
import re, sys, os
|
|
|
|
# Mapping: lowercase hex → token replacement
|
|
# Ordered longest-first so #ffffff matches before #fff
|
|
COLOR_MAP = {
|
|
# Slate scale (exact Radix values from tokens.css)
|
|
'#111113': 'var(--slate-1)',
|
|
'#18191b': 'var(--slate-2)',
|
|
'#1e2024': 'var(--slate-3)',
|
|
'#262830': 'var(--slate-4)',
|
|
'#2e3039': 'var(--slate-5)',
|
|
'#363842': 'var(--slate-6)',
|
|
'#43454f': 'var(--slate-7)',
|
|
'#565867': 'var(--slate-8)',
|
|
'#6b6e7b': 'var(--slate-9)',
|
|
'#7c7f8c': 'var(--slate-10)',
|
|
'#9b9daa': 'var(--slate-11)',
|
|
'#ededf0': 'var(--slate-12)',
|
|
|
|
# Backgrounds close to slate steps
|
|
'#1e1e2e': 'var(--bg-card)',
|
|
'#1e1e3a': 'var(--bg-card)',
|
|
'#1a1a2e': 'var(--bg-card)',
|
|
'#1a1a1a': 'var(--bg-page)',
|
|
'#121225': 'var(--bg-page)',
|
|
'#141425': 'var(--bg-page)',
|
|
'#252538': 'var(--bg-hover)',
|
|
'#2a2a2a': 'var(--bg-hover)',
|
|
'#2a2a3a': 'var(--bg-hover)',
|
|
'#2a2a4a': 'var(--bg-hover)',
|
|
|
|
# Slate approximations (grays)
|
|
'#333333': 'var(--slate-5)',
|
|
'#333': 'var(--slate-5)',
|
|
'#3a3a4a': 'var(--slate-5)',
|
|
'#444444': 'var(--slate-6)',
|
|
'#444': 'var(--slate-6)',
|
|
'#555555': 'var(--slate-7)',
|
|
'#555': 'var(--slate-7)',
|
|
'#666666': 'var(--text-muted)',
|
|
'#666': 'var(--text-muted)',
|
|
'#888888': 'var(--text-muted)',
|
|
'#888': 'var(--text-muted)',
|
|
'#9e9e9e': 'var(--slate-10)',
|
|
'#aaaaaa': 'var(--text-secondary)',
|
|
'#aaa': 'var(--text-secondary)',
|
|
'#bbbbbb': 'var(--slate-11)',
|
|
'#bbbb': 'var(--slate-11)',
|
|
'#cccccc': 'var(--slate-11)',
|
|
'#ccc': 'var(--slate-11)',
|
|
'#d0d0d0': 'var(--slate-11)',
|
|
'#e0e0e0': 'var(--slate-11)',
|
|
'#eeeeee': 'var(--slate-12)',
|
|
'#eee': 'var(--slate-12)',
|
|
'#ffffff': 'var(--text-on-accent)',
|
|
'#fff': 'var(--text-on-accent)',
|
|
'#000000': '#000000', # keep pure black (rare, used for shadows)
|
|
'#000': '#000',
|
|
|
|
# Blue scale (accent)
|
|
'#4fc3f7': 'var(--blue-10)',
|
|
'#45b7d1': 'var(--blue-9)',
|
|
'#3aa6c3': 'var(--blue-8)',
|
|
'#4ecdc4': 'var(--blue-9)',
|
|
'#4a9eff': 'var(--blue-9)',
|
|
'#3b82f6': 'var(--blue-9)',
|
|
'#29b6f6': 'var(--blue-10)',
|
|
'#68bdfa': 'var(--blue-11)',
|
|
'#aedcff': 'var(--blue-12)',
|
|
'#1a73e8': 'var(--blue-9)',
|
|
'#2196f3': 'var(--blue-9)',
|
|
'#42a5f5': 'var(--blue-10)',
|
|
|
|
# Semantic: red/alert
|
|
'#e5484d': 'var(--alert)',
|
|
'#ef5350': 'var(--alert)',
|
|
'#dc3545': 'var(--alert)',
|
|
'#dc2626': 'var(--alert)',
|
|
'#f44336': 'var(--alert)',
|
|
'#ff4757': 'var(--alert)',
|
|
'#c82333': 'var(--alert)',
|
|
'#b91c1c': 'var(--alert)',
|
|
'#f87171': 'var(--alert)',
|
|
'#e74c3c': 'var(--alert)',
|
|
'#ff6b6b': 'var(--alert)',
|
|
|
|
# Semantic: green/ok
|
|
'#46a758': 'var(--ok)',
|
|
'#66bb6a': 'var(--ok)',
|
|
'#4caf50': 'var(--ok)',
|
|
'#81c784': 'var(--ok)',
|
|
'#22c55e': 'var(--ok)',
|
|
'#22c65e': 'var(--ok)',
|
|
'#4ade80': 'var(--ok)',
|
|
'#66bb6a': 'var(--ok)',
|
|
'#2e7d32': 'var(--ok)',
|
|
'#43a047': 'var(--ok)',
|
|
'#1b5e20': 'var(--ok)',
|
|
|
|
# Semantic: amber/warn
|
|
'#e5a00d': 'var(--warn)',
|
|
'#ffa726': 'var(--warn)',
|
|
'#ffa502': 'var(--warn)',
|
|
'#ffc107': 'var(--warn)',
|
|
'#fbbf24': 'var(--warn)',
|
|
'#ff9800': 'var(--warn)',
|
|
'#ffb300': 'var(--warn)',
|
|
'#f57c00': 'var(--warn)',
|
|
'#ffca28': 'var(--warn)',
|
|
|
|
# Purple (replace with blue accent per design system)
|
|
'#ab47bc': 'var(--blue-9)',
|
|
'#ba68c8': 'var(--blue-10)',
|
|
'#9c27b0': 'var(--blue-8)',
|
|
'#a78bfa': 'var(--blue-10)',
|
|
'#9c4cb3': 'var(--blue-9)',
|
|
|
|
# Slate for Tailwind-like grays
|
|
'#475569': 'var(--slate-7)',
|
|
'#64748b': 'var(--slate-9)',
|
|
|
|
# Gradient endpoints (apdetection.css)
|
|
'#667eea': 'var(--blue-7)',
|
|
'#764ba2': 'var(--blue-9)',
|
|
|
|
# Additional blues
|
|
'#3a8ee6': 'var(--blue-9)',
|
|
'#2563eb': 'var(--blue-9)',
|
|
'#16a34a': 'var(--ok)',
|
|
'#7db4ff': 'var(--blue-11)',
|
|
'#a5ccff': 'var(--blue-12)',
|
|
'#4299e1': 'var(--blue-9)',
|
|
'#0066cc': 'var(--blue-9)',
|
|
'#007aff': 'var(--blue-9)',
|
|
'#00bcd4': 'var(--blue-9)',
|
|
'#3498db': 'var(--blue-9)',
|
|
'#3579c5': 'var(--blue-8)',
|
|
|
|
# Additional greens
|
|
'#34c759': 'var(--ok)',
|
|
'#2ecc71': 'var(--ok)',
|
|
'#1abc9c': 'var(--ok)',
|
|
|
|
# Additional ambers/oranges
|
|
'#fb923c': 'var(--warn)',
|
|
'#ed8936': 'var(--warn)',
|
|
'#ff9500': 'var(--warn)',
|
|
'#ffb432': 'var(--warn)',
|
|
'#e6c84c': 'var(--warn)',
|
|
'#f39c12': 'var(--warn)',
|
|
'#e67e22': 'var(--warn)',
|
|
'#feedba': 'var(--warn)',
|
|
|
|
# Additional reds
|
|
'#ff3b30': 'var(--alert)',
|
|
'#f66': 'var(--alert)',
|
|
'#d32f2f': 'var(--alert)',
|
|
'#e57373': 'var(--alert)',
|
|
|
|
# Purples → blue accent (dark-only design system)
|
|
'#a55eea': 'var(--blue-10)',
|
|
'#7e57c2': 'var(--blue-9)',
|
|
'#9b59b6': 'var(--blue-9)',
|
|
'#af52de': 'var(--blue-10)',
|
|
|
|
# Slate/gray approximations
|
|
'#747d8c': 'var(--slate-9)',
|
|
'#607d8b': 'var(--slate-9)',
|
|
'#95a5a6': 'var(--slate-10)',
|
|
'#34495e': 'var(--slate-6)',
|
|
'#a0a0b0': 'var(--text-secondary)',
|
|
'#16162a': 'var(--bg-card)',
|
|
'#2ed573': 'var(--ok)',
|
|
'#ddd': 'var(--text-secondary)',
|
|
'#0a0a0a': 'var(--slate-1)',
|
|
'#6c6': 'var(--ok)',
|
|
'#f66': 'var(--alert)',
|
|
'#98989d': 'var(--text-secondary)',
|
|
'#86868b': 'var(--text-secondary)',
|
|
'#1d1d1f': 'var(--text-primary)',
|
|
'#38383a': 'var(--border-default)',
|
|
'#2c2c2e': 'var(--bg-card)',
|
|
'#1c1c1e': 'var(--bg-page)',
|
|
'#e5e5ea': 'var(--border-default)',
|
|
'#e5e5e7': 'var(--border-default)',
|
|
'#ebebeb': 'var(--border-default)',
|
|
'#f5f5f7': 'var(--bg-page)',
|
|
|
|
# Ambient time-of-day (light colors → dark equivalents)
|
|
'#f0f4f8': 'var(--bg-page)',
|
|
'#fef3e7': 'var(--bg-page)',
|
|
'#1a365d': 'var(--text-primary)',
|
|
'#7c2d12': 'var(--warn)',
|
|
|
|
# Exact Radix blue scale values used as non-token references
|
|
'#11181e': 'var(--blue-1)',
|
|
'#152233': 'var(--blue-2)',
|
|
'#1a2e47': 'var(--blue-3)',
|
|
'#1e3a5f': 'var(--blue-4)',
|
|
'#224777': 'var(--blue-5)',
|
|
'#26558f': 'var(--blue-6)',
|
|
'#2e6aad': 'var(--blue-7)',
|
|
'#3e96e8': 'var(--blue-9)',
|
|
'#4daaf5': 'var(--blue-10)',
|
|
'#16213e': 'var(--blue-3)',
|
|
}
|
|
|
|
def replace_hex_in_css(content, filepath):
|
|
"""Replace hex colors with tokens, preserving context."""
|
|
lines = content.split('\n')
|
|
result = []
|
|
changes = 0
|
|
|
|
for line in lines:
|
|
new_line = line
|
|
# Find all hex colors in the line
|
|
# Match #xxx or #xxxxxx (3 or 6 hex digits)
|
|
hex_pattern = re.compile(r'#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b')
|
|
|
|
matches = hex_pattern.finditer(line)
|
|
for m in reversed(list(matches)): # reversed to preserve positions
|
|
hex_val = m.group(0).lower()
|
|
if hex_val in COLOR_MAP:
|
|
replacement = COLOR_MAP[hex_val]
|
|
if replacement != m.group(0): # skip if mapping is identity
|
|
new_line = new_line[:m.start()] + replacement + new_line[m.end():]
|
|
changes += 1
|
|
|
|
result.append(new_line)
|
|
|
|
return '\n'.join(result), changes
|
|
|
|
def process_file(filepath):
|
|
with open(filepath, 'r') as f:
|
|
content = f.read()
|
|
|
|
new_content, changes = replace_hex_in_css(content, filepath)
|
|
|
|
if changes > 0:
|
|
with open(filepath, 'w') as f:
|
|
f.write(new_content)
|
|
print(f" {os.path.basename(filepath)}: {changes} replacements")
|
|
else:
|
|
print(f" {os.path.basename(filepath)}: no changes needed")
|
|
|
|
return changes
|
|
|
|
if __name__ == '__main__':
|
|
css_dir = os.path.dirname(os.path.abspath(__file__))
|
|
total = 0
|
|
|
|
for fname in sorted(os.listdir(css_dir)):
|
|
if not fname.endswith('.css') or fname == 'tokens.css' or fname.startswith('_'):
|
|
continue
|
|
fpath = os.path.join(css_dir, fname)
|
|
total += process_file(fpath)
|
|
|
|
print(f"\nTotal replacements: {total}")
|