Hallmarks
A trusted-by logo cloud section in three variants: a marquee belt composed from Frieze, a grid whose logos ignite from ghost to full contrast in a seeded stamp-landing scatter on scroll-in, and a relay row where one slot at a time plate-flips to a logo not currently shown. Marks sit grayscale and dimmed at rest, lift to full contrast on hover, and are height-normalized; eyebrow/heading framing included. Renders as a static full-contrast grid under reduced motion.
The preview is live. The source is Pro.
One purchase, lifetime access: every pro component's source, CLI install with your own registry token, and all future drops.
Installation
CLI
npx shadcn@latest add @crucible/hallmarksManual — install dependencies, then copy the source
npm install motionProps
| Prop | Type | Default | Description |
|---|---|---|---|
| logos | HallmarkLogo[] | eight brand-free placeholder wordmarks | Marks on the wall. |
| variant | "grid" | "marquee" | "relay" | "grid" | Display mode. grid ignites marks from ghost to full contrast in a seeded scatter on scroll-in; marquee composes the Frieze belt inside the section frame; relay shows a fixed row where one slot at a time plate-flips to a different logo. |
| eyebrow | React.ReactNode | "Trusted by" | Small uppercase kicker above the heading. Pass null/empty to omit. |
| heading | React.ReactNode | Optional heading rendered as an h2 beneath the eyebrow. Omitted by default. | |
| frieze | Omit<FriezeProps, "children"> | Passthrough props for the composed Frieze belt (marquee variant only). | |
| pattern | "scatter" | "sweep" | "scatter" | Grid ignition order: seeded scatter or a plain left-to-right sweep. |
| stagger | number | 0.06 | Seconds between consecutive grid ignitions. |
| threshold | number | 0.35 | IntersectionObserver threshold that triggers the grid ignition. |
| interval | number | 2400 | Milliseconds between relay plate-flips (clamped to ≥ 600). |
| slots | number | 5 | Visible slots in the relay row (clamped to the logo count). |
| restOpacity | number | 0.55 | Resting opacity of each mark before hover lifts it to full. |
| grayscale | number | 1 | Grayscale amount applied to marks at rest, 0–1. |
| gap | number | 48 | Gap between marks, in pixels (also forwarded to Frieze in marquee mode). |
| logoHeight | number | 28 | Normalized mark height in pixels — SVGs and images scale to this. |
| seed | number | 7 | Seed for the scatter ignition order and the relay slot rotation. |
| colors | string[] | ["rgba(255,255,255,0.5)"] | Accent palette; colors[0] tints the eyebrow kicker. |
| paused | boolean | false | Freeze all choreography: settled grid, halted belt, suspended relay. |
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"section">, "children"> — they pass through to the underlying element. | |||
Honors prefers-reduced-motion with a designed static fallback, and passes className through.