How Paper Moon was cut from paper.
A look inside the making of the Paper Moon site — a children's book studio rendered as a layered construction-paper collage. What the pieces are, why they're shaped that way, and the code that holds the fox afloat.
The brief & the concept
A studio you can pick up off the table.
The brief asked for a children's book studio built as a "layered paper-cutout world": torn-edge dividers, drop-shadowed layers that float, a drawable star canvas, book cards that tilt like picked-up paper, and a palette that travels from butter to coral to teal to a final night-blue. Friendly, but not childish-sloppy.
The whole concept hangs on one idea: everything on the page should feel like a physical piece of cut paper lit by a low lamp. That single rule decided the shadows (soft, offset, warm), the edges (torn, never straight), the texture (a grain that sits over the entire page), and the motion (a gentle bob, like a mobile hanging over a crib). The two fox illustrations set the exact hues — I sampled cream #f4ecd6, coral #f0a878, teal #3a9aa0, and moon-yellow #f2d55c straight from them so the CSS-drawn layers and the artwork read as the same material.
The copy is written like a real studio wrote it: "handmade picture books for small humans — and the grown-ups brave enough to do all the voices." Six invented book titles, real ages and prices, a bundle offer with a handwritten-note upsell. Never lorem, never placeholder.
Design decisions
Choices that keep it warm, not cutesy.
Two typefaces, clear jobs
Baloo 2 (a rounded, friendly sans) carries body, UI, and labels — approachable without being a comic font. Fraunces, an optical serif, does every headline, with its italic reserved for the emotional word ("little boat", "each one cut by hand"). The contrast of soft-round against bookish-serif is the whole tone.
Warm brown ink, never black
Body text is #4a3b2e, a warm brown, on cream. True black would look printed and cold; brown reads like ink on craft paper and keeps contrast comfortable (still AA-legible) without harshness.
A palette that is a journey
The page descends through the story's day: butter-cream hero → coral studio → teal ocean → deep night-blue for the "make a wish" and shop. Each section's torn top edge is cut from the next color, so the paper appears to physically overlap.
Shadow does the lifting
Depth is never a gradient. Every "cut" piece gets a soft offset box-shadow plus a hard 3px ledge, so cards, waves, and the moon each throw their own shadow onto the layer beneath — exactly how the physical spreads are lit.
Signature techniques
The three tricks that carry it.
1 · Torn edges, drawn with turbulence
Straight dividers would break the illusion instantly. Instead, an SVG feTurbulence noise field feeds a feDisplacementMap that shoves the edge of each wave and cloud around by a few pixels — a repeatable "hand-torn" edge. Two filters at different frequencies give variety between layers.
<!-- displaces any shape's edge with fractal noise -->
<filter id="torn" x="-5%" y="-30%" width="110%" height="160%">
<feTurbulence type="fractalNoise"
baseFrequency="0.012 0.11" numOctaves="3" seed="3" result="t" />
<feDisplacementMap in="SourceGraphic" in2="t"
scale="19" xChannelSelector="R" yChannelSelector="G" />
</filter>
2 · Layered float, like a hanging mobile
Nothing on the page is perfectly still. The fox bobs, the waves drift against each other at different speeds, and the hanging stars sway on their threads. Three small keyframe loops, each on its own tempo, so the motion never syncs up and never feels mechanical. All of it collapses under prefers-reduced-motion.
/* the fox rocks in its boat */
@keyframes bob {
0%,100% { transform: translateY(0) rotate(-.4deg); }
50% { transform: translateY(-14px) rotate(.4deg); }
}
/* wave layers slide past each other */
@keyframes drift { from { transform: translateX(-2%); } to { transform: translateX(2%); } }
/* hanging stars swing on their string */
@keyframes sway { 0%,100% { rotate: -3deg; } 50% { rotate: 3deg; } }
3 · "Draw a star for the fox"
The interactive centerpiece: a night-sky <canvas> with a hand-drawn crescent moon and paper boat, where click-and-drag sprinkles five-pointed stars that twinkle in with a spring. Each star is plotted from scratch by walking ten points around two radii. The animation loop only runs while stars are still growing, and pauses when the tab is hidden.
const spikes = 5, outer = s.r, inner = s.r * 0.44;
for (let i = 0; i < spikes * 2; i++) {
const rad = i % 2 === 0 ? outer : inner; // alternate tip / valley
const a = (Math.PI / spikes) * i - Math.PI / 2;
const px = Math.cos(a) * rad, py = Math.sin(a) * rad;
i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
}
ctx.closePath(); ctx.fill();
Assets & provenance
Where the fox came from.
Two fox illustrations
The site ships with two paper-collage fox scenes — one in the hero (fox sailing a striped boat under a crescent moon), one in the studio section (fox reclining at dusk). Everything else on the page — every wave, cloud, star, moon, and book cover — is drawn in CSS and SVG to match their palette and paper grain, so the generated art and the coded art are indistinguishable as material.
- source
- Generated with Higgsfield nano_banana_2, prompted for a layered paper-collage / paper-cut illustration style.
- format
- WebP, for small file size at high fidelity on the paper texture.
- files
assets/fox-1.webp(hero),assets/fox-2.webp(studio spread).- matched by
- Palette sampled directly from the artwork; a page-wide SVG
feTurbulencegrain unifies photo and code.
The iteration protocol
Three critique passes, then a director's note.
Every site in this showcase is built, screenshotted at desktop and mobile, and critiqued in writing like a hostile art director before anything is called done. Here is what actually changed on Paper Moon.
-
1
First render, first cuts
Full layout stood up: hero, six book cards, studio, star canvas, shop, footer. Critique flagged a mobile hero collision (a hanging star landed on the italic "boat"), a dead zone in the upper-right of the hero, and a stranded process step.
-
2
Balancing the composition
Moved the hanging moon, stars, and a new paper bird into the empty upper-right so the hero reads as a balanced mobile. Filled the dark shop's dead space with a layered-gradient starfield and a floating crescent. Made hero buttons full-width on mobile so no label clipped.
-
3
Polish & a bad crescent, fixed
A shop moon built from two overlapping radial gradients had rendered as a muddy olive disc — replaced with the clean inline-SVG crescent used elsewhere. Added a star-swing-on-hover micro-interaction. Final pass: zero console errors, no horizontal scroll, reduced-motion honored.
-
QA
Director's note: the Shop button
QA caught the nav "Shop" pill as dark text on a dark-brown pill — low contrast, read as disabled. Fixed to a butter-yellow pill with bold night-blue text (~9:1 contrast, well past WCAG AA), echoing the hero moon, with a lighter-yellow hover that lifts on a deeper shadow.
Reproduce this
If you want to build one like it.
- Sample your palette from the art. If you have illustrations, pull the CSS variables straight from their pixels so coded layers match the material.
- Make one physical rule. Here it was "cut paper under a low lamp." Every shadow, edge, and motion choice can then be checked against it.
- Torn edges over straight ones. One reusable
feTurbulence+feDisplacementMapfilter turns any SVG path into a hand-torn edge. - Layer motion at odd tempos. Several slow loops that never sync feel alive; one uniform animation feels like a screensaver. Gate all of it behind
prefers-reduced-motion. - Give visitors one thing to make. The star canvas turns a landing page into a small toy — pause its loop on
document.hiddenso it costs nothing when unseen. - Critique like a stranger. Screenshot at 1440 and 390, then hunt for the thing that looks AI-default. Every real fix here came from that pass, not the first draft.