Kiln & Co. is a fictional small-batch studio pottery brand, built end-to-end — concept, copy, art direction, imagery and code — by Claude (Fable 5) as a portfolio showpiece.
The brief: a craft e-commerce feel — warm, tactile, handmade-but-refined. Sunlit studio, clay under fingernails, Scandinavian-meets-Japanese craft retail. The organizing idea became the kiln as calendar: everything on the site (stock counts, batch numbers, the schedule band, even the newsletter) hangs off the monthly firing rhythm, which gives a shop of four products a believable scarcity story.
DM Serif Display carries the headlines with italic accents in clay; Karla does the reading; a light IBM Plex Mono handles every number on the page — prices, batch counts, kiln dates — for shop-ticket charm.
All six photographs were generated with GPT Image 2 (model: gpt-image-2, quality high, saved as .webp). Hero and studio shots at 1536×1024, products at 1024×1024 on a shared "warm neutral seamless" art direction so the collection reads as one shoot. Each image was visually inspected before shipping.
Zero frameworks, zero build step — one HTML file, one stylesheet, ~230 lines of vanilla JS.
Each product card sits in a perspective: 1400px grid. Pointer position maps to rotateX/rotateY (±10–12°) on the card body, throttled through requestAnimationFrame; the same coordinates drive a radial-gradient glare layer in mix-blend-mode: soft-light. On leave, the card springs back with an overshoot bezier so it lands like soft clay.
const rx = (py - .5) * -10, ry = (px - .5) * 12;
body.style.transform =
`rotateX(${rx}deg) rotateY(${ry}deg) translateZ(6px)`;
glare.style.setProperty('--gx', px*100 + '%'); // gradient follows pointer
A fixed radial gradient of warm window-light hue sits over the hero in mix-blend-mode: multiply. Its center is a CSS custom property eased toward the cursor at 9% per frame (a cheap critically-damped spring), so the light lags like sun through glass.
Every .reveal enters via IntersectionObserver with transform: translateY(34px) scale(.985, 1.03) → identity on a cubic-bezier(.34, 1.56, .4, 1) overshoot curve — elements land with a tiny wobble, like a pot being set down. Batches stagger 70 ms apart.
The button is a CSS grid stack: label and checkmark share one cell and cross-fade/scale with the same overshoot easing while the button recolors to glaze blue. Fourteen dots in the five brand tones burst from the button center via the Web Animations API with randomized angle, distance and gravity-ish fall, then self-remove.
The five-step strip is a native horizontal scroller (momentum on touch for free) upgraded with pointer-capture dragging for mouse users, a click-suppressor when a drag occurred, and ArrowLeft/ArrowRight keyboard support on the focusable strip.
Concentric dashed circles spinning at different speeds and directions (14–34 s, pure CSS) appear as the logomark, a hero ornament and a schedule watermark. A fixed SVG feTurbulence grain layer at 5% opacity, shifted in 3 steps, gives the whole page a stoneware tooth. All motion honors prefers-reduced-motion.
Desktop + mobile screenshots, console and accessibility-tree review of the feature-complete build. Fixed: hero headline wrapping to five lines and pushing the CTAs below the fold (tightened the type clamp); the toast's "hidden" state still peeking into the viewport; reveal animations having no no-JS fallback (hidden state now scoped under an html.js class set inline); the mobile cart button hugging the logo once the nav hides. Elevated: the "sixth verb is wait" footnote under the process strip.
The studio photo read undersized beside its column — recropped from 3:2 to 5:4 with object-position keeping the potter's hands centered, plus a slow hover zoom. The process strip now fades at both edges (gradient mask-image) to signal scrollability. Elevated: the drag hint slides gently, the marquee pauses on hover, product names tint clay on card hover. Also evicted a stray build log from assets/; total page weight 6.2 MB.
Final sweep at 375 / 768 / 1440: verified zero console errors, focus-visible rings on all interactive elements, alt text on every image, semantic landmarks in the accessibility tree, and live interaction checks (add-to-cart morph + confetti + cart bump + toast, newsletter joined state, arrow-key scrolling on the strip). Elevated: squared the /guide asset grid, and this very section was rewritten to describe what the passes actually found.
Full pass log lives in the project's _reports/08-kiln.md.
The site is fully static — deploy the directory as-is:
npx wrangler pages deploy . --project-name kiln-and-co
No environment variables, no functions, no build. Total page weight is dominated by six .webp images; everything else is a few KB of hand-written CSS/JS and Google Fonts.