Skip to content

Instantly share code, notes, and snippets.

@caseywatts
Last active March 13, 2025 21:27
Show Gist options
  • Save caseywatts/3b82dec0fda2dbf10454655700609cd2 to your computer and use it in GitHub Desktop.
Save caseywatts/3b82dec0fda2dbf10454655700609cd2 to your computer and use it in GitHub Desktop.
Maryland Color Scale Generation
// note: this is using OKLCH, see https://oklch.com/
// https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl
import Color from "colorjs.io";
let marylandRedBase = new Color("oklch(52.44% 0.2043 17)");
let marylandAntiRedBase = new Color("oklch(52.44% 0.2043 197)");
let marylandGoldBase = new Color("oklch(84.63% 0.1611 83.87)");
let marylandAntiGoldBase = new Color("lch(65.14% 57.88 274.65)");
let marylandBlueBase = new Color("oklch(68.06% 0.173 281.52)");
let marylandCyanBase = new Color("oklch(66.13% 0.1182 227.75)");
// USWDS shares out luminance values in the color grades table in relative luminance values, not OKLCH luminance values
// https://www.w3.org/WAI/GL/wiki/Relative_luminance
// https://designsystem.digital.gov/design-tokens/color/overview/#magic-number-2
// We generated OKLCH luminance values by translating them out of the uswds blue scale colors on https://oklch.com/
// Our generated luminance values weren't actually in the right ranges, but this was a helpful starting point
const blueLuminanceMapping = {
"05": 96.93,
10: 92.4,
20: 83.32,
30: 74.38,
40: 65.46,
50: 56.14,
60: 47.34,
70: 38.92,
80: 30.08,
90: 20.43,
};
const redCoolVividLuminanceMapping = {
"05": 96.59,
10: 90.96,
20: 81.32,
30: 71.21,
40: 60.9,
50: 50.01,
60: 39.62,
70: 30.05,
80: 18.71,
90: 7.93,
};
const yellowVividLuminanceMapping = {
"05": 96.4,
10: 91.77,
20: 84.75,
30: 72.83,
40: 60.63,
50: 50.51,
60: 42.06,
70: 31.91,
80: 20.64,
90: 7.65,
};
const cyanLuminanceMapping = {
"05": 96.83,
10: 90.97,
20: 80.47,
30: 70.27,
40: 59.66,
50: 49.37,
60: 39.86,
70: 30.28,
80: 22.11,
90: 7.57,
};
function scaleForBaseColor(baseColorName, baseColor, luminanceMapping) {
let baseColorOKLCH = baseColor.to("oklch");
return Object.keys(luminanceMapping).map((grade) => {
const luminance = luminanceMapping[grade] / 100;
let newColor = new Color(baseColorOKLCH).set("l", luminance);
return {
tokenName: `${baseColorName}-${grade}`,
color: newColor,
};
});
}
function relativeLuminance(color) {
const rgbColor = color.toGamut({
space: "srgb",
});
return (
0.2126 * rgbColor.srgb.r +
0.7152 * rgbColor.srgb.g +
0.0722 * rgbColor.srgb.b
);
}
function printHeaderRow() {
console.log(`Token\tHex\tRGBA\tOKLCH\tHSL\tLuminance`);
}
function printColorValues(token, color) {
const hex = color.to("srgb").toString({ format: "hex" });
const rgba = color.to("srgb").toString({ format: "rgba" });
const oklch = color.to("oklch").toString({ format: "oklch" });
const hsl = color.to("hsl").toString({ format: "hsl" });
const luminance = relativeLuminance(color);
console.log(`${token}\t${hex}\t${rgba}\t${oklch}\t${hsl}\t${luminance}`);
}
function printScaleTable(scale) {
scale.forEach((scaleItem) => {
printColorValues(scaleItem.tokenName, scaleItem.color);
});
}
function printScaleCSSVariables(scale) {
scale.forEach((scaleItem) => {
console.log(
`--${scaleItem.tokenName}: ${scaleItem.color.to("oklch").toString({ format: "oklch" })};`,
);
});
}
printHeaderRow();
printScaleTable(
scaleForBaseColor(
"maryland-red",
marylandRedBase,
redCoolVividLuminanceMapping,
),
);
printScaleTable(
scaleForBaseColor(
"maryland-anti-red",
marylandAntiRedBase,
cyanLuminanceMapping,
),
);
printScaleTable(
scaleForBaseColor(
"maryland-gold",
marylandGoldBase,
yellowVividLuminanceMapping,
),
);
printScaleTable(
scaleForBaseColor(
"maryland-anti-gold",
marylandAntiGoldBase,
blueLuminanceMapping,
),
);
printScaleTable(
scaleForBaseColor("maryland-blue", marylandBlueBase, blueLuminanceMapping),
);
printScaleTable(
scaleForBaseColor("maryland-cyan", marylandCyanBase, blueLuminanceMapping),
);
console.log("\n\n\n");
printScaleCSSVariables(
scaleForBaseColor(
"maryland-red",
marylandRedBase,
redCoolVividLuminanceMapping,
),
);
printScaleCSSVariables(
scaleForBaseColor(
"maryland-anti-red",
marylandAntiRedBase,
cyanLuminanceMapping,
),
);
printScaleCSSVariables(
scaleForBaseColor(
"maryland-gold",
marylandGoldBase,
yellowVividLuminanceMapping,
),
);
printScaleCSSVariables(
scaleForBaseColor(
"maryland-anti-gold",
marylandAntiGoldBase,
blueLuminanceMapping,
),
);
printScaleCSSVariables(
scaleForBaseColor("maryland-blue", marylandBlueBase, blueLuminanceMapping),
);
printScaleCSSVariables(
scaleForBaseColor("maryland-cyan", marylandCyanBase, blueLuminanceMapping),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment