@mblinkov/whats-missing 20.0.17 → 20.0.19

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"),re=window.origin+"/cloud/speakid/games/whatsmissing/",B=(r,a)=>r.map(([d,n])=>({src:`${re}${a}/${n.replace(/\s/g,"%20")}.png`,name:n})),ae=[["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"]],le=[["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"]],de=[["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"]],W={food:B(ae,"food"),animals:B(le,"animals"),toys:B(de,"toys")},ce=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),i=require("react"),ge=window.origin+"/cloud/speakid/games/whatsmissing/",$=(a,l)=>a.map(([c,n])=>({src:`${ge}${l}/${n.replace(/\s/g,"%20")}.png`,name:n})),ue=[["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"]],he=[["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"]],N={food:$(ue,"food"),animals:$(he,"animals"),toys:$(pe,"toys")},fe=`
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=ce,document.head.appendChild(r)}const me={animation:"spin 1.4s linear infinite"},s={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100vh",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:"600px",minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"calc(210px * 3 + 20px * 2)",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",...me}},ge=()=>{const r=document.createElement("style");r.textContent=`
6
+ `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const a=document.createElement("style");a.id="spin-keyframes",a.innerHTML=fe,document.head.appendChild(a)}const xe={animation:"spin 1.4s linear infinite"},s={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100vh",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:"600px",minHeight:"100vh",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"calc(210px * 3 + 20px * 2)",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}},ye=()=>{const a=document.createElement("style");a.textContent=`
7
7
  #whats-missing-root, #whats-missing-root * {
8
8
  box-sizing: border-box;
9
9
  font-family: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
@@ -14,9 +14,5 @@
14
14
  display: block;
15
15
  user-select: none;
16
16
  }
17
- html, body {
18
- margin: 0;
19
- padding: 0;
20
- zoom: 1 !important; /* ✅ защита от подзума */
21
- }
22
- `,document.head.appendChild(r)},ue=(r,a)=>{const d=Array.from({length:r.length+1},()=>Array(a.length+1).fill(0));for(let n=0;n<=r.length;n++)d[n][0]=n;for(let n=0;n<=a.length;n++)d[0][n]=n;for(let n=1;n<=r.length;n++)for(let m=1;m<=a.length;m++)d[n][m]=r[n-1]===a[m-1]?d[n-1][m-1]:Math.min(d[n-1][m-1],d[n][m-1],d[n-1][m])+1;return d[r.length][a.length]};function he(){const r=o.useRef(null);o.useEffect(()=>(ge(),()=>{document.body.style.overflow=""}),[]);const[a,d]=o.useState(null),[n,m]=o.useState([]),[w,K]=o.useState(4),[f,L]=o.useState(!1),[j,E]=o.useState(1),[h,Z]=o.useState(null),[g,S]=o.useState("ready"),[G,F]=o.useState(3),[C,T]=o.useState(10),[z,Y]=o.useState(20),[X,R]=o.useState(0),[k,I]=o.useState(!1),[v,D]=o.useState(""),[p,H]=o.useState(!1),[M,q]=o.useState(!1),[O,x]=o.useState(null),[J,A]=o.useState([]),[Q,P]=o.useState([]),[u,ee]=o.useState(!1),[te,U]=o.useState(1);o.useEffect(()=>{const t=()=>{const i=window.innerWidth<768,l=window.innerWidth>=768&&window.innerWidth<1200;if(ee(i||l),!i&&!l){const b=Math.min(window.innerWidth/1440,window.innerHeight/768)*.97;U(b)}else U(1)};return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]);const $=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),N=()=>{if(!a)return;const t=$(W[a]);m(t),L(!0),I(!1),E(1),R(0),A([]),P([]),V(t,[],!0)},V=(t=n,i=Q,l=!1)=>{const c=$(t.length?t:W[a]);let y=Math.floor(Math.random()*c.length),b=c[y].name,_=0;for(;i.includes(b)&&_<20;)y=Math.floor(Math.random()*c.length),b=c[y].name,_++;m(c),Z(y),P([...i,b]),H(!1),D(""),Y(20),x(null),l?(S("ready"),F(3),T(10)):(S("memorize"),T(10))};o.useEffect(()=>{if(!(!f||k||p)){if(g==="ready")if(G<=0)S("memorize");else{const t=setTimeout(()=>F(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="memorize")if(C<=0)S("guess");else{const t=setTimeout(()=>T(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="guess"){if(z<=0){H(!0),x("wrong");const i=n[h].name;A(l=>[...l,{round:j,answer:v,correct:i,result:"wrong"}]);return}const t=setTimeout(()=>Y(i=>i-1),1e3);return()=>clearTimeout(t)}}},[g,G,C,z,f,k,p,n,h,j,v]);const se=()=>{if(h===null||M)return;const t=n[h].name,i=v.toLowerCase().trim();let l="wrong";i===t?(R(c=>c+1),x("correct"),l="correct"):ue(i,t)===1?(R(c=>c+.5),x("almost"),l="almost"):(x("wrong"),l="wrong"),A(c=>[...c,{round:j,answer:i,correct:t,result:l}]),q(!0),setTimeout(()=>{q(!1),H(!0)},600)},ne=()=>j<w?(E(t=>t+1),V()):I(!0),oe=()=>{L(!1),I(!1),d(null)},ie=o.useMemo(()=>e.jsx("div",{style:s.gmLogoFixed,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:s.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:r,style:{width:"100%",height:"100vh",display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease",overflowX:"clip"},children:e.jsx("div",{style:{width:u?"100%":1440,height:u?"100%":768,display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:u?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:u?"none":"0 0 40px rgba(0,0,0,0.1)",margin:u?"0 auto":"unset"},children:e.jsx("div",{style:{transform:u?"none":`scale(${te})`,transformOrigin:"top center",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!u&&ie,!a&&!f&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:s.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:s.gmButton,onClick:()=>d(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:s.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:{...s.gmButton,...w===t?s.gmButtonActive:{}},onClick:()=>K(t),children:t},t))})]})]}),a&&!f&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsxs("h1",{style:s.gmHeadline1,children:["Theme selected: ",a]}),e.jsxs("p",{style:s.gmBodyM,children:["Rounds: ",w]}),e.jsx("button",{style:s.gmButton,onClick:N,children:"▶ Start game"})]}),k&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:s.gmHeadline3,children:["Your score: ",X," / ",w]}),e.jsx("p",{style:{...s.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:s.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:J.map((t,i)=>e.jsxs("tr",{children:[e.jsx("td",{style:s.gmTableCell,children:t.round}),e.jsx("td",{style:s.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:s.gmTableCell,children:t.correct}),e.jsx("td",{style:s.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:s.gmButton,onClick:N,children:"🔁 Play again"}),e.jsx("button",{style:s.gmButton,onClick:oe,children:"⬅️ Choose theme"})]})]}),f&&!k&&e.jsxs("div",{style:s.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[g==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...s.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:s.gmHourglass,children:"⏳"})]}),g==="memorize"&&e.jsxs("p",{style:{...s.gmBodyM,color:"#10b981"},children:["MEMORIZE (",C,")"]}),g==="guess"&&!p&&e.jsxs("p",{style:s.gmBodyM,children:["⏳ Time left: ",z,"s"]})]}),g!=="ready"&&e.jsx("div",{style:{...s.gmGrid,gridTemplateColumns:u?"repeat(2, 1fr)":"repeat(3, 210px)",gridAutoRows:u?"150px":"210px",gap:u?"12px":"20px",justifyItems:"center"},children:n.map((t,i)=>{const l=h===i&&g==="guess"&&!p;return e.jsx("div",{style:{...s.gmCard,...O==="correct"&&h===i?s.gmCorrect:{},...O==="wrong"&&h===i?s.gmWrong:{}},children:!l&&e.jsx("img",{src:t.src,alt:t.name,style:{width:"100%",height:"100%",objectFit:"cover"}})},i)})}),e.jsxs("div",{style:{marginTop:16,height:80},children:[g==="guess"&&!p&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:v,onChange:t=>D(t.target.value),style:s.gmInput}),e.jsx("button",{style:{...s.gmButton,marginLeft:8},onClick:se,disabled:M,children:M?"...":"Check"})]}),p&&e.jsx("button",{style:s.gmButton,onClick:ne,children:"Next round"})]})]})]})})})})}exports.Game=he;exports.themes=W;
17
+ html, body { margin: 0; padding: 0; }
18
+ `,document.head.appendChild(a)},be=(a,l)=>{const c=Array.from({length:a.length+1},()=>Array(l.length+1).fill(0));for(let n=0;n<=a.length;n++)c[n][0]=n;for(let n=0;n<=l.length;n++)c[0][n]=n;for(let n=1;n<=a.length;n++)for(let m=1;m<=l.length;m++)c[n][m]=a[n-1]===l[m-1]?c[n-1][m-1]:Math.min(c[n-1][m-1],c[n][m-1],c[n-1][m])+1;return c[a.length][l.length]};function we(){const a=i.useRef(null);i.useEffect(()=>(ye(),()=>{document.body.style.overflow=""}),[]);const[l,c]=i.useState(null),[n,m]=i.useState([]),[S,te]=i.useState(4),[w,P]=i.useState(!1),[v,Y]=i.useState(1),[x,se]=i.useState(null),[g,k]=i.useState("ready"),[q,D]=i.useState(3),[R,I]=i.useState(10),[H,O]=i.useState(20),[ne,B]=i.useState(0),[C,A]=i.useState(!1),[z,U]=i.useState(""),[b,L]=i.useState(!1),[E,V]=i.useState(!1),[_,j]=i.useState(null),[oe,F]=i.useState([]),[ie,K]=i.useState([]),[h,re]=i.useState(!1),[T,Z]=i.useState(null),[y,W]=i.useState(1);i.useEffect(()=>{const t=()=>{const r=window.innerWidth<768;if(re(r),r){Z(null);return}const p=.97,u=1e3,f=Math.min(window.innerWidth,window.innerHeight),M=Math.max(360,Math.round(f*p)),ee=Math.min(M,u);Z(ee)},o=()=>{try{const r=document.body,p=getComputedStyle(r),u=parseFloat(p.zoom||"");if(u&&!isNaN(u)&&u>0){W(u);return}const f=p.transform;if(f&&f!=="none"){const M=f.match(/matrix\(([^)]+)\)/);if(M){const G=M[1].split(",").map(me=>parseFloat(me))[0];if(G&&!isNaN(G)){W(G);return}}}}catch{}W(1)};t(),o(),window.addEventListener("resize",t),window.addEventListener("resize",o);const d=new MutationObserver(o);return d.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),()=>{window.removeEventListener("resize",t),window.removeEventListener("resize",o),d.disconnect()}},[]);const X=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),J=()=>{if(!l)return;const t=X(N[l]);m(t),P(!0),A(!1),Y(1),B(0),F([]),K([]),Q(t,[],!0)},Q=(t=n,o=ie,d=!1)=>{const r=X(t.length?t:N[l]);let p=Math.floor(Math.random()*r.length),u=r[p].name,f=0;for(;o.includes(u)&&f<20;)p=Math.floor(Math.random()*r.length),u=r[p].name,f++;m(r),se(p),K([...o,u]),L(!1),U(""),O(20),j(null),d?(k("ready"),D(3),I(10)):(k("memorize"),I(10))};i.useEffect(()=>{if(!(!w||C||b)){if(g==="ready")if(q<=0)k("memorize");else{const t=setTimeout(()=>D(o=>o-1),1e3);return()=>clearTimeout(t)}if(g==="memorize")if(R<=0)k("guess");else{const t=setTimeout(()=>I(o=>o-1),1e3);return()=>clearTimeout(t)}if(g==="guess"){if(H<=0){L(!0),j("wrong");const o=n[x].name;F(d=>[...d,{round:v,answer:z,correct:o,result:"wrong"}]);return}const t=setTimeout(()=>O(o=>o-1),1e3);return()=>clearTimeout(t)}}},[g,q,R,H,w,C,b,n,x,v,z]);const ae=()=>{if(x===null||E)return;const t=n[x].name,o=z.toLowerCase().trim();let d="wrong";o===t?(B(r=>r+1),j("correct"),d="correct"):be(o,t)===1?(B(r=>r+.5),j("almost"),d="almost"):(j("wrong"),d="wrong"),F(r=>[...r,{round:v,answer:o,correct:t,result:d}]),V(!0),setTimeout(()=>{V(!1),L(!0)},600)},le=()=>v<S?(Y(t=>t+1),Q()):A(!0),de=()=>{P(!1),A(!1),c(null)},ce=i.useMemo(()=>e.jsx("div",{style:{...s.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:s.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:a,style:{width:"100%",height:"100vh",display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease",overflowX:"clip"},children:e.jsx("div",{style:{width:h?"100%":T?`${Math.round(T*y)}px`:`${Math.round(1e3*y)}px`,height:h?"100%":T?`${Math.round(T*y)}px`:`${Math.round(1e3*y)}px`,display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:h?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:h?"none":"0 0 40px rgba(0,0,0,0.1)",margin:h?"0 auto":"unset",position:"relative"},children:e.jsx("div",{style:{transform:y&&y!==1?`scale(${1/y})`:"none",transformOrigin:"top left",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!h&&ce,!l&&!w&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:s.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:s.gmButton,onClick:()=>c(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:s.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:{...s.gmButton,...S===t?s.gmButtonActive:{}},onClick:()=>te(t),children:t},t))})]})]}),l&&!w&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsxs("h1",{style:s.gmHeadline1,children:["Theme selected: ",l]}),e.jsxs("p",{style:s.gmBodyM,children:["Rounds: ",S]}),e.jsx("button",{style:s.gmButton,onClick:J,children:"▶ Start game"})]}),C&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:s.gmHeadline3,children:["Your score: ",ne," / ",S]}),e.jsx("p",{style:{...s.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:s.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:oe.map((t,o)=>e.jsxs("tr",{children:[e.jsx("td",{style:s.gmTableCell,children:t.round}),e.jsx("td",{style:s.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:s.gmTableCell,children:t.correct}),e.jsx("td",{style:s.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},o))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:s.gmButton,onClick:J,children:"🔁 Play again"}),e.jsx("button",{style:s.gmButton,onClick:de,children:"⬅️ Choose theme"})]})]}),w&&!C&&e.jsxs("div",{style:s.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[g==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...s.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:s.gmHourglass,children:"⏳"})]}),g==="memorize"&&e.jsxs("p",{style:{...s.gmBodyM,color:"#10b981"},children:["MEMORIZE (",R,")"]}),g==="guess"&&!b&&e.jsxs("p",{style:s.gmBodyM,children:["⏳ Time left: ",H,"s"]})]}),g!=="ready"&&e.jsx("div",{style:{...s.gmGrid,gridTemplateColumns:h?"repeat(2, 1fr)":"repeat(3, 210px)",gridAutoRows:h?"150px":"210px",gap:h?"12px":"20px",justifyItems:"center"},children:n.map((t,o)=>{const d=x===o&&g==="guess"&&!b;return e.jsx("div",{style:{...s.gmCard,..._==="correct"&&x===o?s.gmCorrect:{},..._==="wrong"&&x===o?s.gmWrong:{}},children:!d&&e.jsx("img",{src:t.src,alt:t.name,style:{width:"100%",height:"100%",objectFit:"cover"}})},o)})}),e.jsxs("div",{style:{marginTop:16,height:80},children:[g==="guess"&&!b&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:z,onChange:t=>U(t.target.value),style:s.gmInput}),e.jsx("button",{style:{...s.gmButton,marginLeft:8},onClick:ae,disabled:E,children:E?"...":"Check"})]}),b&&e.jsx("button",{style:s.gmButton,onClick:le,children:"Next round"})]})]})]})})})})}exports.Game=we;exports.themes=N;
@@ -1,9 +1,9 @@
1
- import { jsx as t, jsxs as r, Fragment as ae } from "react/jsx-runtime";
2
- import { useRef as de, useEffect as L, useState as s, useMemo as ce } from "react";
3
- const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l.map(([c, o]) => ({
4
- src: `${me}${a}/${o.replace(/\s/g, "%20")}.png`,
1
+ import { jsx as t, jsxs as s, Fragment as pe } from "react/jsx-runtime";
2
+ import { useRef as he, useEffect as N, useState as r, useMemo as fe } from "react";
3
+ const ye = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (l, d) => l.map(([m, o]) => ({
4
+ src: `${ye}${d}/${o.replace(/\s/g, "%20")}.png`,
5
5
  name: o
6
- })), ge = [
6
+ })), xe = [
7
7
  ["apple", "apple"],
8
8
  ["banana", "banana"],
9
9
  ["bread", "bread"],
@@ -29,7 +29,7 @@ const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l
29
29
  ["strawberry", "strawberry"],
30
30
  ["tomato", "tomato"],
31
31
  ["watermelon", "watermelon"]
32
- ], he = [
32
+ ], be = [
33
33
  ["bear", "bear"],
34
34
  ["cat", "cat"],
35
35
  ["crocodile", "crocodile"],
@@ -49,7 +49,7 @@ const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l
49
49
  ["tortoise", "tortoise"],
50
50
  ["wolf", "wolf"],
51
51
  ["zebra", "zebra"]
52
- ], pe = [
52
+ ], we = [
53
53
  ["ball", "ball"],
54
54
  ["balloon", "balloon"],
55
55
  ["blocks", "blocks"],
@@ -69,11 +69,11 @@ const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l
69
69
  ["teddy_bear", "teddy bear"],
70
70
  ["yo-yo", "yo-yo"],
71
71
  ["crayons", "crayons"]
72
- ], Z = {
73
- food: j(ge, "food"),
74
- animals: j(he, "animals"),
75
- toys: j(pe, "toys")
76
- }, ue = `
72
+ ], ne = {
73
+ food: Y(xe, "food"),
74
+ animals: Y(be, "animals"),
75
+ toys: Y(we, "toys")
76
+ }, ve = `
77
77
  @keyframes spin {
78
78
  from { transform: rotate(0deg); }
79
79
  to { transform: rotate(360deg); }
@@ -81,9 +81,9 @@ const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l
81
81
  `;
82
82
  if (typeof document < "u" && !document.getElementById("spin-keyframes")) {
83
83
  const l = document.createElement("style");
84
- l.id = "spin-keyframes", l.innerHTML = ue, document.head.appendChild(l);
84
+ l.id = "spin-keyframes", l.innerHTML = ve, document.head.appendChild(l);
85
85
  }
86
- const fe = {
86
+ const ke = {
87
87
  animation: "spin 1.4s linear infinite"
88
88
  }, n = {
89
89
  gmCenterScreen: {
@@ -233,9 +233,9 @@ const fe = {
233
233
  },
234
234
  gmHourglass: {
235
235
  fontSize: "42px",
236
- ...fe
236
+ ...ke
237
237
  }
238
- }, ye = () => {
238
+ }, Ce = () => {
239
239
  const l = document.createElement("style");
240
240
  l.textContent = `
241
241
  #whats-missing-root, #whats-missing-root * {
@@ -248,92 +248,114 @@ const fe = {
248
248
  display: block;
249
249
  user-select: none;
250
250
  }
251
- html, body {
252
- margin: 0;
253
- padding: 0;
254
- zoom: 1 !important; /* ✅ защита от подзума */
255
- }
251
+ html, body { margin: 0; padding: 0; }
256
252
  `, document.head.appendChild(l);
257
- }, be = (l, a) => {
258
- const c = Array.from({ length: l.length + 1 }, () => Array(a.length + 1).fill(0));
259
- for (let o = 0; o <= l.length; o++) c[o][0] = o;
260
- for (let o = 0; o <= a.length; o++) c[0][o] = o;
253
+ }, Se = (l, d) => {
254
+ const m = Array.from({ length: l.length + 1 }, () => Array(d.length + 1).fill(0));
255
+ for (let o = 0; o <= l.length; o++) m[o][0] = o;
256
+ for (let o = 0; o <= d.length; o++) m[0][o] = o;
261
257
  for (let o = 1; o <= l.length; o++)
262
- for (let g = 1; g <= a.length; g++)
263
- c[o][g] = l[o - 1] === a[g - 1] ? c[o - 1][g - 1] : Math.min(c[o - 1][g - 1], c[o][g - 1], c[o - 1][g]) + 1;
264
- return c[l.length][a.length];
258
+ for (let g = 1; g <= d.length; g++)
259
+ m[o][g] = l[o - 1] === d[g - 1] ? m[o - 1][g - 1] : Math.min(m[o - 1][g - 1], m[o][g - 1], m[o - 1][g]) + 1;
260
+ return m[l.length][d.length];
265
261
  };
266
- function ke() {
267
- const l = de(null);
268
- L(() => (ye(), () => {
262
+ function Me() {
263
+ const l = he(null);
264
+ N(() => (Ce(), () => {
269
265
  document.body.style.overflow = "";
270
266
  }), []);
271
- const [a, c] = s(null), [o, g] = s([]), [k, X] = s(4), [y, E] = s(!1), [v, G] = s(1), [u, J] = s(null), [h, C] = s("ready"), [F, Y] = s(3), [z, R] = s(10), [I, D] = s(20), [Q, H] = s(0), [T, M] = s(!1), [S, U] = s(""), [f, A] = s(!1), [B, $] = s(!1), [N, b] = s(null), [ee, W] = s([]), [te, O] = s([]), [p, ne] = s(!1), [oe, P] = s(1);
272
- L(() => {
267
+ const [d, m] = r(null), [o, g] = r([]), [C, oe] = r(4), [v, D] = r(!1), [S, P] = r(1), [x, ie] = r(null), [u, z] = r("ready"), [O, U] = r(3), [H, B] = r(10), [A, V] = r(20), [re, L] = r(0), [T, j] = r(!1), [M, q] = r(""), [w, F] = r(!1), [W, _] = r(!1), [K, k] = r(null), [se, E] = r([]), [ae, Z] = r([]), [h, le] = r(!1), [R, X] = r(null), [b, G] = r(1);
268
+ N(() => {
273
269
  const e = () => {
274
- const i = window.innerWidth < 768, d = window.innerWidth >= 768 && window.innerWidth < 1200;
275
- if (ne(i || d), !i && !d) {
276
- const w = Math.min(window.innerWidth / 1440, window.innerHeight / 768) * 0.97;
277
- P(w);
278
- } else
279
- P(1);
270
+ const a = window.innerWidth < 768;
271
+ if (le(a), a) {
272
+ X(null);
273
+ return;
274
+ }
275
+ const f = 0.97, p = 1e3, y = Math.min(window.innerWidth, window.innerHeight), I = Math.max(360, Math.round(y * f)), te = Math.min(I, p);
276
+ X(te);
277
+ }, i = () => {
278
+ try {
279
+ const a = document.body, f = getComputedStyle(a), p = parseFloat(f.zoom || "");
280
+ if (p && !isNaN(p) && p > 0) {
281
+ G(p);
282
+ return;
283
+ }
284
+ const y = f.transform;
285
+ if (y && y !== "none") {
286
+ const I = y.match(/matrix\(([^)]+)\)/);
287
+ if (I) {
288
+ const $ = I[1].split(",").map((ue) => parseFloat(ue))[0];
289
+ if ($ && !isNaN($)) {
290
+ G($);
291
+ return;
292
+ }
293
+ }
294
+ }
295
+ } catch {
296
+ }
297
+ G(1);
298
+ };
299
+ e(), i(), window.addEventListener("resize", e), window.addEventListener("resize", i);
300
+ const c = new MutationObserver(i);
301
+ return c.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), () => {
302
+ window.removeEventListener("resize", e), window.removeEventListener("resize", i), c.disconnect();
280
303
  };
281
- return e(), window.addEventListener("resize", e), () => window.removeEventListener("resize", e);
282
304
  }, []);
283
- const V = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), _ = () => {
284
- if (!a) return;
285
- const e = V(Z[a]);
286
- g(e), E(!0), M(!1), G(1), H(0), W([]), O([]), q(e, [], !0);
287
- }, q = (e = o, i = te, d = !1) => {
288
- const m = V(e.length ? e : Z[a]);
289
- let x = Math.floor(Math.random() * m.length), w = m[x].name, K = 0;
290
- for (; i.includes(w) && K < 20; )
291
- x = Math.floor(Math.random() * m.length), w = m[x].name, K++;
292
- g(m), J(x), O([...i, w]), A(!1), U(""), D(20), b(null), d ? (C("ready"), Y(3), R(10)) : (C("memorize"), R(10));
305
+ const J = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), Q = () => {
306
+ if (!d) return;
307
+ const e = J(ne[d]);
308
+ g(e), D(!0), j(!1), P(1), L(0), E([]), Z([]), ee(e, [], !0);
309
+ }, ee = (e = o, i = ae, c = !1) => {
310
+ const a = J(e.length ? e : ne[d]);
311
+ let f = Math.floor(Math.random() * a.length), p = a[f].name, y = 0;
312
+ for (; i.includes(p) && y < 20; )
313
+ f = Math.floor(Math.random() * a.length), p = a[f].name, y++;
314
+ g(a), ie(f), Z([...i, p]), F(!1), q(""), V(20), k(null), c ? (z("ready"), U(3), B(10)) : (z("memorize"), B(10));
293
315
  };
294
- L(() => {
295
- if (!(!y || T || f)) {
296
- if (h === "ready")
297
- if (F <= 0) C("memorize");
316
+ N(() => {
317
+ if (!(!v || T || w)) {
318
+ if (u === "ready")
319
+ if (O <= 0) z("memorize");
298
320
  else {
299
- const e = setTimeout(() => Y((i) => i - 1), 1e3);
321
+ const e = setTimeout(() => U((i) => i - 1), 1e3);
300
322
  return () => clearTimeout(e);
301
323
  }
302
- if (h === "memorize")
303
- if (z <= 0) C("guess");
324
+ if (u === "memorize")
325
+ if (H <= 0) z("guess");
304
326
  else {
305
- const e = setTimeout(() => R((i) => i - 1), 1e3);
327
+ const e = setTimeout(() => B((i) => i - 1), 1e3);
306
328
  return () => clearTimeout(e);
307
329
  }
308
- if (h === "guess") {
309
- if (I <= 0) {
310
- A(!0), b("wrong");
311
- const i = o[u].name;
312
- W((d) => [
313
- ...d,
314
- { round: v, answer: S, correct: i, result: "wrong" }
315
- ]);
330
+ if (u === "guess") {
331
+ if (A <= 0) {
332
+ F(!0), k("wrong");
333
+ const i = o[x].name;
334
+ E((c) => [...c, { round: S, answer: M, correct: i, result: "wrong" }]);
316
335
  return;
317
336
  }
318
- const e = setTimeout(() => D((i) => i - 1), 1e3);
337
+ const e = setTimeout(() => V((i) => i - 1), 1e3);
319
338
  return () => clearTimeout(e);
320
339
  }
321
340
  }
322
- }, [h, F, z, I, y, T, f, o, u, v, S]);
323
- const ie = () => {
324
- if (u === null || B) return;
325
- const e = o[u].name, i = S.toLowerCase().trim();
326
- let d = "wrong";
327
- i === e ? (H((m) => m + 1), b("correct"), d = "correct") : be(i, e) === 1 ? (H((m) => m + 0.5), b("almost"), d = "almost") : (b("wrong"), d = "wrong"), W((m) => [...m, { round: v, answer: i, correct: e, result: d }]), $(!0), setTimeout(() => {
328
- $(!1), A(!0);
341
+ }, [u, O, H, A, v, T, w, o, x, S, M]);
342
+ const de = () => {
343
+ if (x === null || W) return;
344
+ const e = o[x].name, i = M.toLowerCase().trim();
345
+ let c = "wrong";
346
+ i === e ? (L((a) => a + 1), k("correct"), c = "correct") : Se(i, e) === 1 ? (L((a) => a + 0.5), k("almost"), c = "almost") : (k("wrong"), c = "wrong"), E((a) => [...a, { round: S, answer: i, correct: e, result: c }]), _(!0), setTimeout(() => {
347
+ _(!1), F(!0);
329
348
  }, 600);
330
- }, re = () => v < k ? (G((e) => e + 1), q()) : M(!0), se = () => {
331
- E(!1), M(!1), c(null);
332
- }, le = ce(
333
- () => /* @__PURE__ */ t("div", { style: n.gmLogoFixed, children: /* @__PURE__ */ r("picture", { children: [
334
- /* @__PURE__ */ t("source", { srcSet: window.origin + "/cloud/speakid/games/whatsmissing/logo.svg", type: "image/svg+xml" }),
335
- /* @__PURE__ */ t("img", { src: window.origin + "/cloud/speakid/games/whatsmissing/logo.png", alt: "SPEAKID Logo", style: n.gmLogoImg, loading: "lazy" })
336
- ] }) }),
349
+ }, ce = () => S < C ? (P((e) => e + 1), ee()) : j(!0), me = () => {
350
+ D(!1), j(!1), m(null);
351
+ }, ge = fe(
352
+ () => (
353
+ // ensure logo is positioned inside the square container
354
+ /* @__PURE__ */ t("div", { style: { ...n.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ s("picture", { children: [
355
+ /* @__PURE__ */ t("source", { srcSet: window.origin + "/cloud/speakid/games/whatsmissing/logo.svg", type: "image/svg+xml" }),
356
+ /* @__PURE__ */ t("img", { src: window.origin + "/cloud/speakid/games/whatsmissing/logo.png", alt: "SPEAKID Logo", style: n.gmLogoImg, loading: "lazy" })
357
+ ] }) })
358
+ ),
337
359
  []
338
360
  );
339
361
  return /* @__PURE__ */ t(
@@ -354,181 +376,115 @@ function ke() {
354
376
  "div",
355
377
  {
356
378
  style: {
357
- width: p ? "100%" : 1440,
358
- height: p ? "100%" : 768,
379
+ width: h ? "100%" : R ? `${Math.round(R * b)}px` : `${Math.round(1e3 * b)}px`,
380
+ height: h ? "100%" : R ? `${Math.round(R * b)}px` : `${Math.round(1e3 * b)}px`,
359
381
  display: "flex",
360
382
  justifyContent: "center",
361
383
  alignItems: "center",
362
384
  overflow: "hidden",
363
- borderRadius: p ? 0 : "20px",
385
+ borderRadius: h ? 0 : "20px",
364
386
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
365
- boxShadow: p ? "none" : "0 0 40px rgba(0,0,0,0.1)",
366
- margin: p ? "0 auto" : "unset"
387
+ boxShadow: h ? "none" : "0 0 40px rgba(0,0,0,0.1)",
388
+ margin: h ? "0 auto" : "unset",
389
+ position: "relative"
367
390
  },
368
391
  children: /* @__PURE__ */ t(
369
392
  "div",
370
393
  {
371
394
  style: {
372
- transform: p ? "none" : `scale(${oe})`,
373
- transformOrigin: "top center",
374
- // ✅ фикс вертикального смещения
395
+ transform: b && b !== 1 ? `scale(${1 / b})` : "none",
396
+ transformOrigin: "top left",
375
397
  width: "100%",
376
398
  height: "100%",
377
399
  display: "flex",
378
400
  justifyContent: "center",
379
401
  alignItems: "center"
380
402
  },
381
- children: /* @__PURE__ */ r("div", { id: "whats-missing-root", children: [
382
- !p && le,
383
- !a && !y && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
403
+ children: /* @__PURE__ */ s("div", { id: "whats-missing-root", children: [
404
+ !h && ge,
405
+ !d && !v && /* @__PURE__ */ s("div", { style: n.gmCenterScreen, children: [
384
406
  /* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "WHAT'S MISSING?" }),
385
407
  /* @__PURE__ */ t("p", { style: n.gmBodyM, children: "Select a theme:" }),
386
- /* @__PURE__ */ t("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ t("button", { style: n.gmButton, onClick: () => c(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
387
- /* @__PURE__ */ r("div", { style: { marginTop: 24 }, children: [
408
+ /* @__PURE__ */ t("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ t("button", { style: n.gmButton, onClick: () => m(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
409
+ /* @__PURE__ */ s("div", { style: { marginTop: 24 }, children: [
388
410
  /* @__PURE__ */ t("p", { style: n.gmBodyS, children: "Choose number of rounds:" }),
389
411
  /* @__PURE__ */ t("div", { style: { display: "flex", gap: 12, marginTop: 8 }, children: [3, 4, 5].map((e) => /* @__PURE__ */ t(
390
412
  "button",
391
413
  {
392
- style: {
393
- ...n.gmButton,
394
- ...k === e ? n.gmButtonActive : {}
395
- },
396
- onClick: () => X(e),
414
+ style: { ...n.gmButton, ...C === e ? n.gmButtonActive : {} },
415
+ onClick: () => oe(e),
397
416
  children: e
398
417
  },
399
418
  e
400
419
  )) })
401
420
  ] })
402
421
  ] }),
403
- a && !y && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
404
- /* @__PURE__ */ r("h1", { style: n.gmHeadline1, children: [
422
+ d && !v && /* @__PURE__ */ s("div", { style: n.gmCenterScreen, children: [
423
+ /* @__PURE__ */ s("h1", { style: n.gmHeadline1, children: [
405
424
  "Theme selected: ",
406
- a
425
+ d
407
426
  ] }),
408
- /* @__PURE__ */ r("p", { style: n.gmBodyM, children: [
427
+ /* @__PURE__ */ s("p", { style: n.gmBodyM, children: [
409
428
  "Rounds: ",
410
- k
429
+ C
411
430
  ] }),
412
- /* @__PURE__ */ t("button", { style: n.gmButton, onClick: _, children: "▶ Start game" })
431
+ /* @__PURE__ */ t("button", { style: n.gmButton, onClick: Q, children: "▶ Start game" })
413
432
  ] }),
414
- T && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
433
+ T && /* @__PURE__ */ s("div", { style: n.gmCenterScreen, children: [
415
434
  /* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "Results" }),
416
- /* @__PURE__ */ r("h2", { style: n.gmHeadline3, children: [
435
+ /* @__PURE__ */ s("h2", { style: n.gmHeadline3, children: [
417
436
  "Your score: ",
418
- Q,
437
+ re,
419
438
  " / ",
420
- k
439
+ C
421
440
  ] }),
422
441
  /* @__PURE__ */ t("p", { style: { ...n.gmBodyM, color: "#10b981", marginTop: 12 }, children: "Yahoo! You did it! 🍬✨" }),
423
- /* @__PURE__ */ r("table", { style: n.gmTable, children: [
424
- /* @__PURE__ */ t("thead", { children: /* @__PURE__ */ r("tr", { children: [
442
+ /* @__PURE__ */ s("table", { style: n.gmTable, children: [
443
+ /* @__PURE__ */ t("thead", { children: /* @__PURE__ */ s("tr", { children: [
425
444
  /* @__PURE__ */ t("th", { children: "Round" }),
426
445
  /* @__PURE__ */ t("th", { children: "Your Answer" }),
427
446
  /* @__PURE__ */ t("th", { children: "Correct" }),
428
447
  /* @__PURE__ */ t("th", { children: "Result" })
429
448
  ] }) }),
430
- /* @__PURE__ */ t("tbody", { children: ee.map((e, i) => /* @__PURE__ */ r("tr", { children: [
449
+ /* @__PURE__ */ t("tbody", { children: se.map((e, i) => /* @__PURE__ */ s("tr", { children: [
431
450
  /* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.round }),
432
451
  /* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.answer || "—" }),
433
452
  /* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.correct }),
434
453
  /* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.result === "correct" ? "✔ Correct" : e.result === "almost" ? "◐ Almost (0.5)" : "✘ Wrong" })
435
454
  ] }, i)) })
436
455
  ] }),
437
- /* @__PURE__ */ r("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
438
- /* @__PURE__ */ t("button", { style: n.gmButton, onClick: _, children: "🔁 Play again" }),
439
- /* @__PURE__ */ t("button", { style: n.gmButton, onClick: se, children: "⬅️ Choose theme" })
456
+ /* @__PURE__ */ s("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
457
+ /* @__PURE__ */ t("button", { style: n.gmButton, onClick: Q, children: "🔁 Play again" }),
458
+ /* @__PURE__ */ t("button", { style: n.gmButton, onClick: me, children: "⬅️ Choose theme" })
440
459
  ] })
441
460
  ] }),
442
- y && !T && /* @__PURE__ */ r("div", { style: n.gmGameLayout, children: [
443
- /* @__PURE__ */ r(
444
- "div",
445
- {
446
- style: {
447
- minHeight: 160,
448
- display: "flex",
449
- flexDirection: "column",
450
- justifyContent: "center",
451
- alignItems: "center"
452
- },
453
- children: [
454
- h === "ready" && /* @__PURE__ */ r(ae, { children: [
455
- /* @__PURE__ */ t("h1", { style: { ...n.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
456
- /* @__PURE__ */ t("div", { style: n.gmHourglass, children: "⏳" })
457
- ] }),
458
- h === "memorize" && /* @__PURE__ */ r("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
459
- "MEMORIZE (",
460
- z,
461
- ")"
462
- ] }),
463
- h === "guess" && !f && /* @__PURE__ */ r("p", { style: n.gmBodyM, children: [
464
- " Time left: ",
465
- I,
466
- "s"
467
- ] })
468
- ]
469
- }
470
- ),
471
- h !== "ready" && /* @__PURE__ */ t(
472
- "div",
473
- {
474
- style: {
475
- ...n.gmGrid,
476
- gridTemplateColumns: p ? "repeat(2, 1fr)" : "repeat(3, 210px)",
477
- gridAutoRows: p ? "150px" : "210px",
478
- gap: p ? "12px" : "20px",
479
- justifyItems: "center"
480
- },
481
- children: o.map((e, i) => {
482
- const d = u === i && h === "guess" && !f;
483
- return /* @__PURE__ */ t(
484
- "div",
485
- {
486
- style: {
487
- ...n.gmCard,
488
- ...N === "correct" && u === i ? n.gmCorrect : {},
489
- ...N === "wrong" && u === i ? n.gmWrong : {}
490
- },
491
- children: !d && /* @__PURE__ */ t(
492
- "img",
493
- {
494
- src: e.src,
495
- alt: e.name,
496
- style: {
497
- width: "100%",
498
- height: "100%",
499
- objectFit: "cover"
500
- }
501
- }
502
- )
503
- },
504
- i
505
- );
506
- })
507
- }
508
- ),
509
- /* @__PURE__ */ r("div", { style: { marginTop: 16, height: 80 }, children: [
510
- h === "guess" && !f && /* @__PURE__ */ r("div", { children: [
511
- /* @__PURE__ */ t(
512
- "input",
513
- {
514
- type: "text",
515
- placeholder: "Type the missing word",
516
- value: S,
517
- onChange: (e) => U(e.target.value),
518
- style: n.gmInput
519
- }
520
- ),
521
- /* @__PURE__ */ t(
522
- "button",
523
- {
524
- style: { ...n.gmButton, marginLeft: 8 },
525
- onClick: ie,
526
- disabled: B,
527
- children: B ? "..." : "Check"
528
- }
529
- )
461
+ v && !T && /* @__PURE__ */ s("div", { style: n.gmGameLayout, children: [
462
+ /* @__PURE__ */ s("div", { style: { minHeight: 160, display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center" }, children: [
463
+ u === "ready" && /* @__PURE__ */ s(pe, { children: [
464
+ /* @__PURE__ */ t("h1", { style: { ...n.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
465
+ /* @__PURE__ */ t("div", { style: n.gmHourglass, children: "⏳" })
466
+ ] }),
467
+ u === "memorize" && /* @__PURE__ */ s("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
468
+ "MEMORIZE (",
469
+ H,
470
+ ")"
471
+ ] }),
472
+ u === "guess" && !w && /* @__PURE__ */ s("p", { style: n.gmBodyM, children: [
473
+ " Time left: ",
474
+ A,
475
+ "s"
476
+ ] })
477
+ ] }),
478
+ u !== "ready" && /* @__PURE__ */ t("div", { style: { ...n.gmGrid, gridTemplateColumns: h ? "repeat(2, 1fr)" : "repeat(3, 210px)", gridAutoRows: h ? "150px" : "210px", gap: h ? "12px" : "20px", justifyItems: "center" }, children: o.map((e, i) => {
479
+ const c = x === i && u === "guess" && !w;
480
+ return /* @__PURE__ */ t("div", { style: { ...n.gmCard, ...K === "correct" && x === i ? n.gmCorrect : {}, ...K === "wrong" && x === i ? n.gmWrong : {} }, children: !c && /* @__PURE__ */ t("img", { src: e.src, alt: e.name, style: { width: "100%", height: "100%", objectFit: "cover" } }) }, i);
481
+ }) }),
482
+ /* @__PURE__ */ s("div", { style: { marginTop: 16, height: 80 }, children: [
483
+ u === "guess" && !w && /* @__PURE__ */ s("div", { children: [
484
+ /* @__PURE__ */ t("input", { type: "text", placeholder: "Type the missing word", value: M, onChange: (e) => q(e.target.value), style: n.gmInput }),
485
+ /* @__PURE__ */ t("button", { style: { ...n.gmButton, marginLeft: 8 }, onClick: de, disabled: W, children: W ? "..." : "Check" })
530
486
  ] }),
531
- f && /* @__PURE__ */ t("button", { style: n.gmButton, onClick: re, children: "Next round" })
487
+ w && /* @__PURE__ */ t("button", { style: n.gmButton, onClick: ce, children: "Next round" })
532
488
  ] })
533
489
  ] })
534
490
  ] })
@@ -540,6 +496,6 @@ function ke() {
540
496
  );
541
497
  }
542
498
  export {
543
- ke as Game,
544
- Z as themes
499
+ Me as Game,
500
+ ne as themes
545
501
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblinkov/whats-missing",
3
- "version": "20.0.17",
3
+ "version": "20.0.19",
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
@@ -25,11 +25,7 @@ const globalReset = () => {
25
25
  display: block;
26
26
  user-select: none;
27
27
  }
28
- html, body {
29
- margin: 0;
30
- padding: 0;
31
- zoom: 1 !important; /* ✅ защита от подзума */
32
- }
28
+ html, body { margin: 0; padding: 0; }
33
29
  `;
34
30
  document.head.appendChild(style);
35
31
  };
@@ -79,33 +75,70 @@ export default function Game() {
79
75
  const [resultsTable, setResultsTable] = useState<RoundResult[]>([]);
80
76
  const [usedHidden, setUsedHidden] = useState<string[]>([]);
81
77
  const [isMobile, setIsMobile] = useState(false);
82
- const [scale, setScale] = useState(1);
78
+ const [containerSize, setContainerSize] = useState<number | null>(null);
79
+ const [pageScale, setPageScale] = useState<number>(1);
83
80
 
84
81
  // ✅ адаптив под мобилки, планшеты и десктоп
85
82
  useEffect(() => {
86
83
  const resize = () => {
87
84
  const mobile = window.innerWidth < 768;
88
- const tablet = window.innerWidth >= 768 && window.innerWidth < 1200;
89
-
90
- setIsMobile(mobile || tablet);
85
+ setIsMobile(mobile);
86
+ if (mobile) {
87
+ // mobile: fluid full-width layout
88
+ setContainerSize(null);
89
+ return;
90
+ }
91
+ // tablets and desktops: fit into a centered square (max 1000)
92
+ const safeFactor = 0.97;
93
+ const maxSquare = 1000;
94
+ const available = Math.min(window.innerWidth, window.innerHeight);
95
+ const sizePx = Math.max(360, Math.round(available * safeFactor)); // don't go too small
96
+ const finalSize = Math.min(sizePx, maxSquare);
97
+ setContainerSize(finalSize);
98
+ };
91
99
 
92
- if (!mobile && !tablet) {
93
- const baseW = 1440;
94
- const baseH = 768;
95
- // коэффициент безопасности, чтобы кнопка не обрезалась
96
- const ratio = Math.min(window.innerWidth / baseW, window.innerHeight / baseH) * 0.97;
97
- setScale(ratio);
98
- } else {
99
- setScale(1);
100
+ const detectBodyScale = () => {
101
+ try {
102
+ const el = document.body;
103
+ const cs = getComputedStyle(el);
104
+ const zoomVal = parseFloat((cs.zoom as string) || "");
105
+ if (zoomVal && !isNaN(zoomVal) && zoomVal > 0) {
106
+ setPageScale(zoomVal);
107
+ return;
108
+ }
109
+ const tf = cs.transform;
110
+ if (tf && tf !== "none") {
111
+ const m = tf.match(/matrix\(([^)]+)\)/);
112
+ if (m) {
113
+ const parts = m[1].split(",").map((p) => parseFloat(p));
114
+ const a = parts[0];
115
+ if (a && !isNaN(a)) {
116
+ setPageScale(a);
117
+ return;
118
+ }
119
+ }
120
+ }
121
+ } catch (e) {
122
+ // ignore
100
123
  }
124
+ setPageScale(1);
101
125
  };
126
+
102
127
  resize();
128
+ detectBodyScale();
103
129
  window.addEventListener("resize", resize);
104
- return () => window.removeEventListener("resize", resize);
130
+ window.addEventListener("resize", detectBodyScale);
131
+ const mo = new MutationObserver(detectBodyScale);
132
+ mo.observe(document.body, { attributes: true, attributeFilter: ["style", "class"] });
133
+
134
+ return () => {
135
+ window.removeEventListener("resize", resize);
136
+ window.removeEventListener("resize", detectBodyScale);
137
+ mo.disconnect();
138
+ };
105
139
  }, []);
106
140
 
107
- const getRandomSix = (arr: ImageItem[]) =>
108
- [...arr].sort(() => Math.random() - 0.5).slice(0, 6);
141
+ const getRandomSix = (arr: ImageItem[]) => [...arr].sort(() => Math.random() - 0.5).slice(0, 6);
109
142
 
110
143
  const startGame = () => {
111
144
  if (!theme) return;
@@ -168,10 +201,7 @@ export default function Game() {
168
201
  setAnswered(true);
169
202
  setResult("wrong");
170
203
  const correct = files[hiddenIndex!].name;
171
- setResultsTable((prev) => [
172
- ...prev,
173
- { round: currentRound, answer: inputValue, correct, result: "wrong" },
174
- ]);
204
+ setResultsTable((prev) => [...prev, { round: currentRound, answer: inputValue, correct, result: "wrong" }]);
175
205
  return;
176
206
  }
177
207
  const t = setTimeout(() => setTimeLeft((s) => s - 1), 1000);
@@ -204,8 +234,7 @@ export default function Game() {
204
234
  }, 600);
205
235
  };
206
236
 
207
- const nextRound = () =>
208
- currentRound < rounds ? (setCurrentRound((r) => r + 1), startRound()) : setFinished(true);
237
+ const nextRound = () => (currentRound < rounds ? (setCurrentRound((r) => r + 1), startRound()) : setFinished(true));
209
238
 
210
239
  const exitGame = () => {
211
240
  setStarted(false);
@@ -215,7 +244,8 @@ export default function Game() {
215
244
 
216
245
  const MemoizedLogo = useMemo(
217
246
  () => (
218
- <div style={styles.gmLogoFixed}>
247
+ // ensure logo is positioned inside the square container
248
+ <div style={{ ...styles.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }}>
219
249
  <picture>
220
250
  <source srcSet={window.origin + "/cloud/speakid/games/whatsmissing/logo.svg"} type="image/svg+xml" />
221
251
  <img src={window.origin + "/cloud/speakid/games/whatsmissing/logo.png"} alt="SPEAKID Logo" style={styles.gmLogoImg} loading="lazy" />
@@ -236,13 +266,13 @@ export default function Game() {
236
266
  alignItems: "center",
237
267
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
238
268
  transition: "background 0.3s ease",
239
- overflowX: "clip"
269
+ overflowX: "clip",
240
270
  }}
241
271
  >
242
272
  <div
243
273
  style={{
244
- width: isMobile ? "100%" : 1440,
245
- height: isMobile ? "100%" : 768,
274
+ width: isMobile ? "100%" : containerSize ? `${Math.round(containerSize * pageScale)}px` : `${Math.round(1000 * pageScale)}px`,
275
+ height: isMobile ? "100%" : containerSize ? `${Math.round(containerSize * pageScale)}px` : `${Math.round(1000 * pageScale)}px`,
246
276
  display: "flex",
247
277
  justifyContent: "center",
248
278
  alignItems: "center",
@@ -251,12 +281,13 @@ export default function Game() {
251
281
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
252
282
  boxShadow: isMobile ? "none" : "0 0 40px rgba(0,0,0,0.1)",
253
283
  margin: isMobile ? "0 auto" : "unset",
284
+ position: "relative",
254
285
  }}
255
286
  >
256
287
  <div
257
288
  style={{
258
- transform: isMobile ? "none" : `scale(${scale})`,
259
- transformOrigin: "top center", // ✅ фикс вертикального смещения
289
+ transform: pageScale && pageScale !== 1 ? `scale(${1 / pageScale})` : "none",
290
+ transformOrigin: "top left",
260
291
  width: "100%",
261
292
  height: "100%",
262
293
  display: "flex",
@@ -266,6 +297,7 @@ export default function Game() {
266
297
  >
267
298
  <div id="whats-missing-root">
268
299
  {!isMobile && MemoizedLogo}
300
+
269
301
  {/* ====== ИГРОВАЯ ЛОГИКА ====== */}
270
302
  {!theme && !started && (
271
303
  <div style={styles.gmCenterScreen}>
@@ -284,10 +316,7 @@ export default function Game() {
284
316
  {[3, 4, 5].map((n) => (
285
317
  <button
286
318
  key={n}
287
- style={{
288
- ...styles.gmButton,
289
- ...(rounds === n ? styles.gmButtonActive : {}),
290
- }}
319
+ style={{ ...styles.gmButton, ...(rounds === n ? styles.gmButtonActive : {}) }}
291
320
  onClick={() => setRounds(n)}
292
321
  >
293
322
  {n}
@@ -297,30 +326,23 @@ export default function Game() {
297
326
  </div>
298
327
  </div>
299
328
  )}
329
+
300
330
  {theme && !started && (
301
331
  <div style={styles.gmCenterScreen}>
302
332
  <h1 style={styles.gmHeadline1}>Theme selected: {theme}</h1>
303
333
  <p style={styles.gmBodyM}>Rounds: {rounds}</p>
304
- <button style={styles.gmButton} onClick={startGame}>
305
- ▶ Start game
306
- </button>
334
+ <button style={styles.gmButton} onClick={startGame}>▶ Start game</button>
307
335
  </div>
308
336
  )}
337
+
309
338
  {finished && (
310
339
  <div style={styles.gmCenterScreen}>
311
340
  <h1 style={styles.gmHeadline1}>Results</h1>
312
- <h2 style={styles.gmHeadline3}>
313
- Your score: {score} / {rounds}
314
- </h2>
341
+ <h2 style={styles.gmHeadline3}>Your score: {score} / {rounds}</h2>
315
342
  <p style={{ ...styles.gmBodyM, color: "#10b981", marginTop: 12 }}>Yahoo! You did it! 🍬✨</p>
316
343
  <table style={styles.gmTable}>
317
344
  <thead>
318
- <tr>
319
- <th>Round</th>
320
- <th>Your Answer</th>
321
- <th>Correct</th>
322
- <th>Result</th>
323
- </tr>
345
+ <tr><th>Round</th><th>Your Answer</th><th>Correct</th><th>Result</th></tr>
324
346
  </thead>
325
347
  <tbody>
326
348
  {resultsTable.map((r, i) => (
@@ -329,120 +351,48 @@ export default function Game() {
329
351
  <td style={styles.gmTableCell}>{r.answer || "—"}</td>
330
352
  <td style={styles.gmTableCell}>{r.correct}</td>
331
353
  <td style={styles.gmTableCell}>
332
- {r.result === "correct"
333
- ? "✔ Correct"
334
- : r.result === "almost"
335
- ? "◐ Almost (0.5)"
336
- : "✘ Wrong"}
354
+ {r.result === "correct" ? "✔ Correct" : r.result === "almost" ? "◐ Almost (0.5)" : "✘ Wrong"}
337
355
  </td>
338
356
  </tr>
339
357
  ))}
340
358
  </tbody>
341
359
  </table>
342
360
  <div style={{ display: "flex", gap: 12, marginTop: 24 }}>
343
- <button style={styles.gmButton} onClick={startGame}>
344
- 🔁 Play again
345
- </button>
346
- <button style={styles.gmButton} onClick={exitGame}>
347
- ⬅️ Choose theme
348
- </button>
361
+ <button style={styles.gmButton} onClick={startGame}>🔁 Play again</button>
362
+ <button style={styles.gmButton} onClick={exitGame}>⬅️ Choose theme</button>
349
363
  </div>
350
364
  </div>
351
365
  )}
366
+
352
367
  {started && !finished && (
353
368
  <div style={styles.gmGameLayout}>
354
- <div
355
- style={{
356
- minHeight: 160,
357
- display: "flex",
358
- flexDirection: "column",
359
- justifyContent: "center",
360
- alignItems: "center",
361
- }}
362
- >
363
- {phase === "ready" && (
364
- <>
365
- <h1 style={{ ...styles.gmHeadline1, color: "#ec4c44" }}>GET READY</h1>
366
- <div style={styles.gmHourglass}>⏳</div>
367
- </>
368
- )}
369
- {phase === "memorize" && (
370
- <p style={{ ...styles.gmBodyM, color: "#10b981" }}>
371
- MEMORIZE ({memorizeTime})
372
- </p>
373
- )}
374
- {phase === "guess" && !answered && (
375
- <p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>
376
- )}
369
+ <div style={{ minHeight: 160, display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center" }}>
370
+ {phase === "ready" && (<><h1 style={{ ...styles.gmHeadline1, color: "#ec4c44" }}>GET READY</h1><div style={styles.gmHourglass}>⏳</div></>)}
371
+ {phase === "memorize" && (<p style={{ ...styles.gmBodyM, color: "#10b981" }}>MEMORIZE ({memorizeTime})</p>)}
372
+ {phase === "guess" && !answered && (<p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>)}
377
373
  </div>
374
+
378
375
  {phase !== "ready" && (
379
- <div
380
- style={{
381
- ...styles.gmGrid,
382
- gridTemplateColumns: isMobile
383
- ? "repeat(2, 1fr)"
384
- : "repeat(3, 210px)",
385
- gridAutoRows: isMobile ? "150px" : "210px",
386
- gap: isMobile ? "12px" : "20px",
387
- justifyItems: "center",
388
- }}
389
- >
376
+ <div style={{ ...styles.gmGrid, gridTemplateColumns: isMobile ? "repeat(2, 1fr)" : "repeat(3, 210px)", gridAutoRows: isMobile ? "150px" : "210px", gap: isMobile ? "12px" : "20px", justifyItems: "center" }}>
390
377
  {files.map((file, i) => {
391
- const isHidden =
392
- hiddenIndex === i && phase === "guess" && !answered;
378
+ const isHidden = hiddenIndex === i && phase === "guess" && !answered;
393
379
  return (
394
- <div
395
- key={i}
396
- style={{
397
- ...styles.gmCard,
398
- ...(result === "correct" && hiddenIndex === i
399
- ? styles.gmCorrect
400
- : {}),
401
- ...(result === "wrong" && hiddenIndex === i
402
- ? styles.gmWrong
403
- : {}),
404
- }}
405
- >
406
- {!isHidden && (
407
- <img
408
- src={file.src}
409
- alt={file.name}
410
- style={{
411
- width: "100%",
412
- height: "100%",
413
- objectFit: "cover",
414
- }}
415
- />
416
- )}
380
+ <div key={i} style={{ ...styles.gmCard, ...(result === "correct" && hiddenIndex === i ? styles.gmCorrect : {}), ...(result === "wrong" && hiddenIndex === i ? styles.gmWrong : {}) }}>
381
+ {!isHidden && <img src={file.src} alt={file.name} style={{ width: "100%", height: "100%", objectFit: "cover" }} />}
417
382
  </div>
418
383
  );
419
384
  })}
420
385
  </div>
421
386
  )}
387
+
422
388
  <div style={{ marginTop: 16, height: 80 }}>
423
389
  {phase === "guess" && !answered && (
424
390
  <div>
425
- <input
426
- type="text"
427
- placeholder="Type the missing word"
428
- value={inputValue}
429
- onChange={(e) => setInputValue(e.target.value)}
430
- style={styles.gmInput}
431
- />
432
- <button
433
- style={{ ...styles.gmButton, marginLeft: 8 }}
434
- onClick={checkAnswer}
435
- disabled={animating}
436
- >
437
- {animating ? "..." : "Check"}
438
- </button>
391
+ <input type="text" placeholder="Type the missing word" value={inputValue} onChange={(e) => setInputValue(e.target.value)} style={styles.gmInput} />
392
+ <button style={{ ...styles.gmButton, marginLeft: 8 }} onClick={checkAnswer} disabled={animating}>{animating ? "..." : "Check"}</button>
439
393
  </div>
440
394
  )}
441
- {answered && (
442
- <button style={styles.gmButton} onClick={nextRound}>
443
- Next round
444
- </button>
445
- )}
395
+ {answered && <button style={styles.gmButton} onClick={nextRound}>Next round</button>}
446
396
  </div>
447
397
  </div>
448
398
  )}
@@ -451,4 +401,4 @@ export default function Game() {
451
401
  </div>
452
402
  </div>
453
403
  );
454
- }
404
+ }