[{"data":1,"prerenderedAt":2908},["ShallowReactive",2],{"install-powerbi":3},{"data":4,"body":7,"toc":2891},{"title":5,"description":6},"TUX for Power BI","Drop-in report themes and PBIR fragments, generated from\ndesign\u002Ftokens.json. A Power BI report built with these renders the same\nsystem as a TUX web page — same palette, same type lanes, same chart\nfoundations.",{"type":8,"children":9},"root",[10,18,33,69,73,80,92,126,152,273,285,288,294,307,342,602,621,858,870,912,954,957,963,989,994,1027,1053,1058,1067,1116,1156,1169,1174,1214,1226,1271,1296,1323,1326,1332,1343,1348,1427,1438,1450,1453,1459,1470,1479,1508,1789,1807,1814,1842,1851,1879,1977,1989,2010,2033,2039,2096,2121,2126,2146,2149,2155,2166,2297,2300,2306,2334,2339,2344,2390,2416,2419,2425,2454,2499,2502,2508,2543,2563,2575,2578,2584,2597,2679,2692,2695,2701,2836,2839,2845,2872,2885],{"type":11,"tag":12,"props":13,"children":15},"element","h1",{"id":14},"tux-for-power-bi",[16],{"type":17,"value":5},"text",{"type":11,"tag":19,"props":20,"children":21},"p",{},[22,24,31],{"type":17,"value":23},"Drop-in report themes and PBIR fragments, generated from\n",{"type":11,"tag":25,"props":26,"children":28},"code",{"className":27},[],[29],{"type":17,"value":30},"design\u002Ftokens.json",{"type":17,"value":32},". A Power BI report built with these renders the same\nsystem as a TUX web page — same palette, same type lanes, same chart\nfoundations.",{"type":11,"tag":19,"props":34,"children":35},{},[36,38,44,46,51,53,59,61,67],{"type":17,"value":37},"Everything here is ",{"type":11,"tag":39,"props":40,"children":41},"strong",{},[42],{"type":17,"value":43},"generated and committed",{"type":17,"value":45},". Do not hand-edit: edit\n",{"type":11,"tag":25,"props":47,"children":49},{"className":48},[],[50],{"type":17,"value":30},{"type":17,"value":52},", run ",{"type":11,"tag":25,"props":54,"children":56},{"className":55},[],[57],{"type":17,"value":58},"npm run build:kit",{"type":17,"value":60},", commit both.\n",{"type":11,"tag":25,"props":62,"children":64},{"className":63},[],[65],{"type":17,"value":66},"tests\u002Ftux-kit-targets.test.ts",{"type":17,"value":68}," fails CI if a committed file drifts from\nits generator.",{"type":11,"tag":70,"props":71,"children":72},"hr",{},[],{"type":11,"tag":74,"props":75,"children":77},"h2",{"id":76},"whats-in-the-box",[78],{"type":17,"value":79},"What's in the box",{"type":11,"tag":81,"props":82,"children":86},"pre",{"className":83,"code":85,"language":17},[84],"language-text","kit\u002Fpowerbi\u002F\n├── tti-theme.json              light  — import into Desktop or Fabric\n├── tti-theme-dark.json         dark\n├── tti-theme-hc.json           high contrast\n└── pbir\u002F\n    ├── schema-lock.json        pinned $schema URLs + format versions\n    ├── geometry.json           canvas, chrome bands, pills, z-order\n    ├── tmdl\u002F                   ThemeMode + TuxThemeColors (light\u002Fdark)\n    ├── dax\u002F                    same module for Desktop's UI\n    ├── shell\u002F                  drop-in page chrome, per canvas variant\n    │   ├── classic\u002F            15 visuals (10 shell + 5 pill templates)\n    │   └── fluent2\u002F\n    └── fragments\u002F\n        ├── tti\u002F                static colours, light\n        ├── tti-dark\u002F           static colours, dark\n        ├── tti-hc\u002F             static colours, high contrast\n        └── themed\u002F             measure-bound — follows an in-report toggle\n",[87],{"type":11,"tag":25,"props":88,"children":90},{"__ignoreMap":89},"",[91],{"type":17,"value":85},{"type":11,"tag":19,"props":93,"children":94},{},[95,100,102,108,110,116,118,124],{"type":11,"tag":39,"props":96,"children":97},{},[98],{"type":17,"value":99},"Themes",{"type":17,"value":101}," are the zero-tooling path: import one file, every native\nvisual inherits the system. They carry ",{"type":11,"tag":25,"props":103,"children":105},{"className":104},[],[106],{"type":17,"value":107},"dataColors",{"type":17,"value":109},", the structural\ncolour set, sentiment and divergent ramps, ",{"type":11,"tag":25,"props":111,"children":113},{"className":112},[],[114],{"type":17,"value":115},"textClasses",{"type":17,"value":117},", and\n",{"type":11,"tag":25,"props":119,"children":121},{"className":120},[],[122],{"type":17,"value":123},"visualStyles",{"type":17,"value":125}," for 26 visual types.",{"type":11,"tag":19,"props":127,"children":128},{},[129,134,136,142,144,150],{"type":11,"tag":39,"props":130,"children":131},{},[132],{"type":17,"value":133},"PBIR fragments",{"type":17,"value":135}," are JSON objects you splice into a ",{"type":11,"tag":25,"props":137,"children":139},{"className":138},[],[140],{"type":17,"value":141},"visual.json",{"type":17,"value":143},". They\ncover the part that repeats on every visual and that a theme file\n",{"type":11,"tag":145,"props":146,"children":147},"em",{},[148],{"type":17,"value":149},"cannot",{"type":17,"value":151}," express.",{"type":11,"tag":153,"props":154,"children":155},"table",{},[156,180],{"type":11,"tag":157,"props":158,"children":159},"thead",{},[160],{"type":11,"tag":161,"props":162,"children":163},"tr",{},[164,170,175],{"type":11,"tag":165,"props":166,"children":167},"th",{},[168],{"type":17,"value":169},"Fragment",{"type":11,"tag":165,"props":171,"children":172},{},[173],{"type":17,"value":174},"Splice as",{"type":11,"tag":165,"props":176,"children":177},{},[178],{"type":17,"value":179},"Applies to",{"type":11,"tag":181,"props":182,"children":183},"tbody",{},[184,218,248],{"type":11,"tag":161,"props":185,"children":186},{},[187,197,206],{"type":11,"tag":188,"props":189,"children":190},"td",{},[191],{"type":11,"tag":25,"props":192,"children":194},{"className":193},[],[195],{"type":17,"value":196},"card-chrome.json",{"type":11,"tag":188,"props":198,"children":199},{},[200],{"type":11,"tag":25,"props":201,"children":203},{"className":202},[],[204],{"type":17,"value":205},"visualContainerObjects",{"type":11,"tag":188,"props":207,"children":208},{},[209,211,216],{"type":17,"value":210},"every ",{"type":11,"tag":39,"props":212,"children":213},{},[214],{"type":17,"value":215},"content",{"type":17,"value":217}," visual",{"type":11,"tag":161,"props":219,"children":220},{},[221,230,239],{"type":11,"tag":188,"props":222,"children":223},{},[224],{"type":11,"tag":25,"props":225,"children":227},{"className":226},[],[228],{"type":17,"value":229},"table-chrome.json",{"type":11,"tag":188,"props":231,"children":232},{},[233],{"type":11,"tag":25,"props":234,"children":236},{"className":235},[],[237],{"type":17,"value":238},"visual.objects",{"type":11,"tag":188,"props":240,"children":241},{},[242],{"type":11,"tag":25,"props":243,"children":245},{"className":244},[],[246],{"type":17,"value":247},"tableEx",{"type":11,"tag":161,"props":249,"children":250},{},[251,260,268],{"type":11,"tag":188,"props":252,"children":253},{},[254],{"type":11,"tag":25,"props":255,"children":257},{"className":256},[],[258],{"type":17,"value":259},"chart-cartesian.json",{"type":11,"tag":188,"props":261,"children":262},{},[263],{"type":11,"tag":25,"props":264,"children":266},{"className":265},[],[267],{"type":17,"value":238},{"type":11,"tag":188,"props":269,"children":270},{},[271],{"type":17,"value":272},"bar \u002F column \u002F line \u002F area \u002F scatter",{"type":11,"tag":19,"props":274,"children":275},{},[276,278,283],{"type":17,"value":277},"Card chrome goes on charts, tables, slicers and cards — ",{"type":11,"tag":39,"props":279,"children":280},{},[281],{"type":17,"value":282},"not",{"type":17,"value":284}," on shell\nshapes, textboxes or buttons, which carry their own.",{"type":11,"tag":70,"props":286,"children":287},{},[],{"type":11,"tag":74,"props":289,"children":291},{"id":290},"applying-a-theme",[292],{"type":17,"value":293},"Applying a theme",{"type":11,"tag":19,"props":295,"children":296},{},[297,299,305],{"type":17,"value":298},"Three edits, and all three are required. A theme file dropped into\n",{"type":11,"tag":25,"props":300,"children":302},{"className":301},[],[303],{"type":17,"value":304},"StaticResources\u002F",{"type":17,"value":306}," without the other two is silently ignored.",{"type":11,"tag":308,"props":309,"children":310},"ol",{},[311,323],{"type":11,"tag":312,"props":313,"children":314},"li",{},[315,317],{"type":17,"value":316},"File at ",{"type":11,"tag":25,"props":318,"children":320},{"className":319},[],[321],{"type":17,"value":322},"\u003CReport>\u002FStaticResources\u002FRegisteredResources\u002Ftti-theme.json",{"type":11,"tag":312,"props":324,"children":325},{},[326,332,334,340],{"type":11,"tag":25,"props":327,"children":329},{"className":328},[],[330],{"type":17,"value":331},"report.json",{"type":17,"value":333}," → ",{"type":11,"tag":25,"props":335,"children":337},{"className":336},[],[338],{"type":17,"value":339},"resourcePackages",{"type":17,"value":341}," entry:",{"type":11,"tag":81,"props":343,"children":347},{"className":344,"code":345,"language":346,"meta":89,"style":89},"language-json shiki shiki-themes material-theme-lighter github-light github-dark","{\n  \"name\": \"RegisteredResources\",\n  \"type\": \"RegisteredResources\",\n  \"items\": [\n    { \"name\": \"tti-theme.json\", \"path\": \"tti-theme.json\", \"type\": \"CustomTheme\" }\n  ]\n}\n","json",[348],{"type":11,"tag":25,"props":349,"children":350},{"__ignoreMap":89},[351,363,410,447,473,584,593],{"type":11,"tag":352,"props":353,"children":356},"span",{"class":354,"line":355},"line",1,[357],{"type":11,"tag":352,"props":358,"children":360},{"style":359},"--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8",[361],{"type":17,"value":362},"{\n",{"type":11,"tag":352,"props":364,"children":366},{"class":354,"line":365},2,[367,373,379,384,389,395,401,405],{"type":11,"tag":352,"props":368,"children":370},{"style":369},"--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[371],{"type":17,"value":372},"  \"",{"type":11,"tag":352,"props":374,"children":376},{"style":375},"--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[377],{"type":17,"value":378},"name",{"type":11,"tag":352,"props":380,"children":381},{"style":369},[382],{"type":17,"value":383},"\"",{"type":11,"tag":352,"props":385,"children":386},{"style":359},[387],{"type":17,"value":388},":",{"type":11,"tag":352,"props":390,"children":392},{"style":391},"--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF",[393],{"type":17,"value":394}," \"",{"type":11,"tag":352,"props":396,"children":398},{"style":397},"--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF",[399],{"type":17,"value":400},"RegisteredResources",{"type":11,"tag":352,"props":402,"children":403},{"style":391},[404],{"type":17,"value":383},{"type":11,"tag":352,"props":406,"children":407},{"style":359},[408],{"type":17,"value":409},",\n",{"type":11,"tag":352,"props":411,"children":413},{"class":354,"line":412},3,[414,418,423,427,431,435,439,443],{"type":11,"tag":352,"props":415,"children":416},{"style":369},[417],{"type":17,"value":372},{"type":11,"tag":352,"props":419,"children":420},{"style":375},[421],{"type":17,"value":422},"type",{"type":11,"tag":352,"props":424,"children":425},{"style":369},[426],{"type":17,"value":383},{"type":11,"tag":352,"props":428,"children":429},{"style":359},[430],{"type":17,"value":388},{"type":11,"tag":352,"props":432,"children":433},{"style":391},[434],{"type":17,"value":394},{"type":11,"tag":352,"props":436,"children":437},{"style":397},[438],{"type":17,"value":400},{"type":11,"tag":352,"props":440,"children":441},{"style":391},[442],{"type":17,"value":383},{"type":11,"tag":352,"props":444,"children":445},{"style":359},[446],{"type":17,"value":409},{"type":11,"tag":352,"props":448,"children":450},{"class":354,"line":449},4,[451,455,460,464,468],{"type":11,"tag":352,"props":452,"children":453},{"style":369},[454],{"type":17,"value":372},{"type":11,"tag":352,"props":456,"children":457},{"style":375},[458],{"type":17,"value":459},"items",{"type":11,"tag":352,"props":461,"children":462},{"style":369},[463],{"type":17,"value":383},{"type":11,"tag":352,"props":465,"children":466},{"style":359},[467],{"type":17,"value":388},{"type":11,"tag":352,"props":469,"children":470},{"style":359},[471],{"type":17,"value":472}," [\n",{"type":11,"tag":352,"props":474,"children":476},{"class":354,"line":475},5,[477,482,486,491,495,499,503,508,512,517,521,526,530,534,538,542,546,550,554,558,562,566,570,575,579],{"type":11,"tag":352,"props":478,"children":479},{"style":359},[480],{"type":17,"value":481},"    {",{"type":11,"tag":352,"props":483,"children":484},{"style":369},[485],{"type":17,"value":394},{"type":11,"tag":352,"props":487,"children":489},{"style":488},"--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[490],{"type":17,"value":378},{"type":11,"tag":352,"props":492,"children":493},{"style":369},[494],{"type":17,"value":383},{"type":11,"tag":352,"props":496,"children":497},{"style":359},[498],{"type":17,"value":388},{"type":11,"tag":352,"props":500,"children":501},{"style":391},[502],{"type":17,"value":394},{"type":11,"tag":352,"props":504,"children":505},{"style":397},[506],{"type":17,"value":507},"tti-theme.json",{"type":11,"tag":352,"props":509,"children":510},{"style":391},[511],{"type":17,"value":383},{"type":11,"tag":352,"props":513,"children":514},{"style":359},[515],{"type":17,"value":516},",",{"type":11,"tag":352,"props":518,"children":519},{"style":369},[520],{"type":17,"value":394},{"type":11,"tag":352,"props":522,"children":523},{"style":488},[524],{"type":17,"value":525},"path",{"type":11,"tag":352,"props":527,"children":528},{"style":369},[529],{"type":17,"value":383},{"type":11,"tag":352,"props":531,"children":532},{"style":359},[533],{"type":17,"value":388},{"type":11,"tag":352,"props":535,"children":536},{"style":391},[537],{"type":17,"value":394},{"type":11,"tag":352,"props":539,"children":540},{"style":397},[541],{"type":17,"value":507},{"type":11,"tag":352,"props":543,"children":544},{"style":391},[545],{"type":17,"value":383},{"type":11,"tag":352,"props":547,"children":548},{"style":359},[549],{"type":17,"value":516},{"type":11,"tag":352,"props":551,"children":552},{"style":369},[553],{"type":17,"value":394},{"type":11,"tag":352,"props":555,"children":556},{"style":488},[557],{"type":17,"value":422},{"type":11,"tag":352,"props":559,"children":560},{"style":369},[561],{"type":17,"value":383},{"type":11,"tag":352,"props":563,"children":564},{"style":359},[565],{"type":17,"value":388},{"type":11,"tag":352,"props":567,"children":568},{"style":391},[569],{"type":17,"value":394},{"type":11,"tag":352,"props":571,"children":572},{"style":397},[573],{"type":17,"value":574},"CustomTheme",{"type":11,"tag":352,"props":576,"children":577},{"style":391},[578],{"type":17,"value":383},{"type":11,"tag":352,"props":580,"children":581},{"style":359},[582],{"type":17,"value":583}," }\n",{"type":11,"tag":352,"props":585,"children":587},{"class":354,"line":586},6,[588],{"type":11,"tag":352,"props":589,"children":590},{"style":359},[591],{"type":17,"value":592},"  ]\n",{"type":11,"tag":352,"props":594,"children":596},{"class":354,"line":595},7,[597],{"type":11,"tag":352,"props":598,"children":599},{"style":359},[600],{"type":17,"value":601},"}\n",{"type":11,"tag":308,"props":603,"children":604},{"start":412},[605],{"type":11,"tag":312,"props":606,"children":607},{},[608,613,614,620],{"type":11,"tag":25,"props":609,"children":611},{"className":610},[],[612],{"type":17,"value":331},{"type":17,"value":333},{"type":11,"tag":25,"props":615,"children":617},{"className":616},[],[618],{"type":17,"value":619},"themeCollection.customTheme",{"type":17,"value":388},{"type":11,"tag":81,"props":622,"children":624},{"className":344,"code":623,"language":346,"meta":89,"style":89},"\"customTheme\": {\n  \"name\": \"tti-theme.json\",\n  \"type\": \"RegisteredResources\",\n  \"reportVersionAtImport\": { \"visual\": \"2.9.0\", \"page\": \"2.3.1\", \"report\": \"3.3.0\" }\n}\n",[625],{"type":11,"tag":25,"props":626,"children":627},{"__ignoreMap":89},[628,654,689,724,851],{"type":11,"tag":352,"props":629,"children":630},{"class":354,"line":355},[631,635,640,644,650],{"type":11,"tag":352,"props":632,"children":633},{"style":391},[634],{"type":17,"value":383},{"type":11,"tag":352,"props":636,"children":637},{"style":397},[638],{"type":17,"value":639},"customTheme",{"type":11,"tag":352,"props":641,"children":642},{"style":391},[643],{"type":17,"value":383},{"type":11,"tag":352,"props":645,"children":647},{"style":646},"--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8",[648],{"type":17,"value":649},": ",{"type":11,"tag":352,"props":651,"children":652},{"style":359},[653],{"type":17,"value":362},{"type":11,"tag":352,"props":655,"children":656},{"class":354,"line":365},[657,661,665,669,673,677,681,685],{"type":11,"tag":352,"props":658,"children":659},{"style":369},[660],{"type":17,"value":372},{"type":11,"tag":352,"props":662,"children":663},{"style":375},[664],{"type":17,"value":378},{"type":11,"tag":352,"props":666,"children":667},{"style":369},[668],{"type":17,"value":383},{"type":11,"tag":352,"props":670,"children":671},{"style":359},[672],{"type":17,"value":388},{"type":11,"tag":352,"props":674,"children":675},{"style":391},[676],{"type":17,"value":394},{"type":11,"tag":352,"props":678,"children":679},{"style":397},[680],{"type":17,"value":507},{"type":11,"tag":352,"props":682,"children":683},{"style":391},[684],{"type":17,"value":383},{"type":11,"tag":352,"props":686,"children":687},{"style":359},[688],{"type":17,"value":409},{"type":11,"tag":352,"props":690,"children":691},{"class":354,"line":412},[692,696,700,704,708,712,716,720],{"type":11,"tag":352,"props":693,"children":694},{"style":369},[695],{"type":17,"value":372},{"type":11,"tag":352,"props":697,"children":698},{"style":375},[699],{"type":17,"value":422},{"type":11,"tag":352,"props":701,"children":702},{"style":369},[703],{"type":17,"value":383},{"type":11,"tag":352,"props":705,"children":706},{"style":359},[707],{"type":17,"value":388},{"type":11,"tag":352,"props":709,"children":710},{"style":391},[711],{"type":17,"value":394},{"type":11,"tag":352,"props":713,"children":714},{"style":397},[715],{"type":17,"value":400},{"type":11,"tag":352,"props":717,"children":718},{"style":391},[719],{"type":17,"value":383},{"type":11,"tag":352,"props":721,"children":722},{"style":359},[723],{"type":17,"value":409},{"type":11,"tag":352,"props":725,"children":726},{"class":354,"line":449},[727,731,736,740,744,749,753,758,762,766,770,775,779,783,787,792,796,800,804,809,813,817,821,826,830,834,838,843,847],{"type":11,"tag":352,"props":728,"children":729},{"style":369},[730],{"type":17,"value":372},{"type":11,"tag":352,"props":732,"children":733},{"style":375},[734],{"type":17,"value":735},"reportVersionAtImport",{"type":11,"tag":352,"props":737,"children":738},{"style":369},[739],{"type":17,"value":383},{"type":11,"tag":352,"props":741,"children":742},{"style":359},[743],{"type":17,"value":388},{"type":11,"tag":352,"props":745,"children":746},{"style":359},[747],{"type":17,"value":748}," {",{"type":11,"tag":352,"props":750,"children":751},{"style":369},[752],{"type":17,"value":394},{"type":11,"tag":352,"props":754,"children":755},{"style":488},[756],{"type":17,"value":757},"visual",{"type":11,"tag":352,"props":759,"children":760},{"style":369},[761],{"type":17,"value":383},{"type":11,"tag":352,"props":763,"children":764},{"style":359},[765],{"type":17,"value":388},{"type":11,"tag":352,"props":767,"children":768},{"style":391},[769],{"type":17,"value":394},{"type":11,"tag":352,"props":771,"children":772},{"style":397},[773],{"type":17,"value":774},"2.9.0",{"type":11,"tag":352,"props":776,"children":777},{"style":391},[778],{"type":17,"value":383},{"type":11,"tag":352,"props":780,"children":781},{"style":359},[782],{"type":17,"value":516},{"type":11,"tag":352,"props":784,"children":785},{"style":369},[786],{"type":17,"value":394},{"type":11,"tag":352,"props":788,"children":789},{"style":488},[790],{"type":17,"value":791},"page",{"type":11,"tag":352,"props":793,"children":794},{"style":369},[795],{"type":17,"value":383},{"type":11,"tag":352,"props":797,"children":798},{"style":359},[799],{"type":17,"value":388},{"type":11,"tag":352,"props":801,"children":802},{"style":391},[803],{"type":17,"value":394},{"type":11,"tag":352,"props":805,"children":806},{"style":397},[807],{"type":17,"value":808},"2.3.1",{"type":11,"tag":352,"props":810,"children":811},{"style":391},[812],{"type":17,"value":383},{"type":11,"tag":352,"props":814,"children":815},{"style":359},[816],{"type":17,"value":516},{"type":11,"tag":352,"props":818,"children":819},{"style":369},[820],{"type":17,"value":394},{"type":11,"tag":352,"props":822,"children":823},{"style":488},[824],{"type":17,"value":825},"report",{"type":11,"tag":352,"props":827,"children":828},{"style":369},[829],{"type":17,"value":383},{"type":11,"tag":352,"props":831,"children":832},{"style":359},[833],{"type":17,"value":388},{"type":11,"tag":352,"props":835,"children":836},{"style":391},[837],{"type":17,"value":394},{"type":11,"tag":352,"props":839,"children":840},{"style":397},[841],{"type":17,"value":842},"3.3.0",{"type":11,"tag":352,"props":844,"children":845},{"style":391},[846],{"type":17,"value":383},{"type":11,"tag":352,"props":848,"children":849},{"style":359},[850],{"type":17,"value":583},{"type":11,"tag":352,"props":852,"children":853},{"class":354,"line":475},[854],{"type":11,"tag":352,"props":855,"children":856},{"style":359},[857],{"type":17,"value":601},{"type":11,"tag":19,"props":859,"children":860},{},[861,863,868],{"type":17,"value":862},"The theme name, the resource item name, the item path, and the on-disk\nfilename must all match ",{"type":11,"tag":39,"props":864,"children":865},{},[866],{"type":17,"value":867},"including the extension",{"type":17,"value":869},". A mismatch is one of\nthe most common causes of a report that opens with no styling and no\nerror.",{"type":11,"tag":871,"props":872,"children":873},"blockquote",{},[874],{"type":11,"tag":19,"props":875,"children":876},{},[877,887,889,895,897,902,904,910],{"type":11,"tag":39,"props":878,"children":879},{},[880,885],{"type":11,"tag":25,"props":881,"children":883},{"className":882},[],[884],{"type":17,"value":735},{"type":17,"value":886}," is an object, not a string.",{"type":17,"value":888}," Report schema\n3.0.0 changed it, and Microsoft's own published example still shows the\nold flat ",{"type":11,"tag":25,"props":890,"children":892},{"className":891},[],[893],{"type":17,"value":894},"\"5.53\"",{"type":17,"value":896}," form. Copying from the docs produces a ",{"type":11,"tag":25,"props":898,"children":900},{"className":899},[],[901],{"type":17,"value":331},{"type":17,"value":903},"\nthat fails validation. The current values are in\n",{"type":11,"tag":25,"props":905,"children":907},{"className":906},[],[908],{"type":17,"value":909},"pbir\u002Fschema-lock.json",{"type":17,"value":911},".",{"type":11,"tag":871,"props":913,"children":914},{},[915],{"type":11,"tag":19,"props":916,"children":917},{},[918,930,932,937,939,945,947,952],{"type":11,"tag":39,"props":919,"children":920},{},[921,923,928],{"type":17,"value":922},"During PBIR preview, a ",{"type":11,"tag":145,"props":924,"children":925},{},[926],{"type":17,"value":927},"new",{"type":17,"value":929}," theme cannot be registered by file drop\nalone.",{"type":17,"value":931}," ",{"type":11,"tag":25,"props":933,"children":935},{"className":934},[],[936],{"type":17,"value":331},{"type":17,"value":938}," and ",{"type":11,"tag":25,"props":940,"children":942},{"className":941},[],[943],{"type":17,"value":944},"definition.pbir",{"type":17,"value":946}," are not externally\neditable, and ",{"type":11,"tag":25,"props":948,"children":950},{"className":949},[],[951],{"type":17,"value":400},{"type":17,"value":953}," can only be edited for\nalready-registered resources. Introduce the theme once through Desktop\n(View → Theme → Browse for themes), then subsequent updates are a file\nreplace.",{"type":11,"tag":70,"props":955,"children":956},{},[],{"type":11,"tag":74,"props":958,"children":960},{"id":959},"light-and-dark",[961],{"type":17,"value":962},"Light and dark",{"type":11,"tag":19,"props":964,"children":965},{},[966,971,973,979,981,987],{"type":11,"tag":39,"props":967,"children":968},{},[969],{"type":17,"value":970},"Power BI has no native dark mode for report content.",{"type":17,"value":972}," Verified\n2026-08-31 against Microsoft's own documentation: Desktop dark mode is\napplication chrome only (\"Dark mode is not applied to the Report view\nCanvas, including the Filter Pane and Wallpaper\"), mobile explicitly\nexcludes report content, and the service has none. The theme schema has\nno ",{"type":11,"tag":25,"props":974,"children":976},{"className":975},[],[977],{"type":17,"value":978},"colorScheme",{"type":17,"value":980}," key and is ",{"type":11,"tag":25,"props":982,"children":984},{"className":983},[],[985],{"type":17,"value":986},"additionalProperties: false",{"type":17,"value":988},", so it cannot\nbe extended.",{"type":11,"tag":19,"props":990,"children":991},{},[992],{"type":17,"value":993},"That leaves two real options, and they do different jobs:",{"type":11,"tag":19,"props":995,"children":996},{},[997,1002,1004,1009,1011,1017,1019,1025],{"type":11,"tag":39,"props":998,"children":999},{},[1000],{"type":17,"value":1001},"Static",{"type":17,"value":1003}," — ship ",{"type":11,"tag":25,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":17,"value":507},{"type":17,"value":1010}," or ",{"type":11,"tag":25,"props":1012,"children":1014},{"className":1013},[],[1015],{"type":17,"value":1016},"tti-theme-dark.json",{"type":17,"value":1018}," and use the\nmatching ",{"type":11,"tag":25,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":17,"value":1024},"fragments\u002F\u003Ctheme>\u002F",{"type":17,"value":1026},". The report has one fixed appearance.\nNo semantic-model dependency. Use this unless you need a viewer-facing\ntoggle.",{"type":11,"tag":19,"props":1028,"children":1029},{},[1030,1035,1037,1043,1045,1051],{"type":11,"tag":39,"props":1031,"children":1032},{},[1033],{"type":17,"value":1034},"Themed",{"type":17,"value":1036}," — use ",{"type":11,"tag":25,"props":1038,"children":1040},{"className":1039},[],[1041],{"type":17,"value":1042},"fragments\u002Fthemed\u002F",{"type":17,"value":1044},", whose colours bind to DAX measures\ninstead of literals. A slicer on a disconnected ",{"type":11,"tag":25,"props":1046,"children":1048},{"className":1047},[],[1049],{"type":17,"value":1050},"ThemeMode",{"type":17,"value":1052}," table drives\nevery bound colour, so a viewer flips the whole report at view time. This\nis the only mechanism that gives a live in-report toggle.",{"type":11,"tag":19,"props":1054,"children":1055},{},[1056],{"type":17,"value":1057},"The model module that backs it is generated from the same tokens:",{"type":11,"tag":81,"props":1059,"children":1062},{"className":1060,"code":1061,"language":17},[84],"pbir\u002Ftmdl\u002FThemeMode.tmdl          the two-row mode table\npbir\u002Ftmdl\u002FTuxThemeColors.tmdl     30 measures, one per colour role\npbir\u002Fdax\u002Ftheme-tables.dax         the same thing for Desktop's UI\n",[1063],{"type":11,"tag":25,"props":1064,"children":1065},{"__ignoreMap":89},[1066],{"type":17,"value":1061},{"type":11,"tag":19,"props":1068,"children":1069},{},[1070,1075,1077,1083,1085,1091,1093,1099,1101,1107,1109,1114],{"type":11,"tag":39,"props":1071,"children":1072},{},[1073],{"type":17,"value":1074},"TMDL projects",{"type":17,"value":1076}," — copy both ",{"type":11,"tag":25,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":17,"value":1082},".tmdl",{"type":17,"value":1084}," files into\n",{"type":11,"tag":25,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":17,"value":1090},"\u003CModel>.SemanticModel\u002Fdefinition\u002Ftables\u002F",{"type":17,"value":1092}," and add a ",{"type":11,"tag":25,"props":1094,"children":1096},{"className":1095},[],[1097],{"type":17,"value":1098},"ref table",{"type":17,"value":1100}," line for\neach in ",{"type":11,"tag":25,"props":1102,"children":1104},{"className":1103},[],[1105],{"type":17,"value":1106},"model.tmdl",{"type":17,"value":1108},". A table file without its ",{"type":11,"tag":25,"props":1110,"children":1112},{"className":1111},[],[1113],{"type":17,"value":1098},{"type":17,"value":1115}," entry is\nsilently ignored, with no error.",{"type":11,"tag":19,"props":1117,"children":1118},{},[1119,1124,1126,1132,1134,1139,1141,1146,1148,1154],{"type":11,"tag":39,"props":1120,"children":1121},{},[1122],{"type":17,"value":1123},"Desktop",{"type":17,"value":1125}," — open ",{"type":11,"tag":25,"props":1127,"children":1129},{"className":1128},[],[1130],{"type":17,"value":1131},"dax\u002Ftheme-tables.dax",{"type":17,"value":1133}," and follow the header: two\n",{"type":11,"tag":145,"props":1135,"children":1136},{},[1137],{"type":17,"value":1138},"New table",{"type":17,"value":1140}," expressions, then one ",{"type":11,"tag":145,"props":1142,"children":1143},{},[1144],{"type":17,"value":1145},"New measure",{"type":17,"value":1147}," per role with\n",{"type":11,"tag":25,"props":1149,"children":1151},{"className":1150},[],[1152],{"type":17,"value":1153},"TuxThemeColors",{"type":17,"value":1155}," as the home table.",{"type":11,"tag":19,"props":1157,"children":1158},{},[1159,1161,1167],{"type":17,"value":1160},"Then put a slicer on ",{"type":11,"tag":25,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":17,"value":1166},"ThemeMode[Mode]",{"type":17,"value":1168},", set it to tile mode, and sync it\nacross pages.",{"type":11,"tag":19,"props":1170,"children":1171},{},[1172],{"type":17,"value":1173},"Roles are grouped into display folders — Surface, Text, Accent, Table,\nChart, Semantic, Shell, Tooltip. Two behaviours worth knowing, both of\nwhich fall out of the tokens rather than being special-cased:",{"type":11,"tag":1175,"props":1176,"children":1177},"ul",{},[1178,1196],{"type":11,"tag":312,"props":1179,"children":1180},{},[1181,1187,1189,1194],{"type":11,"tag":25,"props":1182,"children":1184},{"className":1183},[],[1185],{"type":17,"value":1186},"Shell*",{"type":17,"value":1188}," roles are ",{"type":11,"tag":39,"props":1190,"children":1191},{},[1192],{"type":17,"value":1193},"theme-invariant",{"type":17,"value":1195}," — the masthead stays maroon in\ndark mode, per the on-brand rule.",{"type":11,"tag":312,"props":1197,"children":1198},{},[1199,1205,1207,1212],{"type":11,"tag":25,"props":1200,"children":1202},{"className":1201},[],[1203],{"type":17,"value":1204},"Tooltip*",{"type":17,"value":1206}," roles ",{"type":11,"tag":39,"props":1208,"children":1209},{},[1210],{"type":17,"value":1211},"invert",{"type":17,"value":1213},", because a tooltip wants the opposite\nsurface from the page it sits on.",{"type":11,"tag":19,"props":1215,"children":1216},{},[1217,1219,1224],{"type":17,"value":1218},"The measure names are a ",{"type":11,"tag":39,"props":1220,"children":1221},{},[1222],{"type":17,"value":1223},"hard contract",{"type":17,"value":1225}," with the fragments. Renaming\none breaks every report that has already spliced them in.",{"type":11,"tag":871,"props":1227,"children":1228},{},[1229],{"type":11,"tag":19,"props":1230,"children":1231},{},[1232,1234,1239,1241,1247,1249,1255,1257,1261,1263,1269],{"type":17,"value":1233},"The measures return hex literals on purpose. Power BI's newer ",{"type":11,"tag":145,"props":1235,"children":1236},{},[1237],{"type":17,"value":1238},"named\ntheme colors",{"type":17,"value":1240}," feature — where a measure returns ",{"type":11,"tag":25,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":17,"value":1246},"\"background\"",{"type":17,"value":1248}," instead\nof ",{"type":11,"tag":25,"props":1250,"children":1252},{"className":1251},[],[1253],{"type":17,"value":1254},"#FFFFFF",{"type":17,"value":1256}," — resolves against whichever theme is currently applied,\nand a report has exactly one. It makes a report theme-portable; it\n",{"type":11,"tag":39,"props":1258,"children":1259},{},[1260],{"type":17,"value":149},{"type":17,"value":1262}," drive a live toggle, because both branches of the ",{"type":11,"tag":25,"props":1264,"children":1266},{"className":1265},[],[1267],{"type":17,"value":1268},"IF",{"type":17,"value":1270},"\ncollapse to the same colour. Do not refactor these measures onto it.",{"type":11,"tag":19,"props":1272,"children":1273},{},[1274,1276,1281,1283,1294],{"type":17,"value":1275},"Two approaches that were tried and abandoned upstream, recorded so they\naren't retried: ",{"type":11,"tag":39,"props":1277,"children":1278},{},[1279],{"type":17,"value":1280},"bookmarks",{"type":17,"value":1282}," with duplicated per-mode pages (maintenance\ndoubles with every page, slicer sync is fragile), and ",{"type":11,"tag":39,"props":1284,"children":1285},{},[1286,1288],{"type":17,"value":1287},"field parameters\nwith ",{"type":11,"tag":25,"props":1289,"children":1291},{"className":1290},[],[1292],{"type":17,"value":1293},"GENERATESERIES",{"type":17,"value":1295}," (fine for two or three colours, doesn't scale to\na full role set).",{"type":11,"tag":19,"props":1297,"children":1298},{},[1299,1301,1305,1307,1313,1315,1321],{"type":17,"value":1300},"High contrast is ",{"type":11,"tag":39,"props":1302,"children":1303},{},[1304],{"type":17,"value":282},{"type":17,"value":1306}," a toggle state — it's a separately applied\ntheme. Use ",{"type":11,"tag":25,"props":1308,"children":1310},{"className":1309},[],[1311],{"type":17,"value":1312},"tti-theme-hc.json",{"type":17,"value":1314}," with the static ",{"type":11,"tag":25,"props":1316,"children":1318},{"className":1317},[],[1319],{"type":17,"value":1320},"fragments\u002Ftti-hc\u002F",{"type":17,"value":1322}," lane.",{"type":11,"tag":70,"props":1324,"children":1325},{},[],{"type":11,"tag":74,"props":1327,"children":1329},{"id":1328},"geometry",[1330],{"type":17,"value":1331},"Geometry",{"type":11,"tag":19,"props":1333,"children":1334},{},[1335,1341],{"type":11,"tag":25,"props":1336,"children":1338},{"className":1337},[],[1339],{"type":17,"value":1340},"pbir\u002Fgeometry.json",{"type":17,"value":1342}," carries the report shell layout: chrome band\nheights, content area, nav pill stride, and the z-order scheme.",{"type":11,"tag":19,"props":1344,"children":1345},{},[1346],{"type":17,"value":1347},"Two canvas variants are emitted because Fluent 2 (GA August 2026) moved\nthe default canvas to 1920×1080 while existing reports stay at 1280×920:",{"type":11,"tag":153,"props":1349,"children":1350},{},[1351,1372],{"type":11,"tag":157,"props":1352,"children":1353},{},[1354],{"type":11,"tag":161,"props":1355,"children":1356},{},[1357,1362,1367],{"type":11,"tag":165,"props":1358,"children":1359},{},[1360],{"type":17,"value":1361},"Variant",{"type":11,"tag":165,"props":1363,"children":1364},{},[1365],{"type":17,"value":1366},"Canvas",{"type":11,"tag":165,"props":1368,"children":1369},{},[1370],{"type":17,"value":1371},"Base theme",{"type":11,"tag":181,"props":1373,"children":1374},{},[1375,1401],{"type":11,"tag":161,"props":1376,"children":1377},{},[1378,1387,1392],{"type":11,"tag":188,"props":1379,"children":1380},{},[1381],{"type":11,"tag":25,"props":1382,"children":1384},{"className":1383},[],[1385],{"type":17,"value":1386},"classic",{"type":11,"tag":188,"props":1388,"children":1389},{},[1390],{"type":17,"value":1391},"1280 × 920",{"type":11,"tag":188,"props":1393,"children":1394},{},[1395],{"type":11,"tag":25,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":17,"value":1400},"CY26SU08",{"type":11,"tag":161,"props":1402,"children":1403},{},[1404,1413,1418],{"type":11,"tag":188,"props":1405,"children":1406},{},[1407],{"type":11,"tag":25,"props":1408,"children":1410},{"className":1409},[],[1411],{"type":17,"value":1412},"fluent2",{"type":11,"tag":188,"props":1414,"children":1415},{},[1416],{"type":17,"value":1417},"1920 × 1080",{"type":11,"tag":188,"props":1419,"children":1420},{},[1421],{"type":11,"tag":25,"props":1422,"children":1424},{"className":1423},[],[1425],{"type":17,"value":1426},"Fluent2-CY26SU08",{"type":11,"tag":19,"props":1428,"children":1429},{},[1430,1432,1436],{"type":17,"value":1431},"Chrome bands are type-driven and do ",{"type":11,"tag":39,"props":1433,"children":1434},{},[1435],{"type":17,"value":282},{"type":17,"value":1437}," scale with the canvas — only\nthe content area does. Pick the variant matching your report's base\ntheme.",{"type":11,"tag":19,"props":1439,"children":1440},{},[1441,1443,1448],{"type":17,"value":1442},"The z-order scheme reserves ",{"type":11,"tag":39,"props":1444,"children":1445},{},[1446],{"type":17,"value":1447},"9000–15000",{"type":17,"value":1449}," for content visuals.\nEverything outside that window is shell chrome. Keep content inside it\nand chrome never collides.",{"type":11,"tag":70,"props":1451,"children":1452},{},[],{"type":11,"tag":74,"props":1454,"children":1456},{"id":1455},"the-report-shell",[1457],{"type":17,"value":1458},"The report shell",{"type":11,"tag":19,"props":1460,"children":1461},{},[1462,1468],{"type":11,"tag":25,"props":1463,"children":1465},{"className":1464},[],[1466],{"type":17,"value":1467},"pbir\u002Fshell\u002F\u003Ccanvas>\u002F",{"type":17,"value":1469}," holds ready-to-copy visuals — one folder per\nvisual, matching PBIR's on-disk layout exactly:",{"type":11,"tag":81,"props":1471,"children":1474},{"className":1472,"code":1473,"language":17},[84],"cp -R kit\u002Fpowerbi\u002Fpbir\u002Fshell\u002Ffluent2\u002F* \\\n      MyReport.Report\u002Fdefinition\u002Fpages\u002F\u003Cpage>\u002Fvisuals\u002F\n",[1475],{"type":11,"tag":25,"props":1476,"children":1477},{"__ignoreMap":89},[1478],{"type":17,"value":1473},{"type":11,"tag":19,"props":1480,"children":1481},{},[1482,1484,1490,1492,1498,1500,1506],{"type":17,"value":1483},"Ten of them are the page chrome, and they are identical on every page of\na report — only ",{"type":11,"tag":25,"props":1485,"children":1487},{"className":1486},[],[1488],{"type":17,"value":1489},"nav_title_page",{"type":17,"value":1491},", ",{"type":11,"tag":25,"props":1493,"children":1495},{"className":1494},[],[1496],{"type":17,"value":1497},"nav_title_context",{"type":17,"value":1499}," and\n",{"type":11,"tag":25,"props":1501,"children":1503},{"className":1502},[],[1504],{"type":17,"value":1505},"nav_title_footer_support",{"type":17,"value":1507}," carry copy you'll want to change:",{"type":11,"tag":153,"props":1509,"children":1510},{},[1511,1532],{"type":11,"tag":157,"props":1512,"children":1513},{},[1514],{"type":11,"tag":161,"props":1515,"children":1516},{},[1517,1522,1527],{"type":11,"tag":165,"props":1518,"children":1519},{},[1520],{"type":17,"value":1521},"Visual",{"type":11,"tag":165,"props":1523,"children":1524},{},[1525],{"type":17,"value":1526},"Type",{"type":11,"tag":165,"props":1528,"children":1529},{},[1530],{"type":17,"value":1531},"Follows the toggle?",{"type":11,"tag":181,"props":1533,"children":1534},{},[1535,1563,1591,1617,1641,1665,1690,1713,1735,1763],{"type":11,"tag":161,"props":1536,"children":1537},{},[1538,1547,1552],{"type":11,"tag":188,"props":1539,"children":1540},{},[1541],{"type":11,"tag":25,"props":1542,"children":1544},{"className":1543},[],[1545],{"type":17,"value":1546},"shell_canvas_bg",{"type":11,"tag":188,"props":1548,"children":1549},{},[1550],{"type":17,"value":1551},"shape",{"type":11,"tag":188,"props":1553,"children":1554},{},[1555,1557],{"type":17,"value":1556},"yes — ",{"type":11,"tag":25,"props":1558,"children":1560},{"className":1559},[],[1561],{"type":17,"value":1562},"PageBackground",{"type":11,"tag":161,"props":1564,"children":1565},{},[1566,1575,1579],{"type":11,"tag":188,"props":1567,"children":1568},{},[1569],{"type":11,"tag":25,"props":1570,"children":1572},{"className":1571},[],[1573],{"type":17,"value":1574},"nav_btn_content_tray",{"type":11,"tag":188,"props":1576,"children":1577},{},[1578],{"type":17,"value":1551},{"type":11,"tag":188,"props":1580,"children":1581},{},[1582,1583,1589],{"type":17,"value":1556},{"type":11,"tag":25,"props":1584,"children":1586},{"className":1585},[],[1587],{"type":17,"value":1588},"BorderColor",{"type":17,"value":1590}," @97%",{"type":11,"tag":161,"props":1592,"children":1593},{},[1594,1603,1607],{"type":11,"tag":188,"props":1595,"children":1596},{},[1597],{"type":11,"tag":25,"props":1598,"children":1600},{"className":1599},[],[1601],{"type":17,"value":1602},"nav_btn_footer_bg",{"type":11,"tag":188,"props":1604,"children":1605},{},[1606],{"type":17,"value":1551},{"type":11,"tag":188,"props":1608,"children":1609},{},[1610,1615],{"type":11,"tag":39,"props":1611,"children":1612},{},[1613],{"type":17,"value":1614},"no",{"type":17,"value":1616}," — brand",{"type":11,"tag":161,"props":1618,"children":1619},{},[1620,1629,1633],{"type":11,"tag":188,"props":1621,"children":1622},{},[1623],{"type":11,"tag":25,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":17,"value":1628},"nav_btn_header_bg",{"type":11,"tag":188,"props":1630,"children":1631},{},[1632],{"type":17,"value":1551},{"type":11,"tag":188,"props":1634,"children":1635},{},[1636,1640],{"type":11,"tag":39,"props":1637,"children":1638},{},[1639],{"type":17,"value":1614},{"type":17,"value":1616},{"type":11,"tag":161,"props":1642,"children":1643},{},[1644,1653,1657],{"type":11,"tag":188,"props":1645,"children":1646},{},[1647],{"type":11,"tag":25,"props":1648,"children":1650},{"className":1649},[],[1651],{"type":17,"value":1652},"nav_btn_header_accent_rule",{"type":11,"tag":188,"props":1654,"children":1655},{},[1656],{"type":17,"value":1551},{"type":11,"tag":188,"props":1658,"children":1659},{},[1660,1664],{"type":11,"tag":39,"props":1661,"children":1662},{},[1663],{"type":17,"value":1614},{"type":17,"value":1616},{"type":11,"tag":161,"props":1666,"children":1667},{},[1668,1676,1681],{"type":11,"tag":188,"props":1669,"children":1670},{},[1671],{"type":11,"tag":25,"props":1672,"children":1674},{"className":1673},[],[1675],{"type":17,"value":1505},{"type":11,"tag":188,"props":1677,"children":1678},{},[1679],{"type":17,"value":1680},"textbox",{"type":11,"tag":188,"props":1682,"children":1683},{},[1684,1688],{"type":11,"tag":39,"props":1685,"children":1686},{},[1687],{"type":17,"value":1614},{"type":17,"value":1689}," — static on brand",{"type":11,"tag":161,"props":1691,"children":1692},{},[1693,1701,1705],{"type":11,"tag":188,"props":1694,"children":1695},{},[1696],{"type":11,"tag":25,"props":1697,"children":1699},{"className":1698},[],[1700],{"type":17,"value":1489},{"type":11,"tag":188,"props":1702,"children":1703},{},[1704],{"type":17,"value":1680},{"type":11,"tag":188,"props":1706,"children":1707},{},[1708,1712],{"type":11,"tag":39,"props":1709,"children":1710},{},[1711],{"type":17,"value":1614},{"type":17,"value":1689},{"type":11,"tag":161,"props":1714,"children":1715},{},[1716,1725,1730],{"type":11,"tag":188,"props":1717,"children":1718},{},[1719],{"type":11,"tag":25,"props":1720,"children":1722},{"className":1721},[],[1723],{"type":17,"value":1724},"shell_theme_slicer",{"type":11,"tag":188,"props":1726,"children":1727},{},[1728],{"type":17,"value":1729},"slicer",{"type":11,"tag":188,"props":1731,"children":1732},{},[1733],{"type":17,"value":1734},"— the control itself",{"type":11,"tag":161,"props":1736,"children":1737},{},[1738,1747,1751],{"type":11,"tag":188,"props":1739,"children":1740},{},[1741],{"type":11,"tag":25,"props":1742,"children":1744},{"className":1743},[],[1745],{"type":17,"value":1746},"nav_btn_nav_bg",{"type":11,"tag":188,"props":1748,"children":1749},{},[1750],{"type":17,"value":1551},{"type":11,"tag":188,"props":1752,"children":1753},{},[1754,1755,1761],{"type":17,"value":1556},{"type":11,"tag":25,"props":1756,"children":1758},{"className":1757},[],[1759],{"type":17,"value":1760},"CardBackground",{"type":17,"value":1762}," @4%",{"type":11,"tag":161,"props":1764,"children":1765},{},[1766,1774,1778],{"type":11,"tag":188,"props":1767,"children":1768},{},[1769],{"type":11,"tag":25,"props":1770,"children":1772},{"className":1771},[],[1773],{"type":17,"value":1497},{"type":11,"tag":188,"props":1775,"children":1776},{},[1777],{"type":17,"value":1680},{"type":11,"tag":188,"props":1779,"children":1780},{},[1781,1783],{"type":17,"value":1782},"yes — titled, ",{"type":11,"tag":25,"props":1784,"children":1786},{"className":1785},[],[1787],{"type":17,"value":1788},"TextPrimary",{"type":11,"tag":19,"props":1790,"children":1791},{},[1792,1794,1798,1800,1805],{"type":17,"value":1793},"Brand chrome deliberately does ",{"type":11,"tag":39,"props":1795,"children":1796},{},[1797],{"type":17,"value":282},{"type":17,"value":1799}," respond to the toggle: the\nmasthead stays maroon in dark mode. Anything sitting ",{"type":11,"tag":145,"props":1801,"children":1802},{},[1803],{"type":17,"value":1804},"on",{"type":17,"value":1806}," that maroon\n(page title, footer label) is static white for the same reason — it is\nalways readable there, so it needs no measure.",{"type":11,"tag":1808,"props":1809,"children":1811},"h3",{"id":1810},"nav-pills",[1812],{"type":17,"value":1813},"Nav pills",{"type":11,"tag":19,"props":1815,"children":1816},{},[1817,1819,1825,1827,1833,1835,1840],{"type":17,"value":1818},"The remaining five visuals are pill templates, because the pill count is\nper-report. ",{"type":11,"tag":25,"props":1820,"children":1822},{"className":1821},[],[1823],{"type":17,"value":1824},"nav_pill_active*",{"type":17,"value":1826}," is positioned at index 0 and\n",{"type":11,"tag":25,"props":1828,"children":1830},{"className":1829},[],[1831],{"type":17,"value":1832},"nav_pill_inactive*",{"type":17,"value":1834}," at index 1; replicate the inactive set per page and\nplace pill ",{"type":11,"tag":145,"props":1836,"children":1837},{},[1838],{"type":17,"value":1839},"n",{"type":17,"value":1841}," at:",{"type":11,"tag":81,"props":1843,"children":1846},{"className":1844,"code":1845,"language":17},[84],"x = pills.startX + n * pills.stride     (from geometry.json)\n",[1847],{"type":11,"tag":25,"props":1848,"children":1849},{"__ignoreMap":89},[1850],{"type":17,"value":1845},{"type":11,"tag":19,"props":1852,"children":1853},{},[1854,1856,1861,1863,1869,1871,1877],{"type":17,"value":1855},"Each pill is ",{"type":11,"tag":39,"props":1857,"children":1858},{},[1859],{"type":17,"value":1860},"three or four layered visuals, not one button",{"type":17,"value":1862},". That\nlooks redundant until you try the obvious thing: ",{"type":11,"tag":25,"props":1864,"children":1866},{"className":1865},[],[1867],{"type":17,"value":1868},"actionButton",{"type":17,"value":1870}," text\nrendering is unreliable in generated PBIR — labels vanish or misalign —\nand ",{"type":11,"tag":25,"props":1872,"children":1874},{"className":1873},[],[1875],{"type":17,"value":1876},"text.fontColor",{"type":17,"value":1878}," cannot take a measureRef at all. So chrome, label,\nand click target are separated:",{"type":11,"tag":153,"props":1880,"children":1881},{},[1882,1902],{"type":11,"tag":157,"props":1883,"children":1884},{},[1885],{"type":11,"tag":161,"props":1886,"children":1887},{},[1888,1893,1897],{"type":11,"tag":165,"props":1889,"children":1890},{},[1891],{"type":17,"value":1892},"Layer",{"type":11,"tag":165,"props":1894,"children":1895},{},[1896],{"type":17,"value":1521},{"type":11,"tag":165,"props":1898,"children":1899},{},[1900],{"type":17,"value":1901},"Why",{"type":11,"tag":181,"props":1903,"children":1904},{},[1905,1926,1948],{"type":11,"tag":161,"props":1906,"children":1907},{},[1908,1912,1921],{"type":11,"tag":188,"props":1909,"children":1910},{},[1911],{"type":17,"value":1551},{"type":11,"tag":188,"props":1913,"children":1914},{},[1915],{"type":11,"tag":25,"props":1916,"children":1918},{"className":1917},[],[1919],{"type":17,"value":1920},"nav_pill_*",{"type":11,"tag":188,"props":1922,"children":1923},{},[1924],{"type":17,"value":1925},"fill, radius, shadow",{"type":11,"tag":161,"props":1927,"children":1928},{},[1929,1934,1943],{"type":11,"tag":188,"props":1930,"children":1931},{},[1932],{"type":17,"value":1933},"label",{"type":11,"tag":188,"props":1935,"children":1936},{},[1937],{"type":11,"tag":25,"props":1938,"children":1940},{"className":1939},[],[1941],{"type":17,"value":1942},"nav_pill_*_label",{"type":11,"tag":188,"props":1944,"children":1945},{},[1946],{"type":17,"value":1947},"predictable text rendering",{"type":11,"tag":161,"props":1949,"children":1950},{},[1951,1956,1965],{"type":11,"tag":188,"props":1952,"children":1953},{},[1954],{"type":17,"value":1955},"hit target",{"type":11,"tag":188,"props":1957,"children":1958},{},[1959],{"type":11,"tag":25,"props":1960,"children":1962},{"className":1961},[],[1963],{"type":17,"value":1964},"nav_pill_inactive_hit",{"type":11,"tag":188,"props":1966,"children":1967},{},[1968,1970,1975],{"type":17,"value":1969},"invisible ",{"type":11,"tag":25,"props":1971,"children":1973},{"className":1972},[],[1974],{"type":17,"value":1868},{"type":17,"value":1976},", click only",{"type":11,"tag":19,"props":1978,"children":1979},{},[1980,1982,1987],{"type":17,"value":1981},"The active pill needs no hit target — it ",{"type":11,"tag":145,"props":1983,"children":1984},{},[1985],{"type":17,"value":1986},"is",{"type":17,"value":1988}," the current page.",{"type":11,"tag":19,"props":1990,"children":1991},{},[1992,1994,2000,2002,2008],{"type":17,"value":1993},"Two calibrated offsets that look like typos and are not: the active\nlabel sits at ",{"type":11,"tag":25,"props":1995,"children":1997},{"className":1996},[],[1998],{"type":17,"value":1999},"pillY + 2",{"type":17,"value":2001}," and the inactive at ",{"type":11,"tag":25,"props":2003,"children":2005},{"className":2004},[],[2006],{"type":17,"value":2007},"pillY + 8",{"type":17,"value":2009},". Active uses\nparagraph text (internal top padding); inactive uses title text (renders\nat the top of its box). Without the different offsets they don't sit\nlevel.",{"type":11,"tag":19,"props":2011,"children":2012},{},[2013,2023,2025,2031],{"type":11,"tag":39,"props":2014,"children":2015},{},[2016,2021],{"type":11,"tag":25,"props":2017,"children":2019},{"className":2018},[],[2020],{"type":17,"value":1964},{"type":17,"value":2022}," still needs its page-navigation target.",{"type":17,"value":2024}," The\ninvisible button is emitted with its chrome suppressed but no\n",{"type":11,"tag":25,"props":2026,"children":2028},{"className":2027},[],[2029],{"type":17,"value":2030},"navigationSection",{"type":17,"value":2032}," binding — that value is the destination page's slug,\nwhich only exists once you have pages. Set it in Desktop, or via the\ninjector when it lands.",{"type":11,"tag":1808,"props":2034,"children":2036},{"id":2035},"theme-responsive-text",[2037],{"type":17,"value":2038},"Theme-responsive text",{"type":11,"tag":19,"props":2040,"children":2041},{},[2042,2044,2050,2052,2056,2058,2063,2065,2071,2073,2079,2081,2086,2088,2094],{"type":17,"value":2043},"A textbox's paragraph ",{"type":11,"tag":25,"props":2045,"children":2047},{"className":2046},[],[2048],{"type":17,"value":2049},"textStyle.color",{"type":17,"value":2051}," is a plain string and ",{"type":11,"tag":39,"props":2053,"children":2054},{},[2055],{"type":17,"value":149},{"type":17,"value":2057},"\ntake a measureRef, so any label that must follow the toggle is rendered\nthrough the visual's ",{"type":11,"tag":145,"props":2059,"children":2060},{},[2061],{"type":17,"value":2062},"title",{"type":17,"value":2064}," instead: paragraph text cleared to empty,\ncopy in ",{"type":11,"tag":25,"props":2066,"children":2068},{"className":2067},[],[2069],{"type":17,"value":2070},"title.text",{"type":17,"value":2072},", colour in ",{"type":11,"tag":25,"props":2074,"children":2076},{"className":2075},[],[2077],{"type":17,"value":2078},"title.fontColor",{"type":17,"value":2080},". ",{"type":11,"tag":25,"props":2082,"children":2084},{"className":2083},[],[2085],{"type":17,"value":1497},{"type":17,"value":2087},"\nand ",{"type":11,"tag":25,"props":2089,"children":2091},{"className":2090},[],[2092],{"type":17,"value":2093},"nav_pill_inactive_label",{"type":17,"value":2095}," both use this.",{"type":11,"tag":19,"props":2097,"children":2098},{},[2099,2101,2106,2108,2112,2113,2119],{"type":17,"value":2100},"Use ",{"type":11,"tag":25,"props":2102,"children":2104},{"className":2103},[],[2105],{"type":17,"value":17},{"type":17,"value":2107}," — ",{"type":11,"tag":39,"props":2109,"children":2110},{},[2111],{"type":17,"value":282},{"type":17,"value":931},{"type":11,"tag":25,"props":2114,"children":2116},{"className":2115},[],[2117],{"type":17,"value":2118},"titleText",{"type":17,"value":2120},", which is an embedded-JS-API property\nand fails PBIR schema validation outright.",{"type":11,"tag":19,"props":2122,"children":2123},{},[2124],{"type":17,"value":2125},"Titled text needs more vertical room than paragraph text, or a bounding\nbox appears around it. The calibrated minimums are 64px for 10pt content\nlabels, 46px for nav labels, 55px for an 18pt page title.",{"type":11,"tag":19,"props":2127,"children":2128},{},[2129,2131,2137,2139,2144],{"type":17,"value":2130},"The emitted themes pin ",{"type":11,"tag":25,"props":2132,"children":2134},{"className":2133},[],[2135],{"type":17,"value":2136},"baseTheme: \"Fluent2-CY26SU08\"",{"type":17,"value":2138},". A custom theme\nlayers ",{"type":11,"tag":145,"props":2140,"children":2141},{},[2142],{"type":17,"value":2143},"on top of",{"type":17,"value":2145}," a base theme and inherits anything it doesn't define,\nso leaving it unpinned means inheriting whatever the consuming report\ncarries — and Fluent 2 vs Classic differ in padding, corner radius,\ncanvas size and title defaults.",{"type":11,"tag":70,"props":2147,"children":2148},{},[],{"type":11,"tag":74,"props":2150,"children":2152},{"id":2151},"deprecated-visual-types",[2153],{"type":17,"value":2154},"Deprecated visual types",{"type":11,"tag":19,"props":2156,"children":2157},{},[2158,2164],{"type":11,"tag":25,"props":2159,"children":2161},{"className":2160},[],[2162],{"type":17,"value":2163},"schema-lock.json",{"type":17,"value":2165}," carries the migration map. Emitting the left-hand\nnames produces reports that open today and break later:",{"type":11,"tag":153,"props":2167,"children":2168},{},[2169,2185],{"type":11,"tag":157,"props":2170,"children":2171},{},[2172],{"type":11,"tag":161,"props":2173,"children":2174},{},[2175,2180],{"type":11,"tag":165,"props":2176,"children":2177},{},[2178],{"type":17,"value":2179},"Don't emit",{"type":11,"tag":165,"props":2181,"children":2182},{},[2183],{"type":17,"value":2184},"Emit",{"type":11,"tag":181,"props":2186,"children":2187},{},[2188,2209,2228,2249,2277],{"type":11,"tag":161,"props":2189,"children":2190},{},[2191,2200],{"type":11,"tag":188,"props":2192,"children":2193},{},[2194],{"type":11,"tag":25,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":17,"value":2199},"card",{"type":11,"tag":188,"props":2201,"children":2202},{},[2203],{"type":11,"tag":25,"props":2204,"children":2206},{"className":2205},[],[2207],{"type":17,"value":2208},"cardVisual",{"type":11,"tag":161,"props":2210,"children":2211},{},[2212,2220],{"type":11,"tag":188,"props":2213,"children":2214},{},[2215],{"type":11,"tag":25,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":17,"value":153},{"type":11,"tag":188,"props":2221,"children":2222},{},[2223],{"type":11,"tag":25,"props":2224,"children":2226},{"className":2225},[],[2227],{"type":17,"value":247},{"type":11,"tag":161,"props":2229,"children":2230},{},[2231,2240],{"type":11,"tag":188,"props":2232,"children":2233},{},[2234],{"type":11,"tag":25,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":17,"value":2239},"matrix",{"type":11,"tag":188,"props":2241,"children":2242},{},[2243],{"type":11,"tag":25,"props":2244,"children":2246},{"className":2245},[],[2247],{"type":17,"value":2248},"pivotTable",{"type":11,"tag":161,"props":2250,"children":2251},{},[2252,2268],{"type":11,"tag":188,"props":2253,"children":2254},{},[2255,2261,2262],{"type":11,"tag":25,"props":2256,"children":2258},{"className":2257},[],[2259],{"type":17,"value":2260},"map",{"type":17,"value":1491},{"type":11,"tag":25,"props":2263,"children":2265},{"className":2264},[],[2266],{"type":17,"value":2267},"filledMap",{"type":11,"tag":188,"props":2269,"children":2270},{},[2271],{"type":11,"tag":25,"props":2272,"children":2274},{"className":2273},[],[2275],{"type":17,"value":2276},"azureMap",{"type":11,"tag":161,"props":2278,"children":2279},{},[2280,2289],{"type":11,"tag":188,"props":2281,"children":2282},{},[2283],{"type":11,"tag":25,"props":2284,"children":2286},{"className":2285},[],[2287],{"type":17,"value":2288},"multiRowCard",{"type":11,"tag":188,"props":2290,"children":2291},{},[2292],{"type":11,"tag":25,"props":2293,"children":2295},{"className":2294},[],[2296],{"type":17,"value":2208},{"type":11,"tag":70,"props":2298,"children":2299},{},[],{"type":11,"tag":74,"props":2301,"children":2303},{"id":2302},"validating",[2304],{"type":17,"value":2305},"Validating",{"type":11,"tag":81,"props":2307,"children":2311},{"className":2308,"code":2309,"language":2310,"meta":89,"style":89},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","npm run verify:pbir\n","bash",[2312],{"type":11,"tag":25,"props":2313,"children":2314},{"__ignoreMap":89},[2315],{"type":11,"tag":352,"props":2316,"children":2317},{"class":354,"line":355},[2318,2324,2329],{"type":11,"tag":352,"props":2319,"children":2321},{"style":2320},"--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0",[2322],{"type":17,"value":2323},"npm",{"type":11,"tag":352,"props":2325,"children":2326},{"style":397},[2327],{"type":17,"value":2328}," run",{"type":11,"tag":352,"props":2330,"children":2331},{"style":397},[2332],{"type":17,"value":2333}," verify:pbir\n",{"type":11,"tag":19,"props":2335,"children":2336},{},[2337],{"type":17,"value":2338},"re-checks every pinned schema URL against the live endpoint.",{"type":11,"tag":19,"props":2340,"children":2341},{},[2342],{"type":17,"value":2343},"For structural validation of a whole report, use Microsoft's own offline\nvalidator rather than anything in this repo:",{"type":11,"tag":81,"props":2345,"children":2347},{"className":2308,"code":2346,"language":2310,"meta":89,"style":89},"npx @microsoft\u002Fpowerbi-report-authoring-cli validate \u003Creport-path>\n",[2348],{"type":11,"tag":25,"props":2349,"children":2350},{"__ignoreMap":89},[2351],{"type":11,"tag":352,"props":2352,"children":2353},{"class":354,"line":355},[2354,2359,2364,2369,2375,2380,2385],{"type":11,"tag":352,"props":2355,"children":2356},{"style":2320},[2357],{"type":17,"value":2358},"npx",{"type":11,"tag":352,"props":2360,"children":2361},{"style":397},[2362],{"type":17,"value":2363}," @microsoft\u002Fpowerbi-report-authoring-cli",{"type":11,"tag":352,"props":2365,"children":2366},{"style":397},[2367],{"type":17,"value":2368}," validate",{"type":11,"tag":352,"props":2370,"children":2372},{"style":2371},"--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583",[2373],{"type":17,"value":2374}," \u003C",{"type":11,"tag":352,"props":2376,"children":2377},{"style":397},[2378],{"type":17,"value":2379},"report-pat",{"type":11,"tag":352,"props":2381,"children":2382},{"style":646},[2383],{"type":17,"value":2384},"h",{"type":11,"tag":352,"props":2386,"children":2387},{"style":2371},[2388],{"type":17,"value":2389},">\n",{"type":11,"tag":19,"props":2391,"children":2392},{},[2393,2395,2399,2401,2407,2408,2414],{"type":17,"value":2394},"Note that structural validity does ",{"type":11,"tag":39,"props":2396,"children":2397},{},[2398],{"type":17,"value":282},{"type":17,"value":2400}," imply a correct render. Power\nBI silently ignores a property with the wrong literal type rather than\nrejecting it — ",{"type":11,"tag":25,"props":2402,"children":2404},{"className":2403},[],[2405],{"type":17,"value":2406},"0L",{"type":17,"value":938},{"type":11,"tag":25,"props":2409,"children":2411},{"className":2410},[],[2412],{"type":17,"value":2413},"1D",{"type":17,"value":2415}," are different values, and the wrong one is a\nno-op, not an error. Open the report and look at it.",{"type":11,"tag":70,"props":2417,"children":2418},{},[],{"type":11,"tag":74,"props":2420,"children":2422},{"id":2421},"parity-with-the-web-charts",[2423],{"type":17,"value":2424},"Parity with the web charts",{"type":11,"tag":19,"props":2426,"children":2427},{},[2428,2430,2435,2437,2452],{"type":17,"value":2429},"Building the ",{"type":11,"tag":25,"props":2431,"children":2433},{"className":2432},[],[2434],{"type":17,"value":123},{"type":17,"value":2436}," emitter forced every axis, gridline and\nlegend decision to become a literal, and those decisions are now the\nshared contract in\n",{"type":11,"tag":2438,"props":2439,"children":2443},"a",{"href":2440,"rel":2441},"https:\u002F\u002Fcode.tti.tamu.edu\u002Ftti\u002Ftti-ux\u002Fsrc\u002Fbranch\u002Fmain\u002Fdesign\u002Fchart-foundations.md",[2442],"nofollow",[2444,2450],{"type":11,"tag":25,"props":2445,"children":2447},{"className":2446},[],[2448],{"type":17,"value":2449},"design\u002Fchart-foundations.md",{"type":17,"value":2451}," §2",{"type":17,"value":2453},".\nThat is what makes \"a Power BI report and a TUX page render the same\nsystem\" a checkable claim rather than a slogan.",{"type":11,"tag":19,"props":2455,"children":2456},{},[2457,2459,2465,2467,2473,2475,2481,2483,2489,2491,2497],{"type":17,"value":2458},"One deliberate divergence: web gridlines are ",{"type":11,"tag":25,"props":2460,"children":2462},{"className":2461},[],[2463],{"type":17,"value":2464},"--surface-border",{"type":17,"value":2466}," at 50%\nopacity, while this theme uses ",{"type":11,"tag":25,"props":2468,"children":2470},{"className":2469},[],[2471],{"type":17,"value":2472},"surface.border-subtle",{"type":17,"value":2474},", because a theme's\n",{"type":11,"tag":25,"props":2476,"children":2478},{"className":2477},[],[2479],{"type":17,"value":2480},"gridlineColor",{"type":17,"value":2482}," has no alpha channel. ",{"type":11,"tag":25,"props":2484,"children":2486},{"className":2485},[],[2487],{"type":17,"value":2488},"#EFEEED",{"type":17,"value":2490}," is within a hair of\n",{"type":11,"tag":25,"props":2492,"children":2494},{"className":2493},[],[2495],{"type":17,"value":2496},"#E7E6E6",{"type":17,"value":2498}," composited at 50% on white — same intent, two mechanisms.",{"type":11,"tag":70,"props":2500,"children":2501},{},[],{"type":11,"tag":74,"props":2503,"children":2505},{"id":2504},"why-the-kit-is-split-this-way",[2506],{"type":17,"value":2507},"Why the kit is split this way",{"type":11,"tag":19,"props":2509,"children":2510},{},[2511,2512,2517,2519,2526,2528,2533,2535,2541],{"type":17,"value":37},{"type":11,"tag":39,"props":2513,"children":2514},{},[2515],{"type":17,"value":2516},"Tier 1",{"type":17,"value":2518}," under the\n",{"type":11,"tag":2438,"props":2520,"children":2523},{"href":2521,"rel":2522},"https:\u002F\u002Fcode.tti.tamu.edu\u002Ftti\u002Ftti-ux\u002Fsrc\u002Fbranch\u002Fmain\u002Fdesign\u002Fkit-pipeline.md",[2442],[2524],{"type":17,"value":2525},"kit pipeline doctrine",{"type":17,"value":2527},":\nevery literal resolves from ",{"type":11,"tag":25,"props":2529,"children":2531},{"className":2530},[],[2532],{"type":17,"value":30},{"type":17,"value":2534}," through the same\n",{"type":11,"tag":25,"props":2536,"children":2538},{"className":2537},[],[2539],{"type":17,"value":2540},"palette()",{"type":17,"value":2542}," the theme emitter uses, so a theme and its fragments cannot\ndrift apart.",{"type":11,"tag":19,"props":2544,"children":2545},{},[2546,2548,2553,2555,2561],{"type":17,"value":2547},"That's worth pausing on, because the shell ",{"type":11,"tag":145,"props":2549,"children":2550},{},[2551],{"type":17,"value":2552},"looks",{"type":17,"value":2554}," like component-port\nwork — geometry, layering, a nav system. But the geometry is derived and\nthe colours are token-resolved, so the whole thing is a pure function of\n",{"type":11,"tag":25,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":17,"value":2560},"tokens.json",{"type":17,"value":2562},". It gets deterministic emission and byte locks rather than\nthe port-ledger treatment.",{"type":11,"tag":19,"props":2564,"children":2565},{},[2566,2568,2573],{"type":17,"value":2567},"The theme\u002FPBIR split isn't stylistic either. It falls directly out of the\nno-native-dark-mode constraint above: a theme file can carry colour, type\nand per-visual style, but nothing conditional. Chrome that responds to\n",{"type":11,"tag":145,"props":2569,"children":2570},{},[2571],{"type":17,"value":2572},"state",{"type":17,"value":2574}," has to live in the report's own PBIR JSON, bound to measures.\nHence two halves.",{"type":11,"tag":70,"props":2576,"children":2577},{},[],{"type":11,"tag":74,"props":2579,"children":2581},{"id":2580},"where-this-came-from",[2582],{"type":17,"value":2583},"Where this came from",{"type":11,"tag":19,"props":2585,"children":2586},{},[2587,2589,2595],{"type":17,"value":2588},"Ported from the Power BI & Fabric documentation tree in\n",{"type":11,"tag":25,"props":2590,"children":2592},{"className":2591},[],[2593],{"type":17,"value":2594},"docs-tti-tamu-edu",{"type":17,"value":2596}," — roughly 15,000 lines across 70 files, written\nagainst a real Tableau→Power BI migration that generated ~1,100 visuals.\nThe port re-tokenised it from TAMU\u002FAggieBI branding to TTI and re-pinned\nevery schema version.",{"type":11,"tag":19,"props":2598,"children":2599},{},[2600,2602,2607,2609,2614,2615,2620,2622,2628,2629,2634,2635,2641,2643,2649,2651,2656,2658,2663,2665,2671,2673,2677],{"type":17,"value":2601},"What was worth taking was the ",{"type":11,"tag":39,"props":2603,"children":2604},{},[2605],{"type":17,"value":2606},"non-googleable",{"type":17,"value":2608}," part: that ",{"type":11,"tag":25,"props":2610,"children":2612},{"className":2611},[],[2613],{"type":17,"value":2406},{"type":17,"value":938},{"type":11,"tag":25,"props":2616,"children":2618},{"className":2617},[],[2619],{"type":17,"value":2413},{"type":17,"value":2621},"\nare different values and the wrong one is silently ignored; that a slicer\nneeds ",{"type":11,"tag":25,"props":2623,"children":2625},{"className":2624},[],[2626],{"type":17,"value":2627},"mode: 'Basic'",{"type":17,"value":931},{"type":11,"tag":145,"props":2630,"children":2631},{},[2632],{"type":17,"value":2633},"and",{"type":17,"value":931},{"type":11,"tag":25,"props":2636,"children":2638},{"className":2637},[],[2639],{"type":17,"value":2640},"orientation: \"1D\"",{"type":17,"value":2642}," together to render as\ntiles; that ",{"type":11,"tag":25,"props":2644,"children":2646},{"className":2645},[],[2647],{"type":17,"value":2648},"syncGroup",{"type":17,"value":2650}," lives inside ",{"type":11,"tag":25,"props":2652,"children":2654},{"className":2653},[],[2655],{"type":17,"value":757},{"type":17,"value":2657},"; that a nav pill must be\nthree layered visuals because ",{"type":11,"tag":25,"props":2659,"children":2661},{"className":2660},[],[2662],{"type":17,"value":1868},{"type":17,"value":2664}," text rendering is unreliable\nand its ",{"type":11,"tag":25,"props":2666,"children":2668},{"className":2667},[],[2669],{"type":17,"value":2670},"fontColor",{"type":17,"value":2672}," can't take a measureRef at all; that paragraph text\ncolour can't be measure-bound, so theme-responsive labels have to be\nrendered through the visual's ",{"type":11,"tag":145,"props":2674,"children":2675},{},[2676],{"type":17,"value":2062},{"type":17,"value":2678}," instead.",{"type":11,"tag":19,"props":2680,"children":2681},{},[2682,2684,2690],{"type":17,"value":2683},"What was left behind: the PowerShell generator — the logic moved to a\n",{"type":11,"tag":25,"props":2685,"children":2687},{"className":2686},[],[2688],{"type":17,"value":2689},".mjs",{"type":17,"value":2691}," emitter, and Microsoft's own report-authoring guidance now\nrecommends \"a deterministic Node.js generator\" — and everything\ndata-platform-shaped (Graph ingestion, capacity sizing, semantic-model\nnaming standards). That's a data-platform concern, not a design-system\none.",{"type":11,"tag":70,"props":2693,"children":2694},{},[],{"type":11,"tag":74,"props":2696,"children":2698},{"id":2697},"known-gaps",[2699],{"type":17,"value":2700},"Known gaps",{"type":11,"tag":1175,"props":2702,"children":2703},{},[2704,2738,2760,2785,2818],{"type":11,"tag":312,"props":2705,"children":2706},{},[2707,2712,2714,2720,2722,2728,2730,2736],{"type":11,"tag":39,"props":2708,"children":2709},{},[2710],{"type":17,"value":2711},"Nothing here has been opened in Power BI Desktop.",{"type":17,"value":2713}," 30\u002F30 shell\nvisuals validate against the live ",{"type":11,"tag":25,"props":2715,"children":2717},{"className":2716},[],[2718],{"type":17,"value":2719},"visualContainer\u002F2.9.0",{"type":17,"value":2721}," schema with\nits five remote ",{"type":11,"tag":25,"props":2723,"children":2725},{"className":2724},[],[2726],{"type":17,"value":2727},"$ref",{"type":17,"value":2729},"s resolved, and all three themes against\n",{"type":11,"tag":25,"props":2731,"children":2733},{"className":2732},[],[2734],{"type":17,"value":2735},"reportThemeSchema-2.157",{"type":17,"value":2737}," — but structural validity does not imply a\ncorrect render, precisely because Power BI ignores a wrong literal type\nrather than rejecting it. The smoke test needs Windows.",{"type":11,"tag":312,"props":2739,"children":2740},{},[2741,2758],{"type":11,"tag":39,"props":2742,"children":2743},{},[2744,2749,2751,2756],{"type":11,"tag":25,"props":2745,"children":2747},{"className":2746},[],[2748],{"type":17,"value":1964},{"type":17,"value":2750}," ships without its ",{"type":11,"tag":25,"props":2752,"children":2754},{"className":2753},[],[2755],{"type":17,"value":2030},{"type":17,"value":2757},"\nbinding.",{"type":17,"value":2759}," The value is a destination page slug that only exists once a\nreport has pages, and the source docs never showed the property's JSON\nshape — so it's left to Desktop rather than invented.",{"type":11,"tag":312,"props":2761,"children":2762},{},[2763,2768,2769,2775,2777,2783],{"type":11,"tag":39,"props":2764,"children":2765},{},[2766],{"type":17,"value":2767},"No deep validation in CI.",{"type":17,"value":931},{"type":11,"tag":25,"props":2770,"children":2772},{"className":2771},[],[2773],{"type":17,"value":2774},"verify:pbir",{"type":17,"value":2776}," checks URL reachability\nonly. Schema validation needs ",{"type":11,"tag":25,"props":2778,"children":2780},{"className":2779},[],[2781],{"type":17,"value":2782},"ajv",{"type":17,"value":2784},", currently just a transitive\ndependency; wiring CI to an undeclared transitive dep is how builds\nbreak later.",{"type":11,"tag":312,"props":2786,"children":2787},{},[2788,2793,2795,2801,2802,2808,2810,2816],{"type":11,"tag":39,"props":2789,"children":2790},{},[2791],{"type":17,"value":2792},"Fragment coverage is partial.",{"type":17,"value":2794}," Three fragment types ship —\n",{"type":11,"tag":25,"props":2796,"children":2798},{"className":2797},[],[2799],{"type":17,"value":2800},"card-chrome",{"type":17,"value":1491},{"type":11,"tag":25,"props":2803,"children":2805},{"className":2804},[],[2806],{"type":17,"value":2807},"chart-cartesian",{"type":17,"value":2809}," (bar \u002F column \u002F line \u002F area \u002F\nscatter), and ",{"type":11,"tag":25,"props":2811,"children":2813},{"className":2812},[],[2814],{"type":17,"value":2815},"table-chrome",{"type":17,"value":2817},". Donut, gauge, heatmap, treemap and the\nrest have no fragment yet.",{"type":11,"tag":312,"props":2819,"children":2820},{},[2821,2826,2828,2834],{"type":11,"tag":39,"props":2822,"children":2823},{},[2824],{"type":17,"value":2825},"Not yet built:",{"type":17,"value":2827}," the report scaffold, a ",{"type":11,"tag":25,"props":2829,"children":2831},{"className":2830},[],[2832],{"type":17,"value":2833},"tux-pbir",{"type":17,"value":2835}," injector that\nmints conforming IDs and renumbers z-order on drop-in, and named style\npresets — the closest thing Power BI has to component variants.",{"type":11,"tag":70,"props":2837,"children":2838},{},[],{"type":11,"tag":74,"props":2840,"children":2842},{"id":2841},"status",[2843],{"type":17,"value":2844},"Status",{"type":11,"tag":19,"props":2846,"children":2847},{},[2848,2850,2855,2857,2862,2864,2870],{"type":17,"value":2849},"PBIR is still ",{"type":11,"tag":39,"props":2851,"children":2852},{},[2853],{"type":17,"value":2854},"public preview",{"type":17,"value":2856}," as of 2026-08-31 — GA slipped past its\nQ3 2026 target. It is already the default format for new reports in the\nservice (January 2026) and Desktop (March 2026), and Microsoft has stated\nit becomes the ",{"type":11,"tag":145,"props":2858,"children":2859},{},[2860],{"type":17,"value":2861},"only",{"type":17,"value":2863}," supported format at GA, so building on it is the\nright bet. But schema versions moved roughly monthly before the current\nfreeze; re-run ",{"type":11,"tag":25,"props":2865,"children":2867},{"className":2866},[],[2868],{"type":17,"value":2869},"npm run verify:pbir",{"type":17,"value":2871}," before each release.",{"type":11,"tag":19,"props":2873,"children":2874},{},[2875,2877,2883],{"type":17,"value":2876},"Service-enforced limits worth knowing when generating at scale: 1,000\npages per report, 1,000 visuals per page, 1,000 resource files, 300 MB\ntotal. Windows ",{"type":11,"tag":25,"props":2878,"children":2880},{"className":2879},[],[2881],{"type":17,"value":2882},"MAX_PATH",{"type":17,"value":2884}," (260 chars) also bites, because PBIR nests a\nfolder per visual.",{"type":11,"tag":2886,"props":2887,"children":2888},"style",{},[2889],{"type":17,"value":2890},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":89,"searchDepth":365,"depth":365,"links":2892},[2893,2894,2895,2896,2897,2901,2902,2903,2904,2905,2906,2907],{"id":76,"depth":365,"text":79},{"id":290,"depth":365,"text":293},{"id":959,"depth":365,"text":962},{"id":1328,"depth":365,"text":1331},{"id":1455,"depth":365,"text":1458,"children":2898},[2899,2900],{"id":1810,"depth":412,"text":1813},{"id":2035,"depth":412,"text":2038},{"id":2151,"depth":365,"text":2154},{"id":2302,"depth":365,"text":2305},{"id":2421,"depth":365,"text":2424},{"id":2504,"depth":365,"text":2507},{"id":2580,"depth":365,"text":2583},{"id":2697,"depth":365,"text":2700},{"id":2841,"depth":365,"text":2844},1788285286107]