@@ -286,9 +286,8 @@ function DialogPairing(props: {
286286 } ) )
287287
288288 const refresh = ( ) => (
289- < button
290- type = "button"
291- class = "rounded-[4px] px-1 text-12-regular leading-[var(--line-height-compact)] text-v2-text-text-muted underline-offset-2 hover:text-v2-text-text-base hover:underline focus-visible:underline focus-visible:outline-none disabled:opacity-50"
289+ < Button
290+ variant = "ghost"
292291 disabled = { code . isFetching }
293292 onClick = { ( ) => {
294293 clearTimeout ( copied . timeout )
@@ -297,7 +296,7 @@ function DialogPairing(props: {
297296 } }
298297 >
299298 { ctx . t ( "refresh" ) }
300- </ button >
299+ </ Button >
301300 )
302301
303302 // The QR code carries the remote address as `opencode pair --remote` prints it, {"code","urls"} JSON, which the
@@ -313,7 +312,8 @@ function DialogPairing(props: {
313312 } )
314313
315314 // The QR code's frame, which also holds the setup progress and its failure, so the dialog keeps its size.
316- const frame = "mx-auto aspect-square w-full max-w-[min(320px,calc(100dvh-360px))] shrink-0 rounded-[6px]"
315+ // It spans the dialog's content width, inset as the header is, and shrinks only to fit a short window.
316+ const frame = "mx-auto aspect-square w-full max-w-[calc(100dvh-360px)] shrink-0 rounded-[6px]"
317317
318318 return (
319319 < Dialog fit containerClass = "max-w-[min(400px,calc(100vw-32px))]" >
@@ -328,21 +328,25 @@ function DialogPairing(props: {
328328 aria-label = { ctx . t ( "qr" ) }
329329 innerHTML = { qr ( ) }
330330 />
331- < div class = "flex flex-col items-center gap-1 pb-2" >
332- < Button
333- variant = "neutral"
334- icon = { copy . isSuccess ? "check" : "copy" }
335- disabled = { copy . isPending }
336- onClick = { ( ) => copy . mutate ( ) }
331+ < div class = "flex flex-wrap items-center gap-2" >
332+ < span
333+ class = "me-auto text-12-regular leading-[var(--line-height-compact)] tabular-nums text-v2-text-text-muted"
334+ role = "timer"
335+ aria-live = "off"
337336 >
338- { ctx . t ( copy . isSuccess ? "common.copied" : "copyLink" ) }
339- </ Button >
340- < div class = "flex items-center gap-2 text-12-regular leading-[var(--line-height-compact)] text-v2-text-text-muted" >
341- < span role = "timer" aria-live = "off" >
342- { ctx . t ( "expires" , { time : countdown ( remaining ( ) ) } ) }
343- </ span >
344- < span aria-hidden = "true" > ·</ span >
337+ { ctx . t ( "expires" , { time : countdown ( remaining ( ) ) } ) }
338+ </ span >
339+ { /* The actions wrap together, so a narrow dialog keeps them in one row, right-aligned under the countdown. */ }
340+ < div class = "ms-auto flex items-center gap-2" >
345341 { refresh ( ) }
342+ < Button
343+ variant = "neutral"
344+ icon = { copy . isSuccess ? "check" : "copy" }
345+ disabled = { copy . isPending }
346+ onClick = { ( ) => copy . mutate ( ) }
347+ >
348+ { ctx . t ( copy . isSuccess ? "common.copied" : "copyLink" ) }
349+ </ Button >
346350 </ div >
347351 </ div >
348352 </ Show >
0 commit comments