Docs Block Reference Kinetic Block

Kinetic Block

Animated "kinetic poster" typography. Turns 1-4 short lines of text into a dramatic, motion-design title sequence — letters and lines animate in, hold, and animate out on a shared timeline.

Type: kinetic


When to use

USE for: hero / opening titles, taglines, manifesto statements (1-4 declarative lines), section dividers, short pull-quotes, animated logotypes.

DO NOT use for: body paragraphs, lists, long sentences, prices/data, anything over 4 lines or ~4 words per line. There is no auto-chunker — the block animates exactly the lines you give it.

Strip terminal punctuation. Prefer ALL CAPS or Title Case for heroes.


Two authoring modes

A kinetic block has a Mode toggle:

  • Composition (default) — pick a numbered preset from the catalog and type your lines into one textarea. The preset decides each line's motion/timing. Three composable layers (Hierarchy, Reveal, Accent) refine the look. Fastest path.
  • Per-Line — author each line independently: per line you set text, motion, size (px), font, weight. Maximum control. Use when a preset is close but a specific line needs a different motion/size/font.
  • Most generation should use Composition mode. Reach for Per-Line when the design calls for mixed fonts/sizes per line.


    Settings reference (keys for generation)

    | key | type | default | applies | notes | |---|---|---|---|---| | composition | enum (see catalog) | block-slam | Composition mode | the preset key | | tier | hero / label / equal | hero | scene comps | size hierarchy (see Hierarchy) | | reveal | none / iris / wipe / slit | none | all | stage-level entry mask | | accent | none/slash/backslash/brackets/frame/numeral | none | scene comps | poster overlay | | accent_text | string | "" | accent=numeral | the big background number, e.g. 2024 | | custom_mode | 1/0 | 0 | — | 1 = Per-Line mode | | custom_lines | JSON array | [] | Per-Line | per-line entries (see schema) | | color | hex | #ffffff | all | block text color (single color, no gradient by design) | | loop | 1/0 | 1 | all | replay continuously | | speed | 0.25–3 | 1 | all | timing multiplier | | intensity | 0.5–2 | 1 | all | motion-amplitude multiplier | | height_mode | auto/fixed/vh/fit | auto | scene comps only | a TEXT composition hugs its type and the control is hidden: the space around it belongs to the section, which has its own height and padding. Scene comps paint an absolute stage and add no flow height, so they keep it | | height | px | 400 | height_mode=fixed | acts as a FLOOR, not a cage: the block grows past it rather than cropping | | height_vh | 10-100 | 100 | height_mode=vh | viewport height, so 100 really is a full screen | | as_background | 1/0 | 0 | all | fill the whole SECTION behind the other content, taking no flow space. Height is ignored | | comp_font | px, 0-200 | 0 | Composition | type size in PIXELS. 0 = auto-fit. Replaces the old 1-10 comp_size, which multiplied a viewport-derived base and so meant a different size on every screen. comp_size / comp_scale are still honoured on blocks that carry them | | kinetic_font | font key | system | Composition | family. Per-Line carries a font per line, so this is hidden there | | kinetic_weight | blank / 400-900 | blank | Composition | weight. Blank keeps each composition's own default | | align | left/center/right | center | all | honoured by every composition. On Discs it moves the whole cluster, since the circles sit on a spread rather than being aligned as text | | fill | solid/gradient | solid | all | on a scene composition the gradient paints across the line box | | grad_c1 / grad_c2 | hex | - | fill=gradient | the two stops | | grad_mode | travel/spin/wipe | travel | fill=gradient | how the gradient moves. wipe is the old Wiper composition, which is a gradient MODE now | | grad_speed | 0.25-3 | 1 | fill=gradient | gradient timing | | line_gap | -50 to 100 | 0 | all | space between lines, and between the rows of a line that wraps | | max_width | 0-100 | 0 | Per-Line / line-stack | % of the block a line may fill. 0 means wrapping is OFF | | max_width_tablet | 0-100 | inherit | as above | per-device override | | max_width_mobile | 0-100 | inherit | as above | per-device override | | line_size_0..3 | px, 0-400 | 60/40/30/24 | Composition | size of that line. 0 = the composition's automatic size. A sized line WRAPS rather than shrinking: the px asked for is the px given | | line_weight_0..3 | 0-900 | 900/600/300/300 | Composition | weight of that line. 0 = the block weight. Per-Line carries its own weight per row instead | | kperf | enum (see Performance) | "" | Composition | the ARRIVAL pattern. Per device; none turns it off for a breakpoint | | ksteady | enum (see Performance) | "" | Composition | the STEADY state, what the lines keep doing once arrived. Per device | | kperf_hero | 0-200 | 100 | kperf=handoff/highlight | how far the arrival pushes, as a SHARE of that pattern's own lift. Meaningless on stack/converge, which have no hero | | kpar | 0-100 | 0 | Composition | per-line pointer parallax: the lines lean by different amounts, so the stack reads as having depth. Off on touch and under reduced-motion | | disc_font | px, 20-400 | 30 | Discs | text size. The CIRCLE is built from the word at this size, not the other way round | | disc_ink | hex | "" | Discs | label colour. Blank picks black or white per circle for contrast | | disc_color_0..3 | hex/rgba | "" | Discs | one ink per circle. Blank falls back to color | | disc_link_0..3 | URL | "" | Discs / most comps | a URL makes that LINE (or circle) a real anchor. Blank leaves it plain text | | cube_style | tiles/faces | tiles | Cube | tiles = a letter per sticker, faces = words across the faces | | cube_mono | 1/0 | 0 | Cube | one derived tone instead of the Rubik six |

    Background is transparent — the containing section/cell shows through. For ambient color, use the section's gradient/mesh background, NOT the text.

    With as_background: 1 the block instead fills its whole section, sits behind the other content and takes no flow space — the way to put a composition behind a headline without pushing it down. Height settings do not apply in that mode.


    Per-composition options

    | key | type | default | applies | notes | |---|---|---|---|---| | disc_font | px, 20-400 | 30 | discs | type size, and therefore circle size: each circle is built to hold its own word | | disc_color_0..3 | hex/rgba | blank | discs | one ink per circle; blank falls back to color | | disc_ink | hex/rgba | blank | discs | label colour. Blank = automatic black or white for contrast against each circle | | disc_clip | 1/0 | 1 | discs | 1 cuts the circles at the block edge; 0 lets them bleed into the section | | disc_glow | 1/0 | 0 | discs | soft bloom in each circle's own colour | | disc_sub_0..3 | string | blank | discs | a small second line inside a circle, dropped automatically when the circle is too small for both | | cube_style | faces/tiles | faces | cube | a word per face, or a letter per sticker | | cube_mono | 1/0 | 0 | cube | replaces the six real cube colours with one derived tone | | cube_size | 30-90 | 55 | cube | cube edge, % of the stage | | cyl_diameter | % | 70 | cylinder | drum diameter | | echo_count | 2-16 | 5 | echo | trailing layers | | tide_bubbles | 1/0 | 0 | tide | bubbles rise inside the wave and vanish at the surface |

    Lines as buttons

    | key | type | default | applies | notes | |---|---|---|---|---| | disc_link_0..3 | URL | blank | see below | line N (or circle N on Discs) becomes a real anchor. A filled URL makes it a button and a blank one leaves it alone: there is no separate on/off switch |

    Supported on: Discs, every standard composition, plus Tide, Water, Glitch Loop, Bar Sweep and Echo. NOT available on Cylinder, Puzzle Cube, Extruded, Camera Arc, Type Pulse or Helix, where letters are transformed away from their layout box so a link's clickable area would not match what the reader sees. Do not emit link keys for those.

    The panel hides any control a composition does not read, so a setting that is absent from the UI for a given composition genuinely does nothing there.


    Long headlines go tiny on phones unless you set max_width

    A kinetic line that does not fit on one row is NOT wrapped by default: the font shrinks until it fits. The longer the headline, the smaller the type, and a phone is where it bites. Measured on live pages 2026-08-11: trade-page H1s rendered at 17px on a 375px screen, one marketing hero at 12px, both while looking perfect on a desktop.

    The setting is max_width (percent of the block a line may fill):

    • 0 (the default) means wrapping is off: shrink to fit one row.
    • 100 caps the line at the block width and **wraps at word
    • boundaries**, keeping the intended size. The same headline that rendered at 17px rendered at 54px across two rows.

    Set max_width: 100 on any headline longer than about 20 characters. On desktop it is a no-op when the line already fits, so it is safe everywhere. If a specific breakpoint needs different behaviour, use max_width_tablet / max_width_mobile.

    Composable layers (Composition mode)

    These stack on top of any composition for huge expressive range (composition × hierarchy × reveal × accent).

    Hierarchy (tier) — size relationship between lines

    • hero (default): line 1 is the big hero, the rest are small captions.
    • label: line 1 is a small label, line 2 is the hero, the rest are captions.
    • equal: every line the same size.

    Reveal (reveal) — stage-level entry mask that clips the whole block open

    • iris: a circle expands from the centre.
    • wipe: a hard edge sweeps across.
    • slit: a horizontal slit opens vertically.
    • Plays once on entry; composes with any composition (e.g. Camera Arc revealed through an iris).

    Accent (accent) — poster decoration overlay

    • slash // / backslash \\: a mark at the top-left.
    • brackets [ ]: rules flanking the block.
    • frame: a border inset from the block edges.
    • numeral: a big faint number behind the text — set accent_text (e.g. 2024, 24/7).

    Performance layers

    <!-- BEGIN GENERATED PERFORMANCE --> Two layers, and they are independent: a block can do either, both or neither. The ARRIVAL choreographs the lines against each other on the way in and then ends. The STEADY state is what they keep doing for as long as the page is open. Both run purely on transforms, so neither can change the block's height or move anything else on the page.

    Set kperf for the arrival and ksteady for the steady state. Empty means none. Both are per device (_tablet / _mobile), and none is how a breakpoint switches one OFF.

    Arrival patterns (kperf)

    • Handoff (handoff) - each line is the hero of its own beat, then yields it _(relay, 1400ms per beat, hero 1.55x)_
    • Stack (stack) - the same arrival rhythm with no size change: pure making-room _(relay, 900ms per beat)_
    • Highlight (highlight) - all land together, then one line is lifted at a time while the rest hold back _(walk, 1200ms per beat, hero 1.30x)_
    • Converge (converge) - the lines open spread apart and close into place: one move, no hero _(gather, 1600ms per beat)_

    Steady states (ksteady)

    • Drift (drift) - each line wanders its own small ellipse on its own clock, so the group never repeats a formation _(9000ms)_
    • Wave (wave) - a sine travelling down the stack, each line a third of a cycle behind the one above _(5200ms)_

    A relay pattern retimes each line to arrive ON its beat, so the composition's own entrance offsets are overridden while one is set.

    On a narrow viewport (<768px) the whole arrival runs at 70%, and a hero beat inverts: instead of the arriving line growing, the settled lines recede. The fit already spent the width budget getting the type to fit at all, so there is nothing left to grow into.

    Both are suppressed under prefers-reduced-motion, and neither runs with loop or cycle, which already own the timeline. <!-- END GENERATED PERFORMANCE -->


    Composition catalog

    <!-- BEGIN GENERATED CATALOG --> 35 compositions, generated from the engine catalog. If a key is not listed here it does not exist.

    Compositions marked scene paint their own absolute stage: they honour Hierarchy / Reveal / Accent and they are the only ones that carry a block Height. Everything else hugs its type, and the space around it belongs to the section. custom path means its own renderer without an absolute stage, so the per-letter cursor effects do not apply.

    Scene

    • Cylinder (cylinder) - Lines wrap a horizontal drum that rolls around the X axis. _(scene, 1-4 lines)_
    • Bar Sweep (sweep) - A skewed bar sweeps across and reveals the text in its wake, then wipes it out. _(scene, 1-4 lines)_
    • Extruded (brutal) - Bold extruded letters slide in horizontally with a hard depth shadow. _(scene, 1-4 lines)_
    • Puzzle Cube (cube) - Text rides a tumbling puzzle cube; layer twists slice it apart and reassemble it. _(scene, 1-6 lines)_
    • Glitch Loop (glitchloop) - Bold line, calm between short slice-and-split glitch bursts. _(scene, 1-2 lines)_
    • Echo Zoom (echo) - A word breathes with fading depth echoes; lines take turns. _(scene, 1 line)_
    • Helix (helix) - The text winds a slowly rotating spiral ribbon. _(scene, 1-2 lines)_
    • Water (curtain) - Tall stretched letters ripple like hanging fabric. _(scene, 1-2 lines)_
    • Type Pulse (typepulse) - A packed text block where letters swell and the words repack. _(scene, 1-6 lines)_
    • Tide (tide) - A wavy divider sweeps across and inverts the text it passes. _(scene, 1-4 lines)_
    • Discs (discs) - Words ride overlapping circles that drift in slow orbits. _(scene, 1-4 lines)_
    • Camera Arc (arc) - Letters blast in from the camera, assemble, then blast back out. _(custom path, 1-4 lines)_
    • Slide Assemble (slide) - Letters slide in horizontally in reading order under a fixed // accent, hold, then slide out the same way. _(custom path, 1-4 lines)_

    Cascade and build

    • Block Slam (block-slam) - Hero rises through a tight mask, subtitle bounce-slides from alternating sides. Both fade out. _(1-2 lines)_
    • Triple Cascade (triple-cascade) - Hero zooms with bounce, sub bounce-slides from sides, label rises. Distinct exits. _(1-3 lines)_
    • Wave Build (wave-build) - Each line waves in via a different motion: rise → drop → zoom → blur, all sine-staggered. _(1-4 lines)_
    • Spotlight (spotlight) - Hero blurs in dramatically. Subtitle letter-spaces in below. Both fade out. _(1-2 lines)_
    • Up Cascade (reverse-cascade) - Bottom label glides in, sub bounce-slides, hero rises. Hero exits first via drop. _(1-3 lines)_
    • Slide Stack (slide-stack) - Lines build from alternating sides with bounce and per-letter kick, staggered into a layered stack. _(1-4 lines)_
    • Mixed Cascade (mixed-cascade) - Hero scatter-bursts. Sub bounce-slides from sides. Label blurs in with kick. All blur out. _(1-3 lines)_

    Letter level

    • Pulse Zoom (pulse-zoom) - Hero zooms with bounce. Sub letter-spaces with kick. Label spring-rises. Each line a different motion. _(1-3 lines)_
    • Typewriter (typewriter) - Hero strikes in letter-by-letter. Sub drops in. Label glides in. Then the whole thing un-types, erasing backward letter by letter. _(1-3 lines)_
    • Edge Burst (edge-burst) - Letters converge from the edges to the centre. Hold, then fly out the same way. _(1-2 lines)_
    • Center Burst (center-burst) - Letters explode outward from the centre. Pull back to centre on exit. _(1-2 lines)_
    • Random Rain (random-rain) - Hero letters drop randomly. Sub letters rise randomly from below. Label blurs in randomly. Chaotic build. _(1-3 lines)_
    • Quick Flash (quick-flash) - Snappy zoom in, sub kicks in with letter-spacing pulse. Snappy zoom out. _(1-2 lines)_
    • Side Step (side-step) - Lines glide in from alternating sides. Exit out the OPPOSITE side they came from. _(1-4 lines)_
    • Letter Blur (letter-blur) - Hero letters blur in, sub letter-spaces in, label letters distort in. Different distortion per line. _(1-3 lines)_
    • Rise Fall (rise-fall) - Hero rises in dramatically, falls out via drop. Sub bounce-slides from sides. Letter-kick label optional. _(1-2 lines)_

    Energetic

    • Explosion (explosion) - Letters scatter into place from random angles at full intensity. Sub bounces. Hero blasts out via scatter. _(1-2 lines)_
    • Tremor (tremor) - Hero shakes into place. Sub bounce-slides from sides. Label glitches in. Distinct per line. _(1-3 lines)_
    • Static (static) - Hero noise-flickers in like a broken neon sign. Sub glitches in with chromatic aberration. Holds, fades. _(1-2 lines)_
    • Glitch (glitch) - Hero glitches in with chromatic aberration. Sub distorts in through blur-contrast noise. Both fade with glitch-out. _(1-2 lines)_
    • Distortion (distortion) - Hero resolves out of heavy blur and contrast noise — analog video tuning in. Sub kicks in. Both fade through blur. _(1-2 lines)_

    Not in the picker

    Reachable only on blocks that already carry the key.

    • Wiper (wiper) - A blade sweeps across and repaints the line behind it.
    • <!-- END GENERATED CATALOG -->

    Retired, do not emit: slow-burn (an alias that resolves to spotlight), bracketed, viewfinder, scribbled. These were documented but are not in the shipped catalog.


    Per-Line mode schema

    custom_mode: 1 and custom_lines = a JSON array (max 4 entries):

    ``json [ { "text": "BIG HEAVY", "motion": "rise", "px": 96, "weight": "900" }, { "text": "small serif light", "motion": "fade-in", "px": 34, "font": "Georgia, serif", "weight": "300" }, { "text": "mono medium", "motion": "glide-from-l", "px": 50, "font": "monospace", "weight": "600" } ] ``

    Per entry:

    • text — the line.
    • motion — one of the entry-motion keys below. The matching exit is auto-paired.
    • px — line size in pixels. Omit/blank = auto-fit (engine sizes the line to fit).
    • font — a CSS font-family stack (or omit to inherit). The UI offers a curated set: System, Sans, Serif, Editorial, Humanist, Couture, Display, Stamped, Script, Hand, Marker, Chalk, Mono, Typewriter.
    • weight300900 (omit to inherit the block's heavy default).

    Entry-motion keys (for motion)

    Translate: rise, drop, glide-from-l, glide-from-r, bounce-slide-l, bounce-slide-split, bounce-rise Scale: zoom-in, scatter-in Fade/blur: fade-in, blur-in, spacing-in, letter-kick-in Clip-mask: circle-reveal, slit-open, wipe-right, wipe-left Glitch/noise: glitch-in, distort-in, shake-in, noise-flicker


    Screen-level Auto-advance

    For multi-screen kinetic sequences, set screen_autoplay_seconds (>0) on the screen (Scroll Timeline section), not the block. The screen auto-advances N seconds after becoming active. Pauses when the tab is hidden. Off by default.


    Examples

    Bold hero (Composition): ``yaml composition: block-slam text: | THE FUTURE STARTS HERE ``

    Cinematic single word, revealed through an iris: ``yaml composition: spotlight reveal: iris text: | AWAKE ``

    Poster with year numeral + brackets: ``yaml composition: slide accent: numeral accent_text: "2024" tier: label text: | EST NOIR STUDIO since two thousand ``

    3D drum (short lines): ``yaml composition: cylinder fit_container: 1 text: | EAT DRINK REPEAT ``

    Mixed typography (Per-Line): ``yaml custom_mode: 1 custom_lines: | [ { "text": "BREAKING", "motion": "letter-kick-in", "px": 88, "weight": "900" }, { "text": "the mold", "motion": "glide-from-r", "px": 40, "font": "Georgia, serif", "weight": "400" } ] ``


    Anti-patterns

    • No paragraphs, no >4 lines, no >~4 words/line — they clip at the block edges.
    • No terminal punctuation in kinetic copy.
    • Don't use Cylinder with long multi-word lines — keep them short or the drum faces collide.
    • Don't combine Composition mode and Per-Line mode in one block — pick one (custom_mode decides).
    • Gradient fill does exist (fill: gradient), but it is an accent. Do not put one on every block.
    • Don't enable reveal/accent on every block by default — they're deliberate accents.
    • All motion uses ease-in-out; only the Cylinder spin is linear (continuous loop).