One colour, two places, and why the icons stayed the wrong shade
The icons on this site's hub each sit on a small tinted tile. I changed the GitHub icon from orange to a neutral grey and the Sports icon from green to rose, and when I looked at the result the glyphs had changed but the tiles behind them were still the old colours. Orange behind a white mark, green behind a rose one.
That is not a visual accident. It is what happens when the same decision is written down in two places, and it is worth walking through because almost every site ends up doing it.
Where the colour actually came from
The tile is one element, a 44 pixel square, and it gets its look from two properties in the site's stylesheet:
.card__icon {
background: var(--accent-dim);
box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
Both of those read from --accent, a variable set per card further down the file:
.card--perps { --accent: #f7931a; --accent-dim: #3a2108; }
.card--sports { --accent: #28c76f; --accent-dim: #062a17; }
So the tile is a dark version of the card's accent, with a border that is a translucent version of the same accent. That is a good rule. It means a card's colour is decided once and everything downstream follows.
The glyph itself is a different problem. The icon SVG fills with currentColor, which comes from the text colour of that same element. That colour was set separately, in a generated stylesheet:
.card--sports .card__icon { color: #ff6b7d; }
Two files, two rules, one element. I edited the one that controlled the glyph and left the one that controlled the background, so half the change landed. The page was doing exactly what it was told.
The mistake was not the edit, it was the split
It is tempting to file this as "I forgot to change the other file". The real problem is that a single visual decision, the colour of the Sports card, was expressible in two places that could disagree. Any design system that allows that will drift, because the drift is silent: nothing errors, nothing looks broken in isolation, the page just slowly loses its consistency.
The same thing had already bitten this site once. The Perps card had no .card--perps rule at all for a while, so it silently fell back to the default blue accent and nobody noticed, because blue looks fine. It only became visible when a second card was supposed to look deliberately different from it.
Design tokens do not prevent this on their own. A token is a variable, and a variable can still be overridden per component. What prevents it is a rule about ownership: one place decides a card's colour, and everything else derives from it.
The shape that actually holds
The version that survives editing is one source per card, with the derived values computed from it rather than typed out beside it:
.card--sports {
--accent: #ff6b7d;
--accent-dim: color-mix(in srgb, var(--accent) 18%, #03050c);
}
.card__icon {
background: var(--accent-dim);
box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
.card--sports .card__icon { color: var(--accent); }
Now the card owns one hex value. The tile, its border and the glyph all read from it. To recolour a card you change one line, and there is no second line to forget.
Why not just use the accent everywhere
A fair objection: if everything derives from --accent, why compute a dim version at all? Why not set the tile to the accent and be done?
Because the tile is a surface and the accent is a highlight. A saturated colour that works as a 2 pixel border is far too loud as a 44 pixel block sitting next to body text. The tile needs to be recognisably the same hue but dark enough to sit behind a glyph without competing with the card's own border. That is a real second value, not a duplicate. The difference is that it should be derived from the accent by a formula, so it cannot disagree with it, rather than picked by eye and pasted in.
Mixing toward the page's own background rather than toward black matters too. This site's background is a deep blue, not black, so mixing toward #03050c keeps the dim tints in the same family as everything else. Mixing toward black gives you tiles that read as slightly dirty next to the rest of the page.
What this changed about the icon colours
The original palette had cards sharing a handful of hues: two oranges, two greens, two blues. Each was individually fine and the set was not, because the eye reads a group of coloured tiles as a legend. Two cards with the same accent colour imply a relationship that does not exist.
The current set is deliberately different for every card: white, periwinkle, grey, mint, blue, violet, rose, orange. It took two passes to get there, because the first pass changed only the glyphs and left the tiles behind.
None of that matters as much as the structure underneath. The palette will change again. The next time it does, it should be one edit per card, in one file, and the tiles should follow without being asked.