@@ -306,76 +306,86 @@ const RoverStrip = () => {
306306 "pointer-events-auto flex h-11 w-11 select-none items-center justify-center rounded-full border border-gray-900/15 bg-gray-900/5 text-gray-600 backdrop-blur-sm active:bg-gray-900/15 dark:border-white/15 dark:bg-white/5 dark:text-gray-300 dark:active:bg-white/15" ;
307307
308308 return (
309- < div
310- ref = { containerRef }
311- aria-hidden = "true"
312- className = "pointer-events-none absolute inset-0 z-[1]"
313- >
314- < canvas ref = { canvasRef } className = "block h-full w-full" />
315-
309+ < >
310+ < div
311+ ref = { containerRef }
312+ aria-hidden = "true"
313+ className = "pointer-events-none absolute inset-0 z-[1]"
314+ >
315+ < canvas ref = { canvasRef } className = "block h-full w-full" />
316+ </ div >
317+
318+ { /* Controls live in their own layer above the hero content (z-10) —
319+ on small screens the content column overlaps the bottom strip and
320+ would otherwise swallow the taps. */ }
316321 { ! prefersReducedMotion && (
317- < motion . p
318- initial = { { opacity : 0 } }
319- animate = { { opacity : hintVisible ? 1 : 0 } }
320- transition = { { duration : 0.6 , delay : hintVisible ? 1.2 : 0 } }
321- className = "absolute bottom-2 left-1/2 -translate-x-1/2 whitespace-nowrap text-[11px] tracking-wide text-gray-500/80 dark:text-blue-100/40"
322+ < div
323+ aria-hidden = "true"
324+ className = "pointer-events-none absolute inset-x-0 bottom-0 z-20"
322325 >
323- { coarsePointer ? "◀ ▶ drive · hold ▲ to fly" : "← → drive · hold ↑ to fly" }
324- </ motion . p >
325- ) }
326-
327- { coarsePointer && ! prefersReducedMotion && (
328- < div className = "absolute inset-x-0 bottom-3 flex items-end justify-between px-5" >
329- < div className = "flex gap-3" >
330- < button
331- type = "button"
332- tabIndex = { - 1 }
333- className = { buttonClass }
334- style = { { touchAction : "manipulation" } }
335- onPointerDown = { ( ev ) => {
336- ev . preventDefault ( ) ;
337- press ( "left" ) ;
338- } }
339- onPointerUp = { ( ) => release ( "left" ) }
340- onPointerCancel = { ( ) => release ( "left" ) }
341- onPointerLeave = { ( ) => release ( "left" ) }
342- >
343- < ChevronLeft size = { 20 } />
344- </ button >
345- < button
346- type = "button"
347- tabIndex = { - 1 }
348- className = { buttonClass }
349- style = { { touchAction : "manipulation" } }
350- onPointerDown = { ( ev ) => {
351- ev . preventDefault ( ) ;
352- press ( "right" ) ;
353- } }
354- onPointerUp = { ( ) => release ( "right" ) }
355- onPointerCancel = { ( ) => release ( "right" ) }
356- onPointerLeave = { ( ) => release ( "right" ) }
357- >
358- < ChevronRight size = { 20 } />
359- </ button >
360- </ div >
361- < button
362- type = "button"
363- tabIndex = { - 1 }
364- className = { buttonClass }
365- style = { { touchAction : "manipulation" } }
366- onPointerDown = { ( ev ) => {
367- ev . preventDefault ( ) ;
368- press ( "thrust" ) ;
369- } }
370- onPointerUp = { ( ) => release ( "thrust" ) }
371- onPointerCancel = { ( ) => release ( "thrust" ) }
372- onPointerLeave = { ( ) => release ( "thrust" ) }
326+ < motion . p
327+ initial = { { opacity : 0 } }
328+ animate = { { opacity : hintVisible ? 1 : 0 } }
329+ transition = { { duration : 0.6 , delay : hintVisible ? 1.2 : 0 } }
330+ className = "absolute bottom-2 left-1/2 -translate-x-1/2 whitespace-nowrap text-[11px] tracking-wide text-gray-500/80 dark:text-blue-100/40"
373331 >
374- < ArrowUp size = { 20 } />
375- </ button >
332+ { coarsePointer ? "◀ ▶ drive · hold ▲ to fly" : "← → drive · hold ↑ to fly" }
333+ </ motion . p >
334+
335+ { coarsePointer && (
336+ < div className = "absolute inset-x-0 bottom-3 flex items-end justify-between px-5" >
337+ < div className = "flex gap-3" >
338+ < button
339+ type = "button"
340+ tabIndex = { - 1 }
341+ className = { buttonClass }
342+ style = { { touchAction : "manipulation" } }
343+ onPointerDown = { ( ev ) => {
344+ ev . preventDefault ( ) ;
345+ press ( "left" ) ;
346+ } }
347+ onPointerUp = { ( ) => release ( "left" ) }
348+ onPointerCancel = { ( ) => release ( "left" ) }
349+ onPointerLeave = { ( ) => release ( "left" ) }
350+ >
351+ < ChevronLeft size = { 20 } />
352+ </ button >
353+ < button
354+ type = "button"
355+ tabIndex = { - 1 }
356+ className = { buttonClass }
357+ style = { { touchAction : "manipulation" } }
358+ onPointerDown = { ( ev ) => {
359+ ev . preventDefault ( ) ;
360+ press ( "right" ) ;
361+ } }
362+ onPointerUp = { ( ) => release ( "right" ) }
363+ onPointerCancel = { ( ) => release ( "right" ) }
364+ onPointerLeave = { ( ) => release ( "right" ) }
365+ >
366+ < ChevronRight size = { 20 } />
367+ </ button >
368+ </ div >
369+ < button
370+ type = "button"
371+ tabIndex = { - 1 }
372+ className = { buttonClass }
373+ style = { { touchAction : "manipulation" } }
374+ onPointerDown = { ( ev ) => {
375+ ev . preventDefault ( ) ;
376+ press ( "thrust" ) ;
377+ } }
378+ onPointerUp = { ( ) => release ( "thrust" ) }
379+ onPointerCancel = { ( ) => release ( "thrust" ) }
380+ onPointerLeave = { ( ) => release ( "thrust" ) }
381+ >
382+ < ArrowUp size = { 20 } />
383+ </ button >
384+ </ div >
385+ ) }
376386 </ div >
377387 ) }
378- </ div >
388+ </ >
379389 ) ;
380390} ;
381391
0 commit comments