Make the brand CTA visible and fix two more v3 variable classes

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UytviPMJbXzD8P84nLvXcq
This commit is contained in:
2026-08-25 18:33:28 +02:00
co-authored by Claude Opus 5
parent df22475f54
commit 476dc6a1e9
4 changed files with 35 additions and 13 deletions
+31 -10
View File
@@ -1,8 +1,11 @@
import { useMutation, useQuery } from "@tanstack/react-query"
import { createFileRoute } from "@tanstack/react-router"
import { Check, Copy } from "lucide-react"
import { useEffect } from "react"
import { ApiError, PanelsService } from "@/client"
import { Button } from "@/components/ui/button"
import { useCopyToClipboard } from "@/hooks/useCopyToClipboard"
import { appPath, isPortal, openPortalSession } from "@/lib/portal"
/**
@@ -27,6 +30,8 @@ export const Route = createFileRoute("/panel/")({
})
function PairPanel() {
const [copied, copy] = useCopyToClipboard()
// A code lives ten minutes. Asking for one is the mount, and asking again is
// what happens when this one is no longer recognised.
const start = useMutation({
@@ -98,16 +103,32 @@ function PairPanel() {
</p>
</div>
<p className="font-mono text-6xl font-medium tracking-[0.2em]">
<span data-testid="pairing-code" aria-hidden="true">
{started?.code ?? "······"}
</span>
{/* Spelled out, so a reader says the characters rather than trying
to pronounce them as a word. */}
<span className="sr-only">
{(started?.code ?? "").split("").join(" ")}
</span>
</p>
<div className="flex items-center justify-center gap-4">
<p className="font-mono text-6xl font-medium tracking-[0.2em]">
<span data-testid="pairing-code" aria-hidden="true">
{started?.code ?? "······"}
</span>
{/* Spelled out, so a reader says the characters rather than trying
to pronounce them as a word. */}
<span className="sr-only">
{(started?.code ?? "").split("").join(" ")}
</span>
</p>
{/* Only where it would work: a panel served over plain http on the
LAN has no clipboard, and a button that silently does nothing is
worse than none. */}
{started?.code && navigator.clipboard ? (
<Button
variant="ghost"
size="icon"
className="size-11 shrink-0 text-muted-foreground md:size-8"
aria-label="Copy the code"
onClick={() => copy(started.code)}
>
{copied === started.code ? <Check /> : <Copy />}
</Button>
) : null}
</div>
<p className="text-sm text-muted-foreground">
The code lasts ten minutes; this screen replaces it when it runs out.