REFERENCE
- Gallery page: https://magpui.com/en/i/halloween-shop-lit-by-a-live-candle-0c89ff
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/halloween-shop-lit-by-a-live-candle-0c89ff/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/halloween-shop-lit-by-a-live-candle-0c89ff/clip.mp4
- Original post: https://x.com/mizuno_web/status/2116319238520725989 by @mizuno_web
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
ASSETS
This needs real artwork, not shapes drawn in code. Use the files the user gives you (ask where they are). If you have an image generation tool, generate them with these prompts; otherwise leave clearly marked placeholders.
- Halloween pastry photos: Moody food photography of a Japanese-style pumpkin pudding with whipped cream on a dark ceramic plate, low-key candlelight from the left, deep black background, warm orange highlights, shallow depth of field, 3:2
Inspired by an original Halloween piece by mizu (@mizuno_web) on X: https://x.com/mizuno_web/status/2116319238520725989 . Credit them in a small caption or the footer.
BUILD: Build a seasonal pre-order page for a pastry shop's Halloween sweets, set almost entirely in darkness. A 3D carved jack-o'-lantern with a candle inside sits in the hero; its flickering flame is the page's only light source. The flame's brightness drives the whole page: the headline glow, the buttons and the product photos brighten and dim with every flicker, and products physically closer to the lantern on screen are lit more strongly. Moving the mouse fans the flame (it leans and flickers harder); clicking blows on it (it shrinks almost out, the page goes dark for a moment, then it recovers). It should feel quiet, warm and a little eerie.
DESIGN SYSTEM: Background #050403 with a faint warm radial glow around the lantern (rgba(255,140,40,0.12) at flame strength 1). Headline: an elegant serif (Mincho-style for Japanese or a high-contrast serif for Latin) at 36-44px, color #d98a3a with a text-shadow glow whose blur and opacity scale with flame brightness; small kicker above at 11px letter-spaced #8a6a4a. Body 13px #b9a58c, line-height 1.8. Buttons: primary pill #e8772a with text #1a0d04, 36px tall, radius 999px; secondary outline pill 1px #5a4632 text #d9c3a5. Product cards: photo 240x160 radius 6px, title 15px #e6d3b8, short text 12px, price 12px #a68a6a; cards in a right column with 64px vertical gaps while the lantern stays pinned at left. Reservation section: centered table with 1px #2a2119 row lines, labels left, values right, and an orange CTA.
MOTION: (1) Flame: a value f in [0.55,1] driven by layered noise (2 octaves, 0.8Hz and 3.5Hz) updated every frame; mouse speed adds up to +0.6 jitter amplitude and leans the flame toward the cursor direction (max 15deg) with a 400ms spring. (2) Blow: on click, f tweens to 0.08 over 250ms cubic-bezier(0.4,0,1,1), holds 300ms, then recovers to the noise loop over 1200ms cubic-bezier(0.22,1,0.36,1), with a small smoke wisp rising. (3) Light mapping: every frame write f to a CSS variable --flame; headline glow, button glow and photos use it (photo filter brightness(calc(0.25 + var(--flame) * 0.75 * var(--near)))) where --near is 0.4-1 from each card's distance to the lantern. (4) Scroll: the hero copy fades out, the lantern pins and slides to the left edge over the first 400px of scroll (GSAP ScrollTrigger scrub), product cards fade and rise 24px as they enter (600ms, stagger 120ms). (5) Lantern: slow idle rotation of plus or minus 4deg over 8s.
SECTIONS: Hero (kicker, two-line serif headline, 3D lantern with candle, dates line, primary "Reserve" and secondary "See the sweets" buttons, tiny note); "This year's Halloween sweets" list of 4-6 product cards beside the pinned lantern; "About reservations" table (period, pickup, payment, notes) with CTA; quiet footer.
IMPLEMENTATION: Three.js for the lantern (lathe/sphere geometry with displaced ribs, carved face as emissive cutouts, a PointLight inside whose intensity = f, plus a billboard flame sprite with a small noise shader). Drive f with a gsap.ticker callback and write it to document.documentElement.style.setProperty('--flame', f) so plain CSS handles all page lighting; compute --near per card on resize and scroll. GSAP ScrollTrigger for pinning and reveals. Cap pixel ratio at 1.5, pause rendering when the hero and pinned lantern are offscreen. prefers-reduced-motion: steady flame at 0.85, no flicker, no blow effect, simple fades. Buttons are real links/buttons with visible focus rings; the canvas is aria-hidden; ensure text contrast stays readable at the dimmest flame value (never below 4.5:1 for body text).
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, components and fonts; map the warm palette to the closest tokens; never copy logos, brand names, photos or product copy from the original; use placeholder product photos and text.
SUCCESS CHECK:
- The headline glow and product photos visibly pulse with the candle, and cards nearer the lantern are brighter than far ones.
- Moving the mouse makes the flame flicker harder and lean; clicking blows it nearly out and it recovers smoothly.
- With reduced motion enabled the page is static, warm-lit and fully readable.