# Xray Lens

> A loupe over a polished UI. Inside the glass the surface peels away to the layer underneath, such as model tokens, raw JSON or latency telemetry, lined up with the parts it explains. A switch floods it over the whole card.

An animated React component from KeyframeUI, installed as source with the shadcn CLI. Built with React, Tailwind CSS and Motion.

- Docs and live preview: https://keyframeui.com/components/xray-lens
- Tags: Hover, Interaction, Developer
- npm dependencies: motion, clsx, tailwind-merge

## Installation

Register the @keyframeui registry in `components.json` once per project:

```json
{
  "registries": {
    "@keyframeui": "https://keyframeui.com/r/{name}.json"
  }
}
```

Then add the component. It lands in `components/ui/xray-lens.tsx`, and the CLI also adds `lib/utils.ts` (the `cn` helper) and installs the npm dependencies:

```bash
npx shadcn@latest add @keyframeui/xray-lens
```

Or install by URL, without registering the namespace:

```bash
npx shadcn@latest add https://keyframeui.com/r/xray-lens.json
```

## Usage

The main demo shows typical usage.

### Model Output

A support ticket triaged by an AI. Under the glass every chip and button turns into the field or tool call behind it, and both messages turn into their tokens in place with `XrayLensText`: the reply tinted by confidence, the customer's message with the extracted entities outlined. The lens is `size="36%"`, the switch sits under the card and flips the whole ticket, and on a phone the lens tours the spots by itself.

Install this demo, with the component included:

```bash
npx shadcn@latest add @keyframeui/xray-lens-demo
```

```tsx title="components/xray-lens-demo.tsx"
import type { ReactNode } from "react";

import { XrayLens, XrayLensSpot, XrayLensText } from "@/components/ui/xray-lens";

// A spot's box in the xray: a dashed outline exactly where the UI element sits.
const box = "outline-1 -outline-offset-1 outline-dashed outline-sky-400/50 bg-sky-400/[0.07]";

function Value({ children, className }: { children: ReactNode; className?: string }) {
  return (
    <span
      className={`grid size-full place-items-center font-mono text-[11px] leading-none whitespace-nowrap ${className ?? "text-amber-300"}`}
    >
      {children}
    </span>
  );
}

function Chip({ dot, children }: { dot: string; children: ReactNode }) {
  return (
    <span className="inline-flex h-6 items-center gap-1.5 rounded-full bg-zinc-100 px-2.5 text-xs font-medium text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300">
      <span className={`size-1.5 rounded-full ${dot}`} />
      {children}
    </span>
  );
}

const MESSAGE =
  "I was charged twice for Pro this month, once on Oct 2 and again on Oct 3. Could you refund the extra $49.00?";

// The reply as the model streamed it: each token with its probability. The dates and the
// amount are where it was least sure.
const REPLY: [string, number][] = [
  ["Hi", 0.99], [" Maya", 0.98], [",", 0.99], [" sorry", 0.93], [" about", 0.97], [" that", 0.98],
  [".", 0.99], [" I", 0.95], ["'ve", 0.97], [" refunded", 0.9], [" the", 0.99], [" duplicate", 0.88],
  [" $", 0.7], ["49", 0.62], [".", 0.9], ["00", 0.95], [" charge", 0.97], [",", 0.96], [" so", 0.9],
  [" it", 0.97], [" should", 0.82], [" be", 0.99], [" back", 0.96], [" on", 0.95], [" your", 0.98],
  [" card", 0.97], [" in", 0.94], [" 5", 0.41], [" to", 0.7], [" 7", 0.38], [" days", 0.93], [".", 0.99],
];

function Ticket() {
  return (
    <div className="flex flex-col gap-5 p-5 sm:p-6">
      <div className="flex items-start justify-between gap-4">
        <XrayLensSpot
          label="customer = cus_8Hq2nL"
          xrayClassName={box}
          xray={
            <span className="flex h-full flex-col justify-center gap-1.5 pl-2 font-mono text-[11px] leading-none">
              <span className="text-emerald-300">&quot;cus_8Hq2nL&quot;</span>
              <span className="text-zinc-400">
                plan <span className="text-emerald-300">pro</span> · ltv{" "}
                <span className="text-amber-300">1188</span>
              </span>
            </span>
          }
          className="flex items-center gap-3"
        >
          <span className="grid size-10 place-items-center rounded-full bg-gradient-to-br from-amber-200 to-rose-300 text-sm font-semibold text-rose-950">
            MC
          </span>
          <span className="flex flex-col">
            <span className="text-sm font-medium text-zinc-900 dark:text-zinc-50">Maya Chen</span>
            <span className="text-xs text-zinc-500">maya@northwind.io</span>
          </span>
        </XrayLensSpot>
        <XrayLensSpot
          label="received_at"
          xrayClassName={box}
          xray={<Value>1760531412</Value>}
          className="pt-1 text-xs text-zinc-500 tabular-nums"
        >
          2 min ago
        </XrayLensSpot>
      </div>

      <div className="flex flex-wrap gap-2">
        <XrayLensSpot
          label="classify.intent"
          xrayClassName={box}
          xray={<Value className="text-emerald-300">&quot;refund&quot;</Value>}
        >
          <Chip dot="bg-sky-500">Billing</Chip>
        </XrayLensSpot>
        <XrayLensSpot label="classify.sentiment" xrayClassName={box} xray={<Value>-0.72</Value>}>
          <Chip dot="bg-rose-500">Frustrated</Chip>
        </XrayLensSpot>
        <XrayLensSpot label="route.priority = p1" xrayClassName={box} xray={<Value>sla 2h</Value>}>
          <Chip dot="bg-amber-500">Urgent</Chip>
        </XrayLensSpot>
      </div>

      <XrayLensText
        text={MESSAGE}
        entities={[
          { text: "charged twice", label: "extract.issue = duplicate_charge" },
          { text: "$49.00", label: "extract.amount = 4900" },
        ]}
        label="input · 31 tokens"
        className="text-[15px] leading-relaxed text-pretty text-zinc-700 dark:text-zinc-300"
      />

      <XrayLensSpot
        label="generate.reply"
        xrayClassName={box}
        xray={
          <span className="absolute top-4 left-4 font-mono text-[11px] leading-4">
            <span className="text-violet-300">generate</span>
            <span className="text-zinc-400">
              () · <span className="text-amber-300">61</span> tok · <span className="text-amber-300">412</span>ms
            </span>
          </span>
        }
        className="rounded-xl bg-zinc-50 p-4 ring-1 ring-zinc-950/5 dark:bg-zinc-900 dark:ring-white/10"
      >
        <div className="flex items-center justify-between text-xs leading-4">
          <span className="font-medium text-zinc-900 dark:text-zinc-100">Suggested reply</span>
          <XrayLensSpot
            as="span"
            label="eval.confidence"
            xrayClassName={box}
            xray={<Value>p 0.94</Value>}
            className="inline-block text-zinc-500 tabular-nums"
          >
            94% confident
          </XrayLensSpot>
        </div>
        <XrayLensText
          tokens={REPLY.map(([text, p]) => ({ text, p }))}
          label="output · logprobs"
          className="mt-2 text-sm leading-relaxed text-pretty text-zinc-600 dark:text-zinc-400"
        />
      </XrayLensSpot>

      <div className="flex items-center gap-2">
        <XrayLensSpot
          label="tool_call · stripe"
          xrayClassName={box}
          xray={<Value className="text-violet-300">refunds.create()</Value>}
        >
          <button
            type="button"
            className="h-9 rounded-lg bg-zinc-900 px-3.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-200"
          >
            Refund $49.00
          </button>
        </XrayLensSpot>
        <XrayLensSpot
          label="tool_call · helpdesk"
          xrayClassName={box}
          xray={<Value className="text-violet-300">reply.send()</Value>}
        >
          <button
            type="button"
            className="h-9 rounded-lg px-3.5 text-sm font-medium text-zinc-700 ring-1 ring-zinc-950/10 transition-colors hover:bg-zinc-50 dark:text-zinc-300 dark:ring-white/15 dark:hover:bg-zinc-900"
          >
            Send reply
          </button>
        </XrayLensSpot>
      </div>
    </div>
  );
}

export function XrayLensDemo() {
  return (
    <section className="w-full max-w-xl">
      <XrayLens
        size="36%"
        rest={{ x: 0.26, y: 0.26 }}
        labels={["Ticket", "Model"]}
        toggleClassName="top-full right-auto bottom-auto left-1/2 mt-4 -translate-x-1/2"
        surface={<Ticket />}
        xray={
          <div className="absolute inset-0 bg-[linear-gradient(rgb(56_189_248/0.07)_1px,transparent_1px),linear-gradient(90deg,rgb(56_189_248/0.07)_1px,transparent_1px)] bg-size-[16px_16px]" />
        }
        xrayClassName="bg-[#060a12] text-sky-100"
        className="rounded-2xl bg-white shadow-[0_1px_2px_rgb(0_0_0/0.05),0_16px_40px_-20px_rgb(0_0_0/0.3)] ring-1 ring-zinc-950/5 dark:bg-zinc-950 dark:ring-white/10"
      />
      <p className="mt-20 text-center text-sm text-zinc-500">
        Point at the ticket to see what the model read and returned, or flip the whole card.
      </p>
    </section>
  );
}
```

## Examples

Finished sections built with Xray Lens. Each one installs whole, with the component included.

### Blueprint

A studio's booking card over its own blueprint: component names, type and spacing tokens on wireframe bounds. `mode="drag"` with more `zoom`; pick the lens up and it lifts. The Design/Blueprint switch sits over the photo.

Install this demo, with the component included:

```bash
npx shadcn@latest add @keyframeui/xray-lens-blueprint-demo
```

```tsx title="components/xray-lens-blueprint-demo.tsx"
import type { ReactNode } from "react";

import { XrayLens, XrayLensSpot } from "@/components/ui/xray-lens";

const photo =
  "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?auto=format&fit=crop&w=800&h=600&q=80";

// Blueprint lines: each part of the card drawn as a thin white box.
const line = "outline-1 -outline-offset-1 outline-white/60";

function Part({ name, spec }: { name: string; spec?: string }) {
  return (
    <span className="flex h-full flex-col justify-center gap-0.5 px-1.5 font-mono text-[10px] leading-tight whitespace-nowrap">
      <span className="text-white">{name}</span>
      {spec && <span className="text-sky-200/70">{spec}</span>}
    </span>
  );
}

function Tag({ children }: { children: ReactNode }) {
  return (
    <XrayLensSpot label="Tag" xrayClassName={line} xray={<Part name="<Tag>" />}>
      <span className="inline-flex h-6 items-center rounded-md bg-zinc-100 px-2 text-xs text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300">
        {children}
      </span>
    </XrayLensSpot>
  );
}

function Listing() {
  return (
    <div className="p-3">
      <XrayLensSpot
        label="Image · 4:3 · radius 12"
        xrayClassName={line}
        xray={
          <span className="relative block size-full">
            <svg aria-hidden className="absolute inset-0 size-full text-white/35" preserveAspectRatio="none" viewBox="0 0 100 100">
              <line x1="0" y1="0" x2="100" y2="100" stroke="currentColor" vectorEffect="non-scaling-stroke" />
              <line x1="100" y1="0" x2="0" y2="100" stroke="currentColor" vectorEffect="non-scaling-stroke" />
            </svg>
            <span className="absolute inset-0 grid place-items-center">
              <span className="bg-[#0b3c8f] px-1.5 py-0.5">
                <Part name="<Image ratio=&quot;4/3&quot; />" spec="cover · radius 12" />
              </span>
            </span>
          </span>
        }
      >
        {/* eslint-disable-next-line @next/next/no-img-element -- a remote photo in an installable demo */}
        <img
          src={photo}
          alt="A low timber and glass house lit up at dusk"
          draggable={false}
          className="aspect-4/3 w-full rounded-xl bg-zinc-100 object-cover dark:bg-zinc-900"
        />
      </XrayLensSpot>

      <div className="flex flex-col gap-3 px-1.5 pt-4 pb-1.5">
        <div className="flex items-start justify-between gap-3">
          <XrayLensSpot
            label="Heading · 17/24 · 600"
            xrayClassName={line}
            xray={<Part name="<Heading size=&quot;md&quot;>" spec="17/24 · 600 · -1%" />}
          >
            <h4 className="text-[17px] leading-6 font-semibold tracking-tight text-zinc-900 dark:text-zinc-50">
              Timber House
            </h4>
            <p className="text-sm text-zinc-500">Lake Bohinj, Slovenia</p>
          </XrayLensSpot>
          <XrayLensSpot
            label="Rating"
            xrayClassName={line}
            xray={<Part name="<Rating>" spec="value 4.92" />}
            className="flex items-center gap-1 pt-0.5 text-sm font-medium text-zinc-900 tabular-nums dark:text-zinc-100"
          >
            <svg aria-hidden viewBox="0 0 20 20" className="size-3.5 fill-amber-400">
              <path d="M10 1.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L10 14.9l-5.2 2.7 1-5.8L1.5 7.7l5.9-.9z" />
            </svg>
            4.92
          </XrayLensSpot>
        </div>

        <XrayLensSpot
          label="Stack · row · gap 6"
          xrayClassName={line}
          xray={null}
          className="flex flex-wrap gap-1.5"
        >
          <Tag>Sauna</Tag>
          <Tag>Lake view</Tag>
          <Tag>Sleeps 4</Tag>
        </XrayLensSpot>

        <div className="mt-1 flex items-center justify-between border-t border-zinc-100 pt-3 dark:border-zinc-800">
          <XrayLensSpot
            label="Price · tabular"
            xrayClassName={line}
            xray={<Part name="<Price unit=&quot;night&quot;>" spec="EUR · tabular" />}
            className="text-sm text-zinc-500"
          >
            <span className="text-base font-semibold text-zinc-900 tabular-nums dark:text-zinc-50">€184</span>{" "}
            night
          </XrayLensSpot>
          <XrayLensSpot
            label="Button · md · h 36"
            xrayClassName={line}
            xray={<Part name="<Button>" spec="md · h 36 · px 14" />}
          >
            <button
              type="button"
              className="h-9 rounded-lg bg-zinc-900 px-3.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-200"
            >
              Reserve
            </button>
          </XrayLensSpot>
        </div>
      </div>
    </div>
  );
}

export function XrayLensBlueprintDemo() {
  return (
    <section className="grid w-full max-w-3xl items-center gap-10 sm:grid-cols-[minmax(0,1fr)_20rem]">
      <div>
        <p className="font-mono text-xs tracking-widest text-zinc-500 uppercase">Design systems</p>
        <h3 className="mt-3 text-3xl font-semibold tracking-tight text-balance text-zinc-900 dark:text-zinc-50">
          Built from parts, not pixels.
        </h3>
        <p className="mt-4 max-w-sm text-sm/6 text-pretty text-zinc-600 dark:text-zinc-400">
          Every screen we ship is made of named components and tokens your team can reuse. Pick up
          the loupe and drag it across the card to see the system underneath.
        </p>
      </div>
      <XrayLens
        mode="drag"
        size="55%"
        zoom={1.14}
        rest={{ x: 0.45, y: 0.68 }}
        lensLabel="Blueprint lens"
        labels={["Design", "Blueprint"]}
        toggleClassName="top-5 right-5 bottom-auto"
        surface={<Listing />}
        xray={
          <div className="absolute inset-0 bg-[linear-gradient(rgb(255_255_255/0.07)_1px,transparent_1px),linear-gradient(90deg,rgb(255_255_255/0.07)_1px,transparent_1px)] bg-size-[8px_8px]">
            <div className="absolute inset-0 bg-[linear-gradient(rgb(255_255_255/0.08)_1px,transparent_1px),linear-gradient(90deg,rgb(255_255_255/0.08)_1px,transparent_1px)] bg-size-[40px_40px]" />
          </div>
        }
        xrayClassName="bg-[#0b3c8f] text-white"
        labelClassName="bg-[#0b3c8f]/95 ring-white/25"
        className="w-full rounded-2xl bg-white shadow-[0_1px_2px_rgb(0_0_0/0.05),0_16px_40px_-20px_rgb(0_0_0/0.3)] ring-1 ring-zinc-950/5 dark:bg-zinc-950 dark:ring-white/10"
      />
    </section>
  );
}
```

### Request Trace

An AI search answer over the live trace that produced it: retrieval, generation and citation spans on the request's timeline, and the answer recolored by when each word streamed. `autoPlay` tours the spans on desktop too until the pointer takes over, and `rest={false}` keeps the lens closed before the tour starts.

Install this demo, with the component included:

```bash
npx shadcn@latest add @keyframeui/xray-lens-trace-demo
```

```tsx title="components/xray-lens-trace-demo.tsx"
"use client";

import * as React from "react";

import { XrayLens, XrayLensSpot } from "@/components/ui/xray-lens";

// One trace, in the order it ran. Each span is drawn over the part of the answer it produced.
const TRACE = [
  { id: "embed", ms: 18 },
  { id: "retrieve", ms: 42 },
  { id: "rerank", ms: 31 },
  { id: "generate", ms: 812 },
  { id: "cite", ms: 12 },
  { id: "suggest", ms: 64 },
] as const;

type SpanId = (typeof TRACE)[number]["id"];
type At = { start: number; ms: number };
type Timing = Record<SpanId, At>;

const BASE = Object.fromEntries(TRACE.map((s) => [s.id, s.ms])) as Record<SpanId, number>;

function lay(durations: Record<SpanId, number>) {
  let t = 0;
  const timing = {} as Timing;
  for (const { id } of TRACE) {
    timing[id] = { start: t, ms: durations[id] };
    t += durations[id];
  }
  return { timing, total: t };
}

/** The trace re-measured every couple of seconds, as a live dashboard would show it. */
function useLiveTrace() {
  const [durations, setDurations] = React.useState(BASE);
  React.useEffect(() => {
    const id = window.setInterval(() => {
      setDurations(
        Object.fromEntries(
          TRACE.map((s) => [s.id, Math.round(s.ms * (0.88 + Math.random() * 0.24))]),
        ) as Record<SpanId, number>,
      );
    }, 1600);
    return () => window.clearInterval(id);
  }, []);
  return lay(durations);
}

const spanBox = "outline-1 -outline-offset-1 outline-emerald-400/40 bg-emerald-400/[0.06]";

/** Where a span sits on the whole request's timeline. */
function Bar({ at, total }: { at: At; total: number }) {
  return (
    <span className="relative h-1 min-w-8 flex-1 rounded-full bg-white/10">
      <span
        className="absolute inset-y-0 min-w-[3px] rounded-full bg-emerald-400 transition-[left,width] duration-500"
        style={{ left: `${(at.start / total) * 100}%`, width: `${(at.ms / total) * 100}%` }}
      />
    </span>
  );
}

/** A span in a box: its name and time, its place on the timeline, and a note. */
function Span({ name, at, total, note }: { name: string; at: At; total: number; note?: string }) {
  return (
    <span className="flex h-full min-w-0 flex-col justify-center gap-1.5 px-2.5 font-mono text-[10.5px] leading-none">
      <span className="flex items-center justify-between gap-3 whitespace-nowrap">
        <span className="text-emerald-300">{name}</span>
        <span className="text-zinc-100 tabular-nums">{at.ms}ms</span>
      </span>
      <span className="flex">
        <Bar at={at} total={total} />
      </span>
      {note && <span className="truncate text-zinc-500">{note}</span>}
    </span>
  );
}

/** A span on one line, for the section labels. */
function SpanRow({ name, at, total }: { name: string; at: At; total: number }) {
  return (
    <span className="flex h-full items-center gap-2.5 font-mono text-[10px] leading-none whitespace-nowrap">
      <span className="text-emerald-300">{name}</span>
      <Bar at={at} total={total} />
      <span className="text-zinc-100 tabular-nums">{at.ms}ms</span>
    </span>
  );
}

// The answer as text and citations. The surface and the xray both render it from
// here, so they wrap the same way.
const ANSWER: (string | number)[] = [
  "Create the new key and deploy it alongside the old one. Once traffic has moved over, revoke the old key",
  1,
  ". Both keys stay valid during the overlap, so no request fails",
  2,
  ".",
];
const WORDS = ANSWER.filter((part) => typeof part === "string").join(" ").split(/\s+/).length;

const answer = "text-[15px] leading-relaxed text-pretty";
const cite =
  "mx-0.5 inline-grid size-[18px] place-items-center rounded-full align-[2px] text-[10px] font-semibold";

/** The answer again, each word colored by when it streamed in: green first, violet last. */
function Streamed() {
  let n = 0;
  return (
    <p className={answer}>
      {ANSWER.map((part, i) =>
        typeof part === "number" ? (
          <span key={i} className={`${cite} text-transparent`}>
            {part}
          </span>
        ) : (
          part.split(/(\s+)/).map((word, j) =>
            /\s/.test(word) || !word ? (
              word
            ) : (
              <span key={`${i}-${j}`} style={{ color: `oklch(0.82 0.14 ${160 + (n++ / WORDS) * 140})` }}>
                {word}
              </span>
            ),
          )
        ),
      )}
    </p>
  );
}

const SOURCES = [
  { host: "docs.acme.dev", title: "Rotating API keys", score: "0.91" },
  { host: "acme.dev/blog", title: "Zero-downtime deploys", score: "0.88" },
  { host: "status.acme.dev", title: "Incident 4127", score: "0.64" },
];

function Answer({ timing, total }: { timing: Timing; total: number }) {
  return (
    <div className="flex flex-col gap-5 p-5 sm:p-6">
      <XrayLensSpot
        label="embed · query"
        xrayClassName={spanBox}
        xray={<Span name="embed" at={timing.embed} total={total} note="trace 7f3a2c · 1536 dims" />}
        className="flex h-12 items-center gap-2.5 rounded-xl bg-zinc-100 px-3.5 text-sm text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100"
      >
        <svg aria-hidden viewBox="0 0 20 20" className="size-4 shrink-0 fill-none stroke-zinc-400 stroke-2">
          <circle cx="9" cy="9" r="6" />
          <path d="M13.5 13.5 17 17" strokeLinecap="round" />
        </svg>
        <span className="truncate">How do I rotate API keys without downtime?</span>
      </XrayLensSpot>

      <div>
        <XrayLensSpot
          label="generate"
          xray={<SpanRow name="generate" at={timing.generate} total={total} />}
          className="text-xs leading-4 font-medium tracking-wider text-zinc-500 uppercase"
        >
          Answer
        </XrayLensSpot>
        <XrayLensSpot
          label={`stream · 214 tokens · first at ${Math.round(timing.generate.ms * 0.22)}ms`}
          xray={<Streamed />}
          className="mt-2"
        >
          <p className={`${answer} text-zinc-700 dark:text-zinc-300`}>
            {ANSWER.map((part, i) =>
              typeof part === "number" ? (
                <XrayLensSpot
                  key={i}
                  as="span"
                  label={`cite · doc_${part} · ${timing.cite.ms}ms`}
                  xrayClassName="outline-1 -outline-offset-1 outline-amber-300/80 bg-amber-300/15"
                  xray={
                    <span className="grid size-full place-items-center font-mono text-[9px] text-amber-200">
                      d{part}
                    </span>
                  }
                  className={`${cite} bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300`}
                >
                  {part}
                </XrayLensSpot>
              ) : (
                part
              ),
            )}
          </p>
        </XrayLensSpot>
      </div>

      <div>
        <XrayLensSpot
          label="retrieve"
          xray={<SpanRow name="retrieve" at={timing.retrieve} total={total} />}
          className="text-xs leading-4 font-medium tracking-wider text-zinc-500 uppercase"
        >
          Sources
        </XrayLensSpot>
        <div className="mt-2 grid gap-2 sm:grid-cols-3">
          {SOURCES.map((source, i) => (
            <XrayLensSpot
              key={source.host}
              label={`${i === 2 ? "rerank" : "retrieve"} · doc_${i + 1}`}
              xrayClassName={spanBox}
              xray={
                <Span
                  name={i === 2 ? "rerank" : `doc_${i + 1}`}
                  at={i === 2 ? timing.rerank : timing.retrieve}
                  total={total}
                  note={`score ${source.score}${i === 2 ? " · dropped" : ""}`}
                />
              }
              className="rounded-lg p-2.5 ring-1 ring-zinc-950/10 dark:ring-white/10"
            >
              <p className="truncate text-[11px] text-zinc-500">{source.host}</p>
              <p className="mt-0.5 truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
                {source.title}
              </p>
            </XrayLensSpot>
          ))}
        </div>
      </div>

      <XrayLensSpot
        label="suggest · 2 follow-ups"
        xrayClassName={spanBox}
        xray={<SpanRow name="suggest" at={timing.suggest} total={total} />}
        className="flex flex-wrap gap-2 self-start"
      >
        {["Revoke a leaked key", "Scope a key to one project"].map((q) => (
          <button
            key={q}
            type="button"
            className="h-8 rounded-full px-3 text-xs text-zinc-600 ring-1 ring-zinc-950/10 transition-colors hover:bg-zinc-50 dark:text-zinc-400 dark:ring-white/10 dark:hover:bg-zinc-900"
          >
            {q}
          </button>
        ))}
      </XrayLensSpot>
    </div>
  );
}

export function XrayLensTraceDemo() {
  const { timing, total } = useLiveTrace();
  return (
    <section className="w-full max-w-2xl">
      <div className="mb-8 text-center">
        <p className="font-mono text-xs tracking-widest text-zinc-500 uppercase">Observability</p>
        <h3 className="mt-3 text-3xl font-semibold tracking-tight text-balance text-zinc-900 dark:text-zinc-50">
          Every answer, traced to the millisecond.
        </h3>
      </div>
      <XrayLens
        rest={false}
        size="28%"
        autoPlay
        zoom={1.08}
        lensLabel="Trace lens"
        labels={["Answer", "Trace"]}
        toggleClassName="top-full right-auto bottom-auto left-1/2 mt-4 -translate-x-1/2"
        surface={<Answer timing={timing} total={total} />}
        xray={
          <div className="absolute inset-0 bg-[linear-gradient(90deg,rgb(52_211_153/0.07)_1px,transparent_1px)] bg-size-[24px_100%]" />
        }
        xrayClassName="bg-[#050807] text-zinc-100"
        className="rounded-2xl bg-white shadow-[0_1px_2px_rgb(0_0_0/0.05),0_16px_40px_-20px_rgb(0_0_0/0.3)] ring-1 ring-zinc-950/5 dark:bg-zinc-950 dark:ring-white/10"
      />
      <p className="mt-20 text-center text-sm text-zinc-500">
        The lens tours each span. Point at any part of the answer to take over.
      </p>
    </section>
  );
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `surface` (required) | `React.ReactNode` |  | The polished UI. It sets the frame's size. Mark parts of it with `XrayLensSpot` to give them an xray of their own. |
| `xray` | `React.ReactNode` |  | What's underneath, laid over the same box and shown only inside the lens: a grid, a code dump, a schema. Spots draw on top of it. |
| `mode` | `"hover" \| "drag"` | `"hover"` | `hover`: the lens flies to the pointer and trails it. `drag`: it stays put until it's picked up, and a click elsewhere glides it there. Touch screens always drag. |
| `size` | `number \| string` | `200` | Diameter of the lens: px, or a percentage of the frame's width like `"36%"`, so it shrinks with the card on phones. It never grows past 90% of the frame's shorter side. |
| `zoom` | `number` | `1.06` | Magnification inside the lens, around its center, so whatever sits under the crosshair stays lined up. `1` for none. |
| `rest` | `{ x: number; y: number } \| false` | `{ x: 0.5, y: 0.5 }` | Where the lens waits, as fractions of the frame. It opens there when the frame scrolls into view and glides back when the pointer leaves. `false` keeps it closed until the pointer arrives. |
| `autoPlay` | `boolean \| "touch"` | `"touch"` | Let the lens tour the labeled spots by itself while the frame is in view, pausing on each so its label shows: `"touch"` on touch screens only, `true` everywhere, `false` never. A finger, the pointer or focus takes over; the tour picks up again from the nearest spot. Never with reduced motion. |
| `toggle` | `boolean` | `true` | Show a two-way switch that floods the xray over the whole frame, from the lens or from the switch, so the layer underneath never depends on hover. The magnification settles to 1 under the flood, so everything lines up. |
| `labels` | `[string, string]` | `["Surface", "X-ray"]` | The switch's labels: the surface first, then the xray. |
| `toggleClassName` | `string` |  | Classes for the switch. It sits in the bottom-right corner; on a dense card, move it under the frame with `top-full right-auto bottom-auto left-1/2 mt-4 -translate-x-1/2`. |
| `revealed` | `boolean` |  | Floods the xray over the whole frame. Leave unset to let the switch manage it. |
| `defaultRevealed` | `boolean` | `false` | Whether the xray starts out covering the frame. |
| `onRevealedChange` | `(revealed: boolean) => void` |  | Called when the switch flips the layers. |
| `reticle` | `boolean` | `true` | Draw a crosshair and rim ticks on the glass. |
| `lensLabel` | `string` | `"Inspection lens"` | Accessible name of the lens. It's focusable: arrow keys move it (Shift for bigger steps) and Home sends it back to `rest`. |
| `className` | `string` |  | Classes for the frame. Put the card's radius here so the xray layer follows it. The frame sets `--lens-x`, `--lens-y` and `--lens-r` (px) every frame, so content in either layer can react to the lens. |
| `surfaceClassName` | `string` |  | Classes for the wrapper around `surface`. |
| `xrayClassName` | `string` |  | Classes for the xray layer. It defaults to `bg-zinc-950 text-zinc-100`, so the surface never shows through. |
| `lensClassName` | `string` |  | Classes for the glass, e.g. a different `ring-*` color for the rim. |
| `labelClassName` | `string` |  | Classes for the label that names the spot under the lens. |
| `spot.xray` (required) | `React.ReactNode` |  | `XrayLensSpot`: what this element looks like under the lens. It's drawn in the xray layer in a box with the element's exact position, size and corner radius, and follows it through layout changes. |
| `spot.label` | `string` |  | `XrayLensSpot`: named under the glass while the lens is centered on this element. The smallest spot under the center wins. |
| `spot.xrayClassName` | `string` |  | `XrayLensSpot`: classes for the spot's box in the xray layer, e.g. a dashed outline. |
| `spot.as` | `"div" \| "span"` | `"div"` | `XrayLensSpot`: the wrapper element. Use `span` (with `inline-block`) to mark words inside a paragraph. |
| `spot.className` | `string` |  | `XrayLensSpot`: classes for the wrapper in the surface. |
| `text.text` | `string` |  | `XrayLensText`: the text as the surface shows it. Under the lens it turns into its tokens in place: the copy keeps the text's classes, so it wraps exactly the same way. |
| `text.tokens` | `(string \| { text: string; p?: number; label?: string; className?: string })[]` |  | `XrayLensText`: your model's tokens. With `p` (probability, 0–1) each token is tinted by confidence: green, amber below 0.85, red below 0.5. A `label` makes the token a spot. If they don't spell out `text`, the text is split roughly instead. |
| `text.entities` | `{ text: string; label: string }[]` |  | `XrayLensText`: phrases to outline and label, such as entities the model extracted. Used when the text is split here rather than given as `tokens`. |
| `text.label` | `string` |  | `XrayLensText`: named under the glass. Defaults to the token count. |
| `text.as` | `"p" \| "span" \| "div" \| "li" \| "blockquote"` | `"p"` | `XrayLensText`: the text's element. Its `className` styles both the text and its token copy, so keep colors that differ out of it or let the tokens override them. |

## Source

```tsx title="components/ui/xray-lens.tsx"
"use client";

import * as React from "react";
import {
  animate,
  cancelFrame,
  frame,
  useMotionValue,
  useSpring,
  type AnimationPlaybackControls,
  type MotionValue,
} from "motion/react";

import { cn } from "@/lib/utils";

/* ─────────────────────────────────────────────────────────
 * XRAY LENS STORYBOARD
 *
 *  rest     the surface fills the frame. The xray waits under it,
 *           in the same box, so every part lines up with the part
 *           it explains
 *  intro    the first time the frame scrolls into view, the loupe
 *           opens at `rest`: it grows in on a soft spring and the
 *           magnification swells from 1 to `zoom` as it opens
 *  hover    the loupe flies to the pointer and trails it on a
 *           stiff spring, so it moves like a piece of glass. Inside
 *           it the surface is gone and the xray shows through,
 *           magnified around the lens's center
 *  glint    the highlight on the glass slides against the motion
 *  label    when the lens centers on a spot, its label hangs
 *           under the glass
 *  leave    the loupe glides back to `rest`, or closes with
 *           `rest={false}`
 *  tour     on touch screens (or everywhere, with autoPlay) the
 *           loupe visits each labeled spot in reading order while
 *           the frame is in view, pausing on each. A finger, the
 *           pointer or focus takes over; the tour picks up again
 *           from the nearest spot once they let go
 *  drag     with mode="drag" (and on touch screens) the loupe stays
 *           put until it's picked up. Held, it lifts: it grows a
 *           little, magnifies a little more and its shadow drops.
 *           A tap anywhere else glides it there
 *  reveal   the switch floods the xray across the whole frame from
 *           the switch, or from the lens if it's open: the glass
 *           swells and fades as the circle grows past the corners,
 *           and the magnification settles to 1 so everything lines
 *           up. Switching back pulls the flood in to the lens
 *  keys     the lens is focusable; arrow keys move it, Shift for
 *           bigger steps, Home sends it back to `rest`
 *  reduced  the lens follows the pointer with no lag, opens without
 *           growing and never tours; the switch flips at once
 * ───────────────────────────────────────────────────────── */

const LENS = {
  follow: { stiffness: 420, damping: 38, mass: 0.7 }, // the glass trailing the pointer
  glide: { type: "spring", visualDuration: 0.6, bounce: 0.06 }, // back to rest, to a tap, between tour stops
  open: { type: "spring", visualDuration: 0.45, bounce: 0.22 },
  close: { type: "spring", visualDuration: 0.25, bounce: 0 },
  lift: { type: "spring", visualDuration: 0.3, bounce: 0.3 },
  flood: { duration: 0.85, ease: "easeInOut" }, // the reveal across the whole frame
  liftGrow: 0.05, // the lens grows by this much while it's held
  liftZoom: 0.05, // and magnifies this much more
  liftDrop: 10, // px its shadow drops
  glint: 0.004, // px of glint travel per px/s of speed
  glintMax: 8,
  step: 16, // px per arrow key
  stepLarge: 64, // with Shift
  labelGap: 10, // px between the glass and its label
  dwell: 2200, // ms from one tour stop to the next, glide included
  tourStart: 900, // ms after the frame comes into view
  resume: 1800, // ms after a finger lifts, a drag ends or focus leaves
  resumeMouse: 700, // ms after the pointer leaves, with autoPlay={true}
  minSize: 24,
} as const;

// Where the tour wanders when no spot has a label, as fractions of the frame.
const WANDER: [number, number][] = [
  [0.3, 0.35],
  [0.7, 0.3],
  [0.66, 0.7],
  [0.32, 0.66],
];

const clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));

/** The lens's diameter in px: px as given, or a percentage of the frame's width, never wider than the frame. */
function lensSize(size: number | string, w: number, h: number) {
  const text = String(size).trim();
  const px = typeof size === "number" ? size : text.endsWith("%") ? (parseFloat(text) / 100) * w : parseFloat(text);
  const want = Number.isFinite(px) ? px : 200;
  const most = Math.min(w, h) * 0.9;
  return most > 0 ? clamp(want, LENS.minSize, Math.max(LENS.minSize, most)) : want;
}

/* ── Spots ──────────────────────────────────────────────── */

type Rect = { x: number; y: number; w: number; h: number };
type SpotEntry = { id: string; xray: React.ReactNode; className?: string; label?: string; depth: number };
type SpotTag = "div" | "span" | "p" | "li" | "blockquote";

/**
 * Spots live in the surface but draw in the xray layer. Each one measures its
 * own element and hands the box to this store; the xray layer renders a box
 * per spot, and the lens reads the labels from here.
 */
function createSpots() {
  let root: HTMLDivElement | null = null;
  let list: SpotEntry[] = [];
  const empty: SpotEntry[] = [];
  const rects = new Map<string, Rect & { radius: string }>();
  const boxes = new Map<string, HTMLDivElement>();
  const measurers = new Set<() => void>();
  const listeners = new Set<() => void>();

  const paint = (id: string) => {
    const box = boxes.get(id);
    const rect = rects.get(id);
    if (!box || !rect) return;
    box.style.transform = `translate(${rect.x}px, ${rect.y}px)`;
    box.style.width = `${rect.w}px`;
    box.style.height = `${rect.h}px`;
    box.style.borderRadius = rect.radius;
  };

  return {
    connect(el: HTMLDivElement | null) {
      root = el;
      measurers.forEach((measure) => measure());
    },
    measureAll() {
      measurers.forEach((measure) => measure());
    },
    /** A box in root-local px, with any CSS scale on the way divided out. */
    measure(id: string, el: HTMLElement) {
      if (!root) return;
      const frameRect = root.getBoundingClientRect();
      const kx = root.offsetWidth ? frameRect.width / root.offsetWidth : 1;
      const ky = root.offsetHeight ? frameRect.height / root.offsetHeight : 1;
      const r = el.getBoundingClientRect();
      // The spot's wrapper is usually square; take the corners from what it wraps.
      let radius = getComputedStyle(el).borderRadius;
      if ((!radius || radius === "0px") && el.firstElementChild) {
        radius = getComputedStyle(el.firstElementChild).borderRadius;
      }
      rects.set(id, {
        x: (r.left - frameRect.left) / kx - root.clientLeft,
        y: (r.top - frameRect.top) / ky - root.clientTop,
        w: r.width / kx,
        h: r.height / ky,
        radius,
      });
      paint(id);
    },
    upsert(entry: SpotEntry) {
      const i = list.findIndex((s) => s.id === entry.id);
      const prev = list[i];
      if (
        prev &&
        prev.xray === entry.xray &&
        prev.className === entry.className &&
        prev.label === entry.label &&
        prev.depth === entry.depth
      ) {
        return;
      }
      list = i === -1 ? [...list, entry] : list.map((s, j) => (j === i ? entry : s));
      listeners.forEach((l) => l());
    },
    remove(id: string) {
      rects.delete(id);
      list = list.filter((s) => s.id !== id);
      listeners.forEach((l) => l());
    },
    addMeasurer(fn: () => void) {
      measurers.add(fn);
      return () => {
        measurers.delete(fn);
      };
    },
    attachBox(id: string, el: HTMLDivElement | null) {
      if (el) {
        boxes.set(id, el);
        paint(id);
      } else {
        boxes.delete(id);
      }
    },
    /** The label of the smallest spot that contains a point. */
    labelAt(x: number, y: number) {
      let best: string | undefined;
      let area = Infinity;
      for (const s of list) {
        const r = rects.get(s.id);
        if (!s.label || !r) continue;
        if (x < r.x || y < r.y || x > r.x + r.w || y > r.y + r.h) continue;
        if (r.w * r.h < area) {
          area = r.w * r.h;
          best = s.label;
        }
      }
      return best;
    },
    /** The centers of the labeled spots, in reading order. */
    stops() {
      const points: { x: number; y: number }[] = [];
      for (const s of list) {
        const r = rects.get(s.id);
        if (s.label && r) points.push({ x: r.x + r.w / 2, y: r.y + r.h / 2 });
      }
      return points.sort((a, b) => Math.round(a.y / 24) - Math.round(b.y / 24) || a.x - b.x);
    },
    subscribe(listener: () => void) {
      listeners.add(listener);
      return () => {
        listeners.delete(listener);
      };
    },
    snapshot: () => list,
    serverSnapshot: () => empty,
  };
}

type Spots = ReturnType<typeof createSpots>;

const XrayLensContext = React.createContext<Spots | null>(null);
/** How many spots wrap this one, so a nested spot draws over its parent. */
const SpotDepth = React.createContext(0);

/** Draws a box in the xray layer for every spot in the surface. */
function SpotLayer({ spots }: { spots: Spots }) {
  const list = React.useSyncExternalStore(spots.subscribe, spots.snapshot, spots.serverSnapshot);
  return list.map((spot) => (
    <div
      key={spot.id}
      ref={(el) => {
        spots.attachBox(spot.id, el);
        return () => spots.attachBox(spot.id, null);
      }}
      className={cn("absolute top-0 left-0", spot.className)}
      style={{ zIndex: spot.depth }}
    >
      {spot.xray}
    </div>
  ));
}

export interface XrayLensSpotProps extends React.HTMLAttributes<HTMLElement> {
  /** What this element looks like under the lens. Drawn in the xray layer over the element's exact box. */
  xray: React.ReactNode;
  /** Named under the glass while the lens is centered on this element, and a stop on the tour. */
  label?: string;
  /** The wrapper element. Use `"span"` inside a paragraph. */
  as?: SpotTag;
  /** Classes for the spot's box in the xray layer. It gets the element's size and corner radius. */
  xrayClassName?: string;
}

/**
 * Marks part of the surface and gives it an xray of its own, laid over the
 * element's box so the two line up wherever the layout puts it.
 */
export function XrayLensSpot({
  xray,
  label,
  as = "div",
  xrayClassName,
  children,
  ...props
}: XrayLensSpotProps) {
  const spots = React.useContext(XrayLensContext);
  const depth = React.useContext(SpotDepth);
  const id = React.useId();
  const ref = React.useRef<HTMLElement>(null);

  React.useLayoutEffect(() => {
    spots?.upsert({ id, xray, className: xrayClassName, label, depth });
  });

  React.useLayoutEffect(() => {
    const el = ref.current;
    if (!spots || !el) return;
    const measure = () => spots.measure(id, el);
    const sized = new ResizeObserver(measure);
    sized.observe(el);
    const stop = spots.addMeasurer(measure);
    measure();
    return () => {
      sized.disconnect();
      stop();
      spots.remove(id);
    };
  }, [spots, id]);

  return React.createElement(
    as,
    { ref, ...props },
    <SpotDepth.Provider value={depth + 1}>{children}</SpotDepth.Provider>,
  );
}

/* ── Text as tokens ─────────────────────────────────────── */

/** A token as your model returned it, with its probability (`p`, 0–1) or classes of its own. A `label` makes it a spot. */
export type XrayLensToken = string | { text: string; p?: number; label?: string; className?: string };
/** A phrase to mark in the text, e.g. an entity the model extracted. */
export type XrayLensEntity = { text: string; label: string };

type Token = { text: string; p?: number; label?: string; className?: string };

const ALTERNATE = ["bg-violet-400/25 text-violet-100", "bg-sky-400/20 text-sky-100"];
const ENTITY_BOX = "outline-1 -outline-offset-1 outline-dashed outline-amber-300/80 bg-amber-300/10";
// The copy sits in a box the size of the text's border box, so it drops the margin and fills the box.
const COPY_STYLE: React.CSSProperties = { margin: 0, width: "100%", maxWidth: "none", background: "none" };

const confidence = (p: number) =>
  p >= 0.85
    ? "bg-emerald-400/15 text-emerald-100"
    : p >= 0.5
      ? "bg-amber-400/30 text-amber-100"
      : "bg-rose-500/35 text-rose-100";

/** Splits text roughly the way a tokenizer does: words keep their leading space, long words break in two. */
function tokenize(text: string) {
  return (text.match(/\s?[\w']+|\s?[^\w\s]+|\s+/g) ?? []).flatMap((part) => {
    const word = part.trim();
    if (word.length < 8 || !/^\w+$/.test(word)) return [part];
    const cut = part.length - Math.ceil(word.length / 2);
    return [part.slice(0, cut), part.slice(cut)];
  });
}

/** The text as tokens: `tokens` when they spell out `text`, otherwise split here, with each entity kept whole. */
function toTokens(text: string | undefined, tokens: XrayLensToken[] | undefined, entities: XrayLensEntity[] | undefined) {
  const given = tokens?.map((t): Token => (typeof t === "string" ? { text: t } : t));
  if (given && (text === undefined || given.map((t) => t.text).join("") === text)) return given;
  const out: Token[] = [];
  let rest = text ?? "";
  for (const entity of entities ?? []) {
    const at = rest.indexOf(entity.text);
    if (at === -1 || !entity.text) continue;
    out.push(...tokenize(rest.slice(0, at)).map((t) => ({ text: t })), { text: entity.text, label: entity.label });
    rest = rest.slice(at + entity.text.length);
  }
  out.push(...tokenize(rest).map((t) => ({ text: t })));
  return out;
}

export interface XrayLensTextProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
  /** The text, as the surface shows it. */
  text?: string;
  /** The model's tokens. If they don't spell out `text`, the text is split roughly instead. */
  tokens?: XrayLensToken[];
  /** Phrases to outline and label, e.g. extracted entities. Used when the text is split here. */
  entities?: XrayLensEntity[];
  /** Named under the glass. Defaults to the token count. */
  label?: string;
  /** The text's element. */
  as?: SpotTag;
  /** Classes for the token copy's box in the xray layer. */
  xrayClassName?: string;
}

/**
 * Text that turns into its tokens under the lens. The xray copy keeps the
 * text's classes, so it wraps exactly like the surface and each word sits
 * over itself.
 */
export function XrayLensText({
  text,
  tokens,
  entities,
  label,
  as = "p",
  className,
  xrayClassName,
  ...props
}: XrayLensTextProps) {
  const parts = toTokens(text, tokens, entities);

  // The surface: plain text, with labeled tokens as spots of their own.
  const surface: React.ReactNode[] = [];
  let run = "";
  parts.forEach((t, i) => {
    if (!t.label) {
      run += t.text;
      return;
    }
    if (run) surface.push(run);
    run = "";
    surface.push(
      <XrayLensSpot key={i} as="span" label={t.label} xray={null} xrayClassName={ENTITY_BOX}>
        {t.text}
      </XrayLensSpot>,
    );
  });
  if (run) surface.push(run);

  const copy = React.createElement(
    as,
    { className, style: COPY_STYLE },
    parts.map((t, i) => (
      <span key={i} className={t.className ?? (t.p !== undefined ? confidence(t.p) : ALTERNATE[i % 2])}>
        {t.text}
      </span>
    )),
  );

  return (
    <XrayLensSpot
      as={as}
      label={label ?? `${parts.length} tokens`}
      xray={copy}
      xrayClassName={xrayClassName}
      className={className}
      {...props}
    >
      {surface}
    </XrayLensSpot>
  );
}

/* ── The lens ───────────────────────────────────────────── */

type Options = {
  mode: "hover" | "drag";
  size: number | string;
  zoom: number;
  rest: [number, number] | null;
  autoPlay: boolean | "touch";
  reduced: boolean;
};

type Values = {
  px: MotionValue<number>;
  py: MotionValue<number>;
  sx: MotionValue<number>;
  sy: MotionValue<number>;
  radius: MotionValue<number>;
  lift: MotionValue<number>;
  flood: MotionValue<number>;
};

const INTERACTIVE = "a,button,input,select,textarea,label,summary,[role=button],[contenteditable=true]";

/**
 * Everything per frame lives here, outside React: where the lens is headed,
 * the springs that take it there, the tour and the CSS variables they write.
 */
function createLens(
  els: { root: HTMLDivElement; glass: HTMLDivElement; label: HTMLDivElement; labelText: HTMLSpanElement },
  values: Values,
  spots: Spots,
  initial: Options,
  initiallyRevealed: boolean,
) {
  const { root, glass, label, labelText } = els;
  const { px, py, sx, sy, radius, lift, flood } = values;
  let opts = initial;

  let w = root.clientWidth;
  let h = root.clientHeight;
  let d = lensSize(opts.size, w, h);
  let want = false; // whether the lens is open, or opening
  let atRest = true; // parked at `rest`, so it follows `rest` through resizes
  let hovering = false;
  let focused = false;
  let revealed = initiallyRevealed;
  let inView = false;
  let introduced = false;
  let drag: { id: number; dx: number; dy: number } | null = null;
  let press: { id: number; x: number; y: number } | null = null;
  const client = { x: 0, y: 0 };
  const hoverable = window.matchMedia("(hover: hover) and (pointer: fine)");

  let glide: AnimationPlaybackControls[] = [];
  let sizing: AnimationPlaybackControls | null = null;
  let lifting: AnimationPlaybackControls | null = null;
  let flooding: AnimationPlaybackControls | null = null;
  let shownLabel: string | undefined;
  let writtenSize = -1;

  let tourTimer = 0;
  let touring = false;
  let stop = 0;

  flood.jump(revealed ? 1 : 0);

  const R = () => d / 2;
  const restPoint = () => (opts.rest ? { x: opts.rest[0] * w, y: opts.rest[1] * h } : null);
  const lensX = () => (opts.reduced ? px : sx).get();
  const lensY = () => (opts.reduced ? py : sy).get();

  /** A client point in the frame's px, with any CSS scale divided out. */
  function local(cx: number, cy: number) {
    const rect = root.getBoundingClientRect();
    const kx = root.offsetWidth ? rect.width / root.offsetWidth : 1;
    const ky = root.offsetHeight ? rect.height / root.offsetHeight : 1;
    return { x: (cx - rect.left) / kx - root.clientLeft, y: (cy - rect.top) / ky - root.clientTop };
  }

  function place(x: number, y: number, how: "follow" | "glide" | "jump") {
    x = clamp(x, 0, w);
    y = clamp(y, 0, h);
    glide.forEach((a) => a.stop());
    glide = [];
    if (how === "jump" || opts.reduced) {
      // The source first: its change starts the spring, which the jump then cancels.
      px.jump(x);
      py.jump(y);
      sx.jump(x);
      sy.jump(y);
    } else if (how === "glide") {
      glide = [animate(px, x, LENS.glide), animate(py, y, LENS.glide)];
    } else {
      px.set(x);
      py.set(y);
    }
  }

  function open(on: boolean) {
    const to = on ? R() : 0;
    want = on;
    sizing?.stop();
    if (opts.reduced) radius.jump(to);
    else sizing = animate(radius, to, on ? LENS.open : LENS.close);
  }

  function setLift(on: boolean) {
    lifting?.stop();
    if (opts.reduced) lift.jump(0);
    else lifting = animate(lift, on ? 1 : 0, LENS.lift);
  }

  /** Opens the lens at a point, or glides it there if it's already open. */
  function openAt(x: number, y: number) {
    place(x, y, want ? "glide" : "jump");
    open(true);
  }

  function home() {
    const rest = restPoint();
    if (rest) {
      atRest = true;
      if (want) place(rest.x, rest.y, "glide");
      else openAt(rest.x, rest.y);
    } else if (!focused) {
      open(false);
    }
  }

  /* The tour: the lens visits each labeled spot while nobody's using it. */

  function tourAllowed() {
    if (opts.reduced || !inView || hovering || drag || press || focused || revealed) return false;
    return opts.autoPlay === true || (opts.autoPlay === "touch" && !hoverable.matches);
  }

  function stopTour() {
    window.clearTimeout(tourTimer);
    tourTimer = 0;
    touring = false;
  }

  function startTour(delay: number) {
    stopTour();
    if (tourAllowed()) tourTimer = window.setTimeout(tour, delay);
  }

  function tourStops() {
    const points: { x: number; y: number }[] = [];
    // Nested spots often share a center; visit each place once.
    for (const p of spots.stops()) {
      if (!points.some((q) => Math.hypot(q.x - p.x, q.y - p.y) < R() * 0.4)) points.push(p);
    }
    return points.length ? points : WANDER.map(([fx, fy]) => ({ x: fx * w, y: fy * h }));
  }

  function tour() {
    tourTimer = 0;
    if (!tourAllowed()) {
      touring = false;
      return;
    }
    const points = tourStops();
    if (touring) {
      stop = (stop + 1) % points.length;
    } else if (!want) {
      stop = 0;
      touring = true;
    } else {
      // Pick up from wherever the lens is.
      const x = lensX();
      const y = lensY();
      const away = (i: number) => Math.hypot(points[i].x - x, points[i].y - y);
      stop = points.reduce((best, _, i) => (away(i) < away(best) ? i : best), 0);
      touring = true;
    }
    atRest = false;
    openAt(points[stop].x, points[stop].y);
    tourTimer = window.setTimeout(tour, LENS.dwell);
  }

  let scheduled = false;
  function write() {
    scheduled = false;
    const x = lensX();
    const y = lensY();
    const held = lift.get();
    const f = clamp(flood.get(), 0, 1);
    const k = R() ? clamp(radius.get() / R(), 0, 1.5) : 0;
    const r = Math.max(0, radius.get()) * (1 + LENS.liftGrow * held);
    // The flood grows the mask from the lens out past the farthest corner.
    const far = Math.hypot(Math.max(x, w - x), Math.max(y, h - y)) + 2;
    // The magnification swells in with the lens, so it seems to come into focus, and settles to 1 under the flood.
    const zoom = 1 + (opts.zoom - 1 + LENS.liftZoom * held) * Math.min(k, 1) * (1 - f);
    const gx = opts.reduced ? 0 : clamp(-sx.getVelocity() * LENS.glint, -LENS.glintMax, LENS.glintMax);
    const gy = opts.reduced ? 0 : clamp(-sy.getVelocity() * LENS.glint, -LENS.glintMax, LENS.glintMax);

    const style = root.style;
    if (d !== writtenSize) {
      style.setProperty("--lens-d", `${d}px`);
      writtenSize = d;
    }
    style.setProperty("--lens-x", `${x}px`);
    style.setProperty("--lens-y", `${y}px`);
    style.setProperty("--lens-r", `${r + (far - r) * f}px`);
    style.setProperty("--lens-z", `${zoom}`);
    style.setProperty("--lens-s", `${(R() ? r / R() : 0) * (1 + 0.6 * f)}`);
    style.setProperty("--lens-o", `${1 - clamp(f * 2.5, 0, 1)}`);
    style.setProperty("--lens-lift", `${held}`);
    style.setProperty("--lens-gx", `${gx}px`);
    style.setProperty("--lens-gy", `${gy}px`);
    // Under the flood the glass is gone: it can't be grabbed or focused.
    glass.style.visibility = f > 0.6 ? "hidden" : "";

    const next = k > 0.6 && f < 0.02 ? spots.labelAt(x, y) : undefined;
    if (next !== shownLabel) {
      if (next) {
        labelText.textContent = next;
        if (!opts.reduced) animate(labelText, { opacity: [0, 1], y: [3, 0] }, { duration: 0.18, ease: "easeOut" });
      }
      label.dataset.show = next ? "true" : "false";
      shownLabel = next;
    }
    // The label hangs under the glass, or sits above it near the bottom edge.
    label.style.transform =
      y + r + LENS.labelGap + 28 > h
        ? `translate(-50%, calc(-100% - ${r + LENS.labelGap}px))`
        : `translate(-50%, ${r + LENS.labelGap}px)`;
  }
  const schedule = () => {
    if (scheduled) return;
    scheduled = true;
    frame.render(write);
  };
  const unsubscribe = [px, py, sx, sy, radius, lift, flood].map((v) => v.on("change", schedule));

  const onMove = (e: PointerEvent) => {
    client.x = e.clientX;
    client.y = e.clientY;
    if (drag) {
      if (e.pointerId !== drag.id) return;
      const p = local(e.clientX, e.clientY);
      place(p.x - drag.dx, p.y - drag.dy, "follow");
      return;
    }
    if (opts.mode !== "hover" || e.pointerType === "touch") return;
    const p = local(e.clientX, e.clientY);
    if (!hovering) {
      hovering = true;
      atRest = false;
      stopTour();
      spots.measureAll();
      window.addEventListener("scroll", onScroll, { capture: true, passive: true });
      if (!want) {
        openAt(p.x, p.y);
        return;
      }
    }
    place(p.x, p.y, "follow");
  };

  const onLeave = (e: PointerEvent) => {
    if (drag || !hovering || e.pointerType === "touch") return;
    hovering = false;
    window.removeEventListener("scroll", onScroll, { capture: true });
    if (tourAllowed()) startTour(LENS.resumeMouse);
    else home();
  };

  // The page scrolled under a still pointer: keep the lens on it.
  const onScroll = () => {
    if (!hovering) return;
    const p = local(client.x, client.y);
    place(p.x, p.y, "follow");
  };

  const onDown = (e: PointerEvent) => {
    if (e.button !== 0) return;
    // With a mouse in hover mode the lens is already under the pointer, and clicks belong to the surface.
    if (opts.mode === "hover" && e.pointerType !== "touch") return;
    stopTour();
    if (want && !revealed && glass.contains(e.target as Node)) {
      const p = local(e.clientX, e.clientY);
      e.preventDefault();
      atRest = false;
      drag = { id: e.pointerId, dx: p.x - lensX(), dy: p.y - lensY() };
      root.setPointerCapture(e.pointerId);
      setLift(true);
      return;
    }
    if ((e.target as Element).closest?.(INTERACTIVE)) return;
    // Wait for the release: a swipe that scrolls the page shouldn't move the lens.
    press = { id: e.pointerId, x: e.clientX, y: e.clientY };
  };

  const onUp = (e: PointerEvent) => {
    if (drag && e.pointerId === drag.id) {
      drag = null;
      if (root.hasPointerCapture(e.pointerId)) root.releasePointerCapture(e.pointerId);
      setLift(false);
    } else if (press && e.pointerId === press.id) {
      const tapped = e.type === "pointerup" && Math.hypot(e.clientX - press.x, e.clientY - press.y) < 10;
      press = null;
      if (tapped && !revealed) {
        const p = local(e.clientX, e.clientY);
        atRest = false;
        openAt(p.x, p.y);
      }
    }
    startTour(LENS.resume);
  };

  const onKey = (e: KeyboardEvent) => {
    const step = e.shiftKey ? LENS.stepLarge : LENS.step;
    const moves: Record<string, [number, number]> = {
      ArrowLeft: [-step, 0],
      ArrowRight: [step, 0],
      ArrowUp: [0, -step],
      ArrowDown: [0, step],
    };
    if (e.key === "Home") {
      e.preventDefault();
      const rest = restPoint() ?? { x: w / 2, y: h / 2 };
      atRest = !!opts.rest;
      place(rest.x, rest.y, "glide");
      return;
    }
    const move = moves[e.key];
    if (!move) return;
    e.preventDefault();
    atRest = false;
    place(px.get() + move[0], py.get() + move[1], "follow");
  };

  const onFocus = () => {
    focused = true;
    stopTour();
    if (!want) {
      const rest = restPoint() ?? { x: w / 2, y: h / 2 };
      openAt(rest.x, rest.y);
    }
  };

  const onBlur = () => {
    focused = false;
    if (!hovering && !drag && !opts.rest) open(false);
    startTour(LENS.resume);
  };

  const onHoverChange = () => startTour(0);

  root.addEventListener("pointermove", onMove);
  root.addEventListener("pointerleave", onLeave);
  root.addEventListener("pointerdown", onDown);
  root.addEventListener("pointerup", onUp);
  root.addEventListener("pointercancel", onUp);
  glass.addEventListener("keydown", onKey);
  glass.addEventListener("focus", onFocus);
  glass.addEventListener("blur", onBlur);
  hoverable.addEventListener("change", onHoverChange);

  const sized = new ResizeObserver(() => {
    const [ow, oh] = [w, h];
    w = root.clientWidth;
    h = root.clientHeight;
    const size = lensSize(opts.size, w, h);
    if (size !== d) {
      d = size;
      if (want) {
        sizing?.stop();
        radius.jump(R());
      }
    }
    spots.measureAll();
    const rest = restPoint();
    if (atRest && rest) place(rest.x, rest.y, "jump");
    else if (ow && oh) place((px.get() * w) / ow, (py.get() * h) / oh, "jump");
    schedule();
  });
  sized.observe(root);

  // The first time the frame is in view, the lens opens at rest. The tour runs only while it's in view.
  const seen = new IntersectionObserver(
    ([entry]) => {
      if (!entry) return;
      inView = entry.isIntersecting;
      if (!inView) {
        stopTour();
        return;
      }
      if (!introduced) {
        introduced = true;
        spots.measureAll();
        const rest = restPoint();
        if (rest && !want && !hovering) openAt(rest.x, rest.y);
      }
      if (!tourTimer && !touring) startTour(LENS.tourStart);
    },
    { threshold: 0.35 },
  );
  seen.observe(root);

  // Web fonts can move every spot without resizing anything.
  document.fonts?.ready.then(() => spots.measureAll()).catch(() => {});

  schedule();

  return {
    set(next: Options) {
      const prev = opts;
      opts = next;
      if (prev.reduced !== next.reduced) place(px.get(), py.get(), "jump");
      if (prev.size !== next.size) {
        d = lensSize(next.size, w, h);
        if (want) open(true);
      }
      const moved = prev.rest?.[0] !== next.rest?.[0] || prev.rest?.[1] !== next.rest?.[1];
      if (moved && introduced && atRest && !hovering && !drag && !touring) home();
      if (prev.autoPlay !== next.autoPlay || prev.reduced !== next.reduced) {
        if (tourAllowed()) {
          if (!touring) startTour(0);
        } else {
          stopTour();
        }
      }
      schedule();
    },
    /** Floods the xray over the whole frame, or pulls it back in to the lens. `from` is where it starts when the lens is closed. */
    reveal(on: boolean, from?: { x: number; y: number }) {
      if (on === revealed) return;
      revealed = on;
      stopTour();
      if (from && radius.get() < 1) place(from.x, from.y, "jump");
      flooding?.stop();
      if (opts.reduced) flood.jump(on ? 1 : 0);
      else flooding = animate(flood, on ? 1 : 0, LENS.flood);
      if (!on) startTour(LENS.resume);
    },
    destroy() {
      cancelFrame(write);
      stopTour();
      unsubscribe.forEach((off) => off());
      glide.forEach((a) => a.stop());
      sizing?.stop();
      lifting?.stop();
      flooding?.stop();
      root.removeEventListener("pointermove", onMove);
      root.removeEventListener("pointerleave", onLeave);
      root.removeEventListener("pointerdown", onDown);
      root.removeEventListener("pointerup", onUp);
      root.removeEventListener("pointercancel", onUp);
      glass.removeEventListener("keydown", onKey);
      glass.removeEventListener("focus", onFocus);
      glass.removeEventListener("blur", onBlur);
      hoverable.removeEventListener("change", onHoverChange);
      window.removeEventListener("scroll", onScroll, { capture: true });
      sized.disconnect();
      seen.disconnect();
    },
  };
}

type Lens = ReturnType<typeof createLens>;

const REDUCED = "(prefers-reduced-motion: reduce)";
const subscribeReduced = (onChange: () => void) => {
  const query = window.matchMedia(REDUCED);
  query.addEventListener("change", onChange);
  return () => query.removeEventListener("change", onChange);
};

/** Reduced motion, read so the server and the first client render agree. */
function useReduced() {
  return React.useSyncExternalStore(
    subscribeReduced,
    () => window.matchMedia(REDUCED).matches,
    () => false,
  );
}

/** Twelve ticks around the rim and a crosshair, like the scale on a loupe. */
function Reticle() {
  return (
    <span aria-hidden className="absolute inset-0 rounded-full opacity-70 mix-blend-difference">
      {Array.from({ length: 12 }, (_, i) => (
        <span key={i} className="absolute inset-0" style={{ transform: `rotate(${i * 30}deg)` }}>
          <span
            className={cn(
              "absolute top-1.5 left-1/2 w-px -translate-x-1/2 bg-white",
              i % 3 === 0 ? "h-2" : "h-1",
            )}
          />
        </span>
      ))}
      <span className="absolute top-1/2 left-1/2 h-px w-2 -translate-y-1/2 translate-x-1 bg-white" />
      <span className="absolute top-1/2 right-1/2 h-px w-2 -translate-x-1 -translate-y-1/2 bg-white" />
      <span className="absolute top-1/2 left-1/2 h-2 w-px -translate-x-1/2 translate-y-1 bg-white" />
      <span className="absolute bottom-1/2 left-1/2 h-2 w-px -translate-x-1/2 -translate-y-1 bg-white" />
    </span>
  );
}

export interface XrayLensProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
  /** The polished UI. It sets the frame's size. */
  surface: React.ReactNode;
  /** What's underneath, laid over the same box and shown only inside the lens. */
  xray?: React.ReactNode;
  /** `"hover"`: the lens follows the pointer. `"drag"`: it stays put until it's picked up. Touch screens always drag. */
  mode?: "hover" | "drag";
  /** Diameter of the lens: px, or a percentage of the frame's width like `"36%"`. */
  size?: number | string;
  /** Magnification inside the lens, around its center. `1` for none. */
  zoom?: number;
  /** Where the lens waits, as fractions of the frame. `false` closes it when the pointer leaves. */
  rest?: { x: number; y: number } | false;
  /** Tour the labeled spots while the frame is in view: `"touch"` on touch screens only, `true` everywhere, `false` never. */
  autoPlay?: boolean | "touch";
  /** Floods the xray over the whole frame. Leave unset to let the switch manage it. */
  revealed?: boolean;
  /** Whether the xray starts out covering the frame. */
  defaultRevealed?: boolean;
  /** Called when the switch flips the layers. */
  onRevealedChange?: (revealed: boolean) => void;
  /** Show a two-way switch that floods the xray over the whole frame. */
  toggle?: boolean;
  /** The switch's labels: the surface first, then the xray. */
  labels?: [string, string];
  /** Classes for the switch, e.g. to move it to another corner. */
  toggleClassName?: string;
  /** Draw a crosshair and rim ticks on the glass. */
  reticle?: boolean;
  /** Accessible name of the lens, which is focusable and moves with the arrow keys. */
  lensLabel?: string;
  /** Classes for the wrapper around `surface`. */
  surfaceClassName?: string;
  /** Classes for the xray layer. It defaults to a dark background, so the surface never shows through. */
  xrayClassName?: string;
  /** Classes for the glass. */
  lensClassName?: string;
  /** Classes for the label that names the spot under the lens. */
  labelClassName?: string;
}

/**
 * A loupe over a polished UI. Inside the glass the surface peels away and
 * the layer underneath shows through, lined up with what it explains.
 */
export function XrayLens({
  surface,
  xray,
  mode = "hover",
  size = 200,
  zoom = 1.06,
  rest = { x: 0.5, y: 0.5 },
  autoPlay = "touch",
  revealed,
  defaultRevealed = false,
  onRevealedChange,
  toggle = true,
  labels = ["Surface", "X-ray"],
  toggleClassName,
  reticle = true,
  lensLabel = "Inspection lens",
  surfaceClassName,
  xrayClassName,
  lensClassName,
  labelClassName,
  className,
  style,
  ...props
}: XrayLensProps) {
  const rootRef = React.useRef<HTMLDivElement>(null);
  const glassRef = React.useRef<HTMLDivElement>(null);
  const labelRef = React.useRef<HTMLDivElement>(null);
  const labelTextRef = React.useRef<HTMLSpanElement>(null);
  const lensRef = React.useRef<Lens | null>(null);
  const originRef = React.useRef<{ x: number; y: number } | undefined>(undefined);
  const [spots] = React.useState(createSpots);
  const reduced = useReduced();

  const [own, setOwn] = React.useState(defaultRevealed);
  const shown = revealed ?? own;
  // The markup starts on this side; the lens animates every flip after it.
  const [initial] = React.useState(shown);
  const shownRef = React.useRef(shown);

  const px = useMotionValue(0);
  const py = useMotionValue(0);
  const sx = useSpring(px, LENS.follow);
  const sy = useSpring(py, LENS.follow);
  const radius = useMotionValue(0);
  const lift = useMotionValue(0);
  const flood = useMotionValue(0);

  const options: Options = {
    mode,
    size,
    zoom: Math.max(1, zoom),
    rest: rest ? [clamp(rest.x, 0, 1), clamp(rest.y, 0, 1)] : null,
    autoPlay,
    reduced,
  };
  const optionsRef = React.useRef(options);
  React.useLayoutEffect(() => {
    optionsRef.current = options;
    lensRef.current?.set(options);
  });

  React.useEffect(() => {
    const root = rootRef.current;
    const glass = glassRef.current;
    const label = labelRef.current;
    const labelText = labelTextRef.current;
    if (!root || !glass || !label || !labelText) return;
    spots.connect(root);
    const lens = createLens(
      { root, glass, label, labelText },
      { px, py, sx, sy, radius, lift, flood },
      spots,
      optionsRef.current,
      shownRef.current,
    );
    lensRef.current = lens;
    return () => {
      lens.destroy();
      lensRef.current = null;
      spots.connect(null);
    };
  }, [spots, px, py, sx, sy, radius, lift, flood]);

  React.useEffect(() => {
    shownRef.current = shown;
    lensRef.current?.reveal(shown, originRef.current);
    originRef.current = undefined;
  }, [shown]);

  const choose = (next: boolean, event: React.MouseEvent<HTMLButtonElement>) => {
    if (next === shown) return;
    const root = rootRef.current;
    if (root) {
      // Flood from the button that was pressed, if the lens is closed.
      const frameRect = root.getBoundingClientRect();
      const button = event.currentTarget.getBoundingClientRect();
      const kx = root.offsetWidth ? frameRect.width / root.offsetWidth : 1;
      const ky = root.offsetHeight ? frameRect.height / root.offsetHeight : 1;
      originRef.current = {
        x: (button.left + button.width / 2 - frameRect.left) / kx - root.clientLeft,
        y: (button.top + button.height / 2 - frameRect.top) / ky - root.clientTop,
      };
    }
    if (revealed === undefined) setOwn(next);
    onRevealedChange?.(next);
  };

  const disc: React.CSSProperties = {
    width: "var(--lens-d)",
    height: "var(--lens-d)",
    left: "calc(var(--lens-d) / -2)",
    top: "calc(var(--lens-d) / -2)",
  };

  return (
    <div
      ref={rootRef}
      data-xray-lens=""
      data-revealed={shown ? "true" : "false"}
      className={cn("relative isolate", mode === "hover" && "pointer-fine:cursor-crosshair", className)}
      style={
        {
          "--lens-d": typeof size === "number" ? `${size}px` : "0px",
          "--lens-x": "0px",
          "--lens-y": "0px",
          "--lens-r": initial ? "200vmax" : "0px",
          "--lens-z": "1",
          "--lens-s": "0",
          "--lens-o": "1",
          "--lens-lift": "0",
          "--lens-gx": "0px",
          "--lens-gy": "0px",
          ...style,
        } as React.CSSProperties
      }
      {...props}
    >
      <XrayLensContext.Provider value={spots}>
        {/* Under the flood the surface can't be seen, so it can't be clicked either. */}
        <div className={cn("relative z-0 h-full", shown && "pointer-events-none", surfaceClassName)}>{surface}</div>

        {/* The xray: the same box as the surface, cut to a circle around the lens and magnified about its center. */}
        <div
          aria-hidden
          inert
          className="pointer-events-none absolute inset-0 z-[1] overflow-hidden rounded-[inherit] select-none"
          style={{
            maskImage:
              "radial-gradient(circle var(--lens-r) at var(--lens-x) var(--lens-y), #000 calc(100% - 1px), transparent 100%)",
            WebkitMaskImage:
              "radial-gradient(circle var(--lens-r) at var(--lens-x) var(--lens-y), #000 calc(100% - 1px), transparent 100%)",
          }}
        >
          <div
            className={cn("absolute inset-0 bg-zinc-950 text-zinc-100", xrayClassName)}
            style={{ transformOrigin: "var(--lens-x) var(--lens-y)", transform: "scale(var(--lens-z))" }}
          >
            {xray}
            <SpotLayer spots={spots} />
          </div>
        </div>

        {/* The glass, centered on the lens. */}
        <div
          className="pointer-events-none absolute top-0 left-0 z-[2]"
          style={{ transform: "translate3d(var(--lens-x), var(--lens-y), 0)" }}
        >
          <div
            aria-hidden
            className="absolute rounded-full shadow-[0_22px_44px_-16px_rgb(0_0_0/0.5),0_6px_14px_-6px_rgb(0_0_0/0.3)]"
            style={{
              ...disc,
              opacity: "var(--lens-o)",
              transform: `translateY(calc(var(--lens-lift) * ${LENS.liftDrop}px)) scale(var(--lens-s))`,
            }}
          />
          <div
            ref={glassRef}
            tabIndex={0}
            role="group"
            aria-roledescription="lens"
            aria-label={lensLabel}
            aria-keyshortcuts="ArrowUp ArrowDown ArrowLeft ArrowRight Home"
            className={cn(
              "absolute touch-none rounded-full ring-1 ring-black/25 outline-none focus-visible:ring-2 focus-visible:ring-sky-400 dark:ring-white/20",
              mode === "drag"
                ? "pointer-events-auto cursor-grab active:cursor-grabbing"
                : "pointer-coarse:pointer-events-auto",
              lensClassName,
            )}
            style={{ ...disc, opacity: "var(--lens-o)", transform: "scale(var(--lens-s))" }}
          >
            {/* The edge of a thick lens: a bright rim, a dark band, then a falloff toward the middle. */}
            <span className="absolute inset-0 rounded-full shadow-[inset_0_0_0_1px_rgb(255_255_255/0.55),inset_0_0_0_3px_rgb(0_0_0/0.3),inset_0_0_26px_rgb(0_0_0/0.45)]" />
            {/* A trace of color fringing just inside the rim. */}
            <span className="absolute inset-[3px] rounded-full shadow-[inset_1.5px_1px_0_rgb(56_189_248/0.3),inset_-1.5px_-1px_0_rgb(244_114_182/0.25)]" />
            <span className="absolute inset-0 rounded-full bg-[linear-gradient(155deg,rgb(255_255_255/0.16),rgb(255_255_255/0)_38%,rgb(255_255_255/0)_72%,rgb(255_255_255/0.06))]" />
            <span
              className="absolute top-[9%] left-[16%] h-[12%] w-[36%]"
              style={{ transform: "translate(var(--lens-gx), var(--lens-gy))" }}
            >
              <span className="block size-full -rotate-[32deg] rounded-full bg-[radial-gradient(closest-side,rgb(255_255_255/0.55),rgb(255_255_255/0))]" />
            </span>
            {reticle && <Reticle />}
          </div>
          <div
            ref={labelRef}
            aria-hidden
            data-show="false"
            className={cn(
              "absolute top-0 left-0 flex items-center gap-1.5 rounded-full bg-zinc-950/90 px-2.5 py-1 font-mono text-[11px] leading-4 font-medium whitespace-nowrap text-white opacity-0 shadow-lg ring-1 ring-white/10 backdrop-blur-sm transition-opacity duration-200 data-[show=true]:opacity-100",
              labelClassName,
            )}
          >
            <span className="size-1.5 rounded-full bg-emerald-400" />
            <span ref={labelTextRef} />
          </div>
        </div>

        {toggle && (
          <div
            role="group"
            aria-label="Layers"
            className={cn(
              "absolute right-3 bottom-3 z-[3] grid cursor-default grid-cols-2 rounded-full bg-zinc-950/80 p-1 text-xs font-medium text-white shadow-lg ring-1 ring-white/15 backdrop-blur-md",
              toggleClassName,
            )}
          >
            <span
              aria-hidden
              className={cn(
                "absolute inset-y-1 left-1 w-[calc(50%-0.25rem)] rounded-full bg-white shadow-sm transition-transform duration-300 ease-[cubic-bezier(0.2,0.8,0.2,1)] motion-reduce:transition-none",
                shown && "translate-x-full",
              )}
            />
            {labels.map((text, i) => {
              const active = shown === (i === 1);
              return (
                <button
                  key={i}
                  type="button"
                  aria-pressed={active}
                  onClick={(event) => choose(i === 1, event)}
                  className={cn(
                    "relative cursor-pointer rounded-full px-3 py-1.5 whitespace-nowrap transition-colors duration-200 outline-none focus-visible:ring-2 focus-visible:ring-white/70",
                    active ? "text-zinc-950" : "text-white/75 hover:text-white",
                  )}
                >
                  {text}
                </button>
              );
            })}
          </div>
        )}
      </XrayLensContext.Provider>
    </div>
  );
}
```
