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.