94 lines
2.9 KiB
JavaScript
94 lines
2.9 KiB
JavaScript
|
|
/**
|
||
|
|
* Replace hardcoded hex colors in base.css / overrides.css with
|
||
|
|
* CSS variable references defined in standalone/tokens.css.
|
||
|
|
*
|
||
|
|
* The replacement table maps exact hex values → var() references.
|
||
|
|
* Only standalone/*.css files are processed.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
||
|
|
|
||
|
|
// Color → variable mappings (ordered so longer/more-specific colors are matched first)
|
||
|
|
const REPLACEMENTS = [
|
||
|
|
// Primary accent
|
||
|
|
["#1073cc", "var(--ecom-primary)"],
|
||
|
|
["#0f66b3", "var(--ecom-primary-hover)"],
|
||
|
|
|
||
|
|
// Cyan accent
|
||
|
|
["#1ebddb", "var(--ecom-accent-cyan)"],
|
||
|
|
["#1dbedb", "var(--ecom-accent-cyan)"], // common typo variant
|
||
|
|
["#16c8df", "var(--ecom-accent-cyan-light)"],
|
||
|
|
["#18bfd2", "var(--ecom-accent-cyan-bright)"],
|
||
|
|
["#0f829b", "var(--ecom-accent-cyan-deep)"],
|
||
|
|
|
||
|
|
// White/near-white
|
||
|
|
["#feffff", "var(--ecom-bg-near-white)"],
|
||
|
|
["#fbfdff", "var(--ecom-bg-near-white)"],
|
||
|
|
["#f8fdff", "var(--ecom-bg-near-white)"],
|
||
|
|
["#ffffff", "var(--ecom-bg-white)"],
|
||
|
|
["#fff", "var(--ecom-bg-white)"], // 3-digit short form
|
||
|
|
|
||
|
|
// Light backgrounds
|
||
|
|
["#f8f9fa", "var(--ecom-bg-page)"],
|
||
|
|
["#edf8fb", "var(--ecom-bg-tinted)"],
|
||
|
|
["#edf8ff", "var(--ecom-bg-tinted)"],
|
||
|
|
["#f3f8fa", "var(--ecom-bg-cool)"],
|
||
|
|
["#f8fbfc", "var(--ecom-bg-cool)"],
|
||
|
|
["#eef6f8", "var(--ecom-bg-cool)"],
|
||
|
|
|
||
|
|
// Dark blue backgrounds
|
||
|
|
["#172636", "var(--ecom-bg-dark-blue)"],
|
||
|
|
["#163447", "var(--ecom-bg-deep-blue)"],
|
||
|
|
["#083c67", "var(--ecom-bg-navy)"],
|
||
|
|
["#05233f", "var(--ecom-bg-navy-deep)"],
|
||
|
|
|
||
|
|
// Text
|
||
|
|
["#10202c", "var(--ecom-text-primary)"],
|
||
|
|
["#f5fbff", "var(--ecom-text-on-dark)"],
|
||
|
|
["#738392", "var(--ecom-text-muted)"],
|
||
|
|
["#71818e", "var(--ecom-text-muted)"],
|
||
|
|
["#66798a", "var(--ecom-text-muted)"],
|
||
|
|
["#526474", "var(--ecom-text-muted)"],
|
||
|
|
["#8da0ab", "var(--ecom-text-placeholder)"],
|
||
|
|
|
||
|
|
// Border
|
||
|
|
// NOTE: rgba() colors are NOT replaced — only hex values
|
||
|
|
];
|
||
|
|
|
||
|
|
function processFile(filePath) {
|
||
|
|
let content = readFileSync(filePath, "utf-8");
|
||
|
|
let replaced = 0;
|
||
|
|
|
||
|
|
for (const [hex, variable] of REPLACEMENTS) {
|
||
|
|
// Only replace when the hex appears as a CSS value (not inside comments or var())
|
||
|
|
// Match: colon-space-hex, comma-space-hex, space-hex, etc.
|
||
|
|
// But be careful: don't replace inside existing var() calls
|
||
|
|
const regex = new RegExp(
|
||
|
|
`(?<!var\\([^)]{0,200})${hex.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?![\\da-fA-F])`,
|
||
|
|
"gi"
|
||
|
|
);
|
||
|
|
|
||
|
|
const matches = content.match(regex);
|
||
|
|
if (matches) {
|
||
|
|
replaced += matches.length;
|
||
|
|
content = content.replace(regex, variable);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
writeFileSync(filePath, content, "utf-8");
|
||
|
|
console.log(` ${filePath}: ${replaced} replacements`);
|
||
|
|
return replaced;
|
||
|
|
}
|
||
|
|
|
||
|
|
const files = process.argv.slice(2);
|
||
|
|
if (files.length === 0) {
|
||
|
|
console.error("Usage: node tokenize-colors.mjs <files...>");
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
let total = 0;
|
||
|
|
for (const f of files) {
|
||
|
|
total += processFile(f);
|
||
|
|
}
|
||
|
|
console.log(`Total: ${total} replacements across ${files.length} file(s)`);
|