TITLE: Desert Dunes — Sun Path at Latitude 23 North PROMPT: Build one self-contained HTML page: a scroll-driven desert dune landscape at golden hour. Palette #f7d9a0 sky, #e0a35c dune lit, #8c5a2b dune shadow, #3f2d1e rock, #fff3d6 sun. Structure: a .scroller of height 340vh containing a sticky full-height .scene with overflow hidden, so scroll progress 0-1 maps dawn to dusk. The sky is one element whose gradient reads three custom properties --sk1/--sk2/--sk3 that JavaScript interpolates in RGB through three keyframes (dawn pale blue/peach, noon blue/gold, dusk violet/rust) by setting them on the scene each rAF-throttled scroll frame. The sun is a single radial-gradient disc (bright core, colour stop, transparent halo) positioned with --sunX/--sunY, arcing from 16% left at 46% height up to 84% left at 16% height and back down via Math.sin(Math.PI * q). Five dune layers are absolutely positioned divs with hand-written clip-path polygon ridges (peaks between 44% and 93% height), each filled with a linear-gradient from --lit to --shade whose first stop sits just above its own ridge, each with a diagonal 104deg shadow overlay via ::after (clipped by the parent clip-path) and descending opacity .6 to 1 for aerial perspective. Each dune translates by calc(var(--dp) * var(--shift)) with shifts from -10px to -43px so the ridges parallax against each other as the sun moves. A hand-built camel caravan of three inline SVG silhouettes (rects for legs, ellipses for body and humps, polygon neck, ellipse head, stroked tail) treks across the dunes on a 78s linear translateX; hovering it sweeps a dashed route line in with transform:scaleX(0 -> 1) and lifts two monospace place labels from .38 to .85 opacity. A sand canvas of 70-260 DPR-scaled grains drifts on a sine gust, wraps at the edges and is pushed away from the pointer within a 138px radius. Clicking spawns a DOM ripple ring that expands with a transform-only keyframe and removes itself on animationend. A heat-haze band at 46% height uses one small filter:blur(3px) region over a repeating gradient with a transform-only shimmer. Chrome: Georgia italic wide-tracked title, monospace latitude readout with sun altitude, a scroll hint that slides out of the frame, and a top progress bar scaled with transform. prefers-reduced-motion stops the caravan, haze and grain drift and disables ripples. DESCRIPTION: A long, slow day in one screen. Scrolling is the clock: the sky warms from dawn blue to rust, the sun climbs the left side of the frame and drops toward the right horizon, and the five dune ridges slide against one another like stacked paper. A tiny camel caravan crosses the middle distance and hands you its route on hover, while sand grains sift across the whole scene and scatter away from the cursor. The type is sparse and warm, set in an italic serif title against a monospace field readout. TECHNIQUES: sticky full-height scene over a 340vh scroller with scroll progress driving CSS custom properties; RGB colour interpolation across three keyframe palettes written to --sk1/--sk2/--sk3/--lit/--shade/--sunCol; Math.sin arc for the sun path plus a tabular altitude readout; five hand-authored clip-path ridge polygons with per-layer gradient stops and diagonal shadow overlays; parallax via calc(var(--dp) * var(--shift)) so one custom property drives six transforms; DPR canvas grain field with gust noise, edge wrapping and pointer repulsion; transform-only route reveal and DOM ripple with animationend cleanup; single small blurred heat-haze band; rAF-throttled and quantised scroll writes with a dirty gate. INTERACTION: Scroll to move the sun from dawn to dusk — sky colours, dune lighting, ridge parallax and the sun altitude readout all follow, and the top progress bar scales with position. Move the pointer across the dunes to stir the sand grains away from the cursor. Click anywhere to drop an expanding ripple ring on the sand. Hover the camel caravan to sweep in the dashed route line and the Timbuktu / Segou labels. With prefers-reduced-motion the caravan and haze hold still, the grains do not drift and clicks no longer spawn ripples, but the full scene renders.