A cozy, fully accessible landing page for an imaginary family restaurant in Madrid, built from scratch with vanilla HTML, CSS and JavaScript for the DEV Frontend Challenge: Comfort Food Edition.
{% codepen https://codepen.io/editor/migbolivar/pen/01a000c3-cbbc-7afc-9d0e-922acb5196db %}
La Abuela ("the grandmother") is a tiny four-table restaurant in LavapiΓ©s, Madrid. In 1987, Abuela Carmen opened it with one rule: if it wouldn't be served at her Sunday table, it wouldn't be served here. Forty years later, the menu still has three dishes β caldo, croquetas, lentejas β and the pot still simmers for three hours.
The page tells that story through a warm terracotta-and-cream palette and five illustrations drawn entirely in pure CSS β no images, no SVG, no canvas.
What I built Hero β a clay pot in pure CSS: gradient body with layered inset shadows for volume, decorative band, handles, a two-tongued fire with a glowing core, a wooden table with grain, a light sweep across the heading, and animated organic steam Our story β a bowl of caldo with a wooden spoon and a terracotta heart, all divs and box-shadows The menu β three dish cards, each with its own pure-CSS illustration: a steaming bowl of caldo, three golden croquetas with crispy texture and a pool of salsa, and a dark bowl of lentils with nine individual grains The recipe β an accessible accordion unlocking Abuela's caldo, step by step Quotes β from regulars (including one from Osaka who cried into the caldo) Booking form β with inline validation, clear labels and a friendly confirmation Footer β hours, address, and a wink to Carmen
Every illustration is built the way : nested absolutely-positioned divs, layered box-shadow (inset shadows give the clay its volume and the croquettes their crust), organic border-radius, and radial gradients for light. The pot alone uses four shadow layers to feel round instead of flat. The steam is animated with pure CSS keyframes (and disabled for users who prefer reduced motion) The croquettes' golden heart is an inset highlight β no image, no filter trick The lentil grains are nine individual divs with their own tiny highlights Total: zero , zero , zero canvas β one file, ~37 KB
The challenge judges accessibility β so I treated it as a feature: β 0 violations on axe-core (serious + moderate) β WCAG AA contrast on every text element (I darkened the primary buttons after the first axe pass) β Skip-to-content link, one h1, logical heading order (h2 β h3, no skips) β Semantic landmarks (header, main, footer, section with aria-labelledby) β Keyboard navigable: hamburger menu, accordion and form all work with Tab/Enter β Visible :focus-visible outlines on every interactive element β aria-expanded on nav toggle and accordion buttons, role="region" + aria-label on panels β Live region (role="status") for form feedback β prefers-reduced-motion β animations, steam and scroll reveals are disabled for users who ask for it
Tested at 390px, 360px, 820px and 1440px viewports: no horizontal overflow, no console errors, hamburger navigation kicks in on mobile, grids collapse gracefully, and the illustrations scale down with transform.
What I learned / enjoyed Chasing axe-core to zero violations is a great discipline β the color-contrast pass caught a button I would have shipped as-is grid-template-rows: 0fr β 1fr makes a silky pure-CSS accordion with no height hacks Layered inset box-shadows are the entire trick behind "3D" CSS art β one shadow is flat, four shadows are clay Drawing food in pure CSS is harder than cooking it. The croquettes took three tries and still look suspiciously like planets A 100% vanilla stack keeps the page ~37 KB and instantly embeddable anywhere
HTML5 Β· CSS3 (custom properties, grid, layered box-shadow art, media queries, prefers-reduced-motion) Β· Vanilla JS (IntersectionObserver, ~90 lines) Β· Zero dependencies Β· Zero images Β· Zero SVG
Built for the Frontend Challenge: Comfort Food Edition Β· All recipes belong to Carmen.
