[{"data":1,"prerenderedAt":1200},["ShallowReactive",2],{"i-simple-icons:github":3,"i-lucide:arrow-up-right":8,"i-lucide:loader":10,"labs-en-GB":12},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 2v4m4.2 1.8l2.9-2.9M18 12h4m-5.8 4.2l2.9 2.9M12 18v4m-7.1-2.9l2.9-2.9M2 12h4M4.9 4.9l2.9 2.9\"\u002F>",[13],{"id":14,"title":15,"body":16,"date":1187,"description":1188,"draft":6,"extension":1189,"machineTranslated":6,"meta":1190,"navigation":1191,"path":1192,"seo":1193,"stem":1194,"tags":1195,"translationKey":1198,"__hash__":1199},"labs\u002Fen-gb\u002Flabs\u002Fgoogle-ai-mode-rainbow-rim.md","Google's cursor-following rainbow rim",{"type":17,"value":18,"toc":1177},"minimark",[19,23,26,34,39,47,179,186,197,201,211,490,497,501,507,660,707,710,713,727,734,737,740,768,783,786,808,812,823,827,830,838,845,860,863,870,1085,1096,1099,1105,1112,1115,1124,1128,1131,1166,1173],[20,21,22],"p",{},"The \"AI Mode\" button on google.com does something lovely on hover: a slice of\nrainbow lights up its border and slides along with your cursor. Sweep left to\nright and it reads green → teal → blue. Sweep back and it reads red → orange →\nyellow → green. Same button, same gradient, different colours.",[20,24,25],{},"I pulled the CSS apart to find out how. It turns out to be five ideas stacked on\ntop of each other, and only one of them is a real trick.",[27,28,31],"lab-demo",{"caption":29,"title":30},"Hover and sweep across it — then flip direction.","AI Mode button",[32,33],"ai-mode-button",{},[35,36,38],"h2",{"id":37},"_1-it-is-not-a-border","1. It is not a border",[20,40,41,42,46],{},"The first surprise: nothing here draws a border. The glow layer fills the\n",[43,44,45],"strong",{},"whole"," pill, and then an opaque inner pill — inset by exactly one pixel —\nis painted on top of it.",[48,49,54],"pre",{"className":50,"code":51,"language":52,"meta":53,"style":53},"language-css shiki shiki-themes material-theme-lighter github-light tokyo-night",".glow    { position: absolute; inset: 0; }      \u002F* rainbow fills the pill *\u002F\n.surface { position: absolute; inset: 1px;      \u002F* covers all but the rim *\u002F\n           background: #303134;\n           border-radius: 100px; }\n","css","",[55,56,57,107,142,161],"code",{"__ignoreMap":53},[58,59,62,66,70,74,78,82,86,89,92,94,98,100,103],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sXEfR",".",[58,67,69],{"class":68},"slAiF","glow",[58,71,73],{"class":72},"s9td2","    {",[58,75,77],{"class":76},"s9r1l"," position",[58,79,81],{"class":80},"scI-1",":",[58,83,85],{"class":84},"s1NLD"," absolute",[58,87,88],{"class":80},";",[58,90,91],{"class":76}," inset",[58,93,81],{"class":80},[58,95,97],{"class":96},"sIwlr"," 0",[58,99,88],{"class":80},[58,101,102],{"class":72}," }",[58,104,106],{"class":105},"s5acS","      \u002F* rainbow fills the pill *\u002F\n",[58,108,110,112,115,118,120,122,124,126,128,130,133,137,139],{"class":60,"line":109},2,[58,111,65],{"class":64},[58,113,114],{"class":68},"surface",[58,116,117],{"class":72}," {",[58,119,77],{"class":76},[58,121,81],{"class":80},[58,123,85],{"class":84},[58,125,88],{"class":80},[58,127,91],{"class":76},[58,129,81],{"class":80},[58,131,132],{"class":96}," 1",[58,134,136],{"class":135},"s2CoJ","px",[58,138,88],{"class":80},[58,140,141],{"class":105},"      \u002F* covers all but the rim *\u002F\n",[58,143,145,148,150,154,158],{"class":60,"line":144},3,[58,146,147],{"class":76},"           background",[58,149,81],{"class":80},[58,151,153],{"class":152},"sJICf"," #",[58,155,157],{"class":156},"sr7DH","303134",[58,159,160],{"class":80},";\n",[58,162,164,167,169,172,174,176],{"class":60,"line":163},4,[58,165,166],{"class":76},"           border-radius",[58,168,81],{"class":80},[58,170,171],{"class":96}," 100",[58,173,136],{"class":135},[58,175,88],{"class":80},[58,177,178],{"class":72}," }\n",[20,180,181,182,185],{},"Only the 1px that the inner pill fails to cover survives, and that reads as a\nglowing border. On hover Google adds ",[55,183,184],{},"filter: blur(2px)"," to that inner surface,\nwhich softens its edge and lets the rim bleed inwards a little.",[20,187,188,189,192,193,196],{},"No ",[55,190,191],{},"mask-composite"," ring maths, no ",[55,194,195],{},"border-image",", no SVG stroke. Just occlusion.",[35,198,200],{"id":199},"_2-one-rainbow-painted-once-only-ever-rotated","2. One rainbow, painted once, only ever rotated",[20,202,203,204,207,208,81],{},"The colours come from a single circular element carrying a ",[55,205,206],{},"conic-gradient",".\nIt is never recoloured at runtime — the only thing that ever changes is its\n",[55,209,210],{},"rotate",[48,212,214],{"className":50,"code":213,"language":52,"meta":53,"style":53},".wheel {\n  aspect-ratio: 1 \u002F 1;\n  border-radius: 50%;\n  rotate: var(--wheel);\n  background: conic-gradient(\n    #3186ff 34%, #9378ff 37%, #f96bd6 39%, #fc413d 41%, #fc413d 48%,\n    #ff6b2b 50%, #fec700 52%, #ffdb0f 56%, #88de42 58%, #0ebc5f 61%,\n    #0ebc5f 65%, #2eaab2 70%, #00a9bb 72%, #3186ff 73%, #3186ff 100%);\n}\n",[55,215,216,226,244,259,282,296,361,423,484],{"__ignoreMap":53},[58,217,218,220,223],{"class":60,"line":61},[58,219,65],{"class":64},[58,221,222],{"class":68},"wheel",[58,224,225],{"class":72}," {\n",[58,227,228,231,233,235,239,242],{"class":60,"line":109},[58,229,230],{"class":76},"  aspect-ratio",[58,232,81],{"class":80},[58,234,132],{"class":96},[58,236,238],{"class":237},"sh-sn"," \u002F ",[58,240,241],{"class":96},"1",[58,243,160],{"class":80},[58,245,246,249,251,254,257],{"class":60,"line":144},[58,247,248],{"class":76},"  border-radius",[58,250,81],{"class":80},[58,252,253],{"class":96}," 50",[58,255,256],{"class":135},"%",[58,258,160],{"class":80},[58,260,261,264,266,270,273,277,280],{"class":60,"line":163},[58,262,263],{"class":76},"  rotate",[58,265,81],{"class":80},[58,267,269],{"class":268},"sfnAe"," var",[58,271,272],{"class":72},"(",[58,274,276],{"class":275},"sAiw0","--wheel",[58,278,279],{"class":72},")",[58,281,160],{"class":80},[58,283,285,288,290,293],{"class":60,"line":284},5,[58,286,287],{"class":76},"  background",[58,289,81],{"class":80},[58,291,292],{"class":268}," conic-gradient",[58,294,295],{"class":72},"(\n",[58,297,299,302,305,308,310,313,315,318,321,323,325,327,330,333,335,337,339,342,345,347,349,351,353,356,358],{"class":60,"line":298},6,[58,300,301],{"class":152},"    #",[58,303,304],{"class":156},"3186ff",[58,306,307],{"class":96}," 34",[58,309,256],{"class":135},[58,311,312],{"class":80},",",[58,314,153],{"class":152},[58,316,317],{"class":156},"9378ff",[58,319,320],{"class":96}," 37",[58,322,256],{"class":135},[58,324,312],{"class":80},[58,326,153],{"class":152},[58,328,329],{"class":156},"f96bd6",[58,331,332],{"class":96}," 39",[58,334,256],{"class":135},[58,336,312],{"class":80},[58,338,153],{"class":152},[58,340,341],{"class":156},"fc413d",[58,343,344],{"class":96}," 41",[58,346,256],{"class":135},[58,348,312],{"class":80},[58,350,153],{"class":152},[58,352,341],{"class":156},[58,354,355],{"class":96}," 48",[58,357,256],{"class":135},[58,359,360],{"class":80},",\n",[58,362,364,366,369,371,373,375,377,380,383,385,387,389,392,395,397,399,401,404,407,409,411,413,416,419,421],{"class":60,"line":363},7,[58,365,301],{"class":152},[58,367,368],{"class":156},"ff6b2b",[58,370,253],{"class":96},[58,372,256],{"class":135},[58,374,312],{"class":80},[58,376,153],{"class":152},[58,378,379],{"class":156},"fec700",[58,381,382],{"class":96}," 52",[58,384,256],{"class":135},[58,386,312],{"class":80},[58,388,153],{"class":152},[58,390,391],{"class":156},"ffdb0f",[58,393,394],{"class":96}," 56",[58,396,256],{"class":135},[58,398,312],{"class":80},[58,400,153],{"class":152},[58,402,403],{"class":156},"88de42",[58,405,406],{"class":96}," 58",[58,408,256],{"class":135},[58,410,312],{"class":80},[58,412,153],{"class":152},[58,414,415],{"class":156},"0ebc5f",[58,417,418],{"class":96}," 61",[58,420,256],{"class":135},[58,422,360],{"class":80},[58,424,426,428,430,433,435,437,439,442,445,447,449,451,454,457,459,461,463,465,468,470,472,474,476,478,480,482],{"class":60,"line":425},8,[58,427,301],{"class":152},[58,429,415],{"class":156},[58,431,432],{"class":96}," 65",[58,434,256],{"class":135},[58,436,312],{"class":80},[58,438,153],{"class":152},[58,440,441],{"class":156},"2eaab2",[58,443,444],{"class":96}," 70",[58,446,256],{"class":135},[58,448,312],{"class":80},[58,450,153],{"class":152},[58,452,453],{"class":156},"00a9bb",[58,455,456],{"class":96}," 72",[58,458,256],{"class":135},[58,460,312],{"class":80},[58,462,153],{"class":152},[58,464,304],{"class":156},[58,466,467],{"class":96}," 73",[58,469,256],{"class":135},[58,471,312],{"class":80},[58,473,153],{"class":152},[58,475,304],{"class":156},[58,477,171],{"class":96},[58,479,256],{"class":135},[58,481,279],{"class":72},[58,483,160],{"class":80},[58,485,487],{"class":60,"line":486},9,[58,488,489],{"class":72},"}\n",[20,491,492,493,496],{},"Notice that the interesting part only occupies 34%–73% of the turn — 140° out\nof 360°. Everything outside that is flat ",[55,494,495],{},"#3186ff",": a single 220° arc of blue\nspanning the 0°\u002F360° seam. That padding matters later.",[35,498,500],{"id":499},"_3-a-conic-gradient-used-as-a-mask-carves-out-the-comet","3. A conic gradient used as a mask carves out the comet",[20,502,503,504,81],{},"The parent of the wheel masks it down to a single arc, using two more conic\ngradients combined with ",[55,505,506],{},"mask-composite: intersect",[48,508,510],{"className":50,"code":509,"language":52,"meta":53,"style":53},".window {\n  mask-image:\n    conic-gradient(from var(--window), transparent 0, transparent 50%,\n                   black 68%, black 75%, transparent 89%),\n    conic-gradient(from var(--window), black 30%, transparent 50%, black 70%);\n  mask-composite: intersect;\n}\n",[55,511,512,521,529,566,599,644,656],{"__ignoreMap":53},[58,513,514,516,519],{"class":60,"line":61},[58,515,65],{"class":64},[58,517,518],{"class":68},"window",[58,520,225],{"class":72},[58,522,523,526],{"class":60,"line":109},[58,524,525],{"class":76},"  mask-image",[58,527,528],{"class":80},":\n",[58,530,531,534,536,540,542,544,547,549,551,554,556,558,560,562,564],{"class":60,"line":144},[58,532,533],{"class":268},"    conic-gradient",[58,535,272],{"class":72},[58,537,539],{"class":538},"s4Nsh","from",[58,541,269],{"class":268},[58,543,272],{"class":72},[58,545,546],{"class":275},"--window",[58,548,279],{"class":72},[58,550,312],{"class":80},[58,552,553],{"class":84}," transparent",[58,555,97],{"class":96},[58,557,312],{"class":80},[58,559,553],{"class":84},[58,561,253],{"class":96},[58,563,256],{"class":135},[58,565,360],{"class":80},[58,567,568,571,574,576,578,581,584,586,588,590,593,595,597],{"class":60,"line":163},[58,569,570],{"class":84},"                   black",[58,572,573],{"class":96}," 68",[58,575,256],{"class":135},[58,577,312],{"class":80},[58,579,580],{"class":84}," black",[58,582,583],{"class":96}," 75",[58,585,256],{"class":135},[58,587,312],{"class":80},[58,589,553],{"class":84},[58,591,592],{"class":96}," 89",[58,594,256],{"class":135},[58,596,279],{"class":72},[58,598,360],{"class":80},[58,600,601,603,605,607,609,611,613,615,617,619,622,624,626,628,630,632,634,636,638,640,642],{"class":60,"line":284},[58,602,533],{"class":268},[58,604,272],{"class":72},[58,606,539],{"class":538},[58,608,269],{"class":268},[58,610,272],{"class":72},[58,612,546],{"class":275},[58,614,279],{"class":72},[58,616,312],{"class":80},[58,618,580],{"class":84},[58,620,621],{"class":96}," 30",[58,623,256],{"class":135},[58,625,312],{"class":80},[58,627,553],{"class":84},[58,629,253],{"class":96},[58,631,256],{"class":135},[58,633,312],{"class":80},[58,635,580],{"class":84},[58,637,444],{"class":96},[58,639,256],{"class":135},[58,641,279],{"class":72},[58,643,160],{"class":80},[58,645,646,649,651,654],{"class":60,"line":298},[58,647,648],{"class":76},"  mask-composite",[58,650,81],{"class":80},[58,652,653],{"class":84}," intersect",[58,655,160],{"class":80},[58,657,658],{"class":60,"line":363},[58,659,489],{"class":72},[20,661,662,663,666,667,670,671,674,675,678,679,682,683,686,687,690,691,694,695,698,699,702,703,706],{},"Work the stops out in degrees and the intersection is not the tight arc it\nlooks like. ",[55,664,665],{},"intersect"," composites the layers with Porter-Duff ",[55,668,669],{},"source-in",", so\nwhere both gradients ramp their alphas ",[43,672,673],{},"multiply",". That leaves a long,\nquadratically soft tail: alpha leaves zero at ",[43,676,677],{},"180°",", climbs slowly at first —\nthe product of two rising ramps — reaches full at ",[43,680,681],{},"252°",", holds a plateau to\n",[43,684,685],{},"270°",", then falls away by ",[43,688,689],{},"320°",". That is a comet ",[43,692,693],{},"140° wide"," — 39% of a\nturn — most of it very faint tail.\nThe crisp core layer uses a tighter first mask (",[55,696,697],{},"transparent 62%, black 82%","),\nso it starts at ",[43,700,701],{},"223°"," and peaks at ",[43,704,705],{},"295°",", well past the bloom's plateau.",[20,708,709],{},"I got this wrong on my first pass — I read only the plateau, called the window\n68° wide, and could not then explain why one direction shows six colours. The\nramp is the whole story.",[20,711,712],{},"So the entire effect boils down to two angles:",[714,715,716,722],"ul",{},[717,718,719,721],"li",{},[55,720,546],{}," — where the comet is",[717,723,724,726],{},[55,725,276],{}," — which colours sit under it",[35,728,730,731],{"id":729},"_4-the-actual-trick-scale-7-15","4. The actual trick: ",[55,732,733],{},"scale: 7 1.5",[20,735,736],{},"Here is the part I did not expect. A conic sweep is circular. A button is a\nwide, flat pill. Rotating a conic gradient inside a pill would normally send\nthe highlight around a tight ellipse, not gliding along the long top edge.",[20,738,739],{},"Google fixes this by scaling the masked element non-uniformly:",[48,741,743],{"className":50,"code":742,"language":52,"meta":53,"style":53},".window { scale: 7 1.5; }\n",[55,744,745],{"__ignoreMap":53},[58,746,747,749,751,753,756,758,761,764,766],{"class":60,"line":61},[58,748,65],{"class":64},[58,750,518],{"class":68},[58,752,117],{"class":72},[58,754,755],{"class":76}," scale",[58,757,81],{"class":80},[58,759,760],{"class":96}," 7",[58,762,763],{"class":96}," 1.5",[58,765,88],{"class":80},[58,767,178],{"class":72},[20,769,770,771,774,775,778,779,782],{},"Stretching x by 7 squashes angular space. Run the numbers on a 220 × 44 pill:\nthe top-right corner of the pill sits at unscaled coordinates\n",[55,772,773],{},"(110 \u002F 7, −22 \u002F 1.5)"," ≈ ",[55,776,777],{},"(15.7, −14.7)",", which is only ",[43,780,781],{},"47° off vertical",".\nThe pill's entire top edge spans about ±47° — so a rotation of well under a\nquarter turn walks the highlight from one end to the other, and the arc hugs\nthe edge instead of looking like a pie slice.",[20,784,785],{},"That also makes the cursor mapping straightforward: undo the scale, and take\nthe angle.",[48,787,791],{"className":788,"code":789,"language":790,"meta":53,"style":53},"language-js shiki shiki-themes material-theme-lighter github-light tokyo-night","const angle = Math.atan2(px \u002F scaleX, -py \u002F scaleY) * 180 \u002F Math.PI;\nconst window = angle - 286;   \u002F\u002F 286° sits between the bloom plateau (252–270°)\n                              \u002F\u002F and the core peak (295°)\n","js",[55,792,793,798,803],{"__ignoreMap":53},[58,794,795],{"class":60,"line":61},[58,796,797],{},"const angle = Math.atan2(px \u002F scaleX, -py \u002F scaleY) * 180 \u002F Math.PI;\n",[58,799,800],{"class":60,"line":109},[58,801,802],{},"const window = angle - 286;   \u002F\u002F 286° sits between the bloom plateau (252–270°)\n",[58,804,805],{"class":60,"line":144},[58,806,807],{},"                              \u002F\u002F and the core peak (295°)\n",[35,809,811],{"id":810},"_5-two-copies-for-the-bloom","5. Two copies for the bloom",[20,813,814,815,818,819,822],{},"The whole stack is rendered twice inside the pill: once with ",[55,816,817],{},"filter: blur(5px)","\nand a wide mask window, once with ",[55,820,821],{},"filter: blur(1px)"," and a tighter one. The\nfirst is the halo, the second the bright core. Together they give the effect its\ndepth — a crisp filament sitting inside a soft glow.",[35,824,826],{"id":825},"why-the-colours-depend-on-direction","Why the colours depend on direction",[20,828,829],{},"This was the part that took the longest to work out, and my first answer was\nwrong.",[20,831,832,833,837],{},"My initial guess was that the wheel ",[834,835,836],"em",{},"lags"," behind the window — a spring, with\nthe residual flipping sign depending on travel direction. That produces a\ndirection-dependent tint, but it is speed-dependent: the colours drift while you\nmove and settle back when you slow down. On the real button they do not. Sweep\nslowly or quickly, the palette for a given direction is rock steady.",[20,839,840,841,844],{},"Which means the wheel is not lagging. It is ",[43,842,843],{},"locked"," to the window:",[48,846,848],{"className":788,"code":847,"language":790,"meta":53,"style":53},"wheel = window + offset;                       \u002F\u002F both rotate together\noffset = direction > 0 ? 0 : 45;               \u002F\u002F the only thing direction changes\n",[55,849,850,855],{"__ignoreMap":53},[58,851,852],{"class":60,"line":61},[58,853,854],{},"wheel = window + offset;                       \u002F\u002F both rotate together\n",[58,856,857],{"class":60,"line":109},[58,858,859],{},"offset = direction > 0 ? 0 : 45;               \u002F\u002F the only thing direction changes\n",[20,861,862],{},"Because the two rotate as one, the slice of rainbow under the comet never\ndrifts while you sweep.",[20,864,865,866,869],{},"Now put the offset together with that 140° comet. It is exactly as wide as the\ncolour band — both span 39% of a turn — but that does ",[43,867,868],{},"not"," mean each\ndirection sees all of it, because the two windows sit in different places. Run\nthe mask alpha across Google's stops and the asymmetry is stark:",[871,872,873,892],"table",{},[874,875,876],"thead",{},[877,878,879,883,886,889],"tr",{},[880,881,882],"th",{},"stop",[880,884,885],{},"band°",[880,887,888],{},"→ (offset 0°)",[880,890,891],{},"← (offset 45°)",[893,894,895,909,921,934,947,959,971,984,998,1014,1029,1042,1056,1071],"tbody",{},[877,896,897,901,904,907],{},[898,899,900],"td",{},"blue",[898,902,903],{},"122°",[898,905,906],{},"—",[898,908,906],{},[877,910,911,914,917,919],{},[898,912,913],{},"violet",[898,915,916],{},"133°",[898,918,906],{},[898,920,906],{},[877,922,923,926,929,931],{},[898,924,925],{},"pink",[898,927,928],{},"140°",[898,930,906],{},[898,932,933],{},".01",[877,935,936,939,942,944],{},[898,937,938],{},"red",[898,940,941],{},"148°",[898,943,906],{},[898,945,946],{},".03",[877,948,949,951,954,956],{},[898,950,938],{},[898,952,953],{},"173°",[898,955,906],{},[898,957,958],{},".31",[877,960,961,964,966,968],{},[898,962,963],{},"orange",[898,965,677],{},[898,967,906],{},[898,969,970],{},".43",[877,972,973,976,979,981],{},[898,974,975],{},"amber",[898,977,978],{},"187°",[898,980,933],{},[898,982,983],{},".58",[877,985,986,989,992,995],{},[898,987,988],{},"yellow",[898,990,991],{},"202°",[898,993,994],{},".10",[898,996,997],{},".93",[877,999,1000,1003,1006,1009],{},[898,1001,1002],{},"lime",[898,1004,1005],{},"209°",[898,1007,1008],{},".18",[898,1010,1011],{},[43,1012,1013],{},"1.00",[877,1015,1016,1019,1022,1025],{},[898,1017,1018],{},"green",[898,1020,1021],{},"220°",[898,1023,1024],{},".34",[898,1026,1027],{},[43,1028,1013],{},[877,1030,1031,1033,1036,1039],{},[898,1032,1018],{},[898,1034,1035],{},"234°",[898,1037,1038],{},".63",[898,1040,1041],{},".82",[877,1043,1044,1047,1049,1053],{},[898,1045,1046],{},"teal",[898,1048,681],{},[898,1050,1051],{},[43,1052,1013],{},[898,1054,1055],{},".46",[877,1057,1058,1061,1064,1068],{},[898,1059,1060],{},"cyan",[898,1062,1063],{},"259°",[898,1065,1066],{},[43,1067,1013],{},[898,1069,1070],{},".32",[877,1072,1073,1075,1078,1082],{},[898,1074,900],{},[898,1076,1077],{},"263°",[898,1079,1080],{},[43,1081,1013],{},[898,1083,1084],{},".25",[20,1086,1087,1088,1091,1092,1095],{},"Moving right, the window covers band degrees 180°–263° — only ",[43,1089,1090],{},"59%"," of the\nband. Everything before orange — blue, violet, pink, red — sits outside it and\nis not dimmed but absent. Moving left, the window covers 135°–263°, or ",[43,1093,1094],{},"91%",",\nand everything from pink onwards catches at least a little light.",[20,1097,1098],{},"That is why moving right reads as barely-there yellow into green into a bright\nteal-and-blue tip, while moving left reads as a full rainbow peaking on\nyellow-green. It is the same band both times, lit differently. Reverse direction\nand the offset eases from one value to the other, crossfading rather than\nsnapping.",[20,1100,1101,1102,1104],{},"There is a second reason the right-hand sweep ends so blue. The crisp core layer\npeaks at 295°, and with offset 0° that lands at band degree 295° — past the\nband's end at 263°, out in the flat blue filler. So moving right, the sharp\nfilament is pure ",[55,1103,495],{}," and only the softer bloom behind it carries colour.\nMoving left the same peak lands at 250°, right on the teal.",[20,1106,1107,1108,1111],{},"A consequence worth noting if you build one of these: the two windows overlap by\n95° of their 140° width, roughly two thirds, so the directions ",[43,1109,1110],{},"cannot"," be\ngiven independent palettes. There is one band, and the offsets only choose where\nthe light falls on it.",[20,1113,1114],{},"But that is not the same as having no per-direction control. Take \"bright\" to\nmean alpha ≥ 0.9 and the two zones are completely disjoint — moving right lights\nband degrees 245°–263°, moving left 200°–230°. So each direction's dominant\ncolours are yours to choose independently; it is only the faint tails that are\nshared. In the demo above, the arrows under each swatch show how strongly the\nbloom's window lights that stop in each direction, which turns \"which colours\ndoes this direction show?\" into something you can just read off.",[20,1116,1117,1118,1120,1121,1123],{},"This also explains a detail from earlier: those two custom properties. If the\noffset were a single constant, ",[55,1119,276],{}," would be redundant — you would only\nneed ",[55,1122,546],{},". The second property exists precisely because the offset moves.\nAnd that 219° arc of flat blue in the gradient is what keeps the comet from\nflashing a hard seam when it wanders past the end of the band — with a 140°\ncomet there is always somewhere safe for it to sit.",[35,1125,1127],{"id":1126},"worth-stealing","Worth stealing",[20,1129,1130],{},"The reusable ideas here, independent of rainbows:",[714,1132,1133,1143,1152],{},[717,1134,1135,1138,1139,1142],{},[43,1136,1137],{},"Occlusion beats ring maths."," An opaque inner element inset by ",[834,1140,1141],{},"n"," pixels is\na simpler, cheaper \"glowing border\" than any masked ring.",[717,1144,1145,1148,1149,1151],{},[43,1146,1147],{},"Non-uniform scale as a coordinate transform."," ",[55,1150,733],{}," turns a\ncircular angular space into one that tracks a rectangle's edge. Undo the scale\nin JS to map the cursor back.",[717,1153,1154,1157,1158,1161,1162,1165],{},[43,1155,1156],{},"Animate rotations, not colours."," One static gradient plus two angles is far\ncheaper than rebuilding gradients per frame, and both angles are registerable\nas ",[55,1159,1160],{},"\u003Cangle>"," via ",[55,1163,1164],{},"@property",", so they can be transitioned by CSS.",[20,1167,1168,1169,1172],{},"Open the wiring panel on the demo above — the glow stays lit while it is open —\nand drag ",[55,1170,1171],{},"scale X"," down towards 1: you can watch the angular space un-squash\nand the highlight collapse back into a circular sweep. That single slider is\nthe whole trick.",[1174,1175,1176],"style",{},"html pre.shiki code .sXEfR, html code.shiki .sXEfR{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#E0AF68}html pre.shiki code .slAiF, html code.shiki .slAiF{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#9ECE6A}html pre.shiki code .s9td2, html code.shiki .s9td2{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#9ABDF5}html pre.shiki code .s9r1l, html code.shiki .s9r1l{--shiki-light:#8796B0;--shiki-default:#005CC5;--shiki-dark:#7AA2F7}html pre.shiki code .scI-1, html code.shiki .scI-1{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .s1NLD, html code.shiki .s1NLD{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#FF9E64}html pre.shiki code .sIwlr, html code.shiki .sIwlr{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#FF9E64}html pre.shiki code .s5acS, html code.shiki .s5acS{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#51597D;--shiki-dark-font-style:italic}html pre.shiki code .s2CoJ, html code.shiki .s2CoJ{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#F7768E}html pre.shiki code .sJICf, html code.shiki .sJICf{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#9AA5CE}html pre.shiki code .sr7DH, html code.shiki .sr7DH{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#9AA5CE}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);}html pre.shiki code .sh-sn, html code.shiki .sh-sn{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#BB9AF7}html pre.shiki code .sfnAe, html code.shiki .sfnAe{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#0DB9D7}html pre.shiki code .sAiw0, html code.shiki .sAiw0{--shiki-light:#90A4AE;--shiki-default:#E36209;--shiki-dark:#C0CAF5}html pre.shiki code .s4Nsh, html code.shiki .s4Nsh{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#89DDFF}",{"title":53,"searchDepth":109,"depth":109,"links":1178},[1179,1180,1181,1182,1184,1185,1186],{"id":37,"depth":109,"text":38},{"id":199,"depth":109,"text":200},{"id":499,"depth":109,"text":500},{"id":729,"depth":109,"text":1183},"4. The actual trick: scale: 7 1.5",{"id":810,"depth":109,"text":811},{"id":825,"depth":109,"text":826},{"id":1126,"depth":109,"text":1127},"2026-08-12","How the \"AI Mode\" button on google.com paints a rainbow along its border that follows your cursor — and why the colours change depending on which way you move.","md",{},true,"\u002Fen-gb\u002Flabs\u002Fgoogle-ai-mode-rainbow-rim",{"title":15,"description":1188},"en-gb\u002Flabs\u002Fgoogle-ai-mode-rainbow-rim",[52,206,1196,1197],"mask","reverse-engineering","google-ai-mode-rainbow-rim","3pT-yoKNkBTobLn3riQQ_wJBjAMBsAe_ZGUfyZoyOns",1792626866943]