← Back to series overview

Make It Beautiful: Figma Design System to Stunning Report

Hey everyone, this week I learned what actually makes a report "beautiful" under the hood, it's not the visuals, it's the tokens. One of my customers asked exactly that.

The finale outcome

  • Figma MCP connected, Copilot can read your design system
  • Power BI theme generated from Figma color + type tokens
  • Part 4 report restyled: KPI cards, charts, slicers all on-brand
  • Layout polish from Figma frames + publish + production checklist

Table of Contents

Where we are: the journey so far

But going back to the question my customer had: "How do we make this look like us, not like default Power BI?" Same pattern as EmbedToken years ago, the beautiful part is derived from something upstream. There, the EmbedToken inherited AAD lifetimes. Here, the report inherits Figma tokens. Get the upstream right and the rest follows. This was confirmed to me the same way, by watching a designer change one token and the whole report follow.

1. Loaded
bronze
→
2. Engineered
gold
→
3. Modeled
measures
→
4. Built
functional
→
5. Beautify
you are here

Data flows nightly, the model is certified, the report is correct, but still on the default theme. Designers already solved beauty in Figma. We just have to pipe it through.

Connect Figma MCP

// .vscode/mcp.json, add third server
{
  "servers": {
    "fabric": { "...": "Part 1" },
    "powerbi": { "...": "Part 3" },
    "figma": {
      "type": "stdio",
      "command": "npx",
      "args": ["@figma/mcp-server@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "${env:FIGMA_ACCESS_TOKEN}",
        "FIGMA_FILE_KEYS": "${env:FIGMA_FILE_KEYS}"
      }
    }
  }
}

Get a token via Figma Settings to Personal Access Tokens (file:read, library:read), and copy the file key from your design-system URL.

You: List published libraries and color styles in our Enterprise Design System file
Copilot: Querying Figma MCP…
// MCP: figma.getTeamLibraries() to Enterprise DS v3.2 (245 components)
// MCP: figma.getFileStyles(fileKey, "FILL") to 89 color styles
Found primary, success, warning, danger ramps + KPI Card variants (Default, Compact, Detailed, Alert). Ready to theme.

Tokens to Power BI theme with Copilot

You: Get Enterprise DS color tokens and format as a Power BI theme JSON with dataColors, background, foreground, and card visualStyles (8px radius, subtle shadow)
Copilot:
{
  "name": "Enterprise Design System",
  "dataColors": ["#0052CC","#00875A","#FF8B00","#DE350B","#611F69","#007B83"],
  "background": "#FFFFFF",
  "foreground": "#172B4D",
  "tableAccent": "#0052CC",
  "visualStyles": {
    "*": { "card": [{
      "background": {"color": {"solid": {"color": "#FFFFFF"}}},
      "border": {"color": {"solid": {"color": "#DFE1E6"}}, "radius": 8},
      "shadow": {"color": {"solid": {"color": "#091E421A"}}, "blur": 8, "offsetY": 2}
    }]}
  }
}
// MCP: powerbi.applyTheme(ws, reportId, themeJson)
Theme "Enterprise Design System" applied to Sales Report
Bi-directional sync: add a GitHub Action on Figma library publish webhooks that re-runs token extraction + applyTheme. Design updates flow to BI automatically.

Apply + polish the report

You: The Figma file Executive Dashboard v2, frame Desktop - Full HD, has 4 KPI cards, a bar + line pair, and a 280px slicer rail. Rearrange the Overview page to match, then bind YoY card conditional formatting (green/red)
Copilot:
// MCP: figma.getFrameNodes(fileKey, "Desktop - Full HD")
// MCP: powerbi.updateReportLayout(ws, reportId, "Overview", layoutSpec)
// MCP: powerbi.bindVisual(ws, reportId, "kpi-yoy", {
  measure: "YoY Growth %",
  conditionalFormatting: [{"> 0": "#00875A"}, {"< 0": "#DE350B"}] })
Overview now mirrors Figma: KPI row, bar + line pair, left slicer rail, all on-brand. Repeat once for Product/Customer/Store.
Before / after test: screenshot the default-theme report (Part 4) vs themed report. Same numbers, wildly different trust. Stakeholders approve beautiful faster.

Publish + production checklist

Beauty without guardrails is a demo. Ship it like prod:

  • PBIP validates clean; DAX measures pass 2 test cases each
  • RLS tested per persona (Part 3 roles still enforced after theme change)
  • Visual regression snapshots updated to themed pages
  • Figma token sync Action scheduled; theme version pinned in repo
  • Automation SP least-privilege; secrets in Key Vault / OIDC (local dev stays user-auth)
  • Prod deploy requires approval; refresh + anomaly agents alerting
That's the whole run: Blob shortcut + SQL snapshot to silver (joined) to gold to model to report to beautiful report. That end-to-end line is the series.

I hope this helps someone with the same lakehouse-to-report mess I had. I also want to thank the Fabric and Power BI product folks whose docs and Bridge samples made this verifiable instead of hand-wavy.

As usual, send me a note if you need to know more about this. Thank you!

← Part 4: Build the Report Back to All Articles