Variables Become Your CSS

Can light, dark and high-contrast modes in Figma become working theme CSS you can still read? Six variables, three modes, one headless Claude Code build. All 18 values became CSS custom properties with nothing hard-coded. Then the contrast meter found two failures: one in the palette, and one the agent added in its…

4:05 video6 min readWatch on YouTube

Variables Become Your CSS

Can light, dark and high-contrast modes in Figma become working theme CSS you can still read? Six variables, three modes, one headless Claude Code build. All 18 values became CSS custom properties with nothing hard-coded. Then the contrast meter found two failures: one in the palette, and one the agent added in its theme switch. Telling them apart is the lesson. An agent ran this overnight at Bear's request; Bear has since reviewed it from an educational perspective.

Liam, in for Bear, narrates.

Series: Figma for Educational AI


Chapters

0:00 Cold open 0:15 The overview 0:26 Variables and modes 0:40 The Figma file 0:51 What the agent got 1:03 The headless build 1:14 Variables become CSS 1:29 Three themes rendered 1:43 The contrast formula 1:57 The card's pairs 2:14 The agent's bug 2:30 The fix and the extra 2:43 Whose failure 2:55 Bear's review 3:23 Verdict 3:39 Your turn


YOUR TURN

Paste this into Claude:

"Here are my Figma colour variables for each mode. Compute the contrast ratio of every text and background pair, flag anything under 4.5 to 1, and say whether each failure lives in the palette or in the CSS."

Then check two things yourself:

  • Check: ratios from the formula, not a guess.
  • Check: pairs your design never drew.

Sources

  • https://help.figma.com/hc/en-us/articles/20774752502935
  • https://help.figma.com/hc/en-us/articles/26781702258583
  • https://developers.figma.com/docs/rest-api/webhooks-events/
  • https://www.w3.org/TR/WCAG22/#dfn-relative-luminance
  • https://www.w3.org/TR/WCAG22/#dfn-contrast-ratio
  • https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html

Every factual claim in this video was checked against these sources and the experiment record before rendering. An agent ran the experiment on Bear's Figma for Education account; Bear reviewed the film from an educational perspective. An independent series, not affiliated with or endorsed by Figma.

@NikBearBrown

▶ The full series playlist — Brutalist https://www.youtube.com/playlist?list=PLG9H-C6rp5RU

What this video covers

  • 0:00 — Cold open
  • 0:15 — The overview
  • 0:26 — Variables and modes
  • 0:40 — The Figma file
  • 0:51 — What the agent got
  • 1:03 — The headless build
  • 1:14 — Variables become CSS
  • 1:29 — Three themes rendered
  • 1:43 — The contrast formula
  • 1:57 — The card's pairs
  • 2:14 — The agent's bug
  • 2:30 — The fix and the extra
  • 2:43 — Whose failure
  • 2:55 — Bear's review
  • 3:23 — Verdict
  • 3:39 — Your turn

Transcript

A lightly formatted transcript of the video, with timestamps so you can jump to any section on YouTube.

Cold open

[0:00] Van A Cam, this is Liam in for Bear. Last night at Bear's request, an agent ran this test on his Figma account. Bear has since reviewed it from an educational perspective. The question, can light, dark, and high contrast modes become working CSS that you can still read? Copy Figma's variables exactly and

The overview

[0:17] You copy its mistakes, too. And the agent can add mistakes of its own. Last night's test found one of each. A contrast meter is how you tell them apart. First two words, a variable is a

Variables and modes

[0:27] Named color like color/surface. A mode is a column of values, light, dark, high contrast. Switch a frame's mode and every bound color changes at once. Six variables, three modes, 18 values to get right. Here's the file the

The Figma file

[0:41] Agent built. One study card, every color bound to a variable, no raw hex. Three frames, each set to a mode. These are Figma's own renders pulled through the MCP server.

What the agent got

[0:51] Then the agent asked for the variables. Get variable depths answers one frame at a time. Six names, six colors, no mode names. So, three calls one per frame. One call won't tell an agent your file has modes.

The headless build

[1:03] Those files went to a fresh clawed code session run headless with that one instruction. It read four files, wrote two, a style sheet in a page, and finished in 71 seconds.

Variables become CSS

[1:14] Slash becomes hyphen. Color/text/primary becomes the custom property color-text-primary. One block per theme. All 18 values match Figma. And outside those blocks, not one hard-coded color. That part the agent got right first try.

Three themes rendered

[1:29] Then headless Chrome opened the page and clicked the agent's own switch once per theme, light, dark, high contrast. The card's colors match Figma in all three. A clean handoff so far. Now the question matching can't answer, can you read it?

The contrast formula

[1:43] Contrast has a formula. Turn each color into its relative luminance, a weighted sum of red, green, and blue with green counting most. Divide the lighter by the darker, each plus 500ths. WCAG asks for 4.5:1 for body text, 3:1 for large text.

The card's pairs

[1:57] Every text pair on the card in all three modes, high contrast passes easily. Dark passes, its muted text just clears at 4.65. Light has one failure, the button label white on terracotta 3.12. It fails in Figma too before any code. That's a design finding.

The agent's bug

[2:14] The agent's own mistake is in the switch. On the light page, the high contrast button almost vanishes. Light gray on white 1.32:1. The cause, each button carries a data theme attribute and the palettes hang on that attribute alone. So, each button repaints itself in its own theme.

The fix and the extra

[2:30] The fix is small, scope each palette to the root element. The switch fails on the other two pages, too. And the agent invented an answer panel, terracotta on white, a pair the design never drew. 3.12, another fail.

Whose failure

[2:43] So, whose failure is whose? The light button fails in Figma, so fix it there with a darker terracotta and run it again. The switch fails only in the code. That's the agent's and it took a measurement to catch. The answer panel is both.

Bear's review

[2:55] Bear reviewed this the next day from an educational perspective and he agrees with its point. His note isn't in a chat thread, it's a Figma annotation on the theme modes layer attached to the thing it's about. So, the next agent that reads that layer gets the note, too. The MCP server hands it over with the code and tells the agent not to ignore it. An annotation notifies no one, though. So, if someone else had to look, a small script would tell them on Slack, Discord or email with a link, not a copy of the note. Here, no one else did, so nothing was sent.

Verdict

[3:23] Let's recap with Claude. 18 of 18 values, nothing hard coded first try. The light palette fails double on its button, a design fix. The agent's switch fails on its own. Verdict, middle. An agent ran this overnight. Bear has since reviewed it and the palette fix is still his call.

Your turn

[3:39] Your turn, paste this into Claude. Here are my Figma color variables for each mode. Compute the contrast ratio of every text and background pair, flag anything under 4.5:1, and say whether each failure lives in the palette or in the CSS. It sorts failures by owner, which is the whole lesson here. Then check two things yourself. Are the ratios from the formula not a guess? And did it test pairs your design never drew? Variables become your CSS at Nick Bear Brown.

More from Figma for Educational AI

Nik Bear Brown Poet and Songwriter