Skip to content
Dethink Components

ComponentsScanGridBackground

ScanGridBackground

Move a highlight across a grid background.

On this page

Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.

View registry files

Import the component into your page or component file.

Usage
import { ScanGridBackground } from "@dethink/components";

Try the examples, then open the code to use them in your app. The background fills its container; these previews bound it with a height utility.

Hero composition

The default composition: hero copy and actions render in the content slot above the animated layer, which never intercepts pointer events.

Live status

Watch every deploy as it happens

Observability surfaces that read as continuously monitored — the scan band sweeps the grid on a calm, linear loop.

Show sourceexamples/scan-grid-background/basic.tsx
examples/scan-grid-background/basic.tsx
"use client";

import { Badge, Button, ScanGridBackground } from "@dethink/components";

export function ScanGridBackgroundBasic() {
  return (
    <ScanGridBackground
      className="border-border h-[24rem] rounded-lg border"
      tone="primary"
    >
      <div className="flex h-[24rem] flex-col items-center justify-center gap-4 px-6 text-center">
        <Badge tone="primary" variant="soft">
          Live status
        </Badge>
        <h2 className="text-foreground max-w-xl text-3xl font-semibold tracking-tight">
          Watch every deploy as it happens
        </h2>
        <p className="text-muted-foreground max-w-md text-sm leading-6">
          Observability surfaces that read as continuously monitored — the scan
          band sweeps the grid on a calm, linear loop.
        </p>
        <div className="flex gap-3">
          <Button>Start monitoring</Button>
          <Button variant="outline">View docs</Button>
        </div>
      </div>
    </ScanGridBackground>
  );
}

Directions, density, and speed

direction switches the sweep axis; every other visual axis is a literal token-backed variant.

direction="vertical" · fast
direction="horizontal" · dense · bold · slow
Show sourceexamples/scan-grid-background/directions.tsx
examples/scan-grid-background/directions.tsx
"use client";

import { ScanGridBackground } from "@dethink/components";

export function ScanGridBackgroundDirections() {
  return (
    <div className="grid gap-4 sm:grid-cols-2">
      <ScanGridBackground
        className="border-border h-48 rounded-lg border"
        speed="fast"
        tone="primary"
      >
        <div className="flex h-48 items-end p-4">
          <span className="text-muted-foreground text-xs font-medium">
            direction=&quot;vertical&quot; · fast
          </span>
        </div>
      </ScanGridBackground>
      <ScanGridBackground
        className="border-border h-48 rounded-lg border"
        density="dense"
        direction="horizontal"
        intensity="bold"
        speed="slow"
        tone="foreground"
      >
        <div className="flex h-48 items-end p-4">
          <span className="text-muted-foreground text-xs font-medium">
            direction=&quot;horizontal&quot; · dense · bold · slow
          </span>
        </div>
      </ScanGridBackground>
    </div>
  );
}

Static frame

animate={false} — and any user with a reduced-motion preference — gets this composition: no loops mounted, still designed.

Designed at rest

animate={false} renders the same frame reduced-motion users see: the band frozen at a seeded position, no loops mounted.

Show sourceexamples/scan-grid-background/static.tsx
examples/scan-grid-background/static.tsx
"use client";

import { ScanGridBackground } from "@dethink/components";

export function ScanGridBackgroundStatic() {
  return (
    <ScanGridBackground
      animate={false}
      className="border-border h-56 rounded-lg border"
      tone="primary"
    >
      <div className="flex h-56 flex-col items-center justify-center gap-2 px-6 text-center">
        <h3 className="text-foreground text-xl font-semibold">
          Designed at rest
        </h3>
        <p className="text-muted-foreground max-w-sm text-sm leading-6">
          animate={"{false}"} renders the same frame reduced-motion users see:
          the band frozen at a seeded position, no loops mounted.
        </p>
      </div>
    </ScanGridBackground>
  );
}

ScanGridBackground accepts div props plus the shared background contract — animate, density, intensity, speed, tone, seed — and its own direction axis.

ScanGridBackground props
PropWhat it doesDefault
animatebooleanSet to false to force the static composition regardless of OS motion preference: the band frozen at its seeded position at reduced opacity, with no animation loops mounted.true
direction"vertical" | "horizontal"Sweep axis for the scan band. Vertical sweeps top to bottom; horizontal sweeps left to right. Reflected as data-direction for CSS targeting."vertical"
density"sparse" | "normal" | "dense"Grid cell size (96/56/32px). Denser grids read as more technical; the band lights more lines per sweep."normal"
intensity"faint" | "subtle" | "bold"Opacity tier for the grid pattern. Keep faint or subtle under body copy; bold is for short hero statements."subtle"
speed"slow" | "normal" | "fast"Sweep duration and pause between sweeps (12s/2.5s, 8s/1.5s, 5s/0.75s). Loops pause automatically while the background is offscreen."normal"
tone"foreground" | "muted" | "primary"Semantic token driving the grid and band color via currentColor, so light and dark mode adapt automatically."muted"
seednumberDrives the sweep's start delay and the frozen band position deterministically, so markup is SSR-stable across server and client renders.1
childrenReactNodeHero content rendered in the content slot above the aria-hidden decorative layer. The layer is pointer-events-none, so children stay fully interactive.Not set
getScanGridBackgroundMotionConfig / getScanGridBackgroundGeometry / *ClassNames helpers(speed, reducedMotion) => config, (seed) => geometry, ({ className }) => stringOpen-code escape hatches: read the resolved sweep transition, reuse the seeded delay and frozen offset, or apply the root, layer, and content class recipes to custom elements.Not set