Power BI Report Design
Use pbir for every report mutation. The pbir-format skill is read-only schema context.
If the CLI is unavailable or lacks an operation, stop and report the gap.
Best practices and guidelines for Power BI report design. Follow these guidelines strictly to avoid generic, poorly formatted reports ("Power BI Slop").
Be innovative, pushing boundaries while adhering to data visualization rules and guidelines. Work within Power BI's constraints, aiming for simplicity and effectiveness over aesthetics and decoration. Focus reports, pages, and visuals on answering specific questions and minimizing cognitive load -- not on looking "pretty and impressive".
When a user request contradicts these guidelines, push back and explain better alternatives. The goal is to inform the user of options that lead to improved outcomes.
Design identity (commit before layout)
Before any layout work, lock the report's identity so every later choice has something to cite:
- Pick one tone ... a committed ink budget (
restrained, corporate, editorial, or technical) that fixes accent count, saturation, gridline weight, and how forward annotation gets
- Pick one signature (two at most) ... a single recurring element (header band, single-accent-hue rule, fixed nav rail, KPI silhouette, callout style, target-line convention) repeated identically on every page, so the report reads as one artifact
- Route each page to one shape by the question it answers (
summary, monitoring, exploration, comparison, narrative)
Recording tone and signature once is what turns "use muted colors" into a propagating decision. See references/design-identity.md for the tone budgets and signature catalog, and references/page-shapes.md for routing each page to a shape. Serialize the identity into the theme via the modifying-theme-json skill, not into per-visual overrides.
Core rules
- 3-30-300 Rule: The most important and least detailed information should be in the top-left (KPIs, cards, etc.) while the least important and most detailed information should be in the bottom-right
- Titles: All report pages should have a title using a
textBox visualType or a title in a background image added to the report page canvas
- Visual positioning, alignment, and spacing: All visuals must have equal spacing between them and equal spacing between the edge of the page (the margin). If visuals are unaligned or this spacing is unequal, fix it to ensure alignment and equal spacing
- Themes: Reports should use a theme that differs from the default Power BI themes; a suggested theme is the
sqlbi theme (see the modifying-theme-json skill for applying templates). Themes are preferred because they provide a set of default styles for all charts that can adhere to good design practices and brand or style guidelines
- Semantic Models: Reports in Power BI are complex. They are dependant on an underlying semantic model (either in the .SemanticModel folder, called a "thick report" or a published model in Power BI/Fabric, called a "thin report"). Much of the functionality from a Power BI report comes from its semantic model design or DAX code
- Report extensions, or thin report measures: It is possible to create calculation logic in Power BI report, called "thin report measures" or "visual calculations". These should be used sparingly and only for "report-specific" scenarios
- Visual fields: All data visuals should have field bindings, and all field bindings should be for fields that actually exist in the model; there is no reason for visuals to exist that have no fields bound
- Chart selection: Make smart choices about what visuals to use for each scenario. Visual vocabulary is essential for this skill.
- Use of color: Color and formatting decisions must cite the locked identity (the chosen tone and signature), not be picked per visual. Colors come from the theme (themedataColor) rather than inline hex, so the identity propagates and re-themes cleanly. Colors should be muted and soft; colors that implicitly encode meaning (like red=bad, green=good) should be avoided unless using them for that encoding. Consider colorblindness and use accessible palettes (blues instead of greens with reds, for instance).
- Pre-attentive attributes: Styles and colors should be used to steer and direct attention, and not to decorate charts. Formatting of visuals should be intentional and not purely aesthetic. Styles should where possible be stored in the theme and not in bespoke visual configuration.
- Fonts: Prefer Segoe UI and Segoe UI Semibold. Do not use custom fonts, since they aren't guaranteed to render on user computers. Evaluate whether fonts are sufficiently large to be readable given the visual and page size.
- Page intent: Route each page to exactly one shape by the question it answers (see
references/page-shapes.md). A page trying to answer two questions is two pages.
The insight test (run before building a chart)
A chart is cheap to reject on the spec and expensive to reject on the canvas. Run these five tests against the proposed chart, before any pbir add visual. They are rejection tests, not a generation quota: a chart that passes all five gets built as specced, and no extra candidates are generated to compete with it.
- The title states the insight, not the shape. "Additions peaked in 2019 and have halved since" is a title; "Titles by year" is a caption for an axis that already says so.
- Every mark carries a measure. A mark placed for texture, balance, or to fill a panel is decoration. Cut it.
- Every figure has a denominator, and one denominator. A percentage whose base is unstated is unreadable; a panel that mixes two bases in one frame is wrong, not merely unclear.
- No panel restates its neighbour. If a tooltip, card, or sub-chart shows only what the visual it sits beside already prints, it is a duplicate. This is the most common failure and the easiest to see on the spec.
- The title points the same direction as its own measure. A title claiming growth over a measure that falls is a defect that survives every schema validation, because nothing in the JSON knows what the words mean.
When a chart fails: simplify it to a single comparison, or cut it. Do not repair it in place through successive renders; that is how one bad panel consumes an evening. Record which you chose, and why, in the plan's fog list (see the pbi-plan skill) so the decision is not rediscovered next session.
The test is deliberately blind to how good the chart could be. It discriminates on whether the chart says something, which a render cannot tell you any better than the spec can.
Page Layout Guidelines
Check Page Size Before Modifying
Always query the actual page dimensions before adding or repositioning visuals. Do not assume a page is 1280x720 or 1920x1080 -- templates and existing reports vary. The object model validates that visuals fit within page bounds, so setting position or size without knowing the page dimensions will cause errors. Check the page's page.json file for width and height properties, or use the object model (page.width, page.height) to confirm dimensions first. When resizing visuals via the object model, set width/height before x/y to avoid intermediate states that exceed bounds.
Standard Page Size
- Width: 1280px (default)
- Height: 720px (16:9 aspect ratio)
- Alternative: 1920x1080 for high-resolution displays
Visual Spacing
- Minimum gap between visuals: 16px
- Edge margins: 24-32px from page edges
- Consistent alignment: Use grid-based positioning
- Equal spacing is mandatory: Every gap between adjacent visuals (horizontal and vertical) must be the same value. Every margin from the page edge must be the same value. Calculate positions arithmetically from (margin, gap, page_width, page_height) to guarantee alignment. If visuals are misaligned or gaps are unequal, fix immediately -- this is one of the most visible quality signals in a report.
Detail Gradient
Arrange content following the "detail gradient":
+------------------+------------------+
| KPIs/Cards | KPIs/Cards | <- Top: High-level, important
| (Summary) | (Summary) |
+------------------+------------------+
| |
| Charts/Trends | <- Middle: Context, trends
| (Analysis) |
| |
+------------------+------------------+
| |
| Tables/Details | <- Bottom: Detailed data
| (Drill-down) |
| |
+------------------+------------------+
Visual Count Guidelines
- Maximum visuals per page: 12-15 (performance impact)
- Maximum KPIs/Cards: 4-6 at top
- Maximum slicers: 3 per page (use filter pane instead)
Page Titles
Every page should have a title. Create it through pbir:
pbir add title "Report.Report/Page.Page" "Page Title" --width 500
Title positioning:
- Top-left corner, inside the page margin
- Enough height for the chosen font without clipping
- Width: 400-600px (or page width minus margins)
Theme Guidelines
Always Check Theme First
Before modifying visual formatting:
- Check theme wildcards:
visualStyles["*"]["*"]
- Check visual-type overrides:
visualStyles.lineChart["*"]
- Only override in visual.json if truly one-off
When to Modify Theme vs Visual
- All visuals of a type need change -> theme
- Establishing design standards -> theme
- Single visual exception to a theme rule -> visual
- Content-specific highlight (one callout, one reference line) -> visual
Theme Color Usage
Prefer theme colors over hex codes:
// Good - uses theme color
"expr": {"ThemeDataColor": {"ColorId": 1, "Percent": 0}}
// Avoid in visuals - use only in extension measures
"expr": {"Literal": {"Value": "'#118DFF'"}}
Semantic colors (return from extension measures):
"good" - Positive values (green)
"bad" - Negative values (red)
"neutral" - Neutral/unchanged (gray/yellow)
"minColor" - Gradient minimum
"maxColor" - Gradient maximum
Accessibility (WCAG 2.1)
Alt Text
All visuals should include descriptive alt text:
"visualContainerObjects": {
"general": [{
"properties": {
"altText": {
"expr": {"Literal": {"Value": "'Line chart showing monthly sales trend from January to December 2024'"}}
}
}
}]
}
Color Contrast
- Text on background: minimum 4.5:1 contrast ratio
- Large text (18pt+): minimum 3:1 contrast ratio
- Don't rely solely on color to convey meaning
Font Sizes
- Minimum readable: 12pt
- Recommended for charts: 14pt
- Titles: 16-24pt
- KPI values: 24-48pt
Shadows and Motion
- Minimize drop shadows (vestibular issues)
- Avoid animations where possible
- Use
dropShadow.show: false in theme wildcards
Visual Best Practices
Cards and KPIs
A bare number lacks meaning. Every KPI must answer "Is this good or bad?" (target + gap) and "Is it getting better or worse?" (trend). Key rules:
- Position at top or left of page, maximum 5 per page
- Prefer
kpi visual type over card when a target exists -- it has built-in indicator, goal, and trend line data roles
- Always include a target and gap (absolute + percentage). If no target measure exists, discuss with the user: propose adding a prior-year measure to the semantic model (use Tabular Editor CLI or the
tmdl skill), or creating an extension measure as a fallback. Common targets: prior year (CALCULATE([Measure], DATEADD('Date'[Date], -1, YEAR))), budget, or rolling average
- If no clear target exists, ask the user -- do not leave KPIs bare. Discuss whether prior period, budget, or a custom threshold makes sense
- Apply conditional formatting to the gap, not the primary value
- Pair color with a secondary cue (arrow/icon) for accessibility
- Round aggressively at summary level ("518M" not "517,893,412")
- Choose actionable metrics that drive decisions over vanity metrics (apply the "20% change test": if this number changed 20%, should someone act differently?)
- Hide redundant auto-generated subtitles
- Use SVG extension measures for inline icons (see the
svg-visuals skill in the custom-visuals plugin)
For complete guidance on KPI design, targets, trends, formatting hierarchy, icon implementation, accessible palettes, and anti-patterns, consult references/cards-and-kpis.md.
Charts
- Sort by value descending (unless time-based)
- Minimize gridlines and axes clutter
- Use muted colors for non-essential elements
- Highlight key data points sparingly
For chart-type selection (encoding hierarchy, Cleveland-McGill ranking), data-label discipline, and small-multiples guidance, consult references/chart-selection.md.
Refuse common LLM defaults. Gauge-as-KPI, monochrome categorical bars, missing sort, card walls, raw field names as titles, inline hex, off-grid drift, dual y-axis, 3D, and oversized pies are plausible-looking attractors that defeat the reader. When a request reaches for one, push back with the better option; see references/anti-patterns.md.
Tables and Matrices
Tables require deliberate design -- "easy to create" differs from "easy to read." Key rules:
- Position at bottom for detail drill-down (3-30-300 rule)
- Decision-making first: define the question, audience, and action before building
- Use
matrix over tableEx when 2+ categorical columns form a hierarchy (Key Account > Account > Product)
- Subtract, don't add: remove gridlines and heavy banding; let whitespace separate rows
- Sort by the most important measure (often variance), not alphabetically
- Apply data bars to the primary measure column for magnitude scanning
- Apply color scales to variance columns only -- formatting everything means formatting nothing
- Add sparklines where temporal context ("improving or declining?") matters
- Show full precision (no display units) -- tables are where readers go for detail
- Indent hierarchy row labels with U+00A0; leading ASCII spaces are trimmed on render, and filters on the label then stop matching
For complete guidance on table vs matrix selection, formatting philosophy, conditional formatting techniques, sparklines, hierarchy design, row-label indentation, and anti-patterns, consult references/tables-and-matrices.md.
Slicers
- Maximum 3 per page
- Position consistently (top or left)
- Use filter pane for additional filters
- Consider sync slicers across pages
Filter Pane
The filter pane has its own information architecture beyond color and chrome. Key decisions: lock vs hide per filter card, how to name cards without renaming model fields, and report-level settings (Apply button, search, allow-change-filter-type). See references/filter-pane.md.
Mobile
Power BI does not reflow a desktop page for portrait; the phone layout is a hand-picked subset re-placed on a narrow grid. Nothing renders on a phone until explicitly opted in with a mobile.json. See references/mobile.md for the subset-selection model and file mechanics.
Report Evaluation Criteria
When asked to evaluate or audit a report, focus on objective criteria. Subjective evaluation is difficult for AI -- the report cannot be "seen" directly, and there is no intuitive sense of aesthetics, cognitive load, or effectiveness. Emphasize this limitation to users.
Objective Checklist
- Page count: More than 5-8 pages is typically excessive
- Visuals per page: Count is a proxy; query cost per visual is the driver (see
references/layout-guidelines.md performance section). Textboxes, images, shapes, and buttons do not emit queries.
- Theme usage: Reports should use a custom theme for consistent formatting
- Layout consistency:
- Equal spacing between visuals?
- Page has a title?
- Follows detail gradient (important top-left, detailed bottom-right)?
- Cards/KPIs at top or left, fewer than 4-6?
- Fewer than 3 slicers (use filter pane instead)?
- Helpful elements (refresh date, links, context)?
- Color effectiveness:
- Conditional formatting used sparingly (not causing overload)?
- Colors muted and passive (not loud and bright)?
- Negative-sentiment colors (red, orange) only for negative values?
- Information:ink ratio: Non-essential elements reduced (lighter gridlines, disabled unnecessary axes/labels)?
- Readability: Font sizes sufficient for all elements?
- Accessibility: Minimal shadows to avoid vestibular issues?
- Font consistency: Limited font sizes, simple readable fonts that work on all devices?
- Sorting: Visuals sorted descending unless there's a reason otherwise (time-based, etc.)?
Evaluation Output
When evaluating, provide:
- Issues found with specific locations
- Severity (critical, warning, suggestion)
- Recommended fixes with commands or patterns
The design gate
Before declaring a design done, run the closing gate in references/quality-gate.md. It is not the planning-stage checklist that runs before the build; it runs against the finished artifact and decides whether it ships. It verifies the identity propagated, every page has one intent, spacing and margins are equal and on-grid, callouts are backed by model evidence, and accessibility is met. Because an agent cannot see the canvas, pair the gate with the screenshot-review loop in the pbir-cli skill: render the pages, look, and confirm what the JSON inferred.
Implementing an approved design
Once a design is agreed, the failure mode changes. It stops being "is this good" and becomes "did we
build the thing we agreed, without breaking what was already there". The rules for that phase are in
references/implementing-a-design.md: apply the delta only and never replace existing chrome,
check what else consumes a shared object before editing it, validate and then actually look before
claiming done, defer cleanup rather than fighting a file lock, and write a reverse brief from the
report's current state when another design round is needed. They are technique-agnostic and apply to
any design source.
Common Design Issues
Issue: Cognitive Overload
Symptoms: Too many colors, visuals, or data points
Fix:
- Reduce visual count
- Use muted color palette
- Apply detail gradient
- Hide non-essential elements
Issue: Inconsistent Spacing
Symptoms: Uneven gaps, misaligned visuals
Fix:
- Use grid-based positioning
- Standardize visual sizes
- Apply consistent margins
Issue: Poor Readability
Symptoms: Small fonts, low contrast
Fix:
- Increase font sizes (minimum 12pt)
- Check color contrast ratios
- Use appropriate font weights
References
references/design-identity.md -- Commit-first identity: tone budgets (restrained/corporate/editorial/technical), the signature catalog, and serializing identity into the theme
references/page-shapes.md -- Routing each page to one shape by intent (summary/monitoring/exploration/comparison/narrative): what belongs, what stays off, layout lean
references/anti-patterns.md -- Cross-cutting defaults to refuse (gauge-as-KPI, monochrome bars, missing sort, card walls, raw titles, inline hex, off-grid, dual-axis, 3D, oversized pie) with the repair
references/quality-gate.md -- The design gate: closing checks (identity propagated, one intent per page, equal spacing, evidence-backed callouts, accessibility) in issue/location/severity/fix form
references/cards-and-kpis.md -- KPI card design: targets, gaps, trends, formatting hierarchy, icons, accessible palettes, anti-patterns, review checklist
references/tables-and-matrices.md -- Table and matrix design: decision-making framework, subtract-don't-add philosophy, conditional formatting, sorting, sparklines, matrix hierarchies, row-label indentation (U+00A0), anti-patterns
references/layout-guidelines.md -- Canvas dimensions, spacing tiers (intra-group/inter-group/margin), alignment rules, performance cost model
references/visual-colors.md -- Color principles, CF basis decision (gradient vs rules vs field-value vs icons), semantic tokens, accessibility
references/page-titles.md -- Title implementation, accessible title wording, hidden-title/alt-text rule
references/chart-selection.md -- Encoding hierarchy (Cleveland-McGill ranking), chart type routing, data-label discipline, small multiples
references/tooltips-and-annotations.md -- Report-page tooltip design, when not to use one, annotation primitives for guided analytics
references/filter-pane.md -- Lock vs hide, card naming, card order, Applied/Available styling, report-level settings
references/mobile.md -- Phone layout as a curated subset, mobile.json mechanics, what to include/exclude
references/custom-visuals.md -- Build-vs-buy ranking, AppSource/org-store tradeoffs, licensing gaps
references/implementing-a-design.md -- Turning an approved design into a report: delta-only application, preserving existing chrome, shared-object scope discipline, validate-then-look verification, deferred cleanup, and the reverse design brief with its template
Related Skills
Report Structure and Format
pbir-format (pbip plugin) -- PBIR JSON format reference for visual.json, page.json, report.json structure
pbip (pbip plugin) -- PBIP project structure, table/measure renames, project forking
Custom Visuals
Reports often need visuals beyond what Power BI provides natively. Always consider in-repo code paths before reaching for a packaged third-party visual. See references/custom-visuals.md for the build-vs-buy decision and AppSource/org-store tradeoffs.
Skill routing for in-repo code visuals (all in the custom-visuals plugin; add with claude plugin install custom-visuals@power-bi-agentic-dev):
deneb-visuals -- Vega/Vega-Lite declarative visuals; preferred for advanced custom interactive charts (cross-filtering, tooltips, hover)
svg-visuals -- SVG via DAX measures; preferred for inline table/matrix/card graphics with no row cap issues
python-visuals -- matplotlib/seaborn scripts (static PNG); for statistical visualizations that must compute at render time
r-visuals -- ggplot2 scripts (static PNG); where R's statistical ecosystem has no Python peer (forecast, pheatmap, corrplot)
Semantic Model
Reports are highly dependent on the underlying semantic model for their functionality. Most report capabilities -- measures, calculated columns, relationships, hierarchies, row-level security -- are defined in the semantic model, not the report. When designing or modifying reports, you will frequently need to understand or modify the model. Key skills:
tmdl (pbip plugin) -- Direct TMDL file editing for measures, columns, relationships
te-docs (tabular-editor plugin) -- Tabular Editor CLI for model operations
c-sharp-scripting (tabular-editor plugin) -- C# scripts for bulk model changes
bpa-rules (tabular-editor plugin) -- Best Practice Analyzer rules for model quality
connect-pbid (pbi-desktop plugin) -- Connect to Power BI Desktop's local Analysis Services instance for live model queries and modifications
1---2name: pbi-report-design3description: The Power BI report design canon covering design identity, visual hierarchy and the 3-30-300 rule, layout/spacing/alignment, color discipline, chart selection, KPI and card design, tables and matrices, accessibility, and the closing design gate. The shared reference home for report design judgment, routed to by the create-pbi-report, pbir-cli, review-report, modifying-theme-json, and custom-visual skills. Load when committing a design identity or making a design, layout, color, chart-selection, or accessibility decision for a report.4---56# Power BI Report Design78> **Use `pbir` for every report mutation.** The `pbir-format` skill is read-only schema context.9> If the CLI is unavailable or lacks an operation, stop and report the gap.1011Best practices and guidelines for Power BI report design. Follow these guidelines strictly to avoid generic, poorly formatted reports ("Power BI Slop").1213Be innovative, pushing boundaries while adhering to data visualization rules and guidelines. Work within Power BI's constraints, aiming for simplicity and effectiveness over aesthetics and decoration. Focus reports, pages, and visuals on answering specific questions and minimizing cognitive load -- not on looking "pretty and impressive".1415When a user request contradicts these guidelines, push back and explain better alternatives. The goal is to inform the user of options that lead to improved outcomes.1617## Design identity (commit before layout)1819Before any layout work, lock the report's identity so every later choice has something to cite:20211. **Pick one tone** ... a committed ink budget (`restrained`, `corporate`, `editorial`, or `technical`) that fixes accent count, saturation, gridline weight, and how forward annotation gets222. **Pick one signature** (two at most) ... a single recurring element (header band, single-accent-hue rule, fixed nav rail, KPI silhouette, callout style, target-line convention) repeated identically on every page, so the report reads as one artifact233. **Route each page to one shape** by the question it answers (`summary`, `monitoring`, `exploration`, `comparison`, `narrative`)2425Recording tone and signature once is what turns "use muted colors" into a propagating decision. See `references/design-identity.md` for the tone budgets and signature catalog, and `references/page-shapes.md` for routing each page to a shape. Serialize the identity into the theme via the `modifying-theme-json` skill, not into per-visual overrides.2627## Core rules28291. **3-30-300 Rule:** The most important and least detailed information should be in the top-left (KPIs, cards, etc.) while the least important and most detailed information should be in the bottom-right302. **Titles:** All report pages should have a title using a `textBox` visualType or a title in a background image added to the report page canvas313. **Visual positioning, alignment, and spacing:** All visuals must have equal spacing between them and equal spacing between the edge of the page (the margin). If visuals are unaligned or this spacing is unequal, fix it to ensure alignment and equal spacing324. **Themes:** Reports should use a theme that differs from the default Power BI themes; a suggested theme is the `sqlbi` theme (see the `modifying-theme-json` skill for applying templates). Themes are preferred because they provide a set of default styles for all charts that can adhere to good design practices and brand or style guidelines335. **Semantic Models:** Reports in Power BI are complex. They are dependant on an underlying semantic model (either in the .SemanticModel folder, called a "thick report" or a published model in Power BI/Fabric, called a "thin report"). Much of the functionality from a Power BI report comes from its semantic model design or DAX code346. **Report extensions, or thin report measures:** It is possible to create calculation logic in Power BI report, called "thin report measures" or "visual calculations". These should be used sparingly and only for "report-specific" scenarios357. **Visual fields:** All data visuals should have field bindings, and all field bindings should be for fields that actually exist in the model; there is no reason for visuals to exist that have no fields bound368. **Chart selection:** Make smart choices about what visuals to use for each scenario. Visual vocabulary is essential for this skill.379. **Use of color:** Color and formatting decisions must cite the locked identity (the chosen tone and signature), not be picked per visual. Colors come from the theme (themedataColor) rather than inline hex, so the identity propagates and re-themes cleanly. Colors should be muted and soft; colors that implicitly encode meaning (like red=bad, green=good) should be avoided unless using them for that encoding. Consider colorblindness and use accessible palettes (blues instead of greens with reds, for instance).3810. **Pre-attentive attributes:** Styles and colors should be used to steer and direct attention, and not to decorate charts. Formatting of visuals should be intentional and not purely aesthetic. Styles should where possible be stored in the theme and not in bespoke visual configuration.3911. **Fonts:** Prefer *Segoe UI* and *Segoe UI Semibold*. Do not use custom fonts, since they aren't guaranteed to render on user computers. Evaluate whether fonts are sufficiently large to be readable given the visual and page size.4012. **Page intent:** Route each page to exactly one shape by the question it answers (see `references/page-shapes.md`). A page trying to answer two questions is two pages.4142## The insight test (run before building a chart)4344A chart is cheap to reject on the spec and expensive to reject on the canvas. Run these five tests against the *proposed* chart, before any `pbir add visual`. They are rejection tests, not a generation quota: a chart that passes all five gets built as specced, and no extra candidates are generated to compete with it.45461. **The title states the insight, not the shape.** "Additions peaked in 2019 and have halved since" is a title; "Titles by year" is a caption for an axis that already says so.472. **Every mark carries a measure.** A mark placed for texture, balance, or to fill a panel is decoration. Cut it.483. **Every figure has a denominator, and one denominator.** A percentage whose base is unstated is unreadable; a panel that mixes two bases in one frame is wrong, not merely unclear.494. **No panel restates its neighbour.** If a tooltip, card, or sub-chart shows only what the visual it sits beside already prints, it is a duplicate. This is the most common failure and the easiest to see on the spec.505. **The title points the same direction as its own measure.** A title claiming growth over a measure that falls is a defect that survives every schema validation, because nothing in the JSON knows what the words mean.5152**When a chart fails:** simplify it to a single comparison, or cut it. Do not repair it in place through successive renders; that is how one bad panel consumes an evening. Record which you chose, and why, in the plan's fog list (see the **`pbi-plan`** skill) so the decision is not rediscovered next session.5354The test is deliberately blind to how good the chart could be. It discriminates on whether the chart says something, which a render cannot tell you any better than the spec can.5556## Page Layout Guidelines5758### Check Page Size Before Modifying5960**Always query the actual page dimensions before adding or repositioning visuals.** Do not assume a page is 1280x720 or 1920x1080 -- templates and existing reports vary. The object model validates that visuals fit within page bounds, so setting position or size without knowing the page dimensions will cause errors. Check the page's `page.json` file for `width` and `height` properties, or use the object model (`page.width`, `page.height`) to confirm dimensions first. When resizing visuals via the object model, set `width`/`height` before `x`/`y` to avoid intermediate states that exceed bounds.6162### Standard Page Size6364- **Width:** 1280px (default)65- **Height:** 720px (16:9 aspect ratio)66- Alternative: 1920x1080 for high-resolution displays6768### Visual Spacing6970- **Minimum gap between visuals:** 16px71- **Edge margins:** 24-32px from page edges72- **Consistent alignment:** Use grid-based positioning73- **Equal spacing is mandatory:** Every gap between adjacent visuals (horizontal and vertical) must be the same value. Every margin from the page edge must be the same value. Calculate positions arithmetically from (margin, gap, page_width, page_height) to guarantee alignment. If visuals are misaligned or gaps are unequal, fix immediately -- this is one of the most visible quality signals in a report.7475### Detail Gradient7677Arrange content following the "detail gradient":7879```80+------------------+------------------+81| KPIs/Cards | KPIs/Cards | <- Top: High-level, important82| (Summary) | (Summary) |83+------------------+------------------+84| |85| Charts/Trends | <- Middle: Context, trends86| (Analysis) |87| |88+------------------+------------------+89| |90| Tables/Details | <- Bottom: Detailed data91| (Drill-down) |92| |93+------------------+------------------+94```9596### Visual Count Guidelines9798- **Maximum visuals per page:** 12-15 (performance impact)99- **Maximum KPIs/Cards:** 4-6 at top100- **Maximum slicers:** 3 per page (use filter pane instead)101102## Page Titles103104Every page should have a title. Create it through `pbir`:105106```bash107pbir add title "Report.Report/Page.Page" "Page Title" --width 500108```109110**Title positioning:**111112- Top-left corner, inside the page margin113- Enough height for the chosen font without clipping114- Width: 400-600px (or page width minus margins)115116## Theme Guidelines117118### Always Check Theme First119120Before modifying visual formatting:1211221. Check theme wildcards: `visualStyles["*"]["*"]`1232. Check visual-type overrides: `visualStyles.lineChart["*"]`1243. Only override in visual.json if truly one-off125126### When to Modify Theme vs Visual127128- All visuals of a type need change -> theme129- Establishing design standards -> theme130- Single visual exception to a theme rule -> visual131- Content-specific highlight (one callout, one reference line) -> visual132133### Theme Color Usage134135**Prefer theme colors over hex codes:**136137```json138// Good - uses theme color139"expr": {"ThemeDataColor": {"ColorId": 1, "Percent": 0}}140141// Avoid in visuals - use only in extension measures142"expr": {"Literal": {"Value": "'#118DFF'"}}143```144145**Semantic colors (return from extension measures):**146147- `"good"` - Positive values (green)148- `"bad"` - Negative values (red)149- `"neutral"` - Neutral/unchanged (gray/yellow)150- `"minColor"` - Gradient minimum151- `"maxColor"` - Gradient maximum152153## Accessibility (WCAG 2.1)154155### Alt Text156157All visuals should include descriptive alt text:158159```json160"visualContainerObjects": {161 "general": [{162 "properties": {163 "altText": {164 "expr": {"Literal": {"Value": "'Line chart showing monthly sales trend from January to December 2024'"}}165 }166 }167 }]168}169```170171### Color Contrast172173- Text on background: minimum 4.5:1 contrast ratio174- Large text (18pt+): minimum 3:1 contrast ratio175- Don't rely solely on color to convey meaning176177### Font Sizes178179- **Minimum readable:** 12pt180- **Recommended for charts:** 14pt181- **Titles:** 16-24pt182- **KPI values:** 24-48pt183184### Shadows and Motion185186- Minimize drop shadows (vestibular issues)187- Avoid animations where possible188- Use `dropShadow.show: false` in theme wildcards189190## Visual Best Practices191192### Cards and KPIs193194A bare number lacks meaning. Every KPI must answer "Is this good or bad?" (target + gap) and "Is it getting better or worse?" (trend). Key rules:195196- Position at top or left of page, maximum 5 per page197- **Prefer `kpi` visual type over `card`** when a target exists -- it has built-in indicator, goal, and trend line data roles198- Always include a **target** and **gap** (absolute + percentage). If no target measure exists, discuss with the user: propose adding a prior-year measure to the semantic model (use Tabular Editor CLI or the `tmdl` skill), or creating an extension measure as a fallback. Common targets: prior year (`CALCULATE([Measure], DATEADD('Date'[Date], -1, YEAR))`), budget, or rolling average199- **If no clear target exists, ask the user** -- do not leave KPIs bare. Discuss whether prior period, budget, or a custom threshold makes sense200- Apply conditional formatting to the **gap**, not the primary value201- Pair color with a secondary cue (arrow/icon) for accessibility202- Round aggressively at summary level ("518M" not "517,893,412")203- Choose **actionable metrics** that drive decisions over vanity metrics (apply the "20% change test": if this number changed 20%, should someone act differently?)204- Hide redundant auto-generated subtitles205- Use SVG extension measures for inline icons (see the `svg-visuals` skill in the **custom-visuals** plugin)206207For complete guidance on KPI design, targets, trends, formatting hierarchy, icon implementation, accessible palettes, and anti-patterns, consult **`references/cards-and-kpis.md`**.208209### Charts210211- Sort by value descending (unless time-based)212- Minimize gridlines and axes clutter213- Use muted colors for non-essential elements214- Highlight key data points sparingly215216For chart-type selection (encoding hierarchy, Cleveland-McGill ranking), data-label discipline, and small-multiples guidance, consult **`references/chart-selection.md`**.217218**Refuse common LLM defaults.** Gauge-as-KPI, monochrome categorical bars, missing sort, card walls, raw field names as titles, inline hex, off-grid drift, dual y-axis, 3D, and oversized pies are plausible-looking attractors that defeat the reader. When a request reaches for one, push back with the better option; see **`references/anti-patterns.md`**.219220### Tables and Matrices221222Tables require deliberate design -- "easy to create" differs from "easy to read." Key rules:223224- Position at bottom for detail drill-down (3-30-300 rule)225- **Decision-making first**: define the question, audience, and action before building226- Use `matrix` over `tableEx` when 2+ categorical columns form a hierarchy (Key Account > Account > Product)227- **Subtract, don't add**: remove gridlines and heavy banding; let whitespace separate rows228- Sort by the most important measure (often variance), not alphabetically229- Apply **data bars** to the primary measure column for magnitude scanning230- Apply **color scales** to variance columns only -- formatting everything means formatting nothing231- Add sparklines where temporal context ("improving or declining?") matters232- Show full precision (no display units) -- tables are where readers go for detail233- Indent hierarchy row labels with **U+00A0**; leading ASCII spaces are trimmed on render, and filters on the label then stop matching234235For complete guidance on table vs matrix selection, formatting philosophy, conditional formatting techniques, sparklines, hierarchy design, row-label indentation, and anti-patterns, consult **`references/tables-and-matrices.md`**.236237### Slicers238239- Maximum 3 per page240- Position consistently (top or left)241- Use filter pane for additional filters242- Consider sync slicers across pages243244### Filter Pane245246The filter pane has its own information architecture beyond color and chrome. Key decisions: lock vs hide per filter card, how to name cards without renaming model fields, and report-level settings (Apply button, search, allow-change-filter-type). See **`references/filter-pane.md`**.247248### Mobile249250Power BI does not reflow a desktop page for portrait; the phone layout is a hand-picked subset re-placed on a narrow grid. Nothing renders on a phone until explicitly opted in with a `mobile.json`. See **`references/mobile.md`** for the subset-selection model and file mechanics.251252## Report Evaluation Criteria253254When asked to evaluate or audit a report, focus on objective criteria. Subjective evaluation is difficult for AI -- the report cannot be "seen" directly, and there is no intuitive sense of aesthetics, cognitive load, or effectiveness. Emphasize this limitation to users.255256### Objective Checklist2572581. **Page count:** More than 5-8 pages is typically excessive2592. **Visuals per page:** Count is a proxy; query cost per visual is the driver (see `references/layout-guidelines.md` performance section). Textboxes, images, shapes, and buttons do not emit queries.2603. **Theme usage:** Reports should use a custom theme for consistent formatting2614. **Layout consistency:**262 - Equal spacing between visuals?263 - Page has a title?264 - Follows detail gradient (important top-left, detailed bottom-right)?265 - Cards/KPIs at top or left, fewer than 4-6?266 - Fewer than 3 slicers (use filter pane instead)?267 - Helpful elements (refresh date, links, context)?2685. **Color effectiveness:**269 - Conditional formatting used sparingly (not causing overload)?270 - Colors muted and passive (not loud and bright)?271 - Negative-sentiment colors (red, orange) only for negative values?2726. **Information:ink ratio:** Non-essential elements reduced (lighter gridlines, disabled unnecessary axes/labels)?2737. **Readability:** Font sizes sufficient for all elements?2748. **Accessibility:** Minimal shadows to avoid vestibular issues?2759. **Font consistency:** Limited font sizes, simple readable fonts that work on all devices?27610. **Sorting:** Visuals sorted descending unless there's a reason otherwise (time-based, etc.)?277278### Evaluation Output279280When evaluating, provide:281282- Issues found with specific locations283- Severity (critical, warning, suggestion)284- Recommended fixes with commands or patterns285286### The design gate287288Before declaring a design done, run the closing gate in **`references/quality-gate.md`**. It is not the planning-stage checklist that runs before the build; it runs against the finished artifact and decides whether it ships. It verifies the identity propagated, every page has one intent, spacing and margins are equal and on-grid, callouts are backed by model evidence, and accessibility is met. Because an agent cannot see the canvas, pair the gate with the screenshot-review loop in the **`pbir-cli`** skill: render the pages, look, and confirm what the JSON inferred.289290## Implementing an approved design291292Once a design is agreed, the failure mode changes. It stops being "is this good" and becomes "did we293build the thing we agreed, without breaking what was already there". The rules for that phase are in294**`references/implementing-a-design.md`**: apply the delta only and never replace existing chrome,295check what else consumes a shared object before editing it, validate and then actually look before296claiming done, defer cleanup rather than fighting a file lock, and write a reverse brief from the297report's current state when another design round is needed. They are technique-agnostic and apply to298any design source.299300## Common Design Issues301302### Issue: Cognitive Overload303304**Symptoms:** Too many colors, visuals, or data points305306**Fix:**307308- Reduce visual count309- Use muted color palette310- Apply detail gradient311- Hide non-essential elements312313### Issue: Inconsistent Spacing314315**Symptoms:** Uneven gaps, misaligned visuals316317**Fix:**318319- Use grid-based positioning320- Standardize visual sizes321- Apply consistent margins322323### Issue: Poor Readability324325**Symptoms:** Small fonts, low contrast326327**Fix:**328329- Increase font sizes (minimum 12pt)330- Check color contrast ratios331- Use appropriate font weights332333## References334335- **`references/design-identity.md`** -- Commit-first identity: tone budgets (restrained/corporate/editorial/technical), the signature catalog, and serializing identity into the theme336- **`references/page-shapes.md`** -- Routing each page to one shape by intent (summary/monitoring/exploration/comparison/narrative): what belongs, what stays off, layout lean337- **`references/anti-patterns.md`** -- Cross-cutting defaults to refuse (gauge-as-KPI, monochrome bars, missing sort, card walls, raw titles, inline hex, off-grid, dual-axis, 3D, oversized pie) with the repair338- **`references/quality-gate.md`** -- The design gate: closing checks (identity propagated, one intent per page, equal spacing, evidence-backed callouts, accessibility) in issue/location/severity/fix form339- **`references/cards-and-kpis.md`** -- KPI card design: targets, gaps, trends, formatting hierarchy, icons, accessible palettes, anti-patterns, review checklist340- **`references/tables-and-matrices.md`** -- Table and matrix design: decision-making framework, subtract-don't-add philosophy, conditional formatting, sorting, sparklines, matrix hierarchies, row-label indentation (U+00A0), anti-patterns341- **`references/layout-guidelines.md`** -- Canvas dimensions, spacing tiers (intra-group/inter-group/margin), alignment rules, performance cost model342- **`references/visual-colors.md`** -- Color principles, CF basis decision (gradient vs rules vs field-value vs icons), semantic tokens, accessibility343- **`references/page-titles.md`** -- Title implementation, accessible title wording, hidden-title/alt-text rule344- **`references/chart-selection.md`** -- Encoding hierarchy (Cleveland-McGill ranking), chart type routing, data-label discipline, small multiples345- **`references/tooltips-and-annotations.md`** -- Report-page tooltip design, when not to use one, annotation primitives for guided analytics346- **`references/filter-pane.md`** -- Lock vs hide, card naming, card order, Applied/Available styling, report-level settings347- **`references/mobile.md`** -- Phone layout as a curated subset, `mobile.json` mechanics, what to include/exclude348- **`references/custom-visuals.md`** -- Build-vs-buy ranking, AppSource/org-store tradeoffs, licensing gaps349- **`references/implementing-a-design.md`** -- Turning an approved design into a report: delta-only application, preserving existing chrome, shared-object scope discipline, validate-then-look verification, deferred cleanup, and the reverse design brief with its template350351## Related Skills352353### Report Structure and Format354355- **`pbir-format`** (pbip plugin) -- PBIR JSON format reference for visual.json, page.json, report.json structure356- **`pbip`** (pbip plugin) -- PBIP project structure, table/measure renames, project forking357358### Custom Visuals359360Reports often need visuals beyond what Power BI provides natively. Always consider in-repo code paths before reaching for a packaged third-party visual. See **`references/custom-visuals.md`** for the build-vs-buy decision and AppSource/org-store tradeoffs.361362Skill routing for in-repo code visuals (all in the **custom-visuals** plugin; add with `claude plugin install custom-visuals@power-bi-agentic-dev`):363- **`deneb-visuals`** -- Vega/Vega-Lite declarative visuals; preferred for advanced custom interactive charts (cross-filtering, tooltips, hover)364- **`svg-visuals`** -- SVG via DAX measures; preferred for inline table/matrix/card graphics with no row cap issues365- **`python-visuals`** -- matplotlib/seaborn scripts (static PNG); for statistical visualizations that must compute at render time366- **`r-visuals`** -- ggplot2 scripts (static PNG); where R's statistical ecosystem has no Python peer (forecast, pheatmap, corrplot)367368### Semantic Model369370Reports are highly dependent on the underlying semantic model for their functionality. Most report capabilities -- measures, calculated columns, relationships, hierarchies, row-level security -- are defined in the semantic model, not the report. When designing or modifying reports, you will frequently need to understand or modify the model. Key skills:371372- **`tmdl`** (pbip plugin) -- Direct TMDL file editing for measures, columns, relationships373- **`te-docs`** (tabular-editor plugin) -- Tabular Editor CLI for model operations374- **`c-sharp-scripting`** (tabular-editor plugin) -- C# scripts for bulk model changes375- **`bpa-rules`** (tabular-editor plugin) -- Best Practice Analyzer rules for model quality376- **`connect-pbid`** (pbi-desktop plugin) -- Connect to Power BI Desktop's local Analysis Services instance for live model queries and modifications