1import{j as a,r as A,A as Xe,T as Je,F as Qe,t as de,U as Ze,V as et,K as tt,a as he}from"./index-DdIJM-_l.js";import{u as at}from"./useSuspenseQuery-Bj7k8sXb.js";import{P as st,V as Ne,a as Me,e as it}from"./arcadeShare-CksMuQ5V.js";import{S as nt}from"./shield-D8Qx_HJR.js";import{P as ot,A as lt,a as rt}from"./pause-16gwaKsT.js";import{A as ct}from"./arrow-left-BL2IAPX1.js";import{R as Te}from"./rotate-ccw-VUJk9J6S.js";import{T as Ge,G as dt}from"./trophy-DdYlxDPQ.js";import{a as ht}from"./CalloutCards-CbI6pdfo.js";import"./useBaseQuery-CHb0wZz4.js";const be=[{name:"PRE-LAUNCH PANIC",sky:"#141b3a",floor:"#1d2550",accent:"#7c5cff"},{name:"LAUNCH DAY DISASTER",sky:"#2a1420",floor:"#35192a",accent:"#ff5a5f"},{name:"POST-LAUNCH SURVIVAL",sky:"#0c2530",floor:"#113240",accent:"#22d3ee"}],Z={broken404:{label:"404",action:"jump",color:"#ff5a5f",problem:"A priority URL vanished without a replacement",why:"Links, rankings and bookmarks pointing at a valuable page hit a dead end. Not every 404 is bad, but losing an important migrated URL is.",fix:"Map every high value old URL to its closest matching new URL with a 301 before launch."},loop:{label:"LOOP",action:"dodge",color:"#f59e0b",problem:"Redirect loops and chains",why:"Users and crawlers never reach a working page, and long chains waste crawl effort.",fix:"Every redirect should go straight to a final 200 page. Crawl your redirect list after launch."},noindex:{label:"NOINDEX",action:"duck",color:"#f59e0b",problem:"Staging noindex left on the live site",why:"Google is being told not to index pages you want to rank, so they can drop out of results.",fix:"Check meta robots and X-Robots-Tag headers on live templates on launch day."},bridge:{label:"LINK",action:"jump",color:"#ff5a5f",problem:"Internal links still point at old URLs",why:"Every click goes through a redirect, which slows users and sends mixed signals about which URLs matter.",fix:"Update navigation, body links and templates to point directly at the new URLs."},canonical:{label:"CANON",action:"dodge",color:"#f59e0b",problem:"Canonical tags pointing at the old site",why:"You are telling Google the old (redirected) URL is the preferred version, which confuses indexing.",fix:"Canonicals on new pages should self reference the correct new URL."},robots:{label:"ROBOTS",action:"dodge",color:"#ff5a5f",problem:"robots.txt blocking the live site",why:"If crawling is blocked, Google cannot see your redirects or your new content.",fix:"Replace the staging robots.txt and test it in Search Console on launch day."},server:{label:"5XX",action:"dodge",color:"#ff5a5f",problem:"Server errors during launch",why:"Google recrawls heavily after a migration. Repeated 5XX errors slow crawling and can drop pages.",fix:"Lo
1ad test before launch and monitor server logs and uptime closely in the first weeks."}},mt=[["broken404","bridge","loop","robots"],["noindex","robots","canonical","server","loop","broken404"],["server","canonical","bridge","noindex","broken404","loop"]],Re={r301:{label:"301",points:100,color:"#22d3ee"},sitemap:{label:"XML",points:75,color:"#22d3ee"},links:{label:"LINKS",points:100,color:"#22d3ee"},canon:{label:"CANON",points:75,color:"#22d3ee"},qa:{label:"QA",points:150,color:"#a3e635"},map:{label:"MAP",points:50,shield:!0,color:"#c084fc"},monitor:{label:"GSC",points:50,shield:!0,color:"#c084fc"}},me=[{id:"redirect-match",phase:0,situation:"Your most valuable product page has moved. What do you do?",answers:["301 to homepage","301 to matching new URL","Delete old URL"],correct:1,explanation:"A permanent redirect to the relevant replacement helps users and Google reach the right page. Mass homepage redirects can be treated as soft 404s.",practice:"Redirect old URLs to their closest equivalent."},{id:"retired",phase:0,situation:"A discontinued product has no replacement or close alternative.",answers:["Return 404 or 410","301 to homepage","Keep it live, blank"],correct:0,explanation:"If there is genuinely no relevant replacement, a 404 or 410 is the honest, correct response. Not every 404 is a mistake.",practice:"Only redirect when a relevant destination exists."},{id:"mapping",phase:0,situation:"Two weeks before launch. What should exist already?",answers:["A launch party","A URL redirect map","A new logo"],correct:1,explanation:"A mapping document pairing every important old URL with its new URL is the backbone of a safe migration.",practice:"Build and sign off the redirect map before launch."},{id:"test-staging",phase:0,situation:"The redirect map is ready. When should you test it?",answers:["After launch","Never, trust it","On staging, before launch"],correct:2,explanation:"Crawl the old URL list against staging to catch chains, loops and wrong destinations before real users do.",practice:"Test redirects before go live."},{id:"noindex",phase:1,situation:"Launch day. Live pages still carry the staging noindex tag.",answers:["Leave it a week","Remove it now","Add more noindex"],correct:1,explanation:"Noindex on important live pages tells Google to drop them. Remove unintended noindex immediately.",practice:"Audit meta robots on every live template."},{id:"robots",phase:1,situation:"robots.txt on the new site says Disallow: /",answers:["Fix it to allow crawling","It's fine","Block Google too"],correct:0,explanation:"A blanket disallow stops Google crawling your new pages and seeing your redirects.",practice:"Swap the staging robots.txt for the live version."},{id:"internal-links",phase:1,situation:"Your menus still link to old URLs that redirect. Best move?",answers:["Redirects cover it","Remove the menu","Update links to new URLs"],correct:2,explanation:"Redirects are a safety net. Internal links should point directly at the final new URLs.",practice:"Update internal links site wide."},{id:"canonical",phase:1,situation:"New pages have canonical tags pointing to the old domain.",answers:["Point to new URLs","Remove all pages","Keep the old ones"],correct:0,explanation:"Canonicals should name the preferred new URL, usually self referencing.",practice:"Check canonicals on every template."},{id:"sitemap",phase:1,situation:"Which URLs belong in the new XML sitemap?",answers:["Old redirected URLs","New indexable 200 URLs","Every URL ever"],correct:1,explanation:"The sitemap should list the new canonical, indexable URLs that return 200.",practice:"Submit a clean new sitemap at launch."},{id:"temp-302",phase:1,situation:"A page is offline for 48 hours of maintenance, then returns at the same URL.",answers:["301 permanently","302 temporarily","Delete it"],correct:1,explanation:"A temporary redirect is right for a genuinely temporary move. 302s are not always wrong.",practice:"Match the redirect type to your intent."},{id:"gsc",phase:2,situation:"The site is live. Where do you watch for crawl and indexing problems?",answers:["Nowhere, it's done","Social media","Search Console"],correct:2,explanation:"Search Console shows indexing, crawl errors and coverage changes on both old and new properties.",practice:"Monitor Search Console daily after launch."}
1,{id:"dip",phase:2,situation:"Organic traffic dips 8% in week one. What now?",answers:["Roll back everything","Investigate by page and template","Panic on Slack"],correct:1,explanation:"Some fluctuation is normal while Google recrawls. Compare against your baseline by page to find real problems.",practice:"Investigate before reacting."},{id:"coa",phase:2,situation:"You moved from oldbrand.com to newbrand.com. What else helps?",answers:["Change of Address tool","Nothing else","Noindex the old site"],correct:0,explanation:"Change of Address in Search Console applies to domain or subdomain moves. It is not needed for a CMS change on the same domain.",practice:"Use Change of Address for domain moves only."},{id:"coa-cms",phase:2,situation:"Same domain, new CMS, some URL paths changed. Use Change of Address?",answers:["Yes, always","No, redirects and monitoring","Move domains too"],correct:1,explanation:"Change of Address is only for domain or subdomain moves. Path changes need redirects and monitoring.",practice:"Pick the tool that matches the migration type."},{id:"home-ok",phase:2,situation:"An old 'Home - Welcome' URL has moved. Where should it redirect?",answers:["A random blog post","404 it","The new homepage"],correct:2,explanation:"A homepage redirect is right when the homepage is genuinely the equivalent page.",practice:"Relevance decides the destination."},{id:"backlinks",phase:2,situation:"Key partners link to old URLs. Anything worth doing?",answers:["Ask them to update links","Block their sites","Nothing ever"],correct:0,explanation:"Redirects pass users through, but updating important external links where practical is cleaner.",practice:"Update top external links where you can."}],ye={before:["Crawl the old site and export all URLs","Record baseline traffic and rankings","Bu
1ild and test the redirect map","Check staging templates and internal links"],during:["Remove staging noindex and robots blocks","Verify 301s go straight to 200 pages","Check canonicals and submit the new sitemap"],after:["Monitor Search Console and server logs","Compare traffic to baseline by page","Fix crawl errors and keep redirects in place"]};function ft(e,i){return i&&e<3e3?"Congratulations! You've successfully migrated your website out of Google.":i?"Googlebot has some questions.":e>12e3?"Congratulations. The developers are speaking to you again.":"The website survived. Your Slack notifications haven't."}const Ae="mm_best_score",ut=[0,8,3,10],pt=[[0,3,7,12],[0,4,7,12],[0,4,7,12],[0,4,7,12]],gt=()=>1+(Math.random()-.5)*.05;class bt{ctx=null;master;music;filter;shaper;sfxBus;gateBus;noiseBuf;distCurve;timer=0;nextTime=0;step=0;bpm=110;distorted=!1;enabled=!1;state={speed:14,cycle:0,health:3,gate:!1,urgency:0,playing:!1};init(){const i=new AudioContext;this.ctx=i;const l=i.createDynamicsCompressor();l.threshold.value=-16,l.ratio.value=5,l.attack.value=.003,l.release.value=.2,this.master=i.createGain(),this.master.gain.value=.6,this.master.connect(l).connect(i.destination),this.music=i.createGain(),this.music.gain.value=0,this.filter=i.createBiquadFilter(),this.filter.type="lowpass",this.filter.frequency.value=16e3,this.shaper=i.createWaveShaper(),this.music.connect(this.filter).connect(this.shaper).connect(this.master),this.sfxBus=i.createGain(),this.sfxBus.gain.value=.85,this.sfxBus.connect(this.master),this.gateBus=i.createGain(),this.gateBus.gain.value=0,this.gateBus.connect(this.master),this.noiseBuf=i.createBuffer(1,i.sampleRate,i.sampleRate);const n=this.noiseBuf.getChannelData(0);for(let c=0;c<n.length;c++)n[c]=Math.random()*2-1;const o=1024;this.distCurve=new Float32Array(new ArrayBuffer(o*4));for(let c=0;c<o;c++){const u=c/o*2-1;this.distCurve[c]=9*u*20*(Math.PI/180)/(Math.PI+6*Math.abs(u))}}setEnabled(i){try{i?(this.ctx||this.init(),this.ctx.resume(),this.enabled=!0,this.timer||(this.nextTime=this.ctx.currentTime+.05,this.timer=setInterval(()=>this.tick(),25))):(this.enabled=!1,this.timer&&clearInterval(this.timer),this.timer=0,this.ctx?.suspend())}catch{}}suspend(){this.timer&&clearInterval(this.timer),this.timer=0,this.ctx?.suspend()}resume(){this.enabled&&this.setEnabled(!0)}dispose(){this.setEnabled(!1),this.ctx?.close(),this.ctx=null}update(i){Object.assign(this.state,i);const l=this.ctx;if(!l||!this.enabled)return;const n=l.currentTime,o=this.state;this.music.gain.setTargetAtTime(o.playing?o.gate?.07:.3:0,n,.25),this.gateBus.gain.setTargetAtTime(o.playing&&o.gate?.45:0,n,.15);const c=o.playing&&o.health<=1;this.filter.frequency.setTargetAtTime(c?1300:16e3,n,.4),c!==this.distorted&&(this.distorted=c,this.shaper.curve=c?this.distCurve:null)}tick(){const i=this.ctx;if(i)for(;this.nextTime<i.currentTime+.12;){this.schedule(this.step,this.nextTime);const l=108+Math.max(0,Math.min(1,(this.state.speed-14)/18))*64;this.bpm+=(l-this.bpm)*.04,this.nextTime+=60/this.bpm/4,this.step=(this.step+1)%64}}schedule(i,l){const n=this.state;if(!n.playing)return;const o=Math.floor(i/16),c=55*2**(ut[o]/12),u=pt[o],p=this.music;if(i%4===0&&this.tone(130,.12,"sine",.35,p,l,42),i%2===0&&this.tone(c*(i%4===0?1:2),.11,"square",.08,p,l),this.tone(c*4*2**(u[i%4]/12),.08,"triangle",.06,p,l),(n.cycle>=1||n.speed>21)&&i%4===2&&this.noise(.04,.05,p,l,7e3),n.speed>27&&i%2===1&&this.noise(.025,.03,p,l,9e3),n.speed>25&&i%8===4&&this.tone(c*8*2**(u[i/4%3|0]/12),.18,"square",.025,p,l),n.gate){const v=this.gateBus,g=n.urgency;i%4===0&&this.tone(55,.22,"sawtooth",.22,v,l,50),i%8===2&&this.tone(233,.12,"square",.05,v,l);const j=g<.4?4:g<.7?2:1;i%j===0&&this.tone(g>.7?1760:1320,.025,"square",.05,v,l),g>.7&&i%8===0&&(this.tone(70,.1,"sine",.5,v,l,40),this.tone(64,.1,"sine",.4,v,l+.14,38))}}tone(i,l,n,o,c,u,p){const d=this.ctx,v=u??d.currentTime,g=d.createOscillator(),j=d.createGain();g.type=n,g.frequency.setValueAtTime(i,v),p&&g.frequency.exponentialRampToValueAtTime(Math.max(20,p),v+l),j.gain.setValueAtTime(1e-4,v),j.gain.exponentialRampToValueAtTime(o,v+.006),j.gain.exponentialRampToValueAtTime(1e-4,v+l),g.connect(j).connect(c),g.start(v),g.stop(v+l+.02)}noise(i,l,n,o,c=800){const u=this.ctx,p=o??u.currentTime,d=u.createBufferSource();d.buffer=this.noiseBuf;const v=u.createBiquadFilter();v.type="highpass",v.frequency.value=c;const g=u.createGain();g.gain.setValueAtTime(l,p),g.gain.exponentialRampToValueAtTime(1e-4,p+i),d.connect(v).connect(g).connect(n),d.start(p,Math.random()*.5),d.stop(p+i+.02)}seq(i,l,n,o,c){const u=this.ctx.currentTime;
1i.forEach((p,d)=>this.tone(p,n,o,c,this.sfxBus,u+d*l))}sfx(i,l=0){const n=this.ctx;if(!n||!this.enabled)return;const o=this.sfxBus,c=gt();switch(i){case"move":this.tone(520*c,.04,"square",.04,o);break;case"bonk":this.tone(150*c,.1,"square",.12,o,void 0,80),this.noise(.05,.08,o,void 0,300);break;case"jump":this.tone(420*c,.13,"square",.06,o,void 0,900);break;case"duck":this.tone(520*c,.11,"triangle",.08,o,void 0,200);break;case"collect":{const u=660*2**(Math.min(l,14)/12);this.tone(u,.07,"sine",.12,o),this.tone(u*1.5,.06,"sine",.05,o,n.currentTime+.03);break}case"streak":this.seq([523,659,784,1046*(1+Math.min(l,4)*.06)],.05,.1,"triangle",.1);break;case"shield":this.tone(300,.3,"triangle",.12,o,void 0,1200),this.tone(600,.3,"sine",.06,o,void 0,2e3);break;case"shieldSave":this.tone(1e3,.18,"triangle",.1,o,void 0,400);break;case"hit":this.noise(.2,.3,o,void 0,150),this.tone(170*c,.22,"sawtooth",.13,o,void 0,55);break;case"lose":this.seq([520,392,262],.09,.12,"sawtooth",.07);break;case"alarm":this.seq([880,660,880,660],.13,.12,"square",.06);break;case"gateOpen":this.tone(220,.5,"sawtooth",.12,o,void 0,90),this.tone(880,.35,"triangle",.06,o);break;case"correct":this.seq([523,659,784,1046,1318],.06,.16,"triangle",.12);break;case"wrong":this.tone(210,.55,"sawtooth",.15,o,void 0,60),this.tone(150,.55,"square",.07,o,void 0,50),this.noise(.3,.12,o,void 0,200);break;case"recover":this.seq([392,523,659,784],.07,.14,"sine",.12);break;case"phase":this.seq([523,659,784,1046],.08,.12,"square",.05);break;case"whoosh":this.noise(.14,.05,o,void 0,2500);break;case"best":this.seq([523,523,784,1046,784,1046,1318],.09,.15,"square",.06);break;case"start":this.seq([392,523,784],.07,.12,"triangle",.1);break}}}function Pe(e,i){const l=parseInt(e.slice(1,7),16),n=o=>Math.max(0,Math.min(255,Math.round(i<0?o*(1+i):o+(255-o)*i)));return`rgb(${n(l>>16)},${n(l>>8&255)},${n(l&255)})`}function ve(e,i,l,n,o,c){e.save(),e.beginPath(),e.rect(i,l,n,o),e.clip(),e.fillStyle="#14141c",e.fillRect(i,l,n,o),e.fillStyle="#facc15";const u=Math.max(3,9*c);for(let p=-o;p<n+o;p+=u*2)e.beginPath(),e.moveTo(i+p,l+o),e.lineTo(i+p+u,l+o),e.lineTo(i+p+u+o,l),e.lineTo(i+p+o,l),e.fill();e.restore()}function we(e,i,l,n,o,c,u){e.fillStyle=Pe(u,.4),e.beginPath(),e.moveTo(i,l),e.lineTo(i+c*.5,l-c),e.lineTo(i+n-c*.5,l-c),e.lineTo(i+n,l),e.closePath(),e.fill();const p=e.createLinearGradient(0,l,0,l+o);p.addColorStop(0,u),p.addColorStop(1,Pe(u,-.55)),e.fillStyle=p,e.fillRect(i,l,n,o),e.fillStyle="rgba(255,255,255,0.3)",e.fillRect(i,l,n,Math.max(1,o*.05)),e.strokeStyle="rgba(0,0,0,0.7)",e.lineWidth=1.2,e.strokeRect(i+.5,l+.5,n-1,o-1)}function Ce(e,i,l,n,o,c){e.save(),e.strokeStyle=c,e.lineWidth=Math.max(2,n*.35),e.lineCap="round",e.lineJoin="round";const u=o?-1:1;for(let p=0;p<2;p++){const d=l+p*n*.6*-u;e.beginPath(),e.moveTo(i-n,d-u*n*.5),e.lineTo(i,d+u*n*.5),e.lineTo(i+n,d-u*n*.5),e.stroke()}e.restore()}function yt(e,i,l,n){e.fillStyle="#facc15",e.strokeStyle="#14141c",e.lineWidth=Math.max(1,n*.12),e.beginPath(),e.moveTo(i,l-n),e.lineTo(i+n,l+n*.75),e.lineTo(i-n,l+n*.75),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#14141c",e.font=`900 ${n*1.1}px Karla, sans-serif`,e.textAlign="center",e.textBaseline="middle",e.fillText("!",i,l+n*.15),e.textBaseline="alphabetic"}function xe(e,i,l,n,o){o<8||(e.font=`900 ${o}px Karla, sans-serif`,e.textAlign="center",e.textBaseline="middle",e.lineWidth=Math.max(2,o*.22),e.strokeStyle="#0b0f24",e.strokeText(i,l,n),e.fillStyle="#ffffff",e.fillText(i,l,n),e.textBaseline="alphabetic")}function De(e,i,l,n,o,c,u,p){const d=i.sc;e.save(),e.globalAlpha=p?.3:1;const v=!p&&c<14&&c>0,g=()=>{v&&(e.shadowColor="rgba(255,60,70,0.95)",e.shadowBlur=6+16*(.5+.5*Math.sin(u*10))*d)},j=()=>{e.shadowBlur=0};if(n.action==="jump"){const b=28*d,y=l*.94,C=i.x-y/2,M=i.y-b;g(),we(e,C,M,y,b,10*d,n.color),j(),ve(e,C,M,y,b*.3,d),xe(e,n.label,i.x,M+b*.66,Math.max(0,15*d)),Ce(e,i.x,M-22*d,9*d,!0,"#ffffff")}else if(n.action==="duck"){const b=l*.96,y=i.x-b/2,C=i.y-120*d,M=34*d;e.fillStyle="rgba(0,0,0,0.45)",e.fillRect(y,i.y-4*d,b,7*d),e.fillStyle="#2a2a3a",e.fillRect(y,C,6*d,120*d),e.fillRect(y+b-6*d,C,6*d,120*d),g(),we(e,y,C,b,M,8*d,n.color),j(),ve(e,y,C+M-8*d,b,8*d,d),xe(e,n.label,i.x,C+M*.4,Math.max(0,15*d)),Ce(e,i.x,C+M+18*d,9*d,!1,"#ffffff")}else{const b=100*d,y=l*.86,C=i.x-y/2,M=i.y-b;if(g(),we(e,C,M,y,b,12*d,n.color),j(),ve(e,C,M,y,b*.12,d),o==="server"){e.fillStyle="rgba(0,0,0,0.35)";for(let D=0;D<4;D++)e.fillRect(C+y*.12,M+b*(.55+D*.1),y*.76,3*d)}d>.18&&yt(e,i.x,M+b*.3,11*d),xe(e,n.label,i.x,M+b*.5,Math.max(0,16*d))}
1e.restore()}function vt(e,i,l,n,o,c){e.fillStyle=o.color+"33",e.beginPath(),e.arc(i,l,n*1.5,0,Math.PI*2),e.fill(),e.fillStyle=o.color,e.beginPath(),e.arc(i,l,n,0,Math.PI*2),e.fill(),e.strokeStyle="#ffffff",e.lineWidth=Math.max(1,n*.12),e.stroke(),n>8&&(e.fillStyle="#07091a",e.font=`bold ${Math.max(8,n*.65)}px Karla, sans-serif`,e.textAlign="center",e.textBaseline="middle",e.fillText(o.label,i,l+1),e.textBaseline="alphabetic");const u=c*3,p=i+Math.cos(u)*n*1.1,d=l+Math.sin(u)*n*1.1,v=Math.max(2,n*.3);e.fillStyle="#ffffff",e.beginPath(),e.moveTo(p,d-v),e.lineTo(p+v*.25,d-v*.25),e.lineTo(p+v,d),e.lineTo(p+v*.25,d+v*.25),e.lineTo(p,d+v),e.lineTo(p-v*.25,d+v*.25),e.lineTo(p-v,d),e.lineTo(p-v*.25,d-v*.25),e.fill()}function wt(e,i,l,n,o){const c=Math.sin(o*9)*4;e.save(),e.font="900 26px Karla, sans-serif",e.textAlign="center",e.textBaseline="middle",e.lineWidth=6,e.strokeStyle="#0b0f24",e.strokeText(n,i,l+c),e.fillStyle="#f59e0b",e.fillText(n,i,l+c),e.restore()}const Le="#ffdcc7",Ee="#f7d26a",Ie="#f6eedd",K="#1f5f5b",pe="#ff7a6b",H="#0b0f24",xt="#2f7bf0";function V(e,i,l,n,o,c,u){e.strokeStyle=H,e.lineWidth=c+2,e.beginPath(),e.moveTo(i,l),e.lineTo(n,o),e.stroke(),e.strokeStyle=u,e.lineWidth=c,e.beginPath(),e.moveTo(i,l),e.lineTo(n,o),e.stroke()}function fe(e,i,l){e.fillStyle="#ffffff",e.strokeStyle=H,e.lineWidth=1.4,e.beginPath(),e.roundRect(i-5,l-4,10,5,2.5),e.fill(),e.stroke(),e.fillStyle=pe,e.fillRect(i-3,l-2.5,6,1.4)}function qe(e,i,l,n,o,c){e.save(),e.translate(i,l),e.scale(n,n),o==="hit"&&e.rotate(Math.sin(c*30)*.18),o==="duck"&&e.scale(1.2,.56),e.lineJoin="round",e.lineCap="round";const u=o==="run"?Math.sin(c*18):0;o==="run"&&e.translate(0,-Math.abs(Math.sin(c*18))*2.5),o==="win"&&e.translate(0,-Math.abs(Math.sin(c*10))*4);const p=o==="run"?Math.sin(c*18+1)*5:o==="jump"?-7:0;if(e.fillStyle=Ee,e.strokeStyle=H,e.lineWidth=1.5,e.beginPath(),e.ellipse(14+p*.4,-60+(o==="jump"?-4:2),4.5,11,.6+p*.06,0,Math.PI*2),e.fill(),e.stroke(),o==="jump")V(e,-5,-22,-10,-16,6,K),V(e,-10,-16,-6,-9,6,K),V(e,5,-22,10,-16,6,K),V(e,10,-16,6,-9,6,K),fe(e,-6,-6),fe(e,6,-6);else{const b=-5+u*6,y=5-u*6;V(e,-5,-22,b,-4-Math.max(0,u)*3,6,K),V(e,5,-22,y,-4-Math.max(0,-u)*3,6,K),fe(e,b,-1-Math.max(0,u)*3),fe(e,y,-1-Math.max(0,-u)*3)}const d=o==="jump"||o==="win",v=b=>{const y=b*12,C=-41,M=d?b*20:o==="duck"?b*18:o==="hit"?b*22:b*16,D=d?-60:o==="duck"?-30:o==="hit"?-48:-28+u*b*6;V(e,y,C,M,D,6,Ie),e.fillStyle=Le,e.strokeStyle=H,e.lineWidth=1.3,e.beginPath(),e.arc(M,D,3,0,Math.PI*2),e.fill(),e.stroke()};v(-1),v(1),e.fillStyle=Ie,e.strokeStyle=H,e.lineWidth=1.6,e.beginPath(),e.roundRect(-14,-46,28,27,8),e.fill(),e.stroke(),e.fillStyle=K,e.fillRect(-13.2,-23.5,26.4,4),e.textAlign="center",e.textBaseline="middle",e.fillStyle=K,e.font="900 4.6px Karla, sans-serif",e.fillText("SARAH FITZ",0,-36),e.fillStyle=pe,e.font="900 5px Karla, sans-serif",e.fillText("SEO.",0,-30.5),e.textBaseline="alphabetic";const g=-59;e.fillStyle=Le,e.strokeStyle=H,e.lineWidth=1.6,e.beginPath(),e.arc(0,g,13,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=Ee,e.beginPath(),e.moveTo(-13,g),e.quadraticCurveTo(-7,g+5,-2,g-4),e.quadraticCurveTo(4,g+4,13,g),e.arc(0,g,13.4,0,Math.PI,!0),e.closePath(),e.fill(),e.stroke(),e.beginPath(),e.ellipse(-12,g+5,3,7,.1,0,Math.PI*2),e.fill(),e.stroke(),e.beginPath(),e.ellipse(12,g+5,3,7,-.1,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=pe,e.beginPath(),e.arc(10,g-10,2.6,0,Math.PI*2),e.fill(),e.stroke();const j=g+3;if(o==="hit"){e.strokeStyle=H,e.lineWidth=1.6;for(const b of[-4.8,4.8])e.beginPath(),e.moveTo(b-2.2,j-2.2),e.lineTo(b+2.2,j+2.2),e.moveTo(b+2.2,j-2.2),e.lineTo(b-2.2,j+2.2),e.stroke();e.fillStyle=H,e.beginPath(),e.arc(0,g+9,2,0,Math.PI*2),e.fill()}else if(o==="win"){e.strokeStyle=H,e.lineWidth=1.6;for(const b of[-4.8,4.8])e.beginPath(),e.arc(b,j+1,2.4,Math.PI*1.1,Math.PI*1.9),e.stroke();e.fillStyle="#b5323a",e.beginPath(),e.moveTo(-4,g+7),e.quadraticCurveTo(0,g+13,4,g+7),e.closePath(),e.fill()}else{for(const b of[-4.8,4.8])e.fillStyle="#ffffff",e.beginPath(),e.ellipse(b,j,3,3.6,0,0,Math.PI*2),e.fill(),e.fillStyle=xt,e.beginPath(),e.arc(b,j+.4,2.3,0,Math.PI*2),e.fill(),e.fillStyle=H,e.beginPath(),e.arc(b,j+.5,1.1,0,Math.PI*2),e.fill(),e.fillStyle="#ffffff",e.beginPath(),e.arc(b+.8,j-.8,.7,0,Math.PI*2),e.fill();o==="jump"?(e.fillStyle="#b5323a",e.beginPath(),e.ellipse(0,g+9,2.4,2,0,0,Math.PI*2),e.fill()):o==="duck"?(e.strokeStyle=H,e.lineWidth=1.4,e.beginPath(),e.moveTo(-2.5,g+9),e.lineTo(2.5,g+9),e.stroke()):(e.strokeStyle=H,e.lineWidth=1.4,e.beginPath(),e.arc(0,g+6,3.4,Math.PI*.15,Math.PI*.85),e.stroke())}e.globalAlpha=.5,e.fillStyle=pe,e.beginPath(),e.arc(-8,g+7,2,0,Math.PI*2),e.arc(8,g+7,2,0,Math.PI*2),e.fill(),e.globalAlpha=1,e.restore(
1)}function kt({kind:e}){const i=A.useRef(null);return A.useEffect(()=>{const l=i.current,n=l.getContext("2d"),o=Math.min(2,window.devicePixelRatio||1),c=150,u=110;l.width=c*o,l.height=u*o,n.setTransform(o,0,0,o,0,0);const p=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches,d=96;let v=0;const g=performance.now(),j=b=>{const y=p?e==="move"?.3:.95:(b-g)/1e3;n.clearRect(0,0,c,u),n.fillStyle="#0b0f24",n.fillRect(0,d,c,u-d),n.fillStyle="#22d3ee55",n.fillRect(0,d,c,2);let C="run",M=48,D=d;if(e==="move"){for(const _ of[25,75,125])n.fillStyle="#22d3ee33",n.fillRect(_-1,d,2,u-d);M=75+Math.sin(y*2.4)*50}else{const _=y%2/2,$=c+30-_*(c+60),X=e==="jump"?{label:"404",action:"jump",color:"#ff5a5f"}:{label:"NOINDEX",action:"duck",color:"#f59e0b"},ee=Math.abs($-M)<34;e==="jump"?(C=ee?"jump":"run",ee&&(D=d-Math.sin(($-M+34)/68*Math.PI)*30)):C=ee?"duck":"run",De(n,{x:$,y:d,sc:.62},70,X,e,99,y,!1)}qe(n,M,D,.78,C,y),p||(v=requestAnimationFrame(j))};return v=requestAnimationFrame(j),()=>cancelAnimationFrame(v)},[e]),a.jsx("canvas",{ref:i,className:"mx-auto block h-[110px] w-[150px] max-w-full","aria-hidden":!0})}const St=[{kind:"move",title:"MOVE",desk:"â â or A / D",mob:"Swipe left or right"},{kind:"jump",title:"JUMP",desk:"â, W or Space",mob:"Swipe up"},{kind:"duck",title:"DUCK",desk:"â or S",mob:"Swipe down"}];function jt({onStart:e}){return a.jsxs("div",{className:"absolute inset-0 overflow-y-auto bg-[color:var(--mm-bg)] p-4 text-center text-[color:var(--mm-text)] sm:p-6",children:[a.jsx("div",{className:"mm-grid absolute inset-0 opacity-30","aria-hidden":!0}),a.jsxs("div",{className:"relative mx-auto max-w-2xl",children:[a.jsx("div",{className:"text-xs font-bold uppercase tracking-[0.3em] text-[color:var(--mm-amber)]",children:"How to play"}),a.jsx("div",{className:"mt-1 font-display text-3xl font-bold text-[color:var(--mm-cyan)] sm:text-5xl",children:"Move. Jump. Duck."}),a.jsx("div",{className:"mt-4 grid grid-cols-3 gap-2 sm:gap-3",children:St.map(i=>a.jsxs("div",{className:"rounded-xl border border-white/15 bg-black/40 p-2",children:[a.jsx(kt,{kind:i.kind}),a.jsx("div",{className:"mt-1 font-display text-lg font-bold sm:text-xl",children:i.title}),a.jsx("div",{className:"hidden text-xs font-semibold opacity-90 sm:block",children:i.desk}),a.jsx("div",{className:"text-[11px] font-semibold leading-tight opacity-90 sm:hidden",children:i.mob})]},i.kind))}),a.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2 text-left text-xs leading-snug",children:[a.jsxs("div",{className:"rounded-lg bg-white/5 p-2",children:[a.jsx("b",{className:"text-[color:var(--mm-red)]",children:"Solid striped blocks"})," are SEO errors. Jump, duck or dodge them."]}),a.jsxs("div",{className:"rounded-lg bg-white/5 p-2",children:[a.jsx("b",{className:"text-[color:var(--mm-cyan)]",children:"Floating round icons"})," are fixes. Run straight through them."]})]}),a.jsx("button",{onClick:e,className:"mm-btn mt-5",children:"START MIGRATION"}),a.jsxs("p",{className:"mt-2 text-[11px] opacity-60",children:[a.jsx("span",{className:"hidden sm:inline",children:"P or Esc pauses."}),a.jsx("span",{className:"sm:hidden",children:"Or use the on-screen pad."})]})]})]})}const Oe="mm_seen_howto",Ue="mm_hints_done",q=60,Be=1.2,ue=[22,28];function Nt({onScoreSaved:e}){const i=A.useRef(null),l=A.useRef(null),[n,o]=A.useState("intro"),[c,u]=A.useState({score:0,health:3,mult:1,streak:0,shield:!1,phase:0,paused:!1,distance:0,gp:0}),[p,d]=A.useState(null),[v,g]=A.useState(null),[j,b]=A.useState(null),[y,C]=A.useState(null),[M,D]=A.useState(!1),[_,$]=A.useState(!0),[X,ee]=A.useState(""),[ie,ne]=A.useState("idle"),[ze,ke]=A.useState(!1),O=A.useRef(null),ge=A.useRef(!0);ge.current=_;const z=A.useRef(null),E=A.useCallback((t,r)=>{ge.current||z.current?.sfx(t,r)},[]);A.useEffect(()=>{_?z.current?.setEnabled(!1):(z.current??=new bt,z.current.setEnabled(!0),O.current&&!O.current.over&&n==="play"&&z.current.update({playing:!0}))},[_]),A.useEffect(()=>()=>z.current?.dispose(),[]),A.useEffect(()=>{try{localStorage.getItem(Oe)||o("howto")}catch{}},[]);const We=()=>{let t=!0;try{t=!localStorage.getItem(Ue)}catch{}return{t:0,speed:14,dist:0,score:0,health:3,mult:1,streak:0,shield:!1,lane:1,x:1,y:0,vy:0,slide:0,invuln:0,flash:0,hitT:0,winT:0,gateProg:0,hints:t?{jump:!1,duck:!1,dodge:!1}:null,objs:[],pops:[],sparks:[],nextSpawn:1.5,nextGate:ue[0],gateActive:!1,slow:0,phase:0,phaseTime:0,cycle:0,correct:0,mistakes:0,mistakeLog:{},usedScenarios:new Set,paused:!1,over:!1,floorOff:0,hudTick:0}},Se=typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches,Y=t=>{const r=O.current;if(!r||r.paused||r.over)return;const f=Math.max(0,Math.min(2,r.lane+t));if(f===r.lane){E("bonk");return}r.lane=f,E("move")},te=()=>{const t=O.current;!t||t.paused||t.over||t.y<=.01&&(t.vy=11,t.slide=0,E("jump"))},oe=()=>{const t=O.current;!t||t.paused||t.over||(t.slide=.7,t.y>0&&(t.vy=-18),E("duck"))},le=()=>{const t=O.current;!t||t.over||(t.paused=!t.paused,u(r=>({...r,paused:t.paused})))},je=(t,r=!1)=>{const f=O.current;if(f.mistakes++,f.mistakeLog[t]=(f.mistakeLog[t]??0)+1,f.streak=0,f.mult=1,f.shield){f.shield=!1,f.invuln=1,E("shieldSave"),ae("SHIELD SAVED YOU","#c084fc");return}f.health--,f.invuln=1.4,f.flash=.4,f.hitT=.6,r||E("hit"),setTimeout(()=>
1E(f.health===1?"alarm":"lose"),r?500:120),de("migration_mayhem_life_lost",{key:t}),f.health<=0&&He()},ae=(t,r,f,N)=>{const S=i.current;if(!S)return;const w=S.clientWidth,L=S.clientHeight;O.current.pops.push({text:t,x:w/2,y:N??L*.55,life:1,color:r})},He=()=>{const t=O.current;t.over=!0,z.current?.update({playing:!1});try{localStorage.setItem(Ue,"1")}catch{}const r=Number(localStorage.getItem(Ae)??0),f=t.score>r;f&&(localStorage.setItem(Ae,String(t.score)),setTimeout(()=>E("best"),900));const N=Object.entries(t.mistakeLog).sort((S,w)=>w[1]-S[1]).slice(0,3).map(([S])=>{if(S in Z){const L=Z[S];return{problem:L.problem,why:L.why,fix:L.fix}}const w=me.find(L=>L.id===S);return{problem:w.situation,why:w.explanation,fix:w.practice}});C({score:t.score,distance:Math.round(t.dist),health:t.health,correct:t.correct,mistakes:t.mistakes,best:Math.max(r,t.score),newBest:f,lessons:N}),d(null),g(null),o("over"),ne("idle"),D(!1),de("migration_mayhem_complete",{score:t.score})},re=()=>{O.current=We(),C(null),d(null),g(null),D(!1),o("play"),b(be[0].name),setTimeout(()=>b(null),1800),z.current?.update({playing:!0,speed:14,health:3,gate:!1,cycle:0}),E("start"),de("migration_mayhem_start"),l.current?.focus()},_e=t=>{const r=mt[t.phase],f=Math.min(1,t.t/150+t.cycle*.25);if(t.t<12){const w=r[Math.floor(Math.random()*r.length)];t.objs.push({t:"obs",kind:w,lane:Math.floor(Math.random()*3),z:q})}else{const w=Math.random()<.35+f*.4?2:1,L=[0,1,2].sort(()=>Math.random()-.5).slice(0,w);let P=0;for(const T of L){let s=r[Math.floor(Math.random()*r.length)];Z[s].action==="dodge"&&P++,P>2&&(s="broken404"),t.objs.push({t:"obs",kind:s,lane:T,z:q})}if(f>.5&&Math.random()<.12){const T=Math.random()<.5?"noindex":"broken404";t.objs=t.objs.filter(s=>s.z<q-.1);for(const s of[0,1,2])t.objs.push({t:"obs",kind:T,lane:s,z:q})}}const N=new Set(t.objs.filter(w=>w.t==="obs"&&w.z>=q-.1).map(w=>w.lane)),S=[0,1,2].filter(w=>!N.has(w));if(S.length&&Math.random()<.8){const w=S[Math.floor(Math.random()*S.length)],L=["r301","sitemap","links","canon","r301","links","qa",Math.random()<.4?"map":"sitemap",Math.random()<.4?"monitor":"canon"],P=L[Math.floor(Math.random()*L.length)];for(let T=0;T<3;T++)t.objs.push({t:"col",kind:P,lane:w,z:q+4+T*3,y:0})}},Fe=t=>{let r=me.filter(N=>N.phase===t.phase&&!t.usedScenarios.has(N.id));r.length||(r=me.filter(N=>!t.usedScenarios.has(N.id))),r.length||(t.usedScenarios.clear(),r=me);const f=r[Math.floor(Math.random()*r.length)];return t.usedScenarios.add(f.id),f};A.useEffect(()=>{if(n!=="play")return;const t=i.current,r=t.getContext("2d");let f=0,N=performance.now();const S=()=>{const s=Math.min(2,window.devicePixelRatio||1);t.width=t.clientWidth*s,t.height=t.clientHeight*s,r.setTransform(s,0,0,s,0,0)};S(),window.addEventListener("resize",S);const w=s=>{const x=Math.min(.05,(s-N)/1e3);N=s;const G=O.current;if(!G)return;const F=t.clientWidth,J=t.clientHeight;!G.paused&&!G.over&&L(G,x),Ke(r,G,F,J),G.over||(f=requestAnimationFrame(w))},L=(s,x)=>{s.t+=x,s.phaseTime+=x;const G=(14+Math.min(16,s.t*.12)+s.cycle*2)*(s.gateActive?.45:1);s.speed+=(G-s.speed)*Math.min(1,x*2);const F=s.speed*x;if(s.dist+=F,s.floorOff=(s.floorOff+F)%4,s.score+=Math.round(F*2*s.mult),s.x+=(s.lane-s.x)*Math.min(1,x*14),s.vy-=32*x,s.y=Math.max(0,s.y+s.vy*x),s.y===0&&(s.vy=Math.max(0,s.vy)),s.slide=Math.max(0,s.slide-x),s.invuln=Math.max(0,s.invuln-x),s.flash=Math.max(0,s.flash-x),s.hitT=Math.max(0,s.hitT-x),s.winT=Math.max(0,s.winT-x),s.phaseTime>40&&(s.phaseTime=0,s.phase=(s.phase+1)%3,s.phase===0&&s.cycle++,b(be[s.phase].name+(s.cycle?` · LEVEL ${s.cycle+1}`:"")),setTimeout(()=>b(null),1800),E("phase"),s.winT=1),!s.gateActive){if(s.nextSpawn-=x,s.nextSpawn<=0){_e(s);const h=Math.max(.55,1.5-s.t*.006-s.cycle*.1);s.nextSpawn=h+Math.random()*.4}if(s.nextGate-=x,s.nextGate<=0&&s.t>15){const h=Fe(s);s.gateActive=!0,s.gateProg=0,s.objs=s.objs.filter(U=>U.z<q*.5),s.objs.push({t:"gate",sc:h,z:q+10}),d(h),g(null),E("gateOpen")}}for(const h of s.objs)h.z-=F;const J=s.lane,Q=Math.round(s.x);for(const h of s.objs){if(h.t==="obs"){const U=Z[h.kind].action;if(!h.hit&&Math.abs(h.z)<Be*.5&&Q===h.lane){const B=U==="jump"&&s.y>.8||U==="duck"&&s.slide>0;!B&&s.invuln<=0?(h.hit=!0,je(h.kind),ae(Z[h.kind].label+"!","#ff5a5f")):B||(h.hit=!0)}if(h.z<16&&h.z>0&&Q===h.lane&&(h.hinted=!0),!h.passed&&h.z<-.6&&(h.passed=!0,!h.hit)){const B=Q===h.lane;B&&U!=="dodge"&&(E("whoosh"),s.hints&&(s.hints[U]=!0)),!B&&U==="dodge"&&h.hinted&&s.hints&&(s.hints.dodge=!0)}}if(h.t==="col"&&!h.got&&Math.abs(h.z)<Be&&h.lane===Q){const U=h;if(!U.got){U.got=!0;
1const B=Re[U.kind];s.streak++,s.streak%5===0?(s.mult=Math.min(5,s.mult+1),ae(`STREAK x${s.mult}`,"#a3e635"),E("streak",s.mult)):E("collect",s.streak%5+(s.mult-1)*2),s.score+=B.points*s.mult,B.shield&&!s.shield?(s.shield=!0,ae("PROTECTED","#c084fc"),E("shield")):ae(`+${B.points*s.mult} ${B.label}`,B.color,void 0,P()*.62);for(let m=0;m<(Se?0:8);m++)s.sparks.push({x:0,y:0,vx:(Math.random()-.5)*240,vy:-Math.random()*240,life:.5,color:B.color})}}if(h.t==="gate"&&!h.done&&(s.gateProg=Math.min(1,Math.max(0,1-h.z/(q+10)))),h.t==="gate"&&!h.done&&h.z<=0){if(h.done=!0,s.gateActive=!1,s.gateProg=0,s.nextGate=ue[0]+Math.random()*(ue[1]-ue[0]),s.nextSpawn=1.2,J===h.sc.correct){s.correct++,s.score+=500*s.mult,s.winT=1.2,E("correct");let B="MIGRATION SAVED! +500";s.health<3&&(s.health++,B+=" · VISIBILITY RESTORED",setTimeout(()=>E("recover"),450)),g({ok:!0,title:B,text:h.sc.explanation})}else g({ok:!1,title:"SEO DISASTER!",text:h.sc.explanation}),E("wrong"),je(h.sc.id,!0);d(null),setTimeout(()=>g(null),4200)}}s.objs=s.objs.filter(h=>h.z>-3);for(const h of s.pops)h.life-=x,h.y-=40*x;s.pops=s.pops.filter(h=>h.life>0);for(const h of s.sparks)h.life-=x,h.x+=h.vx*x,h.y+=h.vy*x,h.vy+=600*x;s.sparks=s.sparks.filter(h=>h.life>0),z.current?.update({speed:s.speed/(s.gateActive?.45:1),cycle:s.cycle,health:s.health,gate:s.gateActive,urgency:s.gateProg??0,playing:!s.over}),s.hudTick-=x,s.hudTick<=0&&(s.hudTick=.1,u({score:s.score,health:s.health,mult:s.mult,streak:s.streak,shield:s.shield,phase:s.phase,paused:s.paused,distance:Math.round(s.dist),gp:s.gateProg??0}))},P=()=>t.clientHeight;f=requestAnimationFrame(w);const T=()=>{document.hidden?(z.current?.suspend(),O.current&&!O.current.over&&(O.current.paused=!0,u(s=>({...s,paused:!0})))):ge.current||z.current?.resume()};return document.addEventListener("visibilitychange",T),()=>{cancelAnimationFrame(f),window.removeEventListener("resize",S),document.removeEventListener("visibilitychange",T),z.current?.update({playing:!1})}},[n]),A.useEffect(()=>{if(n!=="play")return;const t=T=>{const s=T.key.toLowerCase(),x={arrowleft:()=>Y(-1),a:()=>Y(-1),arrowright:()=>Y(1),d:()=>Y(1),arrowup:te,w:te," ":te,arrowdown:oe,s:oe,p:le,escape:le};x[s]&&(T.preventDefault(),x[s]())};window.addEventListener("keydown",t);const r=l.current;let f=0,N=0,S=0;const w=T=>{f=T.touches[0].clientX,N=T.touches[0].clientY,S=Date.now()},L=T=>{T.target.closest("[data-mm-canvas]")&&T.preventDefault()},P=T=>{const s=T.changedTouches[0],x=s.clientX-f,G=s.clientY-N;Date.now()-S>600||Math.max(Math.abs(x),Math.abs(G))<24||(Math.abs(x)>Math.abs(G)?Y(x>0?1:-1):G<0?te():oe())};return r.addEventListener("touchstart",w,{passive:!0}),r.addEventListener("touchmove",L,{passive:!1}),r.addEventListener("touchend",P,{passive:!0}),()=>{window.removeEventListener("keydown",t),r.removeEventListener("touchstart",w),r.removeEventListener("touchmove",L),r.removeEventListener("touchend",P)}},[n]);function Ke(t,r,f,N){const S=be[r.phase],w=N*.32,L=6,P=(m,k,R=0)=>{const I=L/(L+Math.max(-2.5,k)),W=f*.3;return{x:f/2+(m-1)*W*I,y:w+(N-w)*I*.92-R*60*I,sc:I}},T=t.createLinearGradient(0,0,0,w);T.addColorStop(0,"#07091a"),T.addColorStop(1,S.sky),t.fillStyle=T,t.fillRect(0,0,f,N);const s=r.dist*2%120;for(let m=-1;m<f/60+2;m++){const k=m*60-s/2,R=30+(m*37%50+50)%50;t.fillStyle=m%3===0?"#1b2150":"#12173a",t.fillRect(k,w-R,46,R),t.fillStyle=S.accent+"55",t.fillRect(k,w-R,46,5),m%4===1&&(t.fillStyle="#ff5a5f",t.font="bold 9px Karla, sans-serif",t.fillText("404",k+12,w-R+20)),m%5===2&&(t.fillStyle="#22d3ee",t.fillRect(k+8,w-R+12,4,4),t.fillRect(k+16,w-R+12,4,4))}t.fillStyle=S.floor,t.fillRect(0,w,f,N-w);const x=P(-.5,-2.5),G=P(-.5,q),F=P(2.5,-2.5),J=P(2.5,q);t.fillStyle="#0b0f24",t.beginPath(),t.moveTo(G.x,G.y),t.lineTo(J.x,J.y),t.lineTo(F.x,F.y),t.lineTo(x.x,x.y),t.fill();for(let m=4-r.floorOff;m<q;m+=4){const k=P(-.5,m),R=P(2.5,m);t.strokeStyle=S.accent+"40",t.lineWidth=Math.max(1,3*k.sc),t.beginPath(),t.moveTo(k.x,k.y),t.lineTo(R.x,R.y),t.stroke()}for(const m of[-.5,.5,1.5,2.5]){const k=P(m,-2.5),R=P(m,q);t.strokeStyle=m===-.5||m===2.5?S.accent:S.accent+"80",t.lineWidth=2,t.beginPath(),t.moveTo(k.x,k.y),t.lineTo(R.x,R.y),t.stroke()}if(!Se){t.strokeStyle="#ffffff18",t.lineWidth=1;for(let m=0;m<8;m++){const k=(m*97+Math.floor(r.dist*3))%100/100,R=m%2?f*.02+k*f*.12:f*.86+k*f*.12,I=w+k*(N-w);t.beginPath(),t.moveTo(R,I),t.lineTo(R+(m%2?-20:20),I+30),t.stroke()}}const Q=[...r.objs].sort((m,k)=>k.z-m.z);for(const m of Q){if(m.z>q+12)continue;if(m.t==="gate"){for(let I=0;I<3;I++){const W=P(I,m.z),ce=f*.26*W.sc,se=70*W.sc;t.fillStyle="#22d3ee22",t.strokeStyle="#22d3ee",t.lineWidth=2,t.fillRect(W.x-ce/2,W.y-se*2,ce,se),t.strokeRect(W.x-ce/2,W.y-se*2,ce,se),W.sc>.25&&(t.fillStyle="#e0f7ff",t.font=`bold ${Math.max(9,18*W.sc)}px Karla, sans-serif`,t.textAlign="center",t.fillText(["LEFT","CENTRE","RIGHT"][I],W.x,W.y-se*1.4))}continue}if(m.t==="col"){if(m.got)continue;const I=P(m.lane,m.z,.9+Math.sin(r.t*5+m.z)*.15);vt(t,I.x,I.y,22*I.sc,Re[m.kind],r.t+m.z);continue}const k=P(m.lane,m.z),R=Z[m.kind];if(De(t,k,f*.26*k.sc,R,m.kind,m.z,r.t,!!m.hit),r.hints&&!r.hints[R.action]&&!m.hit&&m.z<18&&m.z>1.5&&m.lane===Math.round(r.x)){const I=R.action==="duck"?k.y-150*k.sc:R.action==="jump"?k.y-70*k.sc:k.y-130*k.sc;wt(t,k.x,I,R.action==="jump"?"JUMP!":R.action==="duck"?"DUCK!":"DODGE!",r.t)}}const h=P(r.x,0,r.y),U=P(r.x,0);if(t.fillStyle="#00000066",t.beginPath(),t.ellipse(U.x,U.y,26*U.sc,7*U.sc,0,0,Math.PI*2),t.fill(),!(r.invuln>0&&r.hitT<=0&&Math.floor(r.t*12)%2===0)){const m=h.sc*1.05;r.shield&&(t.strokeStyle="#c084fc",t.lineWidth=3,t.beginPath(),t.arc(h.x,h.y-44*m,58*m,0,Math.PI*2),t.stroke());const k=r.hitT>0?"hit":r.y>.05?"jump":r.slide>0?"duck":r.winT>0?"win":"run";qe(t,h.x,h.y,m,k,r.t)}for(const m of r.sparks)t.globalAlpha=m.life*2,t.fillStyle=m.color,t.fillRect(h.x+m.x,h.y-60+m.y,4,4);t.globalAlpha=1,t.textAlign="center";for(const m of r.pops)t.globalAlpha=Math.min(1,m.life*1.5),t.fillStyle=m.color,t.font="bold 20px Karla, sans-serif",t.fillText(m.text,m.x,m.y);t.globalAlpha=1,r.flash>0&&(t.fillStyle=`rgba(255,60,60,${r.flash})`,t.fillRect(0,0,f,N)),r.paused&&(t.fillStyle="#000a",t.fillRect(0,0,f,N))}const Ye=async()=>
1{if(!(!y||!X.trim())){ne("saving");try{await Ze({data:{gameSlug:"migration_mayhem",name:X.trim().slice(0,10),score:y.correct,points:y.score,timeMs:y.distance,source:"migration_mayhem"}}),ne("saved"),e?.()}catch{ne("error")}}},Ve=async()=>{if(!y)return;const t=`I survived Migration Mayhem with ${y.score.toLocaleString()} points. Can you launch a website without destroying its SEO? Play at sarahfitzseo.com/games/migration-mayhem`;if(de("migration_mayhem_share"),navigator.share)try{await navigator.share({text:t,url:"https://sarahfitzseo.com/games/migration-mayhem"});return}catch{}await it(t)&&(ke(!0),setTimeout(()=>ke(!1),2e3))},$e=[0,33,67,100][Math.max(0,c.health)];return a.jsx("div",{ref:l,tabIndex:-1,className:"mm-cabinet relative mx-auto w-full max-w-3xl overflow-hidden rounded-2xl outline-none",style:{touchAction:n==="play"?"none":"auto"},children:a.jsxs("div",{className:"relative h-[560px] sm:h-[600px] w-full",children:[a.jsx("canvas",{ref:i,"data-mm-canvas":!0,className:"absolute inset-0 h-full w-full","aria-label":"Migration Mayhem game area"}),n==="play"&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"absolute inset-x-0 top-0 flex items-start justify-between gap-2 p-3 text-[color:var(--mm-text)]",children:[a.jsxs("div",{className:"rounded-lg bg-black/50 px-3 py-2",children:[a.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest opacity-80",children:"Organic visibility"}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsxs("span",{className:"font-display text-xl font-bold",children:[$e,"%"]}),a.jsx("div",{className:"flex gap-1",children:[0,1,2].map(t=>a.jsx("span",{className:`h-3 w-6 rounded-sm ${t<c.health?"bg-[color:var(--mm-cyan)]":"bg-white/15"}`},t))}),c.shield&&a.jsx(nt,{className:"h-4 w-4 text-[color:var(--mm-purple)]","aria-label":"Protected"})]})]}),a.jsxs("div",{className:"rounded-lg bg-black/50 px-3 py-2 text-right",children:[a.jsx("div",{className:"font-display text-xl font-bold",children:c.score.toLocaleString()}),a.jsxs("div",{className:"text-[11px] font-semibold opacity-80",children:["x",c.mult," streak ",c.streak%5,"/5 · ",c.distance,"m"]})]})]}),a.jsxs("div",{className:"absolute right-3 top-[76px] flex gap-2",children:[a.jsx("button",{onClick:le,className:"mm-icon-btn","aria-label":c.paused?"Resume":"Pause",children:c.paused?a.jsx(st,{className:"h-4 w-4"}):a.jsx(ot,{className:"h-4 w-4"})}),a.jsx("button",{onClick:()=>$(t=>!t),className:"mm-icon-btn","aria-label":_?"Turn sound on":"Mute",children:_?a.jsx(Ne,{className:"h-4 w-4"}):a.jsx(Me,{className:"h-4 w-4"})})]}),j&&a.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-[38%] text-center font-display text-2xl font-bold tracking-wide text-[color:var(--mm-amber)] drop-shadow-lg sm:text-3xl",children:j}),c.paused&&a.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-4",children:[a.jsx("div",{className:"font-display text-3xl font-bold text-[color:var(--mm-text)]",children:"Paused"}),a.jsx("button",{onClick:le,className:"mm-btn",children:"Resume"})]}),p&&a.jsxs("div",{className:"absolute inset-x-3 top-[118px] rounded-xl border border-[color:var(--mm-cyan)] bg-black/80 p-3 text-[color:var(--mm-text)] shadow-lg",children:[a.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-[color:var(--mm-cyan)]",children:"Migration decision · run into a lane or tap"}),a.jsx("div",{className:"mt-1.5 h-1.5 w-full overflow-hidden rounded-full bg-white/10","aria-hidden":!0,children:a.jsx("div",{className:`h-full rounded-full transition-[width] duration-100 ${c.gp>.7?"bg-[color:var(--mm-red)]":"bg-[color:var(--mm-amber)]"}`,style:{width:`${Math.max(0,1-c.gp)*100}%`}})}),a.jsx("p",{className:"mt-1 font-display text-base font-bold leading-snug sm:text-lg",children:p.situation}),a.jsx("div",{className:"mt-2 grid grid-cols-3 gap-2",children:p.answers.map((t,r)=>a.jsxs("button",{onClick:()=>{O.current&&(O.current.lane=r)},className:`rounded-lg border px-2 py-2 text-xs font-semibold leading-tight sm:text-sm ${c&&O.current?.lane===r?"border-[color:var(--mm-cyan)] bg-[color:var(--mm-cyan)]/20":"border-white/20 bg-white/5"}`,children:[a.jsx("span",{className:"block text-[10px] opacity-70",children:["LEFT","CENTRE","RIGHT"][r]}),t]},r))})]}),v&&a.jsxs("div",{className:`absolute inset-x-3 top-[118px] rounded-xl border p-3 text-[color:var(--mm-text)] ${v.ok?"border-[color:var(--mm-cyan)] bg-[#062a33]/90":"border-[color:var(--mm-red)] bg-[#330a10]/90"}`,role:"status",children:[a.jsx("div",{className:`font-display text-lg font-bold ${v.ok?"text-[color:var(--mm-cyan)]":"text-[color:var(--mm-red)]"}`,children:v.title}),a.jsx("p",{className:"mt-1 text-sm leading-snug",children:v.text})]}),a.jsx("div",{className:"absolute inset-x-0 bottom-3 flex justify-center gap-2 sm:hidden",children:[{f:()=>Y(-1),I:ct,l:"Left"},{f:te,I:lt,l:"Jump"},{f:oe,I:rt,l:"Duck"},{f:()=>Y(1),I:Xe,l:"Right"}].map(({f:t,I:r,l:f})=>a.jsxs("button",{onPointerDown:N=>{N.preventDefault(),t()},className:"mm-pad flex-col !gap-0","aria-label":f,children:[a.jsx(r,{className:"h-5 w-5"}),(f==="Jump"||f==="Duck")&&a.jsx("span",{className:"text-[9px] font-bold leading-none",children:f.toUpperCase()})]},f))})]}),n==="howto"&&a.jsx(jt,{onStart:()=>{try{localStorage.setItem(Oe,"1")}catch{}re()}}),n==="intro"&&a.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-[color:var(--mm-bg)] p-6 text-center text-[color:var(--mm-text)]",children:[a.jsx("div",{className:"mm-grid absolute inset-0 opacity-40","aria-hidden":!0}),a.jsxs("div",{className:"relative",children:[a.jsxs("div",{className:"font-display text-4xl font-bold tracking-tight text-[color:var(--mm-cyan)] drop-shadow sm:text-6xl",children:["MIGRATION",a.jsx("br",{}),"MAYHEM"]}),a.jsx("p",{className:"mt-3 text-sm font-bold uppercase tracking-widest text-[color:var(--mm-amber)]",children:"Save the rankings. Survive the launch."}),a.jsx("p",{className:"mx-auto mt-4 max-w-md text-sm leading-relaxed opacity-90",children:"Your old website is collapsing. Your new website is going live. And somebody forgot the redirect map. Ru
1n, jump and duck your way through migration disasters to protect your organic visibility."}),a.jsx("button",{onClick:re,className:"mm-btn mt-6",children:"START MIGRATION"}),a.jsxs("p",{className:"mt-4 text-xs opacity-70",children:[a.jsx("span",{className:"hidden sm:inline",children:"Arrows or WASD to move, Up or Space to jump, Down to duck, P to pause."}),a.jsx("span",{className:"sm:hidden",children:"Swipe left, right, up to jump, down to duck. Or use the pad."})]}),a.jsxs("div",{className:"mt-3 flex items-center justify-center gap-4 text-xs opacity-80",children:[a.jsx("button",{onClick:()=>o("howto"),className:"underline",children:"How to play"}),a.jsxs("button",{onClick:()=>$(t=>!t),className:"inline-flex items-center gap-1 underline",children:[_?a.jsx(Ne,{className:"h-3.5 w-3.5"}):a.jsx(Me,{className:"h-3.5 w-3.5"})," Sound ",_?"off":"on"]})]})]})]}),n==="over"&&y&&a.jsx("div",{className:"absolute inset-0 overflow-y-auto bg-[color:var(--mm-bg)]/95 p-5 text-[color:var(--mm-text)]",children:M?a.jsxs("div",{className:"mx-auto max-w-lg",children:[a.jsx("div",{className:"font-display text-2xl font-bold text-[color:var(--mm-cyan)]",children:"YOUR MIGRATION REPORT"}),y.lessons.length===0?a.jsx("p",{className:"mt-3 text-sm",children:"No mistakes logged. Impressive. Here is the checklist to keep it that way."}):a.jsx("ol",{className:"mt-3 space-y-3",children:y.lessons.map((t,r)=>a.jsxs("li",{className:"rounded-xl bg-white/5 p-3 text-sm",children:[a.jsx("div",{className:"font-bold text-[color:var(--mm-amber)]",children:t.problem}),a.jsxs("p",{className:"mt-1 opacity-90",children:[a.jsx("strong",{children:"Why it matters:"})," ",t.why]}),a.jsxs("p",{className:"mt-1 opacity-90",children:[a.jsx("strong",{children:"Best practice:"})," ",t.fix]})]},r))}),a.jsx("div",{className:"mt-4 grid gap-3 sm:grid-cols-3",children:[["BEFORE LAUNCH",ye.before],["DURING LAUNCH",ye.during],["AFTER LAUNCH",ye.after]].map(([t,r])=>a.jsxs("div",{className:"rounded-xl border border-white/15 p-3 text-xs",children:[a.jsx("div",{className:"font-bold text-[color:var(--mm-cyan)]",children:t}),a.jsx("ul",{className:"mt-2 list-disc space-y-1 pl-4",children:r.map(f=>a.jsx("li",{children:f},f))})]},t))}),a.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[a.jsx("button",{onClick:()=>D(!1),className:"mm-btn-ghost",children:"Back to score"}),a.jsxs("button",{onClick:re,className:"mm-btn",children:[a.jsx(Te,{className:"h-4 w-4"})," PLAY AGAIN"]})]})]}):a.jsxs("div",{className:"mx-auto max-w-md text-center",children:[a.jsx("div",{className:`font-display text-3xl font-bold ${y.score>12e3?"text-[color:var(--mm-cyan)]":"text-[color:var(--mm-red)]"}`,children:y.score>12e3?"MIGRATION COMPLETE":"MIGRATION FAILED"}),a.jsx("p",{className:"mt-2 text-sm italic opacity-90",children:ft(y.score,y.score<=12e3)}),y.newBest&&a.jsx("div",{className:"mt-3 inline-block rounded-full bg-[color:var(--mm-amber)] px-3 py-1 text-xs font-bold text-black",children:"NEW PERSONAL BEST"}),a.jsx("div",{className:"mt-4 font-display text-5xl font-bold",children:y.score.toLocaleString()}),a.jsx("dl",{className:"mt-4 grid grid-cols-2 gap-2 text-left text-sm",children:[["Distance",`${y.distance}m`],["Visibility left",`${[0,33,67,100][y.health]}%`],["Correct decisions",y.correct],["Mistakes",y.mistakes],["Personal best",y.best.toLocaleString()]].map(([t,r])=>a.jsxs("div",{className:"rounded-lg bg-white/5 px-3 py-2",children:[a.jsx("dt",{className:"text-[11px] uppercase tracking-wider opacity-70",children:t}),a.jsx("dd",{className:"font-bold",children:r})]},t))}),a.jsxs("div",{className:"mt-5 flex flex-wrap justify-center gap-2",children:[a.jsxs("button",{onClick:re,className:"mm-btn",children:[a.jsx(Te,{className:"h-4 w-4"})," PLAY AGAIN"]}),a.jsxs("button",{onClick:Ve,className:"mm-btn-ghost",children:[a.jsx(Je,{className:"h-4 w-4"})," ",ze?"COPIED":"SHARE SCORE"]}),a.jsxs("button",{onClick:()=>D(!0),className:"mm-btn-ghost",children:[a.jsx(Qe,{className:"h-4 w-4"})," MIGRATION REPORT"]})]}),a.jsxs("div",{className:"mt-5 rounded-xl border border-white/15 p-3 text-left",children:[a.jsxs("div",{className:"flex items-center gap-2 text-sm font-bold",children:[a.jsx(Ge,{className:"h-4 w-4 text-[color:var(--mm-amber)]"})," Add to the leaderboard"]}),ie==="saved"?a.jsx("p",{className:"mt-2 text-sm text-[color:var(--mm-cyan)]",children:"Saved. You're on the board below."}):a.jsxs("form",{className:"mt-2 flex gap-2",onSubmit:t=>{t.preventDefault(),Ye()},children:[a.jsx("input",{value:X,onChange:t=>ee(t.target.value.slice(0,10)),placeholder:"Name (10 max)","aria-label":"Display name",className:"min-w-0 flex-1 rounded-lg border border-white/20 bg-black/40 px-3 py-2 text-sm"}),a.jsx("button",{disabled:!X.trim()||ie==="saving",className:"mm-btn !px-4 !py-2 disabled:opacity-50",children:ie==="saving"?"...":"SAVE"})]}),ie==="error"&&a.jsx("p",{className:"mt-1 text-xs text-[color:var(--mm-red)]",children:"Could not save, please try again."})]})]})})]})})}const Mt=[["301 redirects","A permanent redirect sends users and Google from an old URL to its closest matching new URL."],["404 and 410","The right answer for a URL that is gone for good with no relevant replacement. Losing an important page without a redirect is the problem, not 404s in general."],["Noindex","A tag that keeps a page out of Google. Useful on staging, disastrous if it survives on live pages."],["robots.txt","A file that controls crawling. A leftover Disallow: / can hide your whole new site."],["Canonical tags","Tell Google which URL is the preferred version. After a migration they should point at the new URLs."],["XML sitemap","A list of the new, indexable URLs you want Google to find."],["Search Console","Google's free tool for monitoring indexing, crawl errors and performance after launch."],["Change of Address","A Search Console tool for domain or subdomain moves only, not CMS changes on the same domain."]];function Bt(){const{data:e}=at(et()),i=tt();return a.jsxs("article",{children:[a.jsxs("section",{className:"mx-auto max-w-4xl px-5 pt-12 text-center sm:px-6 md:pt-16",children:[a.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-accent/60 px-4 py-1.5 text-xs font-semibold uppercase tracking-wider text-primary",children:[a.jsx(dt,{className:"h-3.5 w-3.5","aria-hidden":!0})," Free SEO arcade game"]}),a.jsx("h1",{className:"mt-5 font-display text-4xl leading-[1.05] text-primary md:text-6xl",children:"Migration Mayhem"}),a.jsx("p",{className:"mx-auto mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground",children:"An endless runner through a website migration going wrong. Dodge broken redirects, leftover noindex tags and server errors, collect the fixes, and make the right call at each migration decision."})]}),a.jsxs("section",{className:"mx-auto max-w-4xl px-3 py-8 sm:px-6",children:[a.jsx(Nt,{onScoreSaved:()=>i.invalidateQueries({queryKey:["game-scores","migration_mayhem"]})}),a.jsx("p",{className:"mt-3 text-center text-xs text-muted-foreground",children:"Organic visibility in the game is a fictional health score, not an estimate of real rankings or traffic."})]}),a.jsx("section",{className:"mx-auto max-w-3xl px-5 pb-10 sm:px-6",children:a.jsxs("div",{className:"rounded-2xl border border-border bg-card p-6",children:[a.jsxs("h2",{className:"flex items-center gap-2 font-display text-2xl text-primary",children:[a.jsx(Ge,{className:"h-5 w-5","aria-hidden":!0})," Leaderboard"]}),e.scores.length===0?a.jsx("p",{className:"mt-3 text-muted-foreground",children:"No scores yet. Be the first name on the board."}):a.jsx("ol",{className:"mt-4 divide-y divide-border",children:e.scores.map((l,n)=>a.jsxs("li",{className:"flex items-center justify-between py-2 text-sm",children:[a.jsxs("span",{className:"flex items-center gap-3",children:[a.jsx("span",{className:"w-6 font-bold text-primary",children:n+1}),l.name]}),a.jsxs("span",{className:"font-semibold",children:[l.points.toLocaleStr
1ing()," pts"]})]},l.id))})]})}),a.jsxs("section",{className:"mx-auto max-w-3xl space-y-8 px-5 pb-16 sm:px-6",children:[a.jsxs("div",{children:[a.jsx("h2",{className:"font-display text-2xl text-primary",children:"How to play"}),a.jsxs("ul",{className:"mt-3 list-disc space-y-1 pl-5 text-muted-foreground",children:[a.jsx("li",{children:"Desktop: arrow keys or WASD to change lanes, Up, W or Space to jump, Down or S to slide, P or Esc to pause."}),a.jsx("li",{children:"Mobile: swipe left, right, up or down, or use the on-screen pad."}),a.jsx("li",{children:"Collect 301s, sitemaps, internal links and canonicals. Five in a row raises your streak multiplier."}),a.jsx("li",{children:"Every 20 to 30 seconds a migration decision appears. Run into the lane with the right answer."}),a.jsx("li",{children:"You have three segments of organic visibility. Redirect maps and monitoring give a one-hit shield."})]})]}),a.jsxs("div",{children:[a.jsx("h2",{className:"font-display text-2xl text-primary",children:"Why website migration SEO matters"}),a.jsx("p",{className:"mt-3 leading-relaxed text-muted-foreground",children:"A website migration can give your business a fresh start, but get the SEO wrong and years of hard-earned search visibility can disappear with the old site. Whether you're redesigning, changing CMS or moving domains, search engines need to understand what's changed, where your content has moved and which pages should remain visible in search. Broken redirects, missing pages, indexing mistakes and overlooked technical details can turn an exciting website launch into an organic traffic nightmare."})]}),a.jsxs("div",{children:[a.jsx("h2",{className:"font-display text-2xl text-primary",children:"What you'll learn"}),a.jsx("dl",{className:"mt-3 grid gap-3 sm:grid-cols-2",children:Mt.map(([l,n])=>a.jsxs("div",{className:"rounded-xl border border-border bg-card p-4",children:[a.jsx("dt",{className:"font-semibold text-primary",children:l}),a.jsx("dd",{className:"mt-1 text-sm text-muted-foreground",children:n})]},l))})]}),a.jsxs("div",{className:"rounded-2xl bg-accent/40 p-6",children:[a.jsx("h2",{className:"font-display text-2xl text-primary",children:"Planning a real migration?"}),a.jsxs("p",{className:"mt-2 text-muted-foreground",children:["I run SEO migrations from redirect mapping to post-launch monitoring. See my"," ",a.jsx(he,{to:"/services/seo-migration",className:"font-semibold text-primary underline underline-offset-4",children:"SEO migration service"}),", the wider ",a.jsx(he,{to:"/services/technical-seo",className:"font-semibold text-primary underline underline-offset-4",children:"technical SEO"})," work, or check a page with the free ",a.jsx(he,{to:"/tools/why-wont-my-page-index",className:"font-semibold text-primary underline underline-offset-4",children:"indexing diagnostic"}),". A full migration guide and downloadable checklist are coming soon."]}),a.jsx("p",{className:"mt-3 text-sm",children:a.jsx(he,{to:"/games",className:"font-semibold text-primary underline underline-offset-4",children:"More SEO games"})})]}),a.jsx("div",{className:"text-center",children:a.jsx(ht,{location:"migration_mayhem"})})]})]})}export{Bt as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.