ComponentsPhysics
Breathing text
Weight breathes in and out over time.
Installation
$ npx shadcn@latest add @textlab/breathing-textNeeds @textlab in your components.json. Setup takes a minute.
Usage
usage.tsx
import { BreathingText } from "@/components/textlab/breathing-text/breathing-text";
<BreathingText as="h2" text="Inhale, exhale" />Variants
breatheheartbeatProps
| Prop | Type | Default | Description |
|---|---|---|---|
| text* | string | – | The copy. |
| variant | "breathe" | "heartbeat" | "breathe" | A slow swell through the word, or a double thump and rest. |
| from | number | 250 | Weight at rest. |
| to | number | 800 | Weight at the peak. |
| speed | number | 3.6 | Seconds per breath. |
| font | string | var(--tl-font-flex) | A variable font with a weight axis. |
| as | ElementType | "span" | Rendered element. |
| reducedMotion | "user" | "always" | "never" | "user" | user follows the OS setting; always shows the still version. |
| className | string | – | Merged onto the root. |
When to use it
Reach for it
- Meditation, health and calm brands.
- Idle and waiting states that should feel alive, not busy.
Skip it
- Fonts without a weight axis.
- Layouts where width changes would push neighbours.
Accessibility and motion
Accessibility
- Letters are aria-hidden; the text is read once.
- Slow and continuous, with no flashing.
Motion
- The breath travels through the word 90 ms per letter.
- Heartbeat thumps twice in the first 40% of each cycle, then rests.
Reduced motion. A still word at a medium weight.
Performance
- A registered CSS property drives font-variation-settings; text reflows within the line each frame, so use it on short words.