@@ -288,63 +288,62 @@ const App: React.FC = () => {
288288 </ div >
289289
290290 < div
291- className = "bg-[#bbada0] p-4 rounded-lg relative touch-none overflow-hidden"
292- style = { { width : '100%' , aspectRatio : '1/1' } }
291+ className = "bg-[#bbada0] p-4 rounded-lg relative touch-none"
293292 onTouchStart = { handleTouchStart }
294293 onTouchEnd = { handleTouchEnd }
295294 >
296- { /* Background grid cells */ }
297- < div className = "grid grid-cols-4 gap-4 absolute inset-4" >
298- { Array ( GRID_SIZE * GRID_SIZE ) . fill ( 0 ) . map ( ( _ , idx ) => (
299- < div key = { `bg- ${ idx } ` } className = "bg-[#cdc1b4] rounded-md" / >
300- ) ) }
301- </ div >
302-
303- { /* Animated tiles */ }
304- < div className = "absolute inset-4 pointer-events-none" >
305- < AnimatePresence >
306- { tiles . map ( ( tile ) => {
307- // Each cell is 25% of container width
308- // Gap between cells is 16px (gap-4)
309- // Position = (index * (cell_width + gap) )
310- const cellPercent = 25 ; // 100% / 4 cells
311- const gapPx = 16 ;
312- const xPos = `calc( ${ tile . col * cellPercent } % + ${ tile . col * gapPx } px)` ;
313- const yPos = `calc(${ tile . row * cellPercent } % + ${ tile . row * gapPx } px)` ;
314- const tileSize = `calc(${ cellPercent } % - ${ gapPx } px)` ;
315-
316- return (
317- < motion . div
318- key = { tile . id }
319- initial = { tile . isNew ? {
320- scale : 0 ,
321- opacity : 0 ,
322- left : xPos ,
323- top : yPos ,
324- } : false }
325- animate = { {
326- scale : 1 ,
327- opacity : 1 ,
328- left : xPos ,
329- top : yPos ,
330- } }
331- exit = { { scale : 0 , opacity : 0 } }
332- transition = { {
333- type : "spring" ,
334- stiffness : 260 ,
335- damping : 26 ,
336- } }
337- className = { `absolute flex items-center justify-center text-3xl font-bold rounded-md ${ getTileColor ( tile . value ) } ` }
338- style = { {
339- width : tileSize ,
340- height : tileSize ,
341- } }
342- >
343- { tile . value }
344- </ motion . div >
345- ) ;
346- } ) }
347- </ AnimatePresence >
295+ { /* Container for both grid and tiles */ }
296+ < div className = "relative" style = { { width : '100%' , paddingBottom : '100%' } } >
297+ { /* Background grid cells */ }
298+ < div className = "absolute inset-0 grid grid-cols-4 gap-4" >
299+ { Array ( GRID_SIZE * GRID_SIZE ) . fill ( 0 ) . map ( ( _ , idx ) => (
300+ < div key = { `bg- ${ idx } ` } className = "bg-[#cdc1b4] rounded-md" / >
301+ ) ) }
302+ </ div >
303+
304+ { /* Animated tiles */ }
305+ < div className = "absolute inset-0 pointer-events-none" >
306+ < AnimatePresence >
307+ { tiles . map ( ( tile ) => {
308+ // Grid has 4 columns with gap-4 (16px )
309+ // Total width = 4 cells + 3 gaps
310+ // Each cell width = (100% - 3*16px) / 4
311+ const gap = 16 ;
312+ const cellWidth = `calc((100% - ${ 3 * gap } px) / 4 )` ;
313+ const xPos = `calc(( ${ cellWidth } + ${ gap } px) * ${ tile . col } )` ;
314+ const yPos = `calc(( ${ cellWidth } + ${ gap } px) * ${ tile . row } )` ;
315+
316+ return (
317+ < motion . div
318+ key = { tile . id }
319+ initial = { tile . isNew ? {
320+ scale : 0 ,
321+ opacity : 0 ,
322+ } : false }
323+ animate = { {
324+ scale : 1 ,
325+ opacity : 1 ,
326+ } }
327+ exit = { { scale : 0 , opacity : 0 } }
328+ transition = { {
329+ type : "spring" ,
330+ stiffness : 260 ,
331+ damping : 26 ,
332+ } }
333+ className = { `absolute flex items-center justify-center text-3xl font-bold rounded-md ${ getTileColor ( tile . value ) } ` }
334+ style = { {
335+ left : xPos ,
336+ top : yPos ,
337+ width : cellWidth ,
338+ height : cellWidth ,
339+ } }
340+ >
341+ { tile . value }
342+ </ motion . div >
343+ ) ;
344+ } ) }
345+ </ AnimatePresence >
346+ </ div >
348347 </ div >
349348
350349 { gameOver && (
0 commit comments