@mblinkov/whats-missing 20.0.30 → 20.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),Se=window.origin+"/cloud/speakid/games/whatsmissing/",Z=(r,m)=>r.map(([l,s])=>({src:`${Se}${m}/${s.replace(/\s/g,"%20")}.png`,name:s})),Ce=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],ke=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],ze=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],_={food:Z(Ce,"food"),animals:Z(ke,"animals"),toys:Z(ze,"toys")},Me=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),ge=window.origin+"/cloud/speakid/games/whatsmissing/",Y=(r,m)=>r.map(([l,i])=>({src:`${ge}${m}/${i.replace(/\s/g,"%20")}.png`,name:i})),he=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],fe=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],pe=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],P={food:Y(he,"food"),animals:Y(fe,"animals"),toys:Y(pe,"toys")},ye=`
2
2
  @keyframes spin {
3
3
  from { transform: rotate(0deg); }
4
4
  to { transform: rotate(360deg); }
5
5
  }
6
- `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const r=document.createElement("style");r.id="spin-keyframes",r.innerHTML=Me,document.head.appendChild(r)}const Re={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"none",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"none",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...Re}},Te=()=>{const r=document.createElement("style");r.textContent=`
6
+ `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const r=document.createElement("style");r.id="spin-keyframes",r.innerHTML=ye,document.head.appendChild(r)}const xe={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"none",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"none",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...xe}},be=()=>{const r=document.createElement("style");r.textContent=`
7
7
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
8
8
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
9
- `,document.head.appendChild(r)},Ie=(r,m)=>{const l=Array.from({length:r.length+1},()=>Array(m.length+1).fill(0));for(let s=0;s<=r.length;s++)l[s][0]=s;for(let s=0;s<=m.length;s++)l[0][s]=s;for(let s=1;s<=r.length;s++)for(let d=1;d<=m.length;d++)l[s][d]=r[s-1]===m[d-1]?l[s-1][d-1]:Math.min(l[s-1][d-1],l[s][d-1],l[s-1][d])+1;return l[r.length][m.length]};function He(r,m={minDesktopWidth:1200,forceResize:!1}){const l=o.useRef(null),s=m.minDesktopWidth??1200,d=!!m.forceResize;o.useLayoutEffect(()=>{if(typeof window>"u"||!r||!r.current)return;const c=r.current,T=()=>{try{const a=document.body,g=getComputedStyle(a),C=parseFloat(a.style&&a.style.zoom||"");if(C&&!isNaN(C)&&C>0)return C;const w=parseFloat(g.zoom||"");if(w&&!isNaN(w)&&w>0)return w;const h=document.createElement("div");h.style.position="absolute",h.style.left="0",h.style.top="0",h.style.width="100px",h.style.height="1px",h.style.visibility="hidden",document.documentElement.appendChild(h);const p=h.getBoundingClientRect();if(document.documentElement.removeChild(h),p&&p.width>0){const I=p.width/100;if(!isNaN(I)&&I>0)return I}}catch{}return 1},j=()=>{if(s&&window.innerWidth<s){M();return}const a=T();if(!a||a===1){M();return}l.current||(l.current={transform:c.style.transform||null,transformOrigin:c.style.transformOrigin||null,width:c.style.width||null,height:c.style.height||null,willChange:c.style.willChange||null});const g=1/a;d&&(c.style.width=`${a*100}%`,c.style.height=`${a*100}%`),c.style.transformOrigin="50% 50%",c.style.transform=`scale(${g})`,c.style.willChange="transform"},M=()=>{if(!l.current)return;const a=l.current;c.style.transform=a.transform??"",c.style.transformOrigin=a.transformOrigin??"",c.style.width=a.width??"",c.style.height=a.height??"",c.style.willChange=a.willChange??"",l.current=null};let b=0;const v=()=>{cancelAnimationFrame(b),b=requestAnimationFrame(j)},S=new MutationObserver(a=>{for(const g of a)if(g.type==="attributes"&&(g.attributeName==="style"||g.attributeName==="class")){v();break}});return S.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",v),v(),()=>{cancelAnimationFrame(b),S.disconnect(),window.removeEventListener("resize",v),M()}},[r,s,d])}function Be({gameCubeSize:r,screenHeight:m,screenWidth:l}){const s=o.useRef(null),d=o.useRef(null),[c,T]=o.useState(null);He(s,{minDesktopWidth:1200,forceResize:!1}),o.useEffect(()=>(Te(),()=>{document.body.style.overflow=""}),[]);const[j,M]=o.useState(null),[b,v]=o.useState([]),[S,a]=o.useState(4),[g,C]=o.useState(!1),[w,h]=o.useState(1),[p,I]=o.useState(null),[y,A]=o.useState("ready"),[K,J]=o.useState(3),[$,G]=o.useState(10),[N,Q]=o.useState(20),[ce,O]=o.useState(0),[E,D]=o.useState(!1),[W,X]=o.useState(""),[R,q]=o.useState(!1),[Y,ee]=o.useState(!1),[te,H]=o.useState(null),[me,P]=o.useState([]),[ue,ne]=o.useState([]),[k,ge]=o.useState(!1);o.useEffect(()=>{if(typeof window>"u")return;const t=()=>{const i=l??window.innerWidth;ge(i<=768)};return t(),window.addEventListener("resize",t),window.addEventListener("orientationchange",t),()=>{window.removeEventListener("resize",t),window.removeEventListener("orientationchange",t)}},[l]),o.useLayoutEffect(()=>{const t=d.current;if(!t||typeof window>"u")return;let i=null;try{i=new ResizeObserver(f=>{for(const u of f){const x=u.contentRect;T(Math.round(Math.min(x.width,x.height)))}}),i.observe(t),T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}catch{T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}return()=>i?.disconnect()},[k]);const oe=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),se=()=>{if(!j)return;const t=oe(_[j]);v(t),C(!0),D(!1),h(1),O(0),P([]),ne([]),ie(t,[],!0)},ie=(t=b,i=ue,f=!1)=>{const u=oe(t.length?t:_[j]);let x=Math.floor(Math.random()*u.length),z=u[x].name,B=0;for(;i.includes(z)&&B<20;)x=Math.floor(Math.random()*u.length),z=u[x].name,B++;v(u),I(x),ne([...i,z]),q(!1),X(""),Q(20),H(null),f?(A("ready"),J(3),G(10)):(A("memorize"),G(10))};o.useEffect(()=>{if(!(!g||E||R)){if(y==="ready")if(K<=0)A("memorize");else{const t=setTimeout(()=>J(i=>i-1),1e3);return()=>clearTimeout(t)}if(y==="memorize")if($<=0)A("guess");else{const t=setTimeout(()=>G(i=>i-1),1e3);return()=>clearTimeout(t)}if(y==="guess"){if(N<=0){q(!0),H("wrong");const i=b[p].name;P(f=>[...f,{round:w,answer:W,correct:i,result:"wrong"}]);return}const t=setTimeout(()=>Q(i=>i-1),1e3);return()=>clearTimeout(t)}}},[y,K,$,N,g,E,R,b,p,w,W]);const he=()=>{if(p===null||Y)return;const t=b[p].name,i=W.toLowerCase().trim();let f="wrong";i===t?(O(u=>u+1),H("correct"),f="correct"):Ie(i,t)===1?(O(u=>u+.5),H("almost"),f="almost"):(H("wrong"),f="wrong"),P(u=>[...u,{round:w,answer:i,correct:t,result:f}]),ee(!0),setTimeout(()=>{ee(!1),q(!0)},600)},fe=()=>w<S?(h(t=>t+1),ie()):D(!0),pe=()=>{C(!1),D(!1),M(null)},ye=o.useMemo(()=>e.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:e.jsxs("picture",{children:[e.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),e.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]),re=1440,le=900,xe=d.current?.clientWidth??l??(typeof window<"u"?window.innerWidth:re),be=d.current?.clientHeight??m??(typeof window<"u"?window.innerHeight:le),U=Math.min(xe/re,be/le);return e.jsx("div",{ref:s,style:{position:"fixed",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",overflow:"hidden",zIndex:1},children:e.jsx("div",{ref:d,style:{width:k?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,height:k?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,borderRadius:k?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",position:"relative",overflow:"hidden",boxShadow:k?"none":"0 0 40px rgba(0,0,0,0.08)",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",style:{transform:`scale(${U})`,transformOrigin:"center center",width:`${100/U}%`,height:`${100/U}%`,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[!k&&ye,!j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:n.gmButton,onClick:()=>M(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),e.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(t=>e.jsx("button",{style:{...n.gmButton,...S===t?n.gmButtonActive:{}},onClick:()=>a(t),children:t},t))})]})]}),j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",j]}),e.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",S]}),e.jsx("button",{style:n.gmButton,onClick:se,children:"▶ Start game"})]}),E&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",ce," / ",S]}),e.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:n.gmTable,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Round"}),e.jsx("th",{children:"Your Answer"}),e.jsx("th",{children:"Correct"}),e.jsx("th",{children:"Result"})]})}),e.jsx("tbody",{children:me.map((t,i)=>e.jsxs("tr",{children:[e.jsx("td",{style:n.gmTableCell,children:t.round}),e.jsx("td",{style:n.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:n.gmTableCell,children:t.correct}),e.jsx("td",{style:n.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},i))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:n.gmButton,onClick:se,children:"🔁 Play again"}),e.jsx("button",{style:n.gmButton,onClick:pe,children:"⬅️ Choose theme"})]})]}),g&&!E&&e.jsxs("div",{style:n.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[y==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),y==="memorize"&&e.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",$,")"]}),y==="guess"&&!R&&e.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",N,"s"]})]}),y!=="ready"&&(()=>{const t=k?12:20,i=32,f=d.current?.clientWidth??Math.min(r??1e3,l??1e3),u=d.current?.clientHeight??Math.min(r??1e3,m??1e3),x=Math.min(f,u),z=typeof window<"u"?window.innerWidth:l??1e3,B=z<600?110:z<900?130:z<1280?150:180,we=4,ae=2,V=Math.max(ae,Math.min(we,Math.floor((x-i+t)/(B+t))||ae)),je=Math.floor((x-i-t*(V-1))/V),L=Math.max(B,je);return e.jsx("div",{style:{...n.gmGrid,gridTemplateColumns:`repeat(${V}, ${L}px)`,gridAutoRows:`${L}px`,gap:`${t}px`,justifyContent:"center",justifyItems:"center",padding:8,boxSizing:"border-box"},children:b.map((de,F)=>{const ve=p===F&&y==="guess"&&!R;return e.jsx("div",{style:{...n.gmCard,width:`${L}px`,height:`${L}px`,padding:L>=160?10:8,boxSizing:"border-box",...te==="correct"&&p===F?n.gmCorrect:{},...te==="wrong"&&p===F?n.gmWrong:{}},children:!ve&&e.jsx("img",{src:de.src,alt:de.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},F)})})})(),e.jsxs("div",{style:{marginTop:16,height:80},children:[y==="guess"&&!R&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:W,onChange:t=>X(t.target.value),style:n.gmInput}),e.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:he,disabled:Y,children:Y?"...":"Check"})]}),R&&e.jsx("button",{type:"button",style:n.gmButton,onClick:fe,children:"Next round"})]})]})]})})})}exports.Game=Be;exports.themes=_;
9
+ `,document.head.appendChild(r)},we=(r,m)=>{const l=Array.from({length:r.length+1},()=>Array(m.length+1).fill(0));for(let i=0;i<=r.length;i++)l[i][0]=i;for(let i=0;i<=m.length;i++)l[0][i]=i;for(let i=1;i<=r.length;i++)for(let u=1;u<=m.length;u++)l[i][u]=r[i-1]===m[u-1]?l[i-1][u-1]:Math.min(l[i-1][u-1],l[i][u-1],l[i-1][u])+1;return l[r.length][m.length]};function je(r,m={minDesktopWidth:1200,forceResize:!1}){const l=o.useRef(null),i=m.minDesktopWidth??1200,u=!!m.forceResize;o.useLayoutEffect(()=>{if(typeof window>"u"||!r||!r.current)return;const d=r.current,T=()=>{try{const a=document.body,g=getComputedStyle(a),C=parseFloat(a.style&&a.style.zoom||"");if(C&&!isNaN(C)&&C>0)return C;const w=parseFloat(g.zoom||"");if(w&&!isNaN(w)&&w>0)return w;const p=document.createElement("div");p.style.position="absolute",p.style.left="0",p.style.top="0",p.style.width="100px",p.style.height="1px",p.style.visibility="hidden",document.documentElement.appendChild(p);const y=p.getBoundingClientRect();if(document.documentElement.removeChild(p),y&&y.width>0){const M=y.width/100;if(!isNaN(M)&&M>0)return M}}catch{}return 1},j=()=>{if(i&&window.innerWidth<i){z();return}const a=T();if(!a||a===1){z();return}l.current||(l.current={transform:d.style.transform||null,transformOrigin:d.style.transformOrigin||null,width:d.style.width||null,height:d.style.height||null,willChange:d.style.willChange||null});const g=1/a;u&&(d.style.width=`${a*100}%`,d.style.height=`${a*100}%`),d.style.transformOrigin="50% 50%",d.style.transform=`scale(${g})`,d.style.willChange="transform"},z=()=>{if(!l.current)return;const a=l.current;d.style.transform=a.transform??"",d.style.transformOrigin=a.transformOrigin??"",d.style.width=a.width??"",d.style.height=a.height??"",d.style.willChange=a.willChange??"",l.current=null};let b=0;const S=()=>{cancelAnimationFrame(b),b=requestAnimationFrame(j)},v=new MutationObserver(a=>{for(const g of a)if(g.type==="attributes"&&(g.attributeName==="style"||g.attributeName==="class")){S();break}});return v.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",S),S(),()=>{cancelAnimationFrame(b),v.disconnect(),window.removeEventListener("resize",S),z()}},[r,i,u])}function Se({gameCubeSize:r,screenHeight:m,screenWidth:l}){const i=o.useRef(null),u=o.useRef(null),[d,T]=o.useState(null);je(i,{minDesktopWidth:1024,forceResize:!1}),o.useEffect(()=>(be(),()=>{document.body.style.overflow=""}),[]);const[j,z]=o.useState(null),[b,S]=o.useState([]),[v,a]=o.useState(4),[g,C]=o.useState(!1),[w,p]=o.useState(1),[y,M]=o.useState(null),[x,H]=o.useState("ready"),[U,V]=o.useState(3),[E,A]=o.useState(10),[W,Z]=o.useState(20),[ie,F]=o.useState(0),[B,$]=o.useState(!1),[L,_]=o.useState(""),[R,G]=o.useState(!1),[N,K]=o.useState(!1),[J,I]=o.useState(null),[re,O]=o.useState([]),[le,Q]=o.useState([]),[h,ae]=o.useState(!1);o.useEffect(()=>{if(typeof window>"u")return;const t=()=>{const s=l??window.innerWidth,c=window.matchMedia&&window.matchMedia("(pointer: coarse)").matches;ae(s<=768||c)};return t(),window.addEventListener("resize",t),window.addEventListener("orientationchange",t),()=>{window.removeEventListener("resize",t),window.removeEventListener("orientationchange",t)}},[l]),o.useLayoutEffect(()=>{const t=u.current;if(!t||typeof window>"u")return;let s=null;try{s=new ResizeObserver(c=>{for(const f of c){const k=f.contentRect;T(Math.round(Math.min(k.width,k.height)))}}),s.observe(t),T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}catch{T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}return()=>s?.disconnect()},[h]);const X=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),ee=()=>{if(!j)return;const t=X(P[j]);S(t),C(!0),$(!1),p(1),F(0),O([]),Q([]),te(t,[],!0)},te=(t=b,s=le,c=!1)=>{const f=X(t.length?t:P[j]);let k=Math.floor(Math.random()*f.length),q=f[k].name,se=0;for(;s.includes(q)&&se<20;)k=Math.floor(Math.random()*f.length),q=f[k].name,se++;S(f),M(k),Q([...s,q]),G(!1),_(""),Z(20),I(null),c?(H("ready"),V(3),A(10)):(H("memorize"),A(10))};o.useEffect(()=>{if(!(!g||B||R)){if(x==="ready")if(U<=0)H("memorize");else{const t=setTimeout(()=>V(s=>s-1),1e3);return()=>clearTimeout(t)}if(x==="memorize")if(E<=0)H("guess");else{const t=setTimeout(()=>A(s=>s-1),1e3);return()=>clearTimeout(t)}if(x==="guess"){if(W<=0){G(!0),I("wrong");const s=b[y].name;O(c=>[...c,{round:w,answer:L,correct:s,result:"wrong"}]);return}const t=setTimeout(()=>Z(s=>s-1),1e3);return()=>clearTimeout(t)}}},[x,U,E,W,g,B,R,b,y,w,L]);const de=()=>{if(y===null||N)return;const t=b[y].name,s=L.toLowerCase().trim();let c="wrong";s===t?(F(f=>f+1),I("correct"),c="correct"):we(s,t)===1?(F(f=>f+.5),I("almost"),c="almost"):(I("wrong"),c="wrong"),O(f=>[...f,{round:w,answer:s,correct:t,result:c}]),K(!0),setTimeout(()=>{K(!1),G(!0)},600)},ce=()=>w<v?(p(t=>t+1),te()):$(!0),me=()=>{C(!1),$(!1),z(null)},ue=o.useMemo(()=>e.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:e.jsxs("picture",{children:[e.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),e.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]),ne=1200,oe=700,D=o.useMemo(()=>{const t=l??(typeof window<"u"?window.innerWidth:ne),s=m??(typeof window<"u"?window.innerHeight:oe),c=Math.min(t/ne,s/oe);return Math.min(1.15,Math.max(.92,c))},[l,m,h]);return e.jsx("div",{ref:i,style:{position:"fixed",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",overflow:"hidden",zIndex:1},children:e.jsx("div",{ref:u,style:{width:h?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,height:h?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,borderRadius:h?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",position:"relative",overflow:"hidden",boxShadow:h?"none":"0 0 40px rgba(0,0,0,0.08)",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",style:{transform:`scale(${D})`,transformOrigin:"center center",transition:"transform 0.2s ease-out",width:`${100/D}%`,height:`${100/D}%`,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[!h&&ue,!j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:n.gmButton,onClick:()=>z(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),e.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(t=>e.jsx("button",{style:{...n.gmButton,...v===t?n.gmButtonActive:{}},onClick:()=>a(t),children:t},t))})]})]}),j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",j]}),e.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",v]}),e.jsx("button",{style:n.gmButton,onClick:ee,children:"▶ Start game"})]}),B&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",ie," / ",v]}),e.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:n.gmTable,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Round"}),e.jsx("th",{children:"Your Answer"}),e.jsx("th",{children:"Correct"}),e.jsx("th",{children:"Result"})]})}),e.jsx("tbody",{children:re.map((t,s)=>e.jsxs("tr",{children:[e.jsx("td",{style:n.gmTableCell,children:t.round}),e.jsx("td",{style:n.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:n.gmTableCell,children:t.correct}),e.jsx("td",{style:n.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},s))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:n.gmButton,onClick:ee,children:"🔁 Play again"}),e.jsx("button",{style:n.gmButton,onClick:me,children:"⬅️ Choose theme"})]})]}),g&&!B&&e.jsxs("div",{style:n.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[x==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),x==="memorize"&&e.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",E,")"]}),x==="guess"&&!R&&e.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",W,"s"]})]}),x!=="ready"&&e.jsx("div",{style:{...n.gmGrid,display:"grid",gridTemplateColumns:`repeat(${h?2:3}, 1fr)`,gridTemplateRows:`repeat(${h?3:2}, 1fr)`,gap:h?12:20,justifyContent:"center",alignContent:"center",padding:h?8:16,width:"100%",height:"100%",maxWidth:h?"100%":600,maxHeight:h?"100%":400,boxSizing:"border-box"},children:b.map((t,s)=>{const c=y===s&&x==="guess"&&!R;return e.jsx("div",{style:{...n.gmCard,width:"100%",height:"100%",...J==="correct"&&y===s?n.gmCorrect:{},...J==="wrong"&&y===s?n.gmWrong:{}},children:!c&&e.jsx("img",{src:t.src,alt:t.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},s)})}),e.jsxs("div",{style:{marginTop:16,height:80},children:[x==="guess"&&!R&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:L,onChange:t=>_(t.target.value),style:n.gmInput}),e.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:de,disabled:N,children:N?"...":"Check"})]}),R&&e.jsx("button",{type:"button",style:n.gmButton,onClick:ce,children:"Next round"})]})]})]})})})}exports.Game=Se;exports.themes=P;
@@ -1,9 +1,9 @@
1
- import { jsx as n, jsxs as l, Fragment as Te } from "react/jsx-runtime";
2
- import { useRef as J, useState as a, useEffect as _, useLayoutEffect as ge, useMemo as Re } from "react";
3
- const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r.map(([s, o]) => ({
4
- src: `${Ie}${u}/${o.replace(/\s/g, "%20")}.png`,
5
- name: o
6
- })), He = [
1
+ import { jsx as n, jsxs as l, Fragment as be } from "react/jsx-runtime";
2
+ import { useRef as V, useState as a, useEffect as P, useLayoutEffect as de, useMemo as le } from "react";
3
+ const we = window.origin + "/cloud/speakid/games/whatsmissing/", U = (r, g) => r.map(([s, i]) => ({
4
+ src: `${we}${g}/${i.replace(/\s/g, "%20")}.png`,
5
+ name: i
6
+ })), xe = [
7
7
  ["apple", "apple"],
8
8
  ["banana", "banana"],
9
9
  ["bread", "bread"],
@@ -29,7 +29,7 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
29
29
  ["strawberry", "strawberry"],
30
30
  ["tomato", "tomato"],
31
31
  ["watermelon", "watermelon"]
32
- ], Be = [
32
+ ], ve = [
33
33
  ["bear", "bear"],
34
34
  ["cat", "cat"],
35
35
  ["crocodile", "crocodile"],
@@ -49,7 +49,7 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
49
49
  ["tortoise", "tortoise"],
50
50
  ["wolf", "wolf"],
51
51
  ["zebra", "zebra"]
52
- ], Ae = [
52
+ ], Ce = [
53
53
  ["ball", "ball"],
54
54
  ["balloon", "balloon"],
55
55
  ["blocks", "blocks"],
@@ -69,11 +69,11 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
69
69
  ["teddy_bear", "teddy bear"],
70
70
  ["yo-yo", "yo-yo"],
71
71
  ["crayons", "crayons"]
72
- ], ue = {
73
- food: K(He, "food"),
74
- animals: K(Be, "animals"),
75
- toys: K(Ae, "toys")
76
- }, Le = `
72
+ ], ae = {
73
+ food: U(xe, "food"),
74
+ animals: U(ve, "animals"),
75
+ toys: U(Ce, "toys")
76
+ }, ke = `
77
77
  @keyframes spin {
78
78
  from { transform: rotate(0deg); }
79
79
  to { transform: rotate(360deg); }
@@ -81,9 +81,9 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
81
81
  `;
82
82
  if (typeof document < "u" && !document.getElementById("spin-keyframes")) {
83
83
  const r = document.createElement("style");
84
- r.id = "spin-keyframes", r.innerHTML = Le, document.head.appendChild(r);
84
+ r.id = "spin-keyframes", r.innerHTML = ke, document.head.appendChild(r);
85
85
  }
86
- const We = {
86
+ const ze = {
87
87
  animation: "spin 1.4s linear infinite"
88
88
  }, t = {
89
89
  gmCenterScreen: {
@@ -239,66 +239,66 @@ const We = {
239
239
  },
240
240
  gmHourglass: {
241
241
  fontSize: "42px",
242
- ...We
242
+ ...ze
243
243
  }
244
- }, Ee = () => {
244
+ }, Se = () => {
245
245
  const r = document.createElement("style");
246
246
  r.textContent = `
247
247
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
248
248
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
249
249
  `, document.head.appendChild(r);
250
- }, je = (r, u) => {
251
- const s = Array.from({ length: r.length + 1 }, () => Array(u.length + 1).fill(0));
252
- for (let o = 0; o <= r.length; o++) s[o][0] = o;
253
- for (let o = 0; o <= u.length; o++) s[0][o] = o;
254
- for (let o = 1; o <= r.length; o++)
255
- for (let c = 1; c <= u.length; c++)
256
- s[o][c] = r[o - 1] === u[c - 1] ? s[o - 1][c - 1] : Math.min(s[o - 1][c - 1], s[o][c - 1], s[o - 1][c]) + 1;
257
- return s[r.length][u.length];
250
+ }, Te = (r, g) => {
251
+ const s = Array.from({ length: r.length + 1 }, () => Array(g.length + 1).fill(0));
252
+ for (let i = 0; i <= r.length; i++) s[i][0] = i;
253
+ for (let i = 0; i <= g.length; i++) s[0][i] = i;
254
+ for (let i = 1; i <= r.length; i++)
255
+ for (let u = 1; u <= g.length; u++)
256
+ s[i][u] = r[i - 1] === g[u - 1] ? s[i - 1][u - 1] : Math.min(s[i - 1][u - 1], s[i][u - 1], s[i - 1][u]) + 1;
257
+ return s[r.length][g.length];
258
258
  };
259
- function Fe(r, u = { minDesktopWidth: 1200, forceResize: !1 }) {
260
- const s = J(null), o = u.minDesktopWidth ?? 1200, c = !!u.forceResize;
261
- ge(() => {
259
+ function Re(r, g = { minDesktopWidth: 1200, forceResize: !1 }) {
260
+ const s = V(null), i = g.minDesktopWidth ?? 1200, u = !!g.forceResize;
261
+ de(() => {
262
262
  if (typeof window > "u" || !r || !r.current) return;
263
- const m = r.current, H = () => {
263
+ const c = r.current, I = () => {
264
264
  try {
265
- const d = document.body, h = getComputedStyle(d), M = parseFloat(d.style && d.style.zoom || "");
266
- if (M && !isNaN(M) && M > 0) return M;
265
+ const d = document.body, h = getComputedStyle(d), S = parseFloat(d.style && d.style.zoom || "");
266
+ if (S && !isNaN(S) && S > 0) return S;
267
267
  const v = parseFloat(h.zoom || "");
268
268
  if (v && !isNaN(v) && v > 0) return v;
269
- const f = document.createElement("div");
270
- f.style.position = "absolute", f.style.left = "0", f.style.top = "0", f.style.width = "100px", f.style.height = "1px", f.style.visibility = "hidden", document.documentElement.appendChild(f);
271
- const y = f.getBoundingClientRect();
272
- if (document.documentElement.removeChild(f), y && y.width > 0) {
273
- const B = y.width / 100;
274
- if (!isNaN(B) && B > 0) return B;
269
+ const y = document.createElement("div");
270
+ y.style.position = "absolute", y.style.left = "0", y.style.top = "0", y.style.width = "100px", y.style.height = "1px", y.style.visibility = "hidden", document.documentElement.appendChild(y);
271
+ const b = y.getBoundingClientRect();
272
+ if (document.documentElement.removeChild(y), b && b.width > 0) {
273
+ const H = b.width / 100;
274
+ if (!isNaN(H) && H > 0) return H;
275
275
  }
276
276
  } catch {
277
277
  }
278
278
  return 1;
279
279
  }, C = () => {
280
- if (o && window.innerWidth < o) {
280
+ if (i && window.innerWidth < i) {
281
281
  R();
282
282
  return;
283
283
  }
284
- const d = H();
284
+ const d = I();
285
285
  if (!d || d === 1) {
286
286
  R();
287
287
  return;
288
288
  }
289
289
  s.current || (s.current = {
290
- transform: m.style.transform || null,
291
- transformOrigin: m.style.transformOrigin || null,
292
- width: m.style.width || null,
293
- height: m.style.height || null,
294
- willChange: m.style.willChange || null
290
+ transform: c.style.transform || null,
291
+ transformOrigin: c.style.transformOrigin || null,
292
+ width: c.style.width || null,
293
+ height: c.style.height || null,
294
+ willChange: c.style.willChange || null
295
295
  });
296
296
  const h = 1 / d;
297
- c && (m.style.width = `${d * 100}%`, m.style.height = `${d * 100}%`), m.style.transformOrigin = "50% 50%", m.style.transform = `scale(${h})`, m.style.willChange = "transform";
297
+ u && (c.style.width = `${d * 100}%`, c.style.height = `${d * 100}%`), c.style.transformOrigin = "50% 50%", c.style.transform = `scale(${h})`, c.style.willChange = "transform";
298
298
  }, R = () => {
299
299
  if (!s.current) return;
300
300
  const d = s.current;
301
- m.style.transform = d.transform ?? "", m.style.transformOrigin = d.transformOrigin ?? "", m.style.width = d.width ?? "", m.style.height = d.height ?? "", m.style.willChange = d.willChange ?? "", s.current = null;
301
+ c.style.transform = d.transform ?? "", c.style.transformOrigin = d.transformOrigin ?? "", c.style.width = d.width ?? "", c.style.height = d.height ?? "", c.style.willChange = d.willChange ?? "", s.current = null;
302
302
  };
303
303
  let x = 0;
304
304
  const k = () => {
@@ -313,93 +313,93 @@ function Fe(r, u = { minDesktopWidth: 1200, forceResize: !1 }) {
313
313
  return z.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), window.addEventListener("resize", k), k(), () => {
314
314
  cancelAnimationFrame(x), z.disconnect(), window.removeEventListener("resize", k), R();
315
315
  };
316
- }, [r, o, c]);
316
+ }, [r, i, u]);
317
317
  }
318
- function De({
318
+ function He({
319
319
  gameCubeSize: r,
320
- screenHeight: u,
320
+ screenHeight: g,
321
321
  screenWidth: s
322
322
  }) {
323
- const o = J(null), c = J(null), [m, H] = a(null);
324
- Fe(o, { minDesktopWidth: 1200, forceResize: !1 }), _(() => (Ee(), () => {
323
+ const i = V(null), u = V(null), [c, I] = a(null);
324
+ Re(i, { minDesktopWidth: 1024, forceResize: !1 }), P(() => (Se(), () => {
325
325
  document.body.style.overflow = "";
326
326
  }), []);
327
- const [C, R] = a(null), [x, k] = a([]), [z, d] = a(4), [h, M] = a(!1), [v, f] = a(1), [y, B] = a(null), [b, E] = a("ready"), [Q, X] = a(3), [G, N] = a(10), [D, ee] = a(20), [he, O] = a(0), [j, q] = a(!1), [F, te] = a(""), [I, Y] = a(!1), [P, ne] = a(!1), [oe, A] = a(null), [fe, U] = a([]), [pe, ie] = a([]), [S, ye] = a(!1);
328
- _(() => {
327
+ const [C, R] = a(null), [x, k] = a([]), [z, d] = a(4), [h, S] = a(!1), [v, y] = a(1), [b, H] = a(null), [w, L] = a("ready"), [Z, _] = a(3), [W, j] = a(10), [F, K] = a(20), [ce, $] = a(0), [A, N] = a(!1), [E, J] = a(""), [M, G] = a(!1), [D, Q] = a(!1), [X, B] = a(null), [me, O] = a([]), [ge, ee] = a([]), [f, ue] = a(!1);
328
+ P(() => {
329
329
  if (typeof window > "u") return;
330
330
  const e = () => {
331
- const i = s ?? window.innerWidth;
332
- ye(i <= 768);
331
+ const o = s ?? window.innerWidth, m = window.matchMedia && window.matchMedia("(pointer: coarse)").matches;
332
+ ue(o <= 768 || m);
333
333
  };
334
334
  return e(), window.addEventListener("resize", e), window.addEventListener("orientationchange", e), () => {
335
335
  window.removeEventListener("resize", e), window.removeEventListener("orientationchange", e);
336
336
  };
337
- }, [s]), ge(() => {
338
- const e = c.current;
337
+ }, [s]), de(() => {
338
+ const e = u.current;
339
339
  if (!e || typeof window > "u") return;
340
- let i = null;
340
+ let o = null;
341
341
  try {
342
- i = new ResizeObserver((p) => {
343
- for (const g of p) {
344
- const w = g.contentRect;
345
- H(Math.round(Math.min(w.width, w.height)));
342
+ o = new ResizeObserver((m) => {
343
+ for (const p of m) {
344
+ const T = p.contentRect;
345
+ I(Math.round(Math.min(T.width, T.height)));
346
346
  }
347
- }), i.observe(e), H(Math.round(Math.min(e.clientWidth, e.clientHeight)));
347
+ }), o.observe(e), I(Math.round(Math.min(e.clientWidth, e.clientHeight)));
348
348
  } catch {
349
- H(Math.round(Math.min(e.clientWidth, e.clientHeight)));
349
+ I(Math.round(Math.min(e.clientWidth, e.clientHeight)));
350
350
  }
351
- return () => i?.disconnect();
352
- }, [S]);
353
- const re = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), se = () => {
351
+ return () => o?.disconnect();
352
+ }, [f]);
353
+ const te = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), ne = () => {
354
354
  if (!C) return;
355
- const e = re(ue[C]);
356
- k(e), M(!0), q(!1), f(1), O(0), U([]), ie([]), le(e, [], !0);
357
- }, le = (e = x, i = pe, p = !1) => {
358
- const g = re(e.length ? e : ue[C]);
359
- let w = Math.floor(Math.random() * g.length), T = g[w].name, L = 0;
360
- for (; i.includes(T) && L < 20; )
361
- w = Math.floor(Math.random() * g.length), T = g[w].name, L++;
362
- k(g), B(w), ie([...i, T]), Y(!1), te(""), ee(20), A(null), p ? (E("ready"), X(3), N(10)) : (E("memorize"), N(10));
355
+ const e = te(ae[C]);
356
+ k(e), S(!0), N(!1), y(1), $(0), O([]), ee([]), oe(e, [], !0);
357
+ }, oe = (e = x, o = ge, m = !1) => {
358
+ const p = te(e.length ? e : ae[C]);
359
+ let T = Math.floor(Math.random() * p.length), Y = p[T].name, se = 0;
360
+ for (; o.includes(Y) && se < 20; )
361
+ T = Math.floor(Math.random() * p.length), Y = p[T].name, se++;
362
+ k(p), H(T), ee([...o, Y]), G(!1), J(""), K(20), B(null), m ? (L("ready"), _(3), j(10)) : (L("memorize"), j(10));
363
363
  };
364
- _(() => {
365
- if (!(!h || j || I)) {
366
- if (b === "ready")
367
- if (Q <= 0) E("memorize");
364
+ P(() => {
365
+ if (!(!h || A || M)) {
366
+ if (w === "ready")
367
+ if (Z <= 0) L("memorize");
368
368
  else {
369
- const e = setTimeout(() => X((i) => i - 1), 1e3);
369
+ const e = setTimeout(() => _((o) => o - 1), 1e3);
370
370
  return () => clearTimeout(e);
371
371
  }
372
- if (b === "memorize")
373
- if (G <= 0) E("guess");
372
+ if (w === "memorize")
373
+ if (W <= 0) L("guess");
374
374
  else {
375
- const e = setTimeout(() => N((i) => i - 1), 1e3);
375
+ const e = setTimeout(() => j((o) => o - 1), 1e3);
376
376
  return () => clearTimeout(e);
377
377
  }
378
- if (b === "guess") {
379
- if (D <= 0) {
380
- Y(!0), A("wrong");
381
- const i = x[y].name;
382
- U((p) => [
383
- ...p,
384
- { round: v, answer: F, correct: i, result: "wrong" }
378
+ if (w === "guess") {
379
+ if (F <= 0) {
380
+ G(!0), B("wrong");
381
+ const o = x[b].name;
382
+ O((m) => [
383
+ ...m,
384
+ { round: v, answer: E, correct: o, result: "wrong" }
385
385
  ]);
386
386
  return;
387
387
  }
388
- const e = setTimeout(() => ee((i) => i - 1), 1e3);
388
+ const e = setTimeout(() => K((o) => o - 1), 1e3);
389
389
  return () => clearTimeout(e);
390
390
  }
391
391
  }
392
- }, [b, Q, G, D, h, j, I, x, y, v, F]);
393
- const be = () => {
394
- if (y === null || P) return;
395
- const e = x[y].name, i = F.toLowerCase().trim();
396
- let p = "wrong";
397
- i === e ? (O((g) => g + 1), A("correct"), p = "correct") : je(i, e) === 1 ? (O((g) => g + 0.5), A("almost"), p = "almost") : (A("wrong"), p = "wrong"), U((g) => [...g, { round: v, answer: i, correct: e, result: p }]), ne(!0), setTimeout(() => {
398
- ne(!1), Y(!0);
392
+ }, [w, Z, W, F, h, A, M, x, b, v, E]);
393
+ const he = () => {
394
+ if (b === null || D) return;
395
+ const e = x[b].name, o = E.toLowerCase().trim();
396
+ let m = "wrong";
397
+ o === e ? ($((p) => p + 1), B("correct"), m = "correct") : Te(o, e) === 1 ? ($((p) => p + 0.5), B("almost"), m = "almost") : (B("wrong"), m = "wrong"), O((p) => [...p, { round: v, answer: o, correct: e, result: m }]), Q(!0), setTimeout(() => {
398
+ Q(!1), G(!0);
399
399
  }, 600);
400
- }, we = () => v < z ? (f((e) => e + 1), le()) : q(!0), xe = () => {
401
- M(!1), q(!1), R(null);
402
- }, ve = Re(
400
+ }, fe = () => v < z ? (y((e) => e + 1), oe()) : N(!0), pe = () => {
401
+ S(!1), N(!1), R(null);
402
+ }, ye = le(
403
403
  () => /* @__PURE__ */ n("div", { style: { ...t.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ l("picture", { children: [
404
404
  /* @__PURE__ */ n(
405
405
  "source",
@@ -419,11 +419,14 @@ function De({
419
419
  )
420
420
  ] }) }),
421
421
  []
422
- ), ae = 1440, de = 900, Ce = c.current?.clientWidth ?? s ?? (typeof window < "u" ? window.innerWidth : ae), ke = c.current?.clientHeight ?? u ?? (typeof window < "u" ? window.innerHeight : de), V = Math.min(Ce / ae, ke / de);
422
+ ), ie = 1200, re = 700, q = le(() => {
423
+ const e = s ?? (typeof window < "u" ? window.innerWidth : ie), o = g ?? (typeof window < "u" ? window.innerHeight : re), m = Math.min(e / ie, o / re);
424
+ return Math.min(1.15, Math.max(0.92, m));
425
+ }, [s, g, f]);
423
426
  return /* @__PURE__ */ n(
424
427
  "div",
425
428
  {
426
- ref: o,
429
+ ref: i,
427
430
  style: {
428
431
  position: "fixed",
429
432
  inset: 0,
@@ -437,15 +440,15 @@ function De({
437
440
  children: /* @__PURE__ */ n(
438
441
  "div",
439
442
  {
440
- ref: c,
443
+ ref: u,
441
444
  style: {
442
- width: S ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, u ?? 1e3)}px`,
443
- height: S ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, u ?? 1e3)}px`,
444
- borderRadius: S ? 0 : "20px",
445
+ width: f ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, g ?? 1e3)}px`,
446
+ height: f ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, g ?? 1e3)}px`,
447
+ borderRadius: f ? 0 : "20px",
445
448
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
446
449
  position: "relative",
447
450
  overflow: "hidden",
448
- boxShadow: S ? "none" : "0 0 40px rgba(0,0,0,0.08)",
451
+ boxShadow: f ? "none" : "0 0 40px rgba(0,0,0,0.08)",
449
452
  display: "flex",
450
453
  justifyContent: "center",
451
454
  alignItems: "center"
@@ -455,17 +458,18 @@ function De({
455
458
  {
456
459
  id: "whats-missing-root",
457
460
  style: {
458
- transform: `scale(${V})`,
461
+ transform: `scale(${q})`,
459
462
  transformOrigin: "center center",
460
- width: `${100 / V}%`,
461
- height: `${100 / V}%`,
463
+ transition: "transform 0.2s ease-out",
464
+ width: `${100 / q}%`,
465
+ height: `${100 / q}%`,
462
466
  display: "flex",
463
467
  flexDirection: "column",
464
468
  justifyContent: "center",
465
469
  alignItems: "center"
466
470
  },
467
471
  children: [
468
- !S && ve,
472
+ !f && ye,
469
473
  !C && !h && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
470
474
  /* @__PURE__ */ n("h1", { style: t.gmHeadline1, children: "WHAT'S MISSING?" }),
471
475
  /* @__PURE__ */ n("p", { style: t.gmBodyM, children: "Select a theme:" }),
@@ -495,13 +499,13 @@ function De({
495
499
  "Rounds: ",
496
500
  z
497
501
  ] }),
498
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: se, children: "▶ Start game" })
502
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: ne, children: "▶ Start game" })
499
503
  ] }),
500
- j && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
504
+ A && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
501
505
  /* @__PURE__ */ n("h1", { style: t.gmHeadline1, children: "Results" }),
502
506
  /* @__PURE__ */ l("h2", { style: t.gmHeadline3, children: [
503
507
  "Your score: ",
504
- he,
508
+ ce,
505
509
  " / ",
506
510
  z
507
511
  ] }),
@@ -513,19 +517,19 @@ function De({
513
517
  /* @__PURE__ */ n("th", { children: "Correct" }),
514
518
  /* @__PURE__ */ n("th", { children: "Result" })
515
519
  ] }) }),
516
- /* @__PURE__ */ n("tbody", { children: fe.map((e, i) => /* @__PURE__ */ l("tr", { children: [
520
+ /* @__PURE__ */ n("tbody", { children: me.map((e, o) => /* @__PURE__ */ l("tr", { children: [
517
521
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.round }),
518
522
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.answer || "—" }),
519
523
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.correct }),
520
524
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.result === "correct" ? "✔ Correct" : e.result === "almost" ? "◐ Almost (0.5)" : "✘ Wrong" })
521
- ] }, i)) })
525
+ ] }, o)) })
522
526
  ] }),
523
527
  /* @__PURE__ */ l("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
524
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: se, children: "🔁 Play again" }),
525
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: xe, children: "⬅️ Choose theme" })
528
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: ne, children: "🔁 Play again" }),
529
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: pe, children: "⬅️ Choose theme" })
526
530
  ] })
527
531
  ] }),
528
- h && !j && /* @__PURE__ */ l("div", { style: t.gmGameLayout, children: [
532
+ h && !A && /* @__PURE__ */ l("div", { style: t.gmGameLayout, children: [
529
533
  /* @__PURE__ */ l(
530
534
  "div",
531
535
  {
@@ -537,87 +541,81 @@ function De({
537
541
  alignItems: "center"
538
542
  },
539
543
  children: [
540
- b === "ready" && /* @__PURE__ */ l(Te, { children: [
544
+ w === "ready" && /* @__PURE__ */ l(be, { children: [
541
545
  /* @__PURE__ */ n("h1", { style: { ...t.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
542
546
  /* @__PURE__ */ n("div", { style: t.gmHourglass, children: "⏳" })
543
547
  ] }),
544
- b === "memorize" && /* @__PURE__ */ l("p", { style: { ...t.gmBodyM, color: "#10b981" }, children: [
548
+ w === "memorize" && /* @__PURE__ */ l("p", { style: { ...t.gmBodyM, color: "#10b981" }, children: [
545
549
  "MEMORIZE (",
546
- G,
550
+ W,
547
551
  ")"
548
552
  ] }),
549
- b === "guess" && !I && /* @__PURE__ */ l("p", { style: t.gmBodyM, children: [
553
+ w === "guess" && !M && /* @__PURE__ */ l("p", { style: t.gmBodyM, children: [
550
554
  "⏳ Time left: ",
551
- D,
555
+ F,
552
556
  "s"
553
557
  ] })
554
558
  ]
555
559
  }
556
560
  ),
557
- b !== "ready" && (() => {
558
- const e = S ? 12 : 20, i = 32, p = c.current?.clientWidth ?? Math.min(r ?? 1e3, s ?? 1e3), g = c.current?.clientHeight ?? Math.min(r ?? 1e3, u ?? 1e3), w = Math.min(p, g), T = typeof window < "u" ? window.innerWidth : s ?? 1e3, L = T < 600 ? 110 : T < 900 ? 130 : T < 1280 ? 150 : 180, ze = 4, ce = 2, Z = Math.max(
559
- ce,
560
- Math.min(
561
- ze,
562
- Math.floor((w - i + e) / (L + e)) || ce
563
- )
564
- ), Me = Math.floor((w - i - e * (Z - 1)) / Z), W = Math.max(L, Me);
565
- return /* @__PURE__ */ n(
566
- "div",
567
- {
568
- style: {
569
- ...t.gmGrid,
570
- gridTemplateColumns: `repeat(${Z}, ${W}px)`,
571
- gridAutoRows: `${W}px`,
572
- gap: `${e}px`,
573
- justifyContent: "center",
574
- justifyItems: "center",
575
- padding: 8,
576
- boxSizing: "border-box"
577
- },
578
- children: x.map((me, $) => {
579
- const Se = y === $ && b === "guess" && !I;
580
- return /* @__PURE__ */ n(
581
- "div",
582
- {
583
- style: {
584
- ...t.gmCard,
585
- width: `${W}px`,
586
- height: `${W}px`,
587
- padding: W >= 160 ? 10 : 8,
588
- boxSizing: "border-box",
589
- ...oe === "correct" && y === $ ? t.gmCorrect : {},
590
- ...oe === "wrong" && y === $ ? t.gmWrong : {}
591
- },
592
- children: !Se && /* @__PURE__ */ n(
593
- "img",
594
- {
595
- src: me.src,
596
- alt: me.name,
597
- style: {
598
- width: "100%",
599
- height: "100%",
600
- objectFit: "cover",
601
- display: "block"
602
- }
603
- }
604
- )
561
+ w !== "ready" && /* @__PURE__ */ n(
562
+ "div",
563
+ {
564
+ style: {
565
+ ...t.gmGrid,
566
+ display: "grid",
567
+ gridTemplateColumns: `repeat(${f ? 2 : 3}, 1fr)`,
568
+ gridTemplateRows: `repeat(${f ? 3 : 2}, 1fr)`,
569
+ gap: f ? 12 : 20,
570
+ justifyContent: "center",
571
+ alignContent: "center",
572
+ padding: f ? 8 : 16,
573
+ width: "100%",
574
+ height: "100%",
575
+ maxWidth: f ? "100%" : 600,
576
+ maxHeight: f ? "100%" : 400,
577
+ boxSizing: "border-box"
578
+ },
579
+ children: x.map((e, o) => {
580
+ const m = b === o && w === "guess" && !M;
581
+ return /* @__PURE__ */ n(
582
+ "div",
583
+ {
584
+ style: {
585
+ ...t.gmCard,
586
+ width: "100%",
587
+ height: "100%",
588
+ ...X === "correct" && b === o ? t.gmCorrect : {},
589
+ ...X === "wrong" && b === o ? t.gmWrong : {}
605
590
  },
606
- $
607
- );
608
- })
609
- }
610
- );
611
- })(),
591
+ children: !m && /* @__PURE__ */ n(
592
+ "img",
593
+ {
594
+ src: e.src,
595
+ alt: e.name,
596
+ style: {
597
+ width: "100%",
598
+ height: "100%",
599
+ objectFit: "cover",
600
+ display: "block"
601
+ }
602
+ }
603
+ )
604
+ },
605
+ o
606
+ );
607
+ })
608
+ }
609
+ ),
612
610
  /* @__PURE__ */ l("div", { style: { marginTop: 16, height: 80 }, children: [
613
- b === "guess" && !I && /* @__PURE__ */ l("div", { children: [
611
+ w === "guess" && !M && /* @__PURE__ */ l("div", { children: [
614
612
  /* @__PURE__ */ n(
615
613
  "input",
616
614
  {
617
615
  type: "text",
618
616
  placeholder: "Type the missing word",
619
- value: F,
620
- onChange: (e) => te(e.target.value),
617
+ value: E,
618
+ onChange: (e) => J(e.target.value),
621
619
  style: t.gmInput
622
620
  }
623
621
  ),
@@ -625,13 +623,13 @@ function De({
625
623
  "button",
626
624
  {
627
625
  style: { ...t.gmButton, marginLeft: 8 },
628
- onClick: be,
629
- disabled: P,
630
- children: P ? "..." : "Check"
626
+ onClick: he,
627
+ disabled: D,
628
+ children: D ? "..." : "Check"
631
629
  }
632
630
  )
633
631
  ] }),
634
- I && /* @__PURE__ */ n("button", { type: "button", style: t.gmButton, onClick: we, children: "Next round" })
632
+ M && /* @__PURE__ */ n("button", { type: "button", style: t.gmButton, onClick: fe, children: "Next round" })
635
633
  ] })
636
634
  ] })
637
635
  ]
@@ -643,6 +641,6 @@ function De({
643
641
  );
644
642
  }
645
643
  export {
646
- De as Game,
647
- ue as themes
644
+ He as Game,
645
+ ae as themes
648
646
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblinkov/whats-missing",
3
- "version": "20.0.30",
3
+ "version": "20.0.31",
4
4
  "main": "dist/whats-missing.umd.js",
5
5
  "module": "dist/whats-missing.es.js",
6
6
  "types": "dist/index.d.ts",
package/src/Game.tsx CHANGED
@@ -157,7 +157,7 @@ export default function Game({
157
157
  const containerRef = useRef<HTMLDivElement | null>(null);
158
158
  const squareRef = useRef<HTMLDivElement | null>(null);
159
159
  const [squareSize, setSquareSize] = useState<number | null>(null);
160
- useNeutralizeBodyZoom(containerRef, { minDesktopWidth: 1200, forceResize: false });
160
+ useNeutralizeBodyZoom(containerRef, { minDesktopWidth: 1024, forceResize: false });
161
161
 
162
162
  useEffect(() => {
163
163
  globalReset();
@@ -191,7 +191,8 @@ export default function Game({
191
191
  if (typeof window === "undefined") return;
192
192
  const update = () => {
193
193
  const w = screenWidth ?? window.innerWidth;
194
- setIsMobile(w <= 768);
194
+ const hasCoarsePointer = window.matchMedia && window.matchMedia('(pointer: coarse)').matches;
195
+ setIsMobile(w <= 768 || hasCoarsePointer);
195
196
  };
196
197
  update();
197
198
  window.addEventListener("resize", update);
@@ -349,13 +350,17 @@ export default function Game({
349
350
  []
350
351
  );
351
352
 
352
- // ✅ масштаб интерфейса под доступный размер контейнера не всей вкладки)
353
- // это устраняет резкие перепады масштаба при открытии DevTools или панелей браузера
354
- const baseWidth = 1440;
355
- const baseHeight = 900;
356
- const effectiveWidth = squareRef.current?.clientWidth ?? (screenWidth ?? (typeof window !== "undefined" ? window.innerWidth : baseWidth));
357
- const effectiveHeight = squareRef.current?.clientHeight ?? (screenHeight ?? (typeof window !== "undefined" ? window.innerHeight : baseHeight));
358
- const scale = Math.min(effectiveWidth / baseWidth, effectiveHeight / baseHeight);
353
+ // ✅ масштаб интерфейса под размеры окна с мягкими лимитами и кэшированием
354
+ // оптимизированные базовые размеры для лучшего покрытия экрана на десктопах
355
+ const baseWidth = 1200;
356
+ const baseHeight = 700;
357
+ const scale = useMemo(() => {
358
+ const effectiveWidth = screenWidth ?? (typeof window !== "undefined" ? window.innerWidth : baseWidth);
359
+ const effectiveHeight = screenHeight ?? (typeof window !== "undefined" ? window.innerHeight : baseHeight);
360
+ const rawScale = Math.min(effectiveWidth / baseWidth, effectiveHeight / baseHeight);
361
+ // мягкие границы роста/сжатия
362
+ return Math.min(1.15, Math.max(0.92, rawScale));
363
+ }, [screenWidth, screenHeight, isMobile]);
359
364
 
360
365
  return (
361
366
  <div
@@ -395,6 +400,7 @@ export default function Game({
395
400
  style={{
396
401
  transform: `scale(${scale})`,
397
402
  transformOrigin: "center center",
403
+ transition: "transform 0.2s ease-out",
398
404
  width: `${100 / scale}%`,
399
405
  height: `${100 / scale}%`,
400
406
  display: "flex",
@@ -523,85 +529,55 @@ export default function Game({
523
529
  )}
524
530
  </div>
525
531
 
526
- {/* Сетка карточек */}
527
- {phase !== "ready" && (() => {
528
- const gap = isMobile ? 12 : 20;
529
- const innerGutters = 32; // total padding inside the grid wrapper
530
- const effW = squareRef.current?.clientWidth ?? Math.min(gameCubeSize ?? 1000, screenWidth ?? 1000);
531
- const effH = squareRef.current?.clientHeight ?? Math.min(gameCubeSize ?? 1000, screenHeight ?? 1000);
532
- const effective = Math.min(effW, effH);
533
-
534
- // choose a comfortable minimum card size per breakpoint
535
- const vw = typeof window !== "undefined" ? window.innerWidth : (screenWidth ?? 1000);
536
- // Tune breakpoints so common laptop sizes (e.g., 1366×768) keep a 3×3 grid
537
- // by allowing a slightly smaller minimum card size when width < 1280.
538
- const minCardBase = vw < 600 ? 110 : vw < 900 ? 130 : vw < 1280 ? 150 : 180;
539
-
540
- // compute columns to best fill available space without going below minCardBase
541
- const maxColumns = 4;
542
- const minColumns = 2;
543
- const possibleColumns = Math.max(
544
- minColumns,
545
- Math.min(
546
- maxColumns,
547
- Math.floor((effective - innerGutters + gap) / (minCardBase + gap)) || minColumns
548
- )
549
- );
550
-
551
- const columns = possibleColumns;
552
- const computed = Math.floor((effective - innerGutters - gap * (columns - 1)) / columns);
553
- const cardSize = Math.max(minCardBase, computed);
554
-
555
- return (
556
- <div
557
- style={{
558
- ...styles.gmGrid,
559
- gridTemplateColumns: `repeat(${columns}, ${cardSize}px)`,
560
- gridAutoRows: `${cardSize}px`,
561
- gap: `${gap}px`,
562
- justifyContent: "center",
563
- justifyItems: "center",
564
- padding: 8,
565
- boxSizing: "border-box",
566
- }}
567
- >
568
- {files.map((file, i) => {
569
- const isHidden = hiddenIndex === i && phase === "guess" && !answered;
570
- return (
571
- <div
572
- key={i}
573
- style={{
574
- ...styles.gmCard,
575
- width: `${cardSize}px`,
576
- height: `${cardSize}px`,
577
- padding: cardSize >= 160 ? 10 : 8,
578
- boxSizing: "border-box",
579
- ...(result === "correct" && hiddenIndex === i
580
- ? styles.gmCorrect
581
- : {}),
582
- ...(result === "wrong" && hiddenIndex === i
583
- ? styles.gmWrong
584
- : {}),
585
- }}
586
- >
587
- {!isHidden && (
588
- <img
589
- src={file.src}
590
- alt={file.name}
591
- style={{
592
- width: "100%",
593
- height: "100%",
594
- objectFit: "cover",
595
- display: "block",
596
- }}
597
- />
598
- )}
599
- </div>
600
- );
601
- })}
602
- </div>
603
- );
604
- })()}
532
+ {/* ===== Сетка карточек (фикс 3×2 на десктопе, 2×3 на мобилках) ===== */}
533
+ {phase !== "ready" && (
534
+ <div
535
+ style={{
536
+ ...styles.gmGrid,
537
+ display: "grid",
538
+ gridTemplateColumns: `repeat(${isMobile ? 2 : 3}, 1fr)`,
539
+ gridTemplateRows: `repeat(${isMobile ? 3 : 2}, 1fr)`,
540
+ gap: isMobile ? 12 : 20,
541
+ justifyContent: "center",
542
+ alignContent: "center",
543
+ padding: isMobile ? 8 : 16,
544
+ width: "100%",
545
+ height: "100%",
546
+ maxWidth: isMobile ? "100%" : 600,
547
+ maxHeight: isMobile ? "100%" : 400,
548
+ boxSizing: "border-box",
549
+ }}
550
+ >
551
+ {files.map((file, i) => {
552
+ const isHidden = hiddenIndex === i && phase === "guess" && !answered;
553
+ return (
554
+ <div
555
+ key={i}
556
+ style={{
557
+ ...styles.gmCard,
558
+ width: "100%",
559
+ height: "100%",
560
+ ...(result === "correct" && hiddenIndex === i ? styles.gmCorrect : {}),
561
+ ...(result === "wrong" && hiddenIndex === i ? styles.gmWrong : {}),
562
+ }}
563
+ >
564
+ {!isHidden && (
565
+ <img
566
+ src={file.src}
567
+ alt={file.name}
568
+ style={{
569
+ width: "100%",
570
+ height: "100%",
571
+ objectFit: "cover",
572
+ display: "block",
573
+ }}
574
+ />
575
+ )}
576
+ </div>
577
+ );
578
+ })}
579
+ </div>
580
+ )}
605
581
 
606
582
  {/* Инпут и кнопки */}
607
583
  <div style={{ marginTop: 16, height: 80 }}>