Flow

Effects / SVG

Paper cutout

Layered flat shapes with soft shadows, like a paper diorama, gently moving in parallax.

Prompt to build it

Build a paper-cutout landscape with layered hills, sea and sun. Stack SVG layers with drop-shadow filters, warm paper colors, and slow per-layer parallax bobbing. Make it responsive, cap devicePixelRatio at 2, pause when off-screen, and show a still frame when prefers-reduced-motion is set. No external libraries.

Tested code

One self-contained HTML file with no libraries: the same code that runs above. Your AI gets it from Flow's get_effect tool.

Show the code
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Paper cutout | Flow effect</title> <!-- Flow effect: Paper cutout (https://flow.donta.io/effects/paper-cutout) Self-contained: no libraries. Copy the .fx-stage element, the CSS and the script into your project and size .fx-stage however you like. --> <style> :root { --display: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif; --body: ui-sans-serif, system-ui, sans-serif; } html, body { margin: 0; min-height: 100%; background: #0e0e10; display: grid; place-items: center; } .fx-stage { width: min(100vw, 960px); } /* Stage that every effect fills. Container units (cqw/cqmin) size the art. */ .fx-stage { position: relative; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 16px; container-type: size; background: #111; isolation: isolate; } .fx-fill { position: absolute; inset: 0; } .fx-fallback { position: absolute; inset: 0; } .fx-center { display: grid; place-items: center; } /* ── Paper cutout ─────────────────────────────── */ .fx-paper { background: #f6dfbf; } .fx-paper svg { width: 100%; height: 100%; } .fx-paper .layer { filter: drop-shadow(0 -1.5px 2px rgba(80, 30, 20, 0.35)); } .fx-paper .l1 { animation: fx-bob-s 7s ease-in-out infinite alternate; } .fx-paper .l2 { animation: fx-bob-s 5.5s ease-in-out infinite alternate-reverse; } .fx-paper .l3 { animation: fx-bob-s 4.5s ease-in-out infinite alternate; } .fx-paper .boat { animation: fx-boat 4s ease-in-out infinite alternate; transform-box: fill-box; transform-origin: center bottom; } @keyframes fx-bob-s { to { translate: 2px 2px; } } @keyframes fx-boat { 0% { rotate: -4deg; translate: -3px 0; } 100% { rotate: 4deg; translate: 3px 0; } } @media (prefers-reduced-motion: reduce) { .fx-stage *, .fx-stage *::before, .fx-stage *::after { animation-play-state: paused !important; } } </style> </head> <body> <div class="fx-stage"> <div class="fx-fill fx-paper"><svg viewBox="0 0 200 150" preserveAspectRatio="xMidYMid slice" aria-hidden="true"> <circle cx="140" cy="44" r="20" fill="#f0884a"/> <path d="M44 34 q4 -4 8 0 q4 -4 8 0" stroke="#7c3b4c" stroke-width="1.6" fill="none"/> <path d="M66 46 q3 -3 6 0 q3 -3 6 0" stroke="#7c3b4c" stroke-width="1.4" fill="none"/> <path class="layer l1" d="M-10 92 Q30 60 70 84 T150 74 T210 86 V160 H-10Z" fill="#e7a77b"/> <path class="layer l2" d="M-10 104 Q40 80 90 100 T210 96 V160 H-10Z" fill="#c8634f"/> <g class="boat"><path d="M92 108 h22 l-4 6 h-14z" fill="#3d2433"/><path d="M103 108 v-16 l9 14z" fill="#fff4e6"/></g> <path class="layer l3" d="M-10 114 Q30 104 70 114 T150 112 T210 116 V160 H-10Z" fill="#7c3b4c"/> </svg></div> </div> </body> </html>

How it works

Stack SVG layers (sky, sun, hills, sea) with drop shadows between them and move each layer a different small amount for depth.

Guardrails

  • Keep parallax subtle (a few pixels) to avoid motion sickness.
  • Respect prefers-reduced-motion: show a still frame instead of the animation.
  • Pause when off-screen or when the tab is hidden (IntersectionObserver + visibilitychange).
  • Keep text off busy animated areas, or give it a solid backing that passes WCAG contrast.
  • One showpiece effect per page. If everything moves, nothing stands out.