<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Migbolivar</title>
    <description>The latest articles on DEV Community by Migbolivar (@migbolivar).</description>
    <link>https://dev.to/migbolivar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4077668%2Fd5327de8-a426-419b-b35b-5739cd4f04f2.jpg</url>
      <title>DEV Community: Migbolivar</title>
      <link>https://dev.to/migbolivar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/migbolivar"/>
    <language>en</language>
    <item>
      <title>La Abuela — Comfort Food from Madrid</title>
      <dc:creator>Migbolivar</dc:creator>
      <pubDate>Fri, 14 Aug 2026 15:13:09 +0000</pubDate>
      <link>https://dev.to/migbolivar/la-abuela-comfort-food-from-madrid-4h6f</link>
      <guid>https://dev.to/migbolivar/la-abuela-comfort-food-from-madrid-4h6f</guid>
      <description>&lt;p&gt;La Abuela — Comfort Food from Madrid 🍲&lt;/p&gt;

&lt;p&gt;A cozy, fully accessible landing page for an imaginary family restaurant in Madrid, built from scratch with &lt;strong&gt;vanilla HTML, CSS and JavaScript&lt;/strong&gt; for the DEV Frontend Challenge: Comfort Food Edition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 Live demo:&lt;/strong&gt; &lt;a href="https://laabuela.bmops.tech" rel="noopener noreferrer"&gt;https://laabuela.bmops.tech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💻 Interactive pen (CodePen):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/migbolivar/embed/01a000c3-cbbc-7afc-9d0e-922acb5196db?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  The story
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;La Abuela&lt;/em&gt; ("the grandmother") is a tiny four-table restaurant in Lavapiés, Madrid. In 1987, Abuela Carmen opened it with one rule: &lt;em&gt;if it wouldn't be served at her Sunday table, it wouldn't be served here.&lt;/em&gt; Forty years later, the menu still has three dishes — caldo, croquetas, lentejas — and the pot still simmers for three hours.&lt;/p&gt;

&lt;p&gt;The page tells that story through a warm terracotta-and-cream palette and &lt;strong&gt;five illustrations drawn entirely in pure CSS&lt;/strong&gt; — no images, no SVG, no canvas.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hero&lt;/strong&gt; — 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&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Our story&lt;/strong&gt; — a bowl of caldo with a wooden spoon and a terracotta heart, all divs and box-shadows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The menu&lt;/strong&gt; — 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&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The recipe&lt;/strong&gt; — an accessible accordion unlocking Abuela's caldo, step by step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quotes&lt;/strong&gt; — from regulars (including one from Osaka who cried into the caldo)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Booking form&lt;/strong&gt; — with inline validation, clear labels and a friendly confirmation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footer&lt;/strong&gt; — hours, address, and a wink to Carmen&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The art is pure CSS — no images, no SVG
&lt;/h2&gt;

&lt;p&gt;Every illustration is built the way : nested absolutely-positioned divs, layered &lt;code&gt;box-shadow&lt;/code&gt; (inset shadows give the clay its volume and the croquettes their crust), organic &lt;code&gt;border-radius&lt;/code&gt;, and radial gradients for light. The pot alone uses four shadow layers to feel round instead of flat.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;steam&lt;/strong&gt; is animated with pure CSS keyframes (and disabled for users who prefer reduced motion)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;croquettes' golden heart&lt;/strong&gt; is an inset highlight — no image, no filter trick&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;lentil grains&lt;/strong&gt; are nine individual divs with their own tiny highlights&lt;/li&gt;
&lt;li&gt;Total: &lt;strong&gt;zero&lt;/strong&gt; &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, &lt;strong&gt;zero&lt;/strong&gt; &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt;, &lt;strong&gt;zero&lt;/strong&gt; canvas — one file, ~37 KB&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Accessibility (it was the first requirement, not an afterthought)
&lt;/h2&gt;

&lt;p&gt;The challenge judges accessibility — so I treated it as a feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;0 violations&lt;/strong&gt; on axe-core (serious + moderate)&lt;/li&gt;
&lt;li&gt;✅ WCAG AA contrast on every text element (I darkened the primary buttons after the first axe pass)&lt;/li&gt;
&lt;li&gt;✅ Skip-to-content link, one &lt;code&gt;h1&lt;/code&gt;, logical heading order (&lt;code&gt;h2&lt;/code&gt; → &lt;code&gt;h3&lt;/code&gt;, no skips)&lt;/li&gt;
&lt;li&gt;✅ Semantic landmarks (&lt;code&gt;header&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;footer&lt;/code&gt;, &lt;code&gt;section&lt;/code&gt; with aria-labelledby)&lt;/li&gt;
&lt;li&gt;✅ Keyboard navigable: hamburger menu, accordion and form all work with Tab/Enter&lt;/li&gt;
&lt;li&gt;✅ Visible &lt;code&gt;:focus-visible&lt;/code&gt; outlines on every interactive element&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;aria-expanded&lt;/code&gt; on nav toggle and accordion buttons, &lt;code&gt;role="region"&lt;/code&gt; + &lt;code&gt;aria-label&lt;/code&gt; on panels&lt;/li&gt;
&lt;li&gt;✅ Live region (&lt;code&gt;role="status"&lt;/code&gt;) for form feedback&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;prefers-reduced-motion&lt;/code&gt; — animations, steam and scroll reveals are disabled for users who ask for it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Responsive
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;transform&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned / enjoyed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Chasing axe-core to &lt;strong&gt;zero violations&lt;/strong&gt; is a great discipline — the color-contrast pass caught a button I would have shipped as-is&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grid-template-rows: 0fr → 1fr&lt;/code&gt; makes a &lt;em&gt;silky&lt;/em&gt; pure-CSS accordion with no height hacks&lt;/li&gt;
&lt;li&gt;Layered inset box-shadows are the entire trick behind "3D" CSS art — one shadow is flat, four shadows are clay&lt;/li&gt;
&lt;li&gt;Drawing food in pure CSS is harder than cooking it. The croquettes took three tries and still look suspiciously like planets&lt;/li&gt;
&lt;li&gt;A 100% vanilla stack keeps the page ~37 KB and instantly embeddable anywhere&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech
&lt;/h2&gt;

&lt;p&gt;HTML5 · CSS3 (custom properties, grid, layered box-shadow art, media queries, &lt;code&gt;prefers-reduced-motion&lt;/code&gt;) · Vanilla JS (IntersectionObserver, ~90 lines) · Zero dependencies · Zero images · Zero SVG&lt;/p&gt;

&lt;p&gt;---#frontendchallenge &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/devteam/join-our-latest-frontend-challenge-comfort-food-edition-28a0"&gt;Frontend Challenge: Comfort Food Edition&lt;/a&gt; · All recipes belong to Carmen.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>devchallenge</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
