diff --git a/src/components/Board/GameplayInterface.tsx b/src/components/Board/GameplayInterface.tsx index 93b85549..f7ed8139 100644 --- a/src/components/Board/GameplayInterface.tsx +++ b/src/components/Board/GameplayInterface.tsx @@ -161,7 +161,7 @@ export const GameplayInterface: React.FC> = ( <>
-
+
> = ( /> ) : null}
-
+
{timeControl != 'unlimited' ? ( { - if (currentMoveRef.current && containerRef.current) { - currentMoveRef.current.scrollIntoView({ + const move = currentMoveRef.current + const container = containerRef.current + if (!move || !container) return + + // scrollIntoView walks every scrollable ancestor up to the document body, + // so it can shift the whole page if the moves panel sits near a viewport + // edge. Scroll the moves panel directly instead, leaving everything above + // it alone. + const moveRect = move.getBoundingClientRect() + const containerRect = container.getBoundingClientRect() + + let topDelta = 0 + if (moveRect.top < containerRect.top) { + topDelta = moveRect.top - containerRect.top + } else if (moveRect.bottom > containerRect.bottom) { + topDelta = moveRect.bottom - containerRect.bottom + } + + let leftDelta = 0 + if (moveRect.left < containerRect.left) { + leftDelta = moveRect.left - containerRect.left + } else if (moveRect.right > containerRect.right) { + leftDelta = moveRect.right - containerRect.right + } + + if (topDelta !== 0 || leftDelta !== 0) { + container.scrollTo({ + top: container.scrollTop + topDelta, + left: container.scrollLeft + leftDelta, behavior: 'smooth', - block: 'nearest', - inline: 'nearest', }) } }, [controller.currentNode]) diff --git a/src/components/Common/ExportGame.tsx b/src/components/Common/ExportGame.tsx index f3205fb7..adc33a5a 100644 --- a/src/components/Common/ExportGame.tsx +++ b/src/components/Common/ExportGame.tsx @@ -98,8 +98,8 @@ export const ExportGame: React.FC = (props) => { } return ( -
-
+
+

FEN @@ -117,14 +117,14 @@ export const ExportGame: React.FC = (props) => { role="button" tabIndex={0} onClick={() => copy(fen)} - className="border-1 group flex w-full cursor-pointer overflow-x-hidden rounded border border-white/5 p-1" + className="border-1 group flex w-full min-w-0 cursor-pointer overflow-x-hidden rounded border border-white/5 p-1" > -

+

{fen}

-
+

@@ -144,7 +144,7 @@ export const ExportGame: React.FC = (props) => { role="button" tabIndex={0} onClick={() => copy(pgn)} - className="group flex w-full cursor-pointer overflow-x-hidden overflow-y-scroll rounded border border-white/5 p-1" + className="group flex h-40 max-h-40 min-h-40 w-full min-w-0 cursor-pointer overflow-x-hidden overflow-y-scroll rounded border border-white/5 p-1" >

{pgn} diff --git a/src/pages/candidates.tsx b/src/pages/candidates.tsx index d480972d..ca78a636 100644 --- a/src/pages/candidates.tsx +++ b/src/pages/candidates.tsx @@ -189,8 +189,8 @@ const PositionPill: React.FC<{ href={playHref} className={`inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-primary shadow-[0_8px_24px_rgba(0,0,0,0.2)] transition ${ completed - ? 'bg-emerald-500/30 hover:bg-emerald-500/34 border border-emerald-100/70 hover:border-emerald-50/80' - : 'bg-rose-500/30 hover:bg-rose-500/34 border border-rose-100/65 hover:border-rose-50/75' + ? 'hover:bg-emerald-500/34 border border-emerald-100/70 bg-emerald-500/30 hover:border-emerald-50/80' + : 'hover:bg-rose-500/34 border border-rose-100/65 bg-rose-500/30 hover:border-rose-50/75' }`} >