Spicing Up the Web: Building "Angaar", an Immersive Indian Comfort Food Experience
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing What I...
找到 201 篇相关文章
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing What I...
La Abuela — Comfort Food from Madrid 🍲 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. 🔗 Live demo: https://laabuela.bmops.tech 💻 Interactive pen (CodePen): The story 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 The art is pure CSS — no images, no SVG 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 CS
Here is a pattern that shows up in almost every codebase: const lastActive =...
One of the best ways to learn React is by building small, practical projects. A currency converter is an excellent example because it introduces state management, user input handling, calculations, and performance optimization—all in a single application. I built a simple currency converter using React that converts from USD to EUR, GBP, and JPY. For simplicity, I used fixed exchange rates instead of calling a live exchange rate API. React applications are interactive because they can respond to user actions. The useState hook allows components to remember values between renders. For this project, I declared it as thus, const [amount, setAmount] = useState(1); const [currency, setCurrency] = useState("EUR"); The amount stores the value entered. The setAmount() updates it. The currency variable stores the selected currency. The setCurrency() changes the selected currency. Whenever either value changes, React automatically re-renders the component. Now, to calculate the conversion, I stored the exchange rate in an object const RATES = { USD: 1, EUR: 0.92, GBP: 0.79, JPY: 157.3 }; The interface contains: A number input. A dropdown menu. A heading displaying the converted amount. Example: ```return ( Currency Converter <input type="number" value={amount} onChange={(e) => setAmount(Number(e.target.value))} /> <select value={currency} onChange={(e) => setCurrency(e.target.value)} > <option value="EUR">EUR</option> <option value="GBP">GBP</option> <option value="JPY">JPY</option> </select> <h2> {amount} USD = {convertedAmount} {currency} </h2> );```
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art. ...
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art. ...
For as long as I've been writing CSS, there's been one direction it refused to look: up. You could style a child based on its parent all day long, but the second you wanted a parent to react to something happening inside it — a checked checkbox, an invalid field, a filled-in input — you were reaching for JavaScript. Every time. It didn't matter how small the interaction was. :has() breaks that rule on purpose, and it's been safe to use in production for a while now — it's supported across Chrome, Edge, Firefox, Safari, and Opera, no polyfill required. I didn't fully appreciate what that meant until I rebuilt a form I'd been maintaining for two years and deleted most of the JavaScript in it. Not all of it — I'll get to where it still earns its place — but most. The rule CSS used to have /* This has always worked: style a child based on the parent */ .card.featured .title { color : gold ; } /* This has never worked, until :has(): style the parent based on a child */ .card :has ( .badge--sold-out ) { opacity : 0.6 ; } :has() reads as "select this element, if it contains a match for whatever's inside the parentheses." Once that clicks, a huge category of things people were writing classList.toggle() calls for turns into a single selector. Styling a label when its input is focused This used to mean a focus and blur listener on the input, toggling a class on the label. Now: .field :has ( input :focus ) { border-color : var ( --accent-color ); box-shadow : 0 0 0 3px color-mix ( in srgb , var ( --accent-color ) 25% , transparent ); } Wrap the label and input in a .field container, and the whole field lights up the moment the input inside it gets focus — no listener, no class toggle, and it can never drift out of sync with the actual focus state, because it is the actual focus state. Required-field indicators that can't go stale I've fixed this bug more times than I want to admit: a form gets a field added, and someone forgets to also add the little red asterisk that's suppo
When a user closes a tab, submits a form, or clicks an external link, you often need to send one last...
What is a Media Query? A media query is basically a condition in CSS. You tell the browser: IF the screen satisfies this condition, THEN apply these CSS rules. For example: @media (min-width: 768px) { .container { display: flex; } } Meaning: "If the viewport is at least 768px wide, make .container a flex container." So think: IF condition is TRUE ↓ apply these CSS rules 2. Why do we need Media Queries? Because users don't have one fixed screen. Your website could be opened on: 📱 Phone 375px wide 📱 Large phone 430px wide 📱 Tablet 768px wide 💻 Laptop 1366px wide 🖥️ Desktop 1920px wide You don't want to create five completely different websites. Instead: ONE HTML + BASE CSS + MEDIA QUERIES ↓ Responsive website 3. What does "Responsive" mean? Responsive means: The website adapts its layout and appearance according to the available screen/device size. `For example: Mobile [ Card ] [ Card ] [ Card ] [ Card ] but on desktop: [ Card ][ Card ][ Card ][ Card ]` Same HTML. CSS changes the layout. 4. The basic Media Query syntax The basic structure is: ``` @media media-type AND (condition) { /* CSS rules */ } For example: @media screen and (max-width: 600px) { body { background: lightblue; } } There are three important pieces: @media ↓ screen ↓ and ↓ (max-width: 600px) ↓ { CSS } Let's understand each one. 5. What is @media? @media tells CSS: "I'm about to write a media query." Example: @media (...) { } It's an at-rule in CSS. Similar CSS at-rules you'll eventually see: @media @import @font-face @keyframes For now, just remember: @media = start a media query 6. What are Media Types? You mentioned: screen / speech etc. YES. 👍 A media type tells CSS what kind of output/device the document is being presented on. Common media types include: screen For screens. Examples: 📱 Smartphone 📱 Tablet 💻 Laptop 🖥️ Desktop Example: @media screen and (max-width: 600px) { ... } print For printed documents / print preview. For example, your webpage looks like: Website [Header] [Navigation] [Button
DASTAN — The Taste of Home 🍲 This is my submission for the Frontend Challenge – Comfort Food Edition, Perfect Landing. What I Built For this challenge, I wanted to create something that felt more like a story than a typical food website. That idea became DASTAN — The Taste of Home . “Dastan” means a story, and the concept behind the project is simple: food is rarely just food. A dish can remind us of a person, a place, a family gathering, or a moment we haven't thought about in years. DASTAN is a visual, editorial-style landing page that explores comfort food from different parts of the world through photography, cultural stories, ingredients, and the people behind the memories. The goal was to make the experience feel warm, premium, and personal from the moment someone opens the page. The Idea The line that shaped the whole design was: Every culture has a taste of home. I wanted the website to communicate that feeling without relying on a traditional recipe-blog layout. Instead, I treated each dish almost like a magazine story. You can discover dishes from different regions, read the story behind them, and explore how food connects people across cultures. The Design I went for an editorial-inspired visual direction rather than a conventional modern dashboard. The design uses: Warm cream backgrounds Deep charcoal sections Muted gold accents Large serif typography Editorial-style food photography Rounded cards Generous spacing Strong visual hierarchy Story-focused content Subtle borders and details I wanted the interface to feel like opening a beautifully designed food magazine. At the same time, I made sure the experience remains comfortable to use on smaller screens. What You'll Find 🌍 Global Comfort Food DASTAN brings together dishes and stories from different parts of the world. Examples include: Tonkotsu Ramen — Japan Hyderabadi Dum Biryani — India Kimchi Jjigae — Korea Lasagna alla Bolognese — Italy Lahori Chicken Karahi — Pakistan Each one is presented as more
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing Most food...
Hoi hoi! I'm @nyaomaru, a frontend engineer who is trying to lose weight. 🐖🙀 I maintain a type...
If you have been following the evolution of Google's framework over the last few years, you know it has been undergoing a silent reconstruction — piece by piece. With the release of Angular 22 on June 3, 2026, this reconstruction is no longer a promise and has become the standard. We are not looking at another batch of experimental features: we are looking at the consolidation of an entirely rethought ecosystem. For those who live and breathe enterprise applications, Clean Architecture, and Microfrontend ecosystems, this is the version that finally delivers what has been promised since Angular 16: an end-to-end reactive framework, zone-less by nature, and with much less ceremony along the way. The experiments are over. Below is what has actually changed — and what you need to do before running ng update . 📖 If you are just starting out: several technical terms in this article (change detection, Signals, SSR, dependency injection, microfrontends...) are explained in a glossary at the end. Read the article from end to end and use the glossary as a reference whenever you have a doubt. What Arrived in Angular 22 OnPush is the new default change detection (the old Default became Eager and is deprecated). Stable Resource API: resource , rxResource , and httpResource are ready for production. Stable Signal Forms: featuring the Submission API, dynamic schemas (Zod/Valibot), and interop with Reactive Forms. New @Service() decorator: shortening @Injectable({ providedIn: 'root' }) . injectAsync : for lazy dependency injection, with prefetch via onIdle . debounced : for native debounce in Signals/Resources. Incremental Hydration: enabled by default. HttpClient : uses FetchBackend by default ( withFetch() is deprecated). Important Router and bootstrap improvements designed for Microfrontends . 1. OnPush as the New Default Change Detection The moment the community has always asked for has arrived: ChangeDetectionStrategy.OnPush is now the default behavior for any new component. T
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art . 🍩 Inspiration I write about WordPress plugins and PHP standards for a living, so when DEV dropped a "Comfort Food" theme for their Frontend Challenge, I didn't need to think twice about what to build. Not ramen, not pancakes — a donut. Specifically, the kind of donut that shows up on your desk right when a deploy breaks and somehow fixes everything. The twist I gave myself: don't just draw a static donut. Let people build one — pick a glaze, pile on toppings, then serve it — and do almost all of it in CSS, with JavaScript kept firmly in the back seat where the challenge rules ask for it to stay. That's how Donut Panic was born. 🎬 Demo Pick a glaze, load it up with sprinkles, drizzle, or powdered sugar, then hit Serve and watch it animate off the plate. 🛠️ Journey No JavaScript is driving the donut — :has() is Here's the part I'm most excited to talk about: every visual change in Donut Panic — the glaze swap, the toppings appearing, the donut lifting off the prep station and landing on the plate — is driven by plain checkbox/radio inputs and the :has() selector. Something like .kitchen:has(#serve:checked) .donut lets a parent element react to the checked state of an input buried somewhere inside it, which means the "Serve" button, the topping toggles, and the glaze picker are all just styled <label> s wired to hidden inputs. No click handlers, no state management — the checkbox is the state. JavaScript only shows up once, and it's not touching the art at all: it smooth-scrolls the stage into view on mobile after you hit Serve, because on a stacked mobile layout the donut can animate off-screen. That's the "sprinkle" of JS the challenge rules allow, used exactly the way it's meant to be — a UX nicety, not a rendering engine. Building the donut from the inside out The donut itself is layered rings, not a single flat shape: A base dough circle with a radial gradient doing double duty as both c
TL;DR — Events in Fitz LiveViews carry data three ways: a click payload ( data-flv-value-* ) tags a button with the value it should send; a form submit ( data-flv-submit ) reads the form's named inputs; and a live value ( @input / @change ) delivers a control's current value in payload["value"] . All three land in the same place — a payload map your handler reads. This post builds a live name list (add / remove / count) that runs both server-rendered and as WebAssembly. (Part 3 of the FitzLiveViews series.) Parts 1 and 2 covered the pitch and the counter. A counter only reads +1 / -1 — no data flows in . Real UIs take input: text, selections, form fields. Here's how that data reaches your handlers. The payload Every event handler has a payload in scope — a Map<Str, Str> . The three mechanisms below all fill it; your handler reads it with payload["key"] (guard with payload.has("key") ): 1. Click payload — a button that carries a value Tag any element with data-flv-value-<key>="{expr}" , and when a data-flv-click on it (or an ancestor) fires, that value rides along: <button data-flv-click= "remove" data-flv-value-item= "{it}" > × </button> event remove () { if ( payload . has ( " item " )) { let target = payload [ " item " ] names = names . filter ( fn ( it ) => it != target ) } } The delete button knows which row it is because the row's value is stamped on it. No IDs threaded through a callback, no closure capture. 2. Form submit — the whole form at once data-flv-submit="handler" on a <form> reads each named input into the payload on submit; data-flv-clear resets a field afterward: <form data-flv-submit= "add" > <input name= "item" placeholder= "Add a name" data-flv-clear /> <button type= "submit" > Add </button> </form> event add () { if ( payload . has ( " item " )) { let n = payload [ " item " ] if ( n != "" ) { names . push ( n ) } } } payload["item"] is the input's value at submit time. No preventDefault , no FormData , no fetch . 3. Live value — @input / @chang
I Built a Cinematic Developer Portfolio Instead of a Traditional One — Here’s What I Learned Most developer portfolios follow the same structure: About. Skills. Projects. Contact. There is nothing wrong with that. But when I started rebuilding mine, I wanted it to feel less like a collection of sections and more like an experience . So what started as a simple portfolio redesign slowly turned into a cinematic, interactive developer portfolio built around my journey as a Software Engineer and AI Developer . 🌐 Live Portfolio: https://pavan-sai-portfolio-xi.vercel.app The Idea I wanted the visitor to feel like they were entering a story rather than opening another resume website. The final experience includes: A cinematic opening sequence A custom soundtrack Full-screen scene-based navigation Animated video backgrounds Project showcases and case studies A personal journey timeline Responsive mobile layouts A cinematic closing scene Smooth transitions between sections The overall visual direction is built around: Black + Champagne Gold + Cinematic Lighting The Portfolio Flow The experience follows a sequence: Intro → Pavan Sai → Hero → About → Skills → Projects → Journey → Contact → Closing Credits Instead of normal vertical scrolling, the main portfolio behaves more like a sequence of scenes. Visitors move through the experience using navigation controls. Project case studies are separate and can scroll normally because they contain more detailed technical information. The Projects Some of the projects featured in the portfolio include: DevPilot AI An AI-powered DevOps incident recovery platform focused on detecting failures, diagnosing issues and helping recover production systems. ROCmPorter Agent An AI-assisted CUDA-to-AMD ROCm migration tool that analyzes repositories, identifies CUDA dependencies and helps generate migration changes. HunarHub A local skilled-worker discovery and service marketplace platform. I also showcase other engineering, AI and full-stack pro
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art . Inspiration In an Indian tech office, no product release, critical bug fix, or late-night deployment is complete without a 5-minute pantry chai break. A steaming clay Kulhad of Ginger Adrak Chai paired with crisp Garma-Garam Samosas is the ultimate comfort food that powers developers through endless coding sprints. This authentic workplace culture and rich street-food nostalgia inspired me to build a pure-CSS interactive art and corporate pantry scene. Demo Live Interactive Demo : Corporate Chai & Samosa Experience CodePen Embed : codepen.io GitHub Repository : Sayista-Yazdani/corporate-chai What I Built Adrak Chai & Samosa is an interactive web experience featuring: Pure CSS Hero Artwork : Handcrafted clay-textured Kulhad Chai cup with a shimmering tea surface, malai rim, and layered rising steam animations. Golden-brown samosas with crisp crimped edges, served on a traditional plate alongside mint and tamarind chutneys. Interactive Corporate Pantry Corner : Fully detailed tea kitchen equipped with a glowing gas stove, boiling tea saucepan with foam, spice jars ( Adrak , Elaichi , Chai Patti ), and stacked clay cups. 4 Distinct Characters : Rohan (Frontend Dev), Amit (Tech Lead), Priya (Product Manager), and Kaka (Pantry Specialist). Web Speech API & Audio Narration : Real voice speech synthesis with gender-matched voice profiles for each character. Character Gaze & Mouth Choreography : Characters automatically look toward whoever is currently speaking with dynamic gaze shifting, listening poses, and animated mouth movements. Journey & Tech Stack Technical Implementation CSS Artwork : Built entirely with CSS gradient meshes, polygon shapes, keyframe animations, and layered pseudo-elements ( ::before / ::after ). Audio Engine : Powered by native window.speechSynthesis with dynamic voice selection and text cleaning. State Management : Reactive data-speaker HTML attributes driving multi-char
A scroll-driven cinematic page about vada pav. No framework, no build step. Just HTML, CSS, and a story worth telling. Dev.to Frontend Challenge submission.
Avoiding "AI Slop" in Design "AI slop" happens when you let artificial intelligence build everything all at once with zero guidance, resulting in generic, corporate-looking interfaces. By taking on the role of a creative director—providing specific style references, establishing a design system, and tweaking the output iteratively—you can steer AI toward unique, high-quality UI. Access & Requirements Before getting started, note where and how to access the tool: Availability: Claude Design 2.0 (Design Labs) is accessible via the Claude Desktop App and web interface. Account Tiers: It requires an active paid plan (Claude Pro, Team, or Enterprise). Free tier accounts do not currently have access to Design Labs. Step 1: Gather Real-World Design Inspiration Before opening any AI tool, establish the visual direction you want to pursue. Browse Live Sites for Style: Use platforms like Mobbin to look at real, production websites rather than static concepts. Filter by Vibe: Search categories by style. For example, selecting a "Fun" filter yields vibrant, interactive sites with custom animations—a sharp contrast to standard corporate templates. Collect Visual References: Take screenshots of specific components (hero sections, cards, layout structures) across different sites that capture your target aesthetic. Step 2: Set Up a Custom Design System in Claude Instead of prompting a full web page from scratch, start by establishing your brand identity inside Claude Design. Launch Design Labs: Open the desktop app, navigate to Design Labs, and select Design Systems > Create Design System . Define Brand Context: Enter your company name and a brief pitch (e.g., FunAddict – We make running fun ). Upload Reference Assets: Drag and drop your curated screenshots directly into the asset uploader. Prompt the System: Instruct Claude to capture the collective mood, colors, and playful UI styles from your screenshots to generate a single, coherent design system. Step 3: Refine Your Design Sy
Compressing data before writing it to IndexedDB or sending it over a slow connection is a real...