Skip to content

Weave Grid

rdloom's signature backdrop: warp and weft threads crossing in a woven grid, with an ember shuttle that passes through slowly.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

Warp and weft

An ember shuttle passes through

import { WeaveGrid } from "@rdloom/react";

export default function WeaveGridBasic() {
  return (
    <div className="flex w-full justify-center">
      <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
        <WeaveGrid />
        <div className="relative text-center">
          <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Warp and weft</p>
          <p className="text-base text-[var(--rd-color-text-muted)]">An ember shuttle passes through</p>
        </div>
      </div>
    </div>
  );
}

Installation

npx rdloom add weave-grid

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/weave-grid.json

Works, but without upgrade tracking, and you import the motion CSS yourself.

Usage

import { WeaveGrid } from "@rdloom/react";

<div className="flex w-full justify-center">
  <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
    <WeaveGrid />
    <div className="relative text-center">
      <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Warp and weft</p>
      <p className="text-base text-[var(--rd-color-text-muted)]">An ember shuttle passes through</p>
    </div>
  </div>
</div>

Faded

Edge to edge

No fade at the sides

import { WeaveGrid } from "@rdloom/react";

export default function WeaveGridFaded() {
  return (
    <div className="flex w-full justify-center">
      <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
        <WeaveGrid size={32} fade={false} />
        <div className="relative text-center">
          <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Edge to edge</p>
          <p className="text-base text-[var(--rd-color-text-muted)]">No fade at the sides</p>
        </div>
      </div>
    </div>
  );
}

Still

Held still

The shuttle stays out

import { WeaveGrid } from "@rdloom/react";

export default function WeaveGridStill() {
  return (
    <div className="flex w-full justify-center">
      <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
        <WeaveGrid isStill />
        <div className="relative text-center">
          <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Held still</p>
          <p className="text-base text-[var(--rd-color-text-muted)]">The shuttle stays out</p>
        </div>
      </div>
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
size

Distance between threads in pixels.

number24
warpColor

Colour of the vertical warp threads.

string"color-mix(in srgb, var(--rd-color-text-default) 16%, transparent)"
weftColor

Colour of the horizontal weft threads.

string"color-mix(in srgb, var(--rd-color-text-default) 16%, transparent)"
accent

Colour of the shuttle pass. Defaults to the ember token.

string"var(--rd-color-ember-500)"
fade

Fades the weave out toward its edges.

booleantrue
duration

Seconds one shuttle pass takes.

number9
isStill

Stops all movement. Moving content should be stoppable.

booleanfalse

Accessibility

Role presentation, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Ignored: it is not announced

What your code must do

  • Pure decoration: aria-hidden, never focusable, and pointer-events none so content on top stays usable
  • Drawn with CSS only, so it needs no JavaScript and is safe in server HTML
  • The shuttle is a soft band that crosses slowly, never a flash
  • Stands still for visitors who ask for less motion (prefers-reduced-motion), with isStill, and inside an rdm-still container
  • Nothing flashes more than 3 times a second (WCAG 2.3.1) and moving content can be stopped (WCAG 2.2.2)
  • Hidden in forced-colors (high contrast) mode so it never fights system colours
  • Keep text on top at 4.5:1 against the effect: use a low-contrast colour

Guidelines

Use it when

  • Branded hero sections and empty states
  • A signature backdrop for rdloom-styled pages

Avoid it when

  • Behind long text
  • Next to other animated backgrounds

Don't

  • A strong thread colour that competes with content
  • Running more than one WeaveGrid in view

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-border-default