[{"data":1,"prerenderedAt":1294},["ShallowReactive",2],{"blog-\u002Fblog\u002Fpanda-never-runs-your-code":3},{"id":4,"title":5,"body":6,"canonical":1284,"date":1285,"description":1286,"draft":1287,"duration":1284,"extension":1066,"lang":1284,"meta":1288,"navigation":106,"path":1289,"place":1284,"placeLink":1284,"readingTime":1284,"seo":1290,"seoTitle":1291,"stem":1292,"updated":1284,"__hash__":1293},"blog\u002Fblog\u002Fpanda-never-runs-your-code.md","Panda never runs your code",{"type":7,"value":8,"toc":1271},"minimark",[9,14,26,38,41,218,225,241,244,266,269,274,277,395,416,426,430,437,458,461,491,516,519,554,559,562,616,623,628,685,710,714,717,793,805,818,839,891,894,935,938,941,950,953,986,1004,1007,1024,1027,1042,1053,1057,1068,1071,1075,1090,1137,1140,1144,1154,1237,1240,1252,1267],[10,11,13],"h3",{"id":12},"what-panda-figures-out-before-your-app-runs","What Panda figures out before your app runs.",[15,16,17],"p",{},[18,19],"img",{"alt":20,"fetchPriority":21,"loading":22,"src":23,"width":24,"height":25},"Panda never runs your code, on a cream background with yellow and green glows, surrounded by the Panda logo and code stickers.","high","eager","\u002Fimages\u002Fblog\u002Fpanda-never-runs-your-code\u002Fcover.svg",1200,630,[15,27,28],{},[29,30,31,32,37],"em",{},"Panda internals, part 4. Start with ",[33,34,36],"a",{"href":35},"\u002Fblog\u002Fbuild-once-at-build-time","Build once, at build time"," if you're new here.",[15,39,40],{},"Here's a component where every color is written right there in the file:",[42,43,48],"pre",{"className":44,"code":45,"language":46,"meta":47,"style":47},"language-tsx shiki shiki-themes github-light github-dark","const colorByType = {\n  primary: 'red.300',\n  secondary: 'blue.300',\n}\n\nfunction Section() {\n  const [type] = useState('primary')\n  const cls = css({\n    color: colorByType[type] ?? 'gray.100',\n  })\n\n  return \u003Csection className={cls} \u002F>\n}\n","tsx","",[49,50,51,71,84,95,101,108,121,151,167,181,187,192,213],"code",{"__ignoreMap":47},[52,53,56,60,64,67],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"szBVR","const",[52,61,63],{"class":62},"sj4cs"," colorByType",[52,65,66],{"class":58}," =",[52,68,70],{"class":69},"sVt8B"," {\n",[52,72,74,77,81],{"class":54,"line":73},2,[52,75,76],{"class":69},"  primary: ",[52,78,80],{"class":79},"sZZnC","'red.300'",[52,82,83],{"class":69},",\n",[52,85,87,90,93],{"class":54,"line":86},3,[52,88,89],{"class":69},"  secondary: ",[52,91,92],{"class":79},"'blue.300'",[52,94,83],{"class":69},[52,96,98],{"class":54,"line":97},4,[52,99,100],{"class":69},"}\n",[52,102,104],{"class":54,"line":103},5,[52,105,107],{"emptyLinePlaceholder":106},true,"\n",[52,109,111,114,118],{"class":54,"line":110},6,[52,112,113],{"class":58},"function",[52,115,117],{"class":116},"sScJk"," Section",[52,119,120],{"class":69},"() {\n",[52,122,124,127,130,133,136,139,142,145,148],{"class":54,"line":123},7,[52,125,126],{"class":58},"  const",[52,128,129],{"class":69}," [",[52,131,132],{"class":62},"type",[52,134,135],{"class":69},"] ",[52,137,138],{"class":58},"=",[52,140,141],{"class":116}," useState",[52,143,144],{"class":69},"(",[52,146,147],{"class":79},"'primary'",[52,149,150],{"class":69},")\n",[52,152,154,156,159,161,164],{"class":54,"line":153},8,[52,155,126],{"class":58},[52,157,158],{"class":62}," cls",[52,160,66],{"class":58},[52,162,163],{"class":116}," css",[52,165,166],{"class":69},"({\n",[52,168,170,173,176,179],{"class":54,"line":169},9,[52,171,172],{"class":69},"    color: colorByType[type] ",[52,174,175],{"class":58},"??",[52,177,178],{"class":79}," 'gray.100'",[52,180,83],{"class":69},[52,182,184],{"class":54,"line":183},10,[52,185,186],{"class":69},"  })\n",[52,188,190],{"class":54,"line":189},11,[52,191,107],{"emptyLinePlaceholder":106},[52,193,195,198,201,205,208,210],{"class":54,"line":194},12,[52,196,197],{"class":58},"  return",[52,199,200],{"class":69}," \u003C",[52,202,204],{"class":203},"s9eBZ","section",[52,206,207],{"class":116}," className",[52,209,138],{"class":58},[52,211,212],{"class":69},"{cls} \u002F>\n",[52,214,216],{"class":54,"line":215},13,[52,217,100],{"class":69},[15,219,220,221,224],{},"Panda only generates CSS for one of them, ",[49,222,223],{},"gray.100",".",[15,226,227,228,230,231,234,235,237,238,240],{},"The reason is that Panda never runs your code. It reads it. At build time it works out each style value from the source alone, and it stops wherever a value depends on something only the running app knows. Here, that's ",[49,229,132],{},", which comes from ",[49,232,233],{},"useState",". If ",[49,236,132],{}," were a plain ",[49,239,59],{},", Panda could follow it and pick the right color.",[15,242,243],{},"So the useful question is what Panda can work out, and where it stops. In short, it follows:",[245,246,247,251,254,260,263],"ol",{},[248,249,250],"li",{},"Constants, destructuring and math.",[248,252,253],{},"Imports from other files.",[248,255,256,257,224],{},"Enums and ",[49,258,259],{},"token()",[248,261,262],{},"Small helper functions.",[248,264,265],{},"Ternaries, as long as both sides are known.",[15,267,268],{},"Anything that depends on props, state or a network response is out of reach.",[270,271,273],"h2",{"id":272},"constants-destructuring-and-math","Constants, destructuring and math",[15,275,276],{},"The simplest case is a value you could find by reading the file top to bottom:",[42,278,282],{"className":279,"code":280,"language":281,"meta":47,"style":47},"language-ts shiki shiki-themes github-light github-dark","const theme = {\n  accent: 'red.300',\n  space: 4,\n} as const\n\nconst { accent } = theme\n\ncss({\n  color: accent,\n  padding: `${theme.space * 2}px`,\n})\n","ts",[49,283,284,295,304,314,325,329,347,351,358,363,390],{"__ignoreMap":47},[52,285,286,288,291,293],{"class":54,"line":55},[52,287,59],{"class":58},[52,289,290],{"class":62}," theme",[52,292,66],{"class":58},[52,294,70],{"class":69},[52,296,297,300,302],{"class":54,"line":73},[52,298,299],{"class":69},"  accent: ",[52,301,80],{"class":79},[52,303,83],{"class":69},[52,305,306,309,312],{"class":54,"line":86},[52,307,308],{"class":69},"  space: ",[52,310,311],{"class":62},"4",[52,313,83],{"class":69},[52,315,316,319,322],{"class":54,"line":97},[52,317,318],{"class":69},"} ",[52,320,321],{"class":58},"as",[52,323,324],{"class":58}," const\n",[52,326,327],{"class":54,"line":103},[52,328,107],{"emptyLinePlaceholder":106},[52,330,331,333,336,339,342,344],{"class":54,"line":110},[52,332,59],{"class":58},[52,334,335],{"class":69}," { ",[52,337,338],{"class":62},"accent",[52,340,341],{"class":69}," } ",[52,343,138],{"class":58},[52,345,346],{"class":69}," theme\n",[52,348,349],{"class":54,"line":123},[52,350,107],{"emptyLinePlaceholder":106},[52,352,353,356],{"class":54,"line":153},[52,354,355],{"class":116},"css",[52,357,166],{"class":69},[52,359,360],{"class":54,"line":169},[52,361,362],{"class":69},"  color: accent,\n",[52,364,365,368,371,374,376,379,382,385,388],{"class":54,"line":183},[52,366,367],{"class":69},"  padding: ",[52,369,370],{"class":79},"`${",[52,372,373],{"class":69},"theme",[52,375,224],{"class":79},[52,377,378],{"class":69},"space",[52,380,381],{"class":58}," *",[52,383,384],{"class":62}," 2",[52,386,387],{"class":79},"}px`",[52,389,83],{"class":69},[52,391,392],{"class":54,"line":189},[52,393,394],{"class":69},"})\n",[15,396,397,398,400,401,403,404,407,408,411,412,415],{},"Panda follows ",[49,399,338],{}," back to ",[49,402,373],{},", and works out the template to ",[49,405,406],{},"8px",". Template literals, math and comparisons all work. So do TypeScript-only wrappers like ",[49,409,410],{},"as const"," and ",[49,413,414],{},"satisfies",", which Panda simply looks through.",[15,417,418,419,421,422,425],{},"The rule for variables is that the value has to stay put. A ",[49,420,59],{}," with a known value works. A ",[49,423,424],{},"let"," works too, unless something reassigns it later. Once a value can change, Panda can't know which version your code sees.",[270,427,429],{"id":428},"imports-from-other-files","Imports from other files",[15,431,432,433,436],{},"Most real styles live in more than one file. Say ",[49,434,435],{},"tokens.ts"," exports a color:",[42,438,440],{"className":279,"code":439,"language":281,"meta":47,"style":47},"export const brand = 'red.300'\n",[49,441,442],{"__ignoreMap":47},[52,443,444,447,450,453,455],{"class":54,"line":55},[52,445,446],{"class":58},"export",[52,448,449],{"class":58}," const",[52,451,452],{"class":62}," brand",[52,454,66],{"class":58},[52,456,457],{"class":79}," 'red.300'\n",[15,459,460],{},"And a component imports it:",[42,462,464],{"className":279,"code":463,"language":281,"meta":47,"style":47},"import { brand } from '.\u002Ftokens'\n\ncss({ color: brand })\n",[49,465,466,480,484],{"__ignoreMap":47},[52,467,468,471,474,477],{"class":54,"line":55},[52,469,470],{"class":58},"import",[52,472,473],{"class":69}," { brand } ",[52,475,476],{"class":58},"from",[52,478,479],{"class":79}," '.\u002Ftokens'\n",[52,481,482],{"class":54,"line":73},[52,483,107],{"emptyLinePlaceholder":106},[52,485,486,488],{"class":54,"line":86},[52,487,355],{"class":116},[52,489,490],{"class":69},"({ color: brand })\n",[15,492,493,494,496,497,500,501,504,505,508,509,512,513,515],{},"Panda follows the import into ",[49,495,435],{}," and reads ",[49,498,499],{},"brand"," there. It resolves paths the same way your tooling does, including ",[49,502,503],{},"tsconfig"," path aliases and ",[49,506,507],{},"package.json"," exports. It also follows ",[49,510,511],{},"export *"," barrels. When ",[49,514,435],{}," changes, the files that import it get re-read too.",[15,517,518],{},"A few shapes it doesn't follow:",[520,521,522,536,548],"ul",{},[248,523,524,528,529,411,532,535],{},[525,526,527],"strong",{},"Default and namespace imports."," ",[49,530,531],{},"import theme from '.\u002Ftheme'",[49,533,534],{},"import * as theme"," aren't followed. Use named imports.",[248,537,538,541,542,544,545,547],{},[525,539,540],{},"Ambiguous barrels."," If two ",[49,543,511],{}," lines both export a ",[49,546,499],{},", Panda can't tell which one you mean, so it leaves it.",[248,549,550,553],{},[525,551,552],{},"Values that aren't static over there either."," Following an import doesn't help if the other file builds the value at runtime.",[270,555,256,557],{"id":556},"enums-and-token",[49,558,259],{},[15,560,561],{},"TypeScript enums work, as long as each member has an explicit value:",[42,563,565],{"className":279,"code":564,"language":281,"meta":47,"style":47},"enum Size {\n  Small = '8px',\n  Large = '16px',\n}\n\ncss({ padding: Size.Large })\n",[49,566,567,577,589,601,605,609],{"__ignoreMap":47},[52,568,569,572,575],{"class":54,"line":55},[52,570,571],{"class":58},"enum",[52,573,574],{"class":116}," Size",[52,576,70],{"class":69},[52,578,579,582,584,587],{"class":54,"line":73},[52,580,581],{"class":62},"  Small",[52,583,66],{"class":58},[52,585,586],{"class":79}," '8px'",[52,588,83],{"class":69},[52,590,591,594,596,599],{"class":54,"line":86},[52,592,593],{"class":62},"  Large",[52,595,66],{"class":58},[52,597,598],{"class":79}," '16px'",[52,600,83],{"class":69},[52,602,603],{"class":54,"line":97},[52,604,100],{"class":69},[52,606,607],{"class":54,"line":103},[52,608,107],{"emptyLinePlaceholder":106},[52,610,611,613],{"class":54,"line":110},[52,612,355],{"class":116},[52,614,615],{"class":69},"({ padding: Size.Large })\n",[15,617,618,619,622],{},"An auto-numbered member, one with no ",[49,620,621],{},"= value",", gets dropped.",[15,624,625,627],{},[49,626,259],{}," is the same idea from the other direction. Instead of Panda following your value, Panda fills in its own:",[42,629,631],{"className":279,"code":630,"language":281,"meta":47,"style":47},"import { token } from '..\u002Fstyled-system\u002Ftokens'\n\ncss({\n  boxShadow:\n    `0 0 0 1px ${token('colors.blue.500')}`,\n})\n",[49,632,633,645,649,655,660,681],{"__ignoreMap":47},[52,634,635,637,640,642],{"class":54,"line":55},[52,636,470],{"class":58},[52,638,639],{"class":69}," { token } ",[52,641,476],{"class":58},[52,643,644],{"class":79}," '..\u002Fstyled-system\u002Ftokens'\n",[52,646,647],{"class":54,"line":73},[52,648,107],{"emptyLinePlaceholder":106},[52,650,651,653],{"class":54,"line":86},[52,652,355],{"class":116},[52,654,166],{"class":69},[52,656,657],{"class":54,"line":97},[52,658,659],{"class":69},"  boxShadow:\n",[52,661,662,665,668,670,673,676,679],{"class":54,"line":103},[52,663,664],{"class":79},"    `0 0 0 1px ${",[52,666,667],{"class":116},"token",[52,669,144],{"class":79},[52,671,672],{"class":79},"'colors.blue.500'",[52,674,675],{"class":79},")",[52,677,678],{"class":79},"}`",[52,680,83],{"class":69},[52,682,683],{"class":54,"line":110},[52,684,394],{"class":69},[15,686,687,688,691,692,695,696,699,700,702,703,706,707,709],{},"At build time, ",[49,689,690],{},"token('colors.blue.500')"," is replaced with the token's actual value, and ",[49,693,694],{},"token.var(...)"," with its ",[49,697,698],{},"var(--...)"," reference. This only happens when ",[49,701,667],{}," comes from your generated ",[49,704,705],{},"styled-system",". A different function that happens to be called ",[49,708,667],{}," is left alone.",[270,711,713],{"id":712},"small-helper-functions","Small helper functions",[15,715,716],{},"Helpers have the most specific rules. This one works:",[42,718,720],{"className":279,"code":719,"language":281,"meta":47,"style":47},"const ring = (color: string) => ({\n  outlineWidth: '2px',\n  outlineColor: color,\n})\n\ncss(ring('blue.500'))\n",[49,721,722,753,763,768,772,776],{"__ignoreMap":47},[52,723,724,726,729,731,734,738,741,744,747,750],{"class":54,"line":55},[52,725,59],{"class":58},[52,727,728],{"class":116}," ring",[52,730,66],{"class":58},[52,732,733],{"class":69}," (",[52,735,737],{"class":736},"s4XuR","color",[52,739,740],{"class":58},":",[52,742,743],{"class":62}," string",[52,745,746],{"class":69},") ",[52,748,749],{"class":58},"=>",[52,751,752],{"class":69}," ({\n",[52,754,755,758,761],{"class":54,"line":73},[52,756,757],{"class":69},"  outlineWidth: ",[52,759,760],{"class":79},"'2px'",[52,762,83],{"class":69},[52,764,765],{"class":54,"line":86},[52,766,767],{"class":69},"  outlineColor: color,\n",[52,769,770],{"class":54,"line":97},[52,771,394],{"class":69},[52,773,774],{"class":54,"line":103},[52,775,107],{"emptyLinePlaceholder":106},[52,777,778,780,782,785,787,790],{"class":54,"line":110},[52,779,355],{"class":116},[52,781,144],{"class":69},[52,783,784],{"class":116},"ring",[52,786,144],{"class":69},[52,788,789],{"class":79},"'blue.500'",[52,791,792],{"class":69},"))\n",[15,794,795,796,798,799,801,802,804],{},"Panda isn't running ",[49,797,784],{},". It reads the function's body, substitutes ",[49,800,789],{}," for ",[49,803,737],{},", and gets a plain object back.",[15,806,807,808,810,811,813,814,817],{},"That only works for a small set of shapes. A helper can be a single arrow expression, or a few ",[49,809,59],{}," or ",[49,812,424],{}," declarations followed by one ",[49,815,816],{},"return",". It can destructure its parameters, use defaults, spread objects and call other helpers that follow the same rules.",[15,819,820,821,824,825,827,828,831,832,411,835,838],{},"It can't use ",[49,822,823],{},"if",", loops, more than one ",[49,826,816],{},", ",[49,829,830],{},"...rest"," patterns, or built-ins like ",[49,833,834],{},".map",[49,836,837],{},"Object.fromEntries",". Those helpers are left unresolved, and their styles don't get generated. Most of the time the fix is a ternary:",[42,840,842],{"className":279,"code":841,"language":281,"meta":47,"style":47},"function ring(color?: string) {\n  if (!color) return {}\n  return { outlineColor: color }\n}\n",[49,843,844,862,880,887],{"__ignoreMap":47},[52,845,846,848,850,852,854,857,859],{"class":54,"line":55},[52,847,113],{"class":58},[52,849,728],{"class":116},[52,851,144],{"class":69},[52,853,737],{"class":736},[52,855,856],{"class":58},"?:",[52,858,743],{"class":62},[52,860,861],{"class":69},") {\n",[52,863,864,867,869,872,875,877],{"class":54,"line":73},[52,865,866],{"class":58},"  if",[52,868,733],{"class":69},[52,870,871],{"class":58},"!",[52,873,874],{"class":69},"color) ",[52,876,816],{"class":58},[52,878,879],{"class":69}," {}\n",[52,881,882,884],{"class":54,"line":86},[52,883,197],{"class":58},[52,885,886],{"class":69}," { outlineColor: color }\n",[52,888,889],{"class":54,"line":97},[52,890,100],{"class":69},[15,892,893],{},"becomes:",[42,895,897],{"className":279,"code":896,"language":281,"meta":47,"style":47},"const ring = (color?: string) =>\n  color ? { outlineColor: color } : {}\n",[49,898,899,920],{"__ignoreMap":47},[52,900,901,903,905,907,909,911,913,915,917],{"class":54,"line":55},[52,902,59],{"class":58},[52,904,728],{"class":116},[52,906,66],{"class":58},[52,908,733],{"class":69},[52,910,737],{"class":736},[52,912,856],{"class":58},[52,914,743],{"class":62},[52,916,746],{"class":69},[52,918,919],{"class":58},"=>\n",[52,921,922,925,928,931,933],{"class":54,"line":73},[52,923,924],{"class":69},"  color ",[52,926,927],{"class":58},"?",[52,929,930],{"class":69}," { outlineColor: color } ",[52,932,740],{"class":58},[52,934,879],{"class":69},[15,936,937],{},"Same behavior, and now it's a shape Panda can read.",[15,939,940],{},"In v1, a JavaScript evaluator did this work. In v2 there's no interpreter at all, which is why helpers have to fit these shapes.",[270,942,944,945,411,948],{"id":943},"ternaries-and","Ternaries, ",[49,946,947],{},"&&",[49,949,175],{},[15,951,952],{},"Panda can't know which branch of a ternary runs, so it keeps both:",[42,954,956],{"className":279,"code":955,"language":281,"meta":47,"style":47},"css({\n  fontWeight: active ? 'bold' : 'normal',\n})\n",[49,957,958,964,982],{"__ignoreMap":47},[52,959,960,962],{"class":54,"line":55},[52,961,355],{"class":116},[52,963,166],{"class":69},[52,965,966,969,971,974,977,980],{"class":54,"line":73},[52,967,968],{"class":69},"  fontWeight: active ",[52,970,927],{"class":58},[52,972,973],{"class":79}," 'bold'",[52,975,976],{"class":58}," :",[52,978,979],{"class":79}," 'normal'",[52,981,83],{"class":69},[52,983,984],{"class":54,"line":86},[52,985,394],{"class":69},[15,987,988,989,411,992,995,996,999,1000,1003],{},"Both ",[49,990,991],{},"bold",[49,993,994],{},"normal"," get CSS. If the condition is something Panda already knows, like ",[49,997,998],{},"size === 'lg'"," with a constant ",[49,1001,1002],{},"size",", it picks the right branch instead.",[15,1005,1006],{},"There's one catch. Both sides have to be workable. If either branch depends on something unknown, Panda drops the whole ternary, not just the bad half.",[15,1008,1009,827,1011,411,1014,1016,1017,1020,1021,224],{},[49,1010,947],{},[49,1012,1013],{},"||",[49,1015,175],{}," behave differently. When Panda can't work out the left side, it uses the right side. So ",[49,1018,1019],{},"isOpen && 'red.300'"," gives you ",[49,1022,1023],{},"red.300",[15,1025,1026],{},"That's the answer to the puzzle from the top:",[42,1028,1030],{"className":279,"code":1029,"language":281,"meta":47,"style":47},"colorByType[type] ?? 'gray.100'\n",[49,1031,1032],{"__ignoreMap":47},[52,1033,1034,1037,1039],{"class":54,"line":55},[52,1035,1036],{"class":69},"colorByType[type] ",[52,1038,175],{"class":58},[52,1040,1041],{"class":79}," 'gray.100'\n",[15,1043,1044,1046,1047,1049,1050,1052],{},[49,1045,132],{}," comes from the running app, so the left side is unknown, and ",[49,1048,175],{}," resolves to its right side. ",[49,1051,223],{}," is the only value Panda ever sees.",[270,1054,1056],{"id":1055},"two-smaller-rules","Two smaller rules",[15,1058,1059,1060,1063,1064,1067],{},"A default value counts. In ",[49,1061,1062],{},"function Button({ size = 'md' })",", Panda generates CSS for ",[49,1065,1066],{},"md",". Anything a caller passes in later is unknown.",[15,1069,1070],{},"A partly known object still counts. If an object mixes static values with runtime ones, Panda keeps the static ones and skips the rest. One unknown property doesn't throw away the whole object.",[270,1072,1074],{"id":1073},"mdx-files-too","MDX files too",[15,1076,1077,1078,1081,1082,1085,1086,1089],{},"Panda reads ",[49,1079,1080],{},".mdx"," files in your ",[49,1083,1084],{},"include"," the same way. It picks up imports, ",[49,1087,1088],{},"{expressions}"," and the props on components:",[42,1091,1095],{"className":1092,"code":1093,"language":1094,"meta":47,"style":47},"language-mdx shiki shiki-themes github-light github-dark","import { Box } from '..\u002Fstyled-system\u002Fjsx'\n\n\u003CBox color=\"red.300\">Hello\u003C\u002FBox>\n","mdx",[49,1096,1097,1109,1113],{"__ignoreMap":47},[52,1098,1099,1101,1104,1106],{"class":54,"line":55},[52,1100,470],{"class":58},[52,1102,1103],{"class":69}," { Box } ",[52,1105,476],{"class":58},[52,1107,1108],{"class":79}," '..\u002Fstyled-system\u002Fjsx'\n",[52,1110,1111],{"class":54,"line":73},[52,1112,107],{"emptyLinePlaceholder":106},[52,1114,1115,1118,1121,1124,1126,1129,1132,1134],{"class":54,"line":86},[52,1116,1117],{"class":69},"\u003C",[52,1119,1120],{"class":62},"Box",[52,1122,1123],{"class":116}," color",[52,1125,138],{"class":58},[52,1127,1128],{"class":79},"\"red.300\"",[52,1130,1131],{"class":69},">Hello\u003C\u002F",[52,1133,1120],{"class":62},[52,1135,1136],{"class":69},">\n",[15,1138,1139],{},"It skips fenced code blocks, inline code, frontmatter and link URLs, so a code example in your docs never turns into real CSS. This landed in Panda 2.1.2. Before that, the Markdown around a component could stop its styles from being found.",[270,1141,1143],{"id":1142},"fixing-the-puzzle","Fixing the puzzle",[15,1145,1146,1147,1149,1150,1153],{},"Since ",[49,1148,132],{}," is only known at runtime, the fix is to put every color somewhere Panda can see it. A ",[49,1151,1152],{},"cva"," recipe does that, because each variant is written out in full:",[42,1155,1157],{"className":279,"code":1156,"language":281,"meta":47,"style":47},"const section = cva({\n  base: { color: 'gray.100' },\n  variants: {\n    type: {\n      primary: { color: 'red.300' },\n      secondary: { color: 'blue.300' },\n    },\n  },\n})\n\nsection({ type })\n",[49,1158,1159,1173,1184,1189,1194,1203,1212,1217,1222,1226,1230],{"__ignoreMap":47},[52,1160,1161,1163,1166,1168,1171],{"class":54,"line":55},[52,1162,59],{"class":58},[52,1164,1165],{"class":62}," section",[52,1167,66],{"class":58},[52,1169,1170],{"class":116}," cva",[52,1172,166],{"class":69},[52,1174,1175,1178,1181],{"class":54,"line":73},[52,1176,1177],{"class":69},"  base: { color: ",[52,1179,1180],{"class":79},"'gray.100'",[52,1182,1183],{"class":69}," },\n",[52,1185,1186],{"class":54,"line":86},[52,1187,1188],{"class":69},"  variants: {\n",[52,1190,1191],{"class":54,"line":97},[52,1192,1193],{"class":69},"    type: {\n",[52,1195,1196,1199,1201],{"class":54,"line":103},[52,1197,1198],{"class":69},"      primary: { color: ",[52,1200,80],{"class":79},[52,1202,1183],{"class":69},[52,1204,1205,1208,1210],{"class":54,"line":110},[52,1206,1207],{"class":69},"      secondary: { color: ",[52,1209,92],{"class":79},[52,1211,1183],{"class":69},[52,1213,1214],{"class":54,"line":123},[52,1215,1216],{"class":69},"    },\n",[52,1218,1219],{"class":54,"line":153},[52,1220,1221],{"class":69},"  },\n",[52,1223,1224],{"class":54,"line":169},[52,1225,394],{"class":69},[52,1227,1228],{"class":54,"line":183},[52,1229,107],{"emptyLinePlaceholder":106},[52,1231,1232,1234],{"class":54,"line":189},[52,1233,204],{"class":116},[52,1235,1236],{"class":69},"({ type })\n",[15,1238,1239],{},"Now every color is in the source, so every color gets CSS, and the runtime only has to pick a class.",[15,1241,1242,1243,1251],{},"That's the pattern behind everything in this post. Panda can work out a lot more than people expect: imports, enums, tokens, helpers, both sides of a ternary. When it can't, move the values into a shape it can read, like a recipe, or list them in ",[33,1244,1248],{"href":1245,"rel":1246},"https:\u002F\u002Fpanda-css.com\u002Fdocs\u002Fstyling\u002Fstatic",[1247],"nofollow",[49,1249,1250],{},"staticCss"," so Panda generates them anyway.",[15,1253,1254],{},[29,1255,1256,1257,827,1259,827,1263,224],{},"Next in the series: how Panda rewrites those ternaries straight into your code. If you missed the earlier parts: ",[33,1258,36],{"href":35},[33,1260,1262],{"href":1261},"\u002Fblog\u002Fevery-style-is-an-atom","Every style is an atom",[33,1264,1266],{"href":1265},"\u002Fblog\u002Flook-it-up-once","Look it up once",[1268,1269,1270],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}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);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":47,"searchDepth":73,"depth":73,"links":1272},[1273,1274,1275,1276,1278,1279,1281,1282,1283],{"id":12,"depth":86,"text":13},{"id":272,"depth":73,"text":273},{"id":428,"depth":73,"text":429},{"id":556,"depth":73,"text":1277},"Enums and token()",{"id":712,"depth":73,"text":713},{"id":943,"depth":73,"text":1280},"Ternaries, && and ??",{"id":1055,"depth":73,"text":1056},{"id":1073,"depth":73,"text":1074},{"id":1142,"depth":73,"text":1143},null,"2026-10-24","Panda CSS reads your source at build time and never runs it. What its static evaluator can follow, where it stops, and how to write styles it can see.",false,{},"\u002Fblog\u002Fpanda-never-runs-your-code",{"title":5,"description":1286},"Panda never runs your code: how Panda CSS evaluates styles statically","blog\u002Fpanda-never-runs-your-code","vlh73NNGB2G3YbBu8hMNkZio8fOVV9h-H3hLHppP6rA",1792871031281]