Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 10.4 — Dark Mode and Theme Tokens
Data Visualization · Example 1 of 2

The same chart in a light card and a dark card, from tokens

The preview cannot switch the system's light or dark preference, so each card carries a class that sets the tokens. A real page writes the same values in @media (prefers-color-scheme: dark) and in [data-theme="dark"] (the build does). In the picture both cards are dark, because the code swapped the first card's class, and its top bar (Quay) is grey: that is the fallback for the misspelled token.

Put every chart colour in CSS custom properties (tokens), draw SVG with var() and currentColor, and a theme becomes one switch with no redraw. Canvas and exported images do not read CSS, so they must be given the resolved colour and redrawn.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 4 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write a repaint function that clears the canvas from the second example and draws the bars with the current --chart-accent, and call it from a button that toggles the dark class.

02

List which parts of the dashboard in Phase 7 hold a hard-coded colour (open stations-bar.js) and say which token each should use.

Explain it without notes

01

Why does an SVG chart that uses var(--chart-accent) change theme with no redraw?

02

What happens to ctx.fillStyle = "var(--chart-accent)", and how do you colour a canvas by token?

03

Why do you need both @media (prefers-color-scheme: dark) and a data-theme rule?

The same chart in a light card and a dark card, from tokens

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

light bar fill: rgb(31, 122, 111) | label fill: rgb(29, 43, 54) | card background: rgb(255, 255, 255)
dark  bar fill: rgb(79, 209, 192) | label fill: rgb(230, 237, 242) | card background: rgb(22, 34, 43)
after swapping one class, the first card's bar fill: rgb(79, 209, 192)
misspelled token, no fallback: rgb(0, 0, 0)
misspelled token, with a fallback: rgb(136, 136, 136)