Proof Rail
A free animated stats rail with a one-shot social-proof trace.
- Uptime
- 99.99%Trailing 12 months
- Deploys
- 42kShipped this week
- Median latency
- 84msGlobal edge
- Product teams
- 1,200+Across 38 countries
Customise
Code
<StatProofRail
ariaLabel="Platform results"
metrics={[
{ id: "uptime", value: "99.99%", label: "Uptime", detail: "Trailing 12 months" },
{ id: "deploys", value: "42k", label: "Deploys", detail: "Shipped this week" },
{ id: "latency", value: "84ms", label: "Median latency", detail: "Global edge" },
{ id: "teams", value: "1,200+", label: "Product teams", detail: "Across 38 countries" },
]}
/>Proof Rail is a free stats component for Next.js and React, styled with Tailwind as a compact social-proof metrics section. Every value remains a static, readable string while a one-shot CSS trace and staggered reveal connect the evidence on first viewport entry.
The server HTML contains every final value, label and detail, so crawlers, no-JavaScript visitors and reduced-motion users receive the complete rail immediately. Desktop uses one shared trace, mobile uses ordered connector segments, and neither animation path counts numbers or measures layout. Sizing is the one deliberate exception: to fit values to real glyph ink rather than an estimate, the rail runs a single bounded measurement pass per mount, font settle, size change and font-affecting className change, and publishes nothing when the reading is unchanged.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/stat-proof-railUsage
import { StatProofRail } from "@/components/stat-proof-rail";
const metrics = [
{
id: "uptime",
value: "99.99%",
label: "Uptime",
detail: "Trailing 12 months",
},
{
id: "deploys",
value: "42k",
label: "Deploys",
detail: "Shipped this week",
},
{
id: "latency",
value: "84ms",
label: "Median latency",
detail: "Global edge",
},
{
id: "teams",
value: "1,200+",
label: "Product teams",
detail: "Across 38 countries",
},
];
export default function PlatformProof() {
return (
<StatProofRail
ariaLabel="Platform results"
metrics={metrics}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| metrics | ProofRailMetric[] | required | Three to six final string values rendered in reading and trace order. |
| direction | "forward" | "reverse" | "forward" | Changes the trace direction and stagger order without changing DOM or visual metric order. |
| traceDuration | number | 1.2 | Trace duration in seconds. Finite values clamp from 0.6 to 2.4 and non-finite values fall back to 1.2. |
| ariaLabel | string | "Company results" | Accessible name for the otherwise headingless region. |
| className | string | undefined | Additional classes merged onto the section root. |
Customisation
Proof Rail exposes Tier 3 variables for its structural rail, travelling trace, markers and surface. Use direction and traceDuration to tune the real one-shot effect while leaving the static evidence unchanged.
<StatProofRail
ariaLabel="Platform results"
metrics={metrics}
direction="reverse"
traceDuration={1.8}
/>
:root {
--proof-rail: var(--border);
--proof-trace: var(--primary);
--proof-marker: var(--primary);
--proof-surface: var(--background);
}Frequently asked questions
- Is Proof Rail free for commercial use?
- Yes. Proof Rail is MIT licensed, so you can use it in personal and commercial projects without attribution.
- Is Proof Rail performant and reduced-motion safe?
- Yes. CSS animates only transforms and opacity after a 30 percent viewport entry, and pauses while the page is hidden. Reduced motion, server rendering and no-JavaScript paths keep every final string and the complete rail visible without animation.
- Do values fit their columns without JavaScript?
- Yes, within an honest limit. The server render sizes every value from a script-aware estimate: East Asian wide glyphs count at their full width and uppercase Latin letters count wider than lowercase, and in columns too narrow for the minimum display size both estimates shrink their values below it rather than clip, so localised and all-caps values stay whole before any JavaScript runs. An estimate cannot know real glyph ink, so all-caps values may render slightly below their ideal size and mixed pathological strings may still need hydration for a perfect fit in the narrowest rails. After hydration every value is re-fit from measured ink, and the rail re-measures whenever its size changes or a className change swaps the inherited font.
- How do I customise the proof trace?
- Set direction to forward or reverse and use traceDuration between 0.6 and 2.4 seconds. Override the proof-rail, proof-trace, proof-marker and proof-surface variables on an ancestor to retheme the rail.