Noise Gate

Before and After Section for React

A before-and-after section. Alerts, pings and complaints drift into the seam between two panels and slide under the calm one, and each card that goes through lights the seam and ticks a counter, or lands as a tidy line in a log.

  • Section
  • Comparison
  • Counter
  • Marketing

Uses motion, clsx, tailwind-merge

Inspired by Cloudflare

Open in ChatGPTOpen in Claude
display
density9
duration15s
bob3px
settle0.32s
rollDuration0.42s
<NoiseGate />

The demo follows as you drag.

Answering tickets with “canned replies”
Answering with Harbor
Resolved 1,284 tickets today
Take this demo to your coding agent.
Add this moment from KeyframeUI to our project and adapt it to our content.

Noise Gate: A before-and-after section. Alerts, pings and complaints drift into the seam between two panels and slide under the calm one, and each card that goes through lights the seam and ticks a counter, or lands as a tidy line in a log.
This demo, Support Inbox: A help desk's pitch. Overdue tickets, angry follow-ups and a refund that fired three times drift into the seam, and every one that goes through ticks Harbor's resolved count. Point at the noise to stop it and read a card.

1. Install it:
   npx shadcn@latest add @keyframeui/noise-gate-demo
   (If the CLI can't find @keyframeui, use https://keyframeui.com/r/noise-gate-demo.json instead.)
   It adds the demo, components/noise-gate-demo.tsx, and the component, components/ui/noise-gate.tsx.

2. Make it ours: our copy, data, images and colors. Keep the structure the motion depends on. If we only need the effect, use <NoiseGate> on its own.

3. These props set its feel. Change them before you change the file:
   - display (default "count"): What the calm side shows on its horizon: a pill with a counter, or a log in which each card that goes through becomes its `resolved` line, newest on top.
   - density (default 9): Most cards on screen at once. Fewer show when the panel is small, so it never turns into a wall.
   - duration (default 15): Seconds a mid-depth card takes to cross the noise panel. Far cards are slower and near ones quicker.
   - bob (default 3): How far each card floats across its lane as it drifts, in px. `0` keeps every card on a straight line.
   - settle (default 0.32): How quickly the stream eases to a stop under the pointer (or with `paused`) and gets going again, as a time constant in seconds. Smaller stops more sharply.
   - rollDuration (default 0.42): Seconds the counter's changed digits take to roll in when a card reaches the gate.

4. Don't change, in components/ui/noise-gate.tsx:
   - One rAF loop moves every card by writing `transform` and `opacity` straight to the DOM and redraws the traces; the stream never re-renders, and the loop sleeps when stopped or off screen.
   - Arrivals are scheduled: each new card starts where it reaches the seam about one beat after the card before it, give or take the jitter, so ticks keep a rhythm instead of bunching.
   - Hover and `paused` ease the whole stream to a stop through one shared factor, never a snap, and the card under the pointer comes forward on top of the rest.
   - Digits are keyed from the right and roll in `popLayout`, so a new leading digit doesn't re-roll the rest; the count reads from an `sr-only` span while the moving parts are `aria-hidden`.
   - Reduced motion shows a seeded, still scatter of cards and traces: no stream and no ticks.
   Its timing is all in the TIMING block at the top of that file.

Docs: https://keyframeui.com/components/noise-gate.md

Installation

Add the component on its own with the CLI, or copy the file in by hand.

The CLI writes components/ui/noise-gate.tsx and installs motion, clsx and tailwind-merge. It needs the @keyframeui registry in components.json; add it once per project.

npx shadcn@latest add @keyframeui/noise-gate

Examples

Finished sections built with Noise Gate. Each one installs whole, with the component included.

Month-End Close

The log display. Missing receipts, a duplicate AWS charge and a spreadsheet four people are editing go through the gate and come out as reconciled lines with their amounts, newest on top.

Closing the books with “one more spreadsheet”
Closing with Ledgerline
  • FX revalued9 invoices
  • Payroll accrued$64,210.00
  • Bank feed categorized312 lines

October closed on the 2nd.

Take this demo to your coding agent.
Add this moment from KeyframeUI to our project and adapt it to our content.

Noise Gate: A before-and-after section. Alerts, pings and complaints drift into the seam between two panels and slide under the calm one, and each card that goes through lights the seam and ticks a counter, or lands as a tidy line in a log.
This demo, Month-End Close: The log display. Missing receipts, a duplicate AWS charge and a spreadsheet four people are editing go through the gate and come out as reconciled lines with their amounts, newest on top.

1. Install it:
   npx shadcn@latest add @keyframeui/noise-gate-ledger-demo
   (If the CLI can't find @keyframeui, use https://keyframeui.com/r/noise-gate-ledger-demo.json instead.)
   It adds the demo, components/noise-gate-ledger-demo.tsx, and the component, components/ui/noise-gate.tsx.

2. Make it ours: our copy, data, images and colors. Keep the structure the motion depends on. If we only need the effect, use <NoiseGate> on its own.

3. These props set its feel. Change them before you change the file:
   - display (default "count"): What the calm side shows on its horizon: a pill with a counter, or a log in which each card that goes through becomes its `resolved` line, newest on top.
   - density (default 9): Most cards on screen at once. Fewer show when the panel is small, so it never turns into a wall.
   - duration (default 15): Seconds a mid-depth card takes to cross the noise panel. Far cards are slower and near ones quicker.
   - bob (default 3): How far each card floats across its lane as it drifts, in px. `0` keeps every card on a straight line.
   - settle (default 0.32): How quickly the stream eases to a stop under the pointer (or with `paused`) and gets going again, as a time constant in seconds. Smaller stops more sharply.
   - rollDuration (default 0.42): Seconds the counter's changed digits take to roll in when a card reaches the gate.

4. Don't change, in components/ui/noise-gate.tsx:
   - One rAF loop moves every card by writing `transform` and `opacity` straight to the DOM and redraws the traces; the stream never re-renders, and the loop sleeps when stopped or off screen.
   - Arrivals are scheduled: each new card starts where it reaches the seam about one beat after the card before it, give or take the jitter, so ticks keep a rhythm instead of bunching.
   - Hover and `paused` ease the whole stream to a stop through one shared factor, never a snap, and the card under the pointer comes forward on top of the rest.
   - Digits are keyed from the right and roll in `popLayout`, so a new leading digit doesn't re-roll the rest; the count reads from an `sr-only` span while the moving parts are `aria-hidden`.
   - Reduced motion shows a seeded, still scatter of cards and traces: no stream and no ticks.
   Its timing is all in the TIMING block at the top of that file.

Docs: https://keyframeui.com/components/noise-gate.md

Focus Section

A whole landing section: heading, subhead, and a calmer, slower gate with a call to action pinned under the counter. The calm panel is ink in light mode and turns white in dark mode.

Your attention, back.

Quietly holds pings, threads and invites until they matter, then hands you one calm digest.

Getting work done with “do not disturb”
Focusing with Quietly
Held back 312 pings today
Take this demo to your coding agent.
Add this moment from KeyframeUI to our project and adapt it to our content.

Noise Gate: A before-and-after section. Alerts, pings and complaints drift into the seam between two panels and slide under the calm one, and each card that goes through lights the seam and ticks a counter, or lands as a tidy line in a log.
This demo, Focus Section: A whole landing section: heading, subhead, and a calmer, slower gate with a call to action pinned under the counter. The calm panel is ink in light mode and turns white in dark mode.

1. Install it:
   npx shadcn@latest add @keyframeui/noise-gate-focus-demo
   (If the CLI can't find @keyframeui, use https://keyframeui.com/r/noise-gate-focus-demo.json instead.)
   It adds the demo, components/noise-gate-focus-demo.tsx, and the component, components/ui/noise-gate.tsx.

2. Make it ours: our copy, data, images and colors. Keep the structure the motion depends on. If we only need the effect, use <NoiseGate> on its own.

3. These props set its feel. Change them before you change the file:
   - display (default "count"): What the calm side shows on its horizon: a pill with a counter, or a log in which each card that goes through becomes its `resolved` line, newest on top.
   - density (default 9): Most cards on screen at once. Fewer show when the panel is small, so it never turns into a wall.
   - duration (default 15): Seconds a mid-depth card takes to cross the noise panel. Far cards are slower and near ones quicker.
   - bob (default 3): How far each card floats across its lane as it drifts, in px. `0` keeps every card on a straight line.
   - settle (default 0.32): How quickly the stream eases to a stop under the pointer (or with `paused`) and gets going again, as a time constant in seconds. Smaller stops more sharply.
   - rollDuration (default 0.42): Seconds the counter's changed digits take to roll in when a card reaches the gate.

4. Don't change, in components/ui/noise-gate.tsx:
   - One rAF loop moves every card by writing `transform` and `opacity` straight to the DOM and redraws the traces; the stream never re-renders, and the loop sleeps when stopped or off screen.
   - Arrivals are scheduled: each new card starts where it reaches the seam about one beat after the card before it, give or take the jitter, so ticks keep a rhythm instead of bunching.
   - Hover and `paused` ease the whole stream to a stop through one shared factor, never a snap, and the card under the pointer comes forward on top of the rest.
   - Digits are keyed from the right and roll in `popLayout`, so a new leading digit doesn't re-roll the rest; the count reads from an `sr-only` span while the moving parts are `aria-hidden`.
   - Reduced motion shows a seeded, still scatter of cards and traces: no stream and no ticks.
   Its timing is all in the TIMING block at the top of that file.

Docs: https://keyframeui.com/components/noise-gate.md

Props

items Required

TypeNoiseGateItem[]

The cards that drift into the gate, cycled in order. Each card is rendered once and reused, so 8 to 12 give enough variety. Their fields are listed below as item.*.

noiseTitle Required

TypeReact.ReactNode

Heading of the noise side. Cards stay below it, so it's never covered. Quoting the old way works well: Answering tickets with “canned replies”.

calmTitle Required

TypeReact.ReactNode

Heading of the calm side, on the same line as the noise heading.

display

Type"count" | "log"Default"count"

What the calm side shows on its horizon: a pill with a counter, or a log in which each card that goes through becomes its resolved line, newest on top.

count

TypenumberDefault0

The counter's starting value. Each card adds its weight when it reaches the gate.

countPrefix

TypeReact.ReactNode

Text before the number in the pill, e.g. "Resolved".

countSuffix

TypeReact.ReactNode

Text after the number, e.g. "tickets today". Screen readers get the whole line, without the rolling digits.

calmFooter

TypeReact.ReactNode

Pinned to the bottom of the calm side: a call to action or a footnote.

density

TypenumberDefault9

Most cards on screen at once. Fewer show when the panel is small, so it never turns into a wall.

duration

TypenumberDefault15

Seconds a mid-depth card takes to cross the noise panel. Far cards are slower and near ones quicker.

bob

TypenumberDefault3

How far each card floats across its lane as it drifts, in px. 0 keeps every card on a straight line.

settle

TypenumberDefault0.32

How quickly the stream eases to a stop under the pointer (or with paused) and gets going again, as a time constant in seconds. Smaller stops more sharply.

rollDuration

TypenumberDefault0.42

Seconds the counter's changed digits take to roll in when a card reaches the gate.

paused

TypebooleanDefaultfalse

Eases the stream to a stop. It also stops while a mouse is over the noise, so a card can be read, and the card under the pointer comes forward.

titleAs

Type"h2" | "h3" | "h4" | "p"Default"h3"

Element for both headings.

height

TypestringDefault"28rem"

Height while the panels sit side by side. Below a 40rem container they stack, and each panel sizes itself.

className

Typestring

Classes for the root, e.g. a max width. Set [--noise-gate-radius:0px] for square corners.

noiseClassName

TypestringDefault"bg-white dark:bg-zinc-950"

Classes for the noise panel.

calmClassName

TypestringDefault"bg-[#3245ff] text-white"

Classes for the calm panel: its background and text color. The pill, the dotted horizon, the seam light and the dots are all drawn in its text color.

item.title Required

TypeReact.ReactNode

NoiseGateItem: the card's main line, up to two lines.

item.detail

TypeReact.ReactNode

NoiseGateItem: a smaller, muted second line.

item.tag

TypeReact.ReactNode

NoiseGateItem: a short label in a pill before the title, e.g. "SLA" or "Overdue".

item.tone

Type"critical" | "warning" | "neutral"Default"neutral"

NoiseGateItem: colors the tag and the icon.

item.icon

TypeReact.ReactNode

NoiseGateItem: a leading icon or avatar, about 20px. SVG icons take the tone's color.

item.mono

TypebooleanDefaultfalse

NoiseGateItem: sets the title in monospace, for log lines, file names and codes.

item.repeat

TypenumberDefault1

NoiseGateItem: stacks up to 4 copies behind the card, like an alert that keeps firing, with a ×n count.

item.weight

TypenumberDefault1

NoiseGateItem: how much the counter goes up when this card reaches the gate.

item.resolved

TypeReact.ReactNode

NoiseGateItem: with display="log", the line this card becomes once it's through. Falls back to title.

item.resolvedDetail

TypeReact.ReactNode

NoiseGateItem: with display="log", a right-aligned value beside resolved, in tabular figures.