AI 资讯
Kitchen-Sune: A Community Cookbook
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing What I Built This is a blast from the past, but it's so lovely I couldn't resist submitting it for this challenge. Kitchen-Sune is a community-driven international recipe book built in collaboration with Front-End Foxes members when we pivoted our nonprofit's efforts from in-person workshops to an international online boot camp during the pandemic. It brings together comfort food recipes from around the globe into a sleek, accessible, and user-friendly Vuepress web application where food lovers and developers alike can discover new dishes. We were happy to host recipes from Ukraine, Kenya, Nigeria, and everywhere in between. Between Jalebi Babies, Moin-Moin, Puff Puff, and Strawberry Mush, we've got you covered for comfort food! Demo Live Demo: Kitchen-Sune App GitHub Repo: https://github.com/FrontEndFoxes/kitchen-sune Check out a preview of the recipe book (this recipe for maple syrup candy came with a video): Journey Revisiting and showcasing this project was a nostalgic process. Working on a community recipe project taught me the importance of building inclusive, easy-to-navigate web interfaces for diverse content as an educatioal tool. We used to use this repo as a way to train boot camp enrollees in how to use GitHub and make a PR to a repo. What I Learned: No matter where we are in our journey, food brings us together. What I'm Proud Of: How timeless and clean the aesthetic remains, making it easy for anyone to find a warm, cozy meal to cook or a snack to throw together (Pandemic Cookies, anyone?). What's Next: Let's keep going! Add your recipe via a PR to the GitHub repo. And I'd love to have more photos to show off your work.
AI 资讯
Pawford Academy — A SwiftUI Puppy Training App with ElevenLabs AI Voice 🐾🎓
This is a submission for Weekend Challenge: Dog Days Edition What I Built Pawford...
AI 资讯
The actual cost of shipping an iOS app in 2026
"How much does it cost to put an app on the App Store" gets answered inconsistently online because most answers either only count Apple's fee, or only count hardware, or quietly assume you're renting expensive cloud infrastructure you don't actually need. Here's every cost, split into what's mandatory and what's a choice. Mandatory: Apple Developer Program — $99/year This is the one cost nobody can avoid. To submit any app to the App Store — free or paid, one app or fifty — you need an active Apple Developer Program membership, which is $99/year, billed annually, direct to Apple. There's no one-time version and no way around it. (There is a free-tier Apple ID for personal on-device testing without paying this, but it doesn't let you submit to TestFlight external testers or the App Store — for an actual public release, the $99/year membership is required.) Required, but where you have genuine choices: building and signing To submit a build, something has to run Xcode's command-line signing and archive tools — that part isn't optional. Where you have a choice is what runs it: Option Cost Recurring? Buy a Mac ~$799+ (Mac mini, entry price) No Rent a cloud Mac ~$20–100+/month Yes GitHub Actions, public repo $0 No GitHub Actions, private repo $0 up to a monthly allowance, then per-minute Only if you exceed the free allowance The short version on that last row: on a public repo, this line item can legitimately be $0, indefinitely. Optional or one-time: the things people assume cost more than they do App Store screenshots and marketing assets. You can generate these yourself for free — from the Simulator or a physical device — no paid tooling required. A physical iPhone for testing. Not strictly required to submit, but you'll want one to sanity-check the finished app before release. TestFlight itself. Free, included in the $99/year membership. App Store listing itself. Free — no fee to list an app beyond the membership. Adding it up For someone shipping a side project on a
AI 资讯
GitHub Actions' free macOS minutes, explained
GitHub Actions is GitHub's built-in CI/CD system — it spins up a fresh virtual machine, runs whatever commands you tell it to, and tears the machine down when it's done. It supports Linux, Windows, and macOS runners. The macOS runners are the interesting part here, because they're actual macOS machines with Xcode's command-line build tools available, which means they can build and sign iOS apps — not just run tests. The headline rule: public repos are free On a public repository, standard GitHub-hosted runner minutes — including macOS — don't cost anything, on any plan, including the free plan. It's a genuine free tier, not a trial or a limited allowance that runs out. One nuance: this covers standard runners. GitHub also offers "larger runners" (more CPU/RAM) — those are billed regardless of repo visibility. A default macOS build for signing and archiving a typical app doesn't need one, so this rarely matters in practice. What changes on a private repo If your repository is private, you get a monthly allowance of free minutes instead of unlimited free usage: Plan Included minutes / month Free 2,000 Pro 3,000 Team 3,000 The number that actually matters for iOS builds is how fast macOS runners burn through that allowance. macOS minutes cost roughly 10x GitHub applies a multiplier against your included minutes: Linux runners run at the baseline rate, macOS runners run at roughly 10x that rate. A 6-minute macOS build eats through the same allowance as roughly 60 minutes of Linux CI. Applied to the table above, a Free-plan private repo effectively gets around 200 macOS-runner-minutes worth of free build time per month before you're billed per minute past it (Pro/Team works out to roughly 300). The practical upshot: if you're fine building in the open, a public repo gets you unlimited macOS build minutes at zero cost, indefinitely. If you'd rather keep the code private, everything about the pipeline still works the same way — you're just drawing from a metered allowance
AI 资讯
Context Is a Platform Capability Now
Watch a developer start an agent session on real enterprise work and you will see a ritual. Before the first useful prompt, they gather. They paste the deployment standard, link the runbook, and explain what the criticality tiers mean. Then they correct the agent's first confident guess about a naming convention the team retired two years ago. Tomorrow they will do it all again, because the agent will not remember. We have quietly decided that this gathering is the developer's job. Every guide to working with AI repeats some version of the same advice: give the model good context. So developers hunt for it, one session at a time, across systems that were never designed to answer an agent's questions. I think that framing is backwards, and I think fixing it is platform work. In Your Platform Has a New User: The Agent , I argued that internal platforms now serve two personas: the developer and the developer's agent. Near the end, I wrote that context is becoming part of the platform. I called it one of the most important developer experience problems of the next few years. That idea got four paragraphs. It deserves an essay, so here is the longer version. The gathering is the tax Agents can remember more than they used to. What they cannot reliably accumulate on their own is organizational truth. A new engineer pays the onboarding cost once, then amortizes it over years of context, hallway conversations, and scar tissue. An agent may retain instructions, memory, or project state. None of those automatically tell it which standard is authoritative, which exception still applies, or which decision was reversed six months ago. Whatever it needs to know about your organization still has to come from somewhere. Now multiply that across hundreds of engineers. People rediscover the same standards, fork the same repo, re-paste the same runbooks, and retype the same corrections, day after day. Quality varies too. Your strongest engineers assemble excellent context and get exce
AI 资讯
Before you pay anyone to migrate your Shopify catalog, make them promise these 17 things — in writing
I audit catalog migrations for a living. Every disaster I've seen was preventable — not by hiring better, but by agreeing in writing what "done" means before work starts. Copy this list. Send it to whoever is doing your migration. Ask them to commit to each line — and note the italics: every promise comes with a way you can check it yourself in about two minutes, no tools, no trust required. Every product made it across — none lost, none duplicated. Compare row counts in both files. Every variant made it across. Pick any product, count its rows in both files. No handle silently renamed ( -1 , -2 suffixes). Search the new file for -1 , -2 . SKUs unchanged and unique. Pick 5 SKUs from your export, find them in the new file. Prices and compare-at prices identical. Pick any product, compare both price fields. Inventory identical. Same spot-check. No missing titles, vendors, types, or prices. Sort each column, look for blanks at the top. Images attached to the right variant , not dumped at product level. Open a product with colors; each color shows its own image. Every image link loads. Click any 5 image URLs. Collections intact. Pick a collection, compare its product count. Custom fields (metafields) survived. Open a product that had them. Every old URL redirects. Try 5 URLs from your old sitemap. No garbled characters. Search the file for †. No description empty or cut short. Read 5 descriptions in both files. Description formatting survived (bullets, tables). Same 5 products. Option names still meaningful ("Size", not "Option1"). Open any product with options. Option values mean what they meant. Compare the value lists. Two more things worth writing down: What happens if a check fails — fix at no charge? partial refund? Agree now, not later. Anything already broken in your source data — list it upfront so nobody argues about whose fault it was. If your provider hesitates to commit to a list like this, that hesitation is information. (I keep a pre-filled version of t
AI 资讯
Architecting a Low-Power Geofencing Engine for Android Background Services
Opening hook It happened during a quiet Friday Jumu'ah prayer. The imam had just reached the most solemn part of the khutbah when a high-pitched, insistent ringtone echoed through the entire hall. Heads turned, whispers started, and the person responsible scrambled to silence their device, only to fumble and drop it in their haste. I sat there, mortified for them, knowing exactly how that sinking feeling felt. It is the universal experience of the modern digital age: the gap between our intentions to be polite and our actual ability to manage our phone's state in public spaces. The problem We live in a world of constant notification, yet we lack a standard way to govern our devices based on our physical context. Android provides AudioManager and NotificationManager , but these are reactive tools that require manual input. I tried using standard alarm-based triggers, but they lacked the spatial awareness I needed. If I am at the office, I want my phone on vibrate. If I am at home, I want it back to normal. If I am at a medical clinic, I need it on silent. Most existing solutions rely on heavy GPS polling, which drains the battery within hours. They treat location services as a raw stream of coordinate data rather than a state-based trigger. I wanted something that functioned entirely in the background, survived system reboots, and operated without a constant drain on the user's battery life. The friction wasn't just about silence; it was about the cognitive load of having to remember to switch profiles. I wanted my phone to handle the context switching for me, autonomously and reliably, without becoming a battery-draining nightmare. The technical decision / implementation To solve this, I moved away from manual polling and adopted the GeofencingClient within the Google Play Services location APIs. The decision to use this over raw LocationManager updates was rooted in battery efficiency. The GeofencingClient pushes the heavy lifting to the OS level. It uses a combina
AI 资讯
When a build breaks, the bug fixes itself
When a build breaks, the bug fixes itself We stopped babysitting CI failures. Now a red build files its own bug — and an AI agent picks it up and ships the fix. PROBLEM — A failed build told no one Our CI would fail, and then… nothing would happen. The failure sat quietly in a build console that nobody keeps open. Eventually someone would notice a change hadn't gone out, go digging, and realize the build had been red for hours. And noticing was the easy part. Actually resolving it meant a whole code session: pull up the logs, find the failing step, reproduce it, and have an engineer sit down and personally shepherd the fix from broken to green. Every red build cost real human hours — plus the invisible tax of the delay before anyone even knew there was a problem. The true cost of a broken build was never the build. It was a person having to find it, understand it, and hand-fix it. SOLUTION — The failure files its own ticket — and an agent takes it from there Now nobody watches a console and nobody triages. The moment a build fails, it automatically files a bug in Shipeasy — our ops platform — as a real, prioritized ticket with the failing step, the branch, and a link to the logs already attached. From there it leaves human hands entirely. Shipeasy hands the bug to an AI agent, which investigates the failure, writes the patch, and opens a pull request against it. The loop that used to be "human notices → human reads logs → human fixes" is now "build fails → bug appears → agent fixes." The engineer's job shrank to reviewing a PR that already exists. DESIGN — How the whole thing hangs together The pipeline is deliberately boring — every hop is either something the cloud already does for free, or a service we already run: Cloud Build — build fails: a red deploy on main publishes automatically Pub/Sub topic → push subscription: filters to FAILURE · TIMEOUT · INTERNAL_ERROR HTTPS POST /webhooks/cloud_build Webhooks::CloudBuildController: verify token · decode · dedupe by
AI 资讯
Clean Code Like a Jedi: The One Principle That Changed My Code Forever
The Quest Begins (The "Why") I still remember the first time I opened a pull request that looked like a novel written by someone who’d had too much coffee. The file was 800 lines long, a single function tried to validate input, fetch data from three different APIs, transform the result, update the UI, and log everything to a console that no one ever looked at. I spent three hours stepping through it with a debugger, only to realize the bug was a typo in a variable name buried three levels deep in a nested if‑statement. When I finally fixed it, I felt like I’d just defeated a dragon… only to discover the dragon had a dozen smaller dragons hiding in its caves. That experience left me wondering: Why does code feel so hard to read, even when it works? The answer wasn’t a fancy framework or a new language feature—it was a simple habit I’d overlooked: making every function do one thing, and do it well . Once I started treating that rule like a sacred oath, the dragons started to shrink, and my code began to feel like a clean, well‑lit hallway instead of a dark, tangled forest. The Revelation (The Insight) The principle is straightforward, yet its impact is massive: each function should have a single responsibility . If you can describe what a function does with a single verb phrase— validateUserInput , fetchUserProfile , renderDashboard —you’re on the right track. If you need an “and” or a “but” in that description, you’ve probably got more than one job packed in. Why does this matter? Readability : A reader can grasp the intent in seconds, not minutes. Testability : Small, focused functions are trivial to unit test. You can mock dependencies and assert outcomes without setting up a whole saga. Debugging : When something goes wrong, the stack trace points you directly to the guilty function, not to a 20‑line monolith where you have to hunt for the offending line. Reusability : A function that does one thing well can be dropped into other parts of the codebase (or even oth
AI 资讯
Gate your CI on a dollar ceiling, not a percentage — the number your finance team actually asks for
Gate your CI on a dollar ceiling, not a percentage — the number your finance team actually asks for Most cost gates for agent/LLM workflows check a delta : did this PR make the run more expensive than the last one, by more than X%? That's a good regression alarm. But it answers a developer's question ("did I make it worse?"), not a budget owner's question ("are we going to blow the monthly number?"). Those are genuinely different gates, and a team that only has the percentage one keeps getting surprised. A workflow can pass every percentage check — each PR adds a harmless-looking 3% — and still cross the line where the absolute monthly spend stops being okay. Percentages compound quietly; dollars are what shows up on the invoice. So the second gate I want on any agent workflow is an absolute ceiling : "a single run of this job must not cost more than $N," full stop, regardless of whether it went up or down since yesterday. Three things make that gate actually usable rather than theater: 1. The ceiling is priced, not token-counted. "Under 2M tokens" is meaningless to the person who signs off on spend, because a token of Opus output and a token of cached Haiku input differ by ~100× in price. The gate has to multiply each token bucket (input, output, cache-write at ~1.25×, cache-read at ~0.1×) by that model's real per-token price and sum to an actual dollar figure. If your gate reports tokens and makes a human convert, nobody converts, and the ceiling drifts. 2. The ceiling is per-run and per-workflow, not global. A nightly full-repo audit and a per-PR lint agent have wildly different legitimate costs; one global number is either too loose for the small job or too tight for the big one. You want to set max-usd on the specific workflow, so each job carries the ceiling that matches what it's for . 3. It shows the headroom, not just pass/fail. "$0.43 of a $0.50 ceiling — 86%" on every run is the line that lets you move the limit before it starts failing builds, instead of
AI 资讯
Why AI Benchmarks Mean Less Than You Think
Every model launch comes with a chart. Bars, usually, or a spider diagram, showing the new model edging past its rivals on a row of benchmarks with acronyms most people cannot expand. The bar is taller. The press writes it up as a leap. And within a week, users report that the new state-of-the-art model is, for their actual work, about the same as the last one or occasionally worse. The benchmark said one thing. Reality said another. This happens so reliably that it is worth understanding the mechanics of the gap. The test is public, which ruins the test The most fundamental problem is contamination. Many popular benchmarks are published, discussed, and sitting on the open web — which is exactly where models get their training data. When the questions and answers to your exam are in the study material, a high score measures memorisation as much as ability. Nobody needs to cheat deliberately; the leak is structural. A model can score brilliantly on a benchmark it has effectively already seen and then flounder on a genuinely novel version of the same task. A benchmark stops measuring intelligence the moment it becomes famous enough to end up in the training data. Fame is the thing that breaks it. The number becomes the marketing, and the marketing corrupts the number There is a commercial feedback loop that makes benchmark figures even less trustworthy than their technical limitations alone would suggest. A high score is not just an engineering result; it is a marketing asset worth an enormous amount in attention, funding and credibility. That raises the stakes on every fractional improvement, and where the stakes are high, the temptation to select, frame and present the numbers favourably is irresistible. Vendors choose which benchmarks to headline, which comparisons to draw, and which unflattering results to leave in an appendix or omit entirely. The chart on the launch slide is not a neutral readout; it is a curated argument. This is not necessarily fraud — it rare
AI 资讯
One-Shot UI Side Effects in BlocSignal: Snackbars, Dialogs, and Navigation Without State Pollution
Every Flutter developer has run into the Sticky State Dilemma . You build a login screen. When authentication fails, your state container emits an error. You catch it in your UI and show a SnackBar . Everything works—until the user rotates their phone, pulls down the notification shade, or types on the virtual keyboard. Suddenly, the widget tree rebuilds. The state container is still holding AuthErrorState("Invalid password") . The UI listener fires again. And a duplicate snackbar appears out of nowhere. In this article, we’ll explore why domain state machines struggle with transient UI events, how the classic BLoC community worked around this with package:bloc_presentation , and how BlocSignal lets you handle one-shot side effects cleanly with zero additional package dependencies . 1. The Root Problem: Persistent State vs. Ephemeral Actions State management in Flutter is designed to model persistent truth over time: Is the user logged in? AuthState.authenticated(user) Is data loading? TodoState.loading What is the cart total? $49.99 Persistent state answers: "What is the system's current condition?" In contrast, UI presentation actions are ephemeral pulses : Show a brief SnackBar toast. Pop up an alert confirmation dialog. Push a new route on the Navigator stack. Vibrate the haptic motor. These actions answer: "What just happened that requires a one-time reaction?" ┌────────────────────────────────────────────────────────┐ │ State vs. Effects │ ├────────────────────────────┬───────────────────────────┤ │ Persistent State │ Ephemeral Side-Effect │ ├────────────────────────────┼───────────────────────────┤ │ • Survived by UI rebuilds │ • Consumed once & gone │ │ • Represented in signals │ • Triggered by an event │ │ • Backed by equality diffs │ • Zero domain state footprint │ └────────────────────────────┴───────────────────────────┘ 2. The Legacy Workarounds (And Their Hidden Costs) Historically in package:bloc and package:flutter_bloc , developers used one of three
AI 资讯
Network Troubleshooting as a Stack: Find Which Layer Is Broken First
The difference between a good infrastructure troubleshooter and someone who restarts services and hopes is a mental model. When "HTTPS times out" lands in your inbox, you don't guess — you know exactly which layer to interrogate first, and in what order. The network is a stack, so treat it like one Every request rides through the same layers, top to bottom: Application → TLS → Port → DNS → Gateway → Route → Interface That's the dependency order — TLS can't work if the port is closed, the port is meaningless if DNS resolved to the wrong host, and none of it matters if your interface has no IP. So you verify in the inverse order, from the ground up: Interface → IP → Route → Gateway → DNS → Port → TLS → Application Start at the bottom because a broken lower layer produces confusing symptoms higher up. Confirm each layer is healthy before you climb. The moment a layer fails, you've found your problem — everything above it is a red herring. Walk it: "HTTPS to api.example.com times out" 1. Interface — do we have a link and an address? ip addr show Look for your primary interface (say eth0 ) in state UP with an inet line like 192.168.1.20/24 . No inet ? DHCP failed or the link is down — stop here, nothing above will work. If the address is present and sane, climb. 2. Route — is there a path to the destination? ip route get 93.184.216.34 This shows the exact route the kernel would pick, including the source IP and gateway ( via 192.168.1.1 dev eth0 src 192.168.1.20 ). If you get "Network is unreachable" or no default route, you've found it. This is also the signature behind the classic curl error "No route to host." 3. Gateway — can we reach the first hop? ping -c3 192.168.1.1 ip neigh show ping tests reachability; ip neigh shows the ARP table. A gateway entry in state REACHABLE with a MAC address means L2 is fine. FAILED or INCOMPLETE means the gateway isn't answering ARP — a VLAN, cabling, or firewall problem. Note that many hosts drop ICMP, so treat a failed ping as a hi
AI 资讯
Don’t overlook Elektron’s budget electronic music instruments
When I'm asked what to buy if you want to get into making electronic music, I often recommend Elektron's budget-minded Model:Samples and Model:Cycles grooveboxes. They don't grab headlines the way Teenage Engineering's gear or the Telepathic Instruments Orchid do, and even compared to the company's higher-end and more niche musical offerings like the Digitakt, Octatrack, […]
AI 资讯
Kubernetes for Beginners: From Local to Production – May the Pods Be With You
The Quest Begins (The "Why") I remember the first time I tried to take a weekend side‑project from my laptop to something that felt “real”. I had a cute Express API that talked to Postman, a PostgreSQL container spun up with docker-compose up , and a React front‑end that lived in its own dev server. Everything worked beautifully … until I hit Ctrl+C on my laptop and the whole thing vanished. I needed a way to say, “Hey, keep this running even if I close my laptop, and if something crashes, bring it back up automatically.” I started poking at Docker Swarm, then Nomad, but the docs felt like reading ancient runes. That’s when a coworker slid over a Slack message: “Just try a Kind cluster. It’s K8s locally, and you’ll see why everyone talks about it.” Spoiler: it felt like discovering the secret level in a classic arcade game. Suddenly I could describe what I wanted my system to look like, and the cluster would make it happen — no more babysitting containers. The Revelation (The Insight) Kubernetes isn’t a mystical black box; it’s a declarative orchestrator . You tell it the desired state of your application (how many replicas, which image, what ports to expose) and it works relentlessly to match reality to that state. If a pod dies, Kubernetes spins up a new one. If you ask for three replicas and only two are running, it creates the missing pod. If you update the image tag, it rolls out the change pod‑by‑pod, keeping traffic flowing. Think of it like the save‑game system in a RPG: you define the story you want to experience, and the engine handles the gritty details of loading, saving, and recovering from crashes. The core objects you’ll meet early on are: Pod – the smallest deployable unit (one or more tightly coupled containers). Deployment – manages a set of identical pods, handles updates and rollbacks. Service – a stable network endpoint that load‑balances traffic to a set of pods. Ingress (optional) – exposes HTTP/HTTPS routes from outside the cluster to service
AI 资讯
🍽️ Masala Dosa House — A Taste of Home
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing What I Built For the Perfect Landing prompt, I built Masala Dosa House , a warm and modern landing page inspired by one of my favorite comfort foods — South Indian Masala Dosa . 🇮🇳 The idea was to create a fictional restaurant website that feels like stepping into a familiar neighborhood dosa spot. The landing page focuses on: 🍽️ Hero section featuring Masala Dosa 🥞 Signature dishes 🥥 Chutneys and sambar 🌿 Traditional South Indian food experience ❤️ A warm, welcoming visual design 📱 Responsive layout for desktop and mobile ✨ Smooth interactions and animations 🎨 Food-inspired colors, typography, and visual elements 📍 Restaurant-style call-to-action sections Rather than creating a generic restaurant landing page, I wanted the entire experience to communicate the feeling behind comfort food — warmth, familiarity, and home . Demo 🍽️ Live Project: Masala Dosa House — A Taste of Home View the Masala Dosa House project on CodePen Journey I started by thinking about what makes a food website feel different from a regular landing page. For me, comfort food isn't only about the food itself. It's about the experience around it — the aroma, the warmth, the familiar presentation, and the feeling of sitting down for a meal that you already know you'll enjoy. That became the design direction for Masala Dosa House . I used a warm visual palette inspired by dosa, banana leaves, spices, chutneys, and traditional South Indian dining. The layout was designed to keep the food as the main focus while making the page easy to navigate. Building the experience I structured the landing page around a simple restaurant journey: Discover → Explore → Choose → Visit The hero section introduces the restaurant and immediately establishes the comfort-food theme. The menu section highlights signature dishes, while supporting sections provide more context about the restaurant and its food. I also focused on making the
AI 资讯
CSS Masala Dosa — A Plate of Comfort 🍽️
This is a submission for Frontend Challenge - Comfort Food Edition, CSS Art . Inspiration For my CSS Art submission, I wanted to create something that represents comfort food from South India — Masala Dosa . 🇮🇳 A crispy, golden dosa served with potato masala, coconut chutney, tomato chutney, and a warm bowl of sambar is more than just a meal. It's one of those dishes that immediately feels familiar and comforting. I decided to recreate the entire plate using HTML and CSS , without using food images or external graphics. The goal was to turn a simple plate of masala dosa into a small CSS illustration while keeping the focus on CSS techniques such as: CSS gradients Radial and repeating gradients Border-radius based shapes Box shadows Pseudo-elements CSS animations Responsive layouts Layering and positioning The project is called "CSS Masala Dosa — A Plate of Comfort" . Demo 🍽️ Live CodePen Project: CSS Masala Dosa — A Plate of Comfort View the CSS Masala Dosa project on CodePen Journey I started with the idea of creating a single plate entirely from CSS . Instead of using an image for the dosa, I built the main shape using layered gradients and rounded shapes. The different colors and textures help create the crispy, golden appearance of the dosa. Then I added the individual elements of the meal: 🥞 Masala Dosa — built using multiple gradients, shadows, and layered shapes. 🥔 Potato Masala — represented using small CSS shapes for potato pieces, onions, and curry leaves. 🥥 Coconut Chutney — created using a circular CSS shape with subtle texture details. 🌶️ Tomato Chutney — another CSS-only circular element with layered gradients. 🥣 Sambar — built as a small bowl using nested circular elements and gradients. 🌿 Banana Leaf — created with gradients, shadows, and a CSS vein to give it a natural appearance. ♨️ Steam — animated using CSS @keyframes to give the dosa a freshly-served feeling. One of the things I particularly enjoyed was creating the food textures without images
AI 资讯
Karachi Ki Raatein: A Love Letter to Midnight Street Food
This is a submission for Frontend Challenge - Comfort Food Edition, Perfect Landing What I Built Karachi Ki Raatein ("Karachi's Nights") — a single-page love letter to the street food that keeps my city awake after dark. Instead of a restaurant or a recipe box, I built it around a real pattern from home: Karachi basically runs on an unofficial food schedule. Maghrib means chai and something fried. Bun kabab happens standing up, mid-errand. Nihari is what you sit down for after Isha. Seekh kabab shows up wherever there's smoke. And halwa puri at 3am is for the people who never went to sleep in the first place. The whole page is built around that rhythm instead of a menu. A few things I'm happy with on the frontend side: A signboard hero with a flickering neon-style headline and hand-drawn CSS/SVG steam rising from a cup — no stock photography anywhere on the page, everything is drawn. A canvas-based particle steam system that replaces the static SVG once JS is available — real particles with drift, turbulence and upward acceleration, and they physically scatter when you move your cursor through them, like waving your hand through actual steam. A live "Night Clock" that reads your real local time ( Date , your timezone, nothing hardcoded) and marks whichever stall is "in season" right now with a pulsing "you are here" badge — so the page behaves differently depending on when you actually open it. A theme built for the medium : dark ink background, ember/turmeric accent colors, a hand-lettered chalk font for the "voice" of the thela-wala mixed with a bold display face for the signage, instead of the usual cream-and-terracotta food-site look. Respects prefers-reduced-motion everywhere (falls back to a static SVG steam loop and skips the canvas sim), keyboard-focusable throughout, fully responsive. Demo Journey I wanted to avoid the obvious comfort-food landing page — cream background, terracotta accents, a hero photo of a steaming bowl. It's a solid look but I see it ev
AI 资讯
CSS Gradients in One Screen: linear, radial, conic, and the rules nobody spells out
If you've only ever shipped linear-gradient(to right, blue, red) , you're using about one-third of what CSS gradients can do. There are only three functions, and the mental model for each is small. Here's the whole thing in one read. The one fact that makes everything click A gradient is not an image file. Per MDN , a <gradient> is a special kind of <image> that the browser generates at render time . So it: scales to any size without blurring (it's drawn, not sampled) weighs zero bytes (no file, no HTTP request) edits with one hex value instead of a re-export That's why gradients exist. Everything below is just how to steer them. Three functions, three shapes Function Shape Reach for it when linear-gradient() straight line along an axis backgrounds, buttons, overlays radial-gradient() outward from a center point spotlights, glows, vignettes conic-gradient() rotational sweep around a center pie charts, color wheels, spinners Linear - the workhorse background : linear-gradient ( to right , #ff7e5f , #feb47b ); /* orange→peach */ background : linear-gradient ( 135 deg , #6366 f1 0 %, #ec4899 100 %); /* indigo→pink */ Direction is an angle ( 45deg ) or a keyword ( to right , to top right ). Stops are a color plus an optional position. Radial - when the fade should read as light background : radial-gradient ( circle , #fff , #000 ); Shape ( circle vs ellipse ), center position, and sizing keywords ( closest-side , farthest-corner ) do the work. Because the fade tracks distance from a point, radial reads as depth - perfect for glows, vignettes, and spotlight effects. Conic - the one most people skip background : conic-gradient ( #f00 0 25 %, #0 f0 25 % 50 %, #00 f 50 % 75 %, #ff0 75 %); Conic sweeps by angle , not distance. That single difference makes it the right tool for pie charts and color wheels - effects that were hacky before conic-gradient() shipped. The rule that surprises everyone Two color stops at the same position don't fade - they make a hard edge: backgrou
AI 资讯
Building an AI Voice Agent for Bharat: My 10-Day Journey
Introduction For the past 10 days, I took part in the 10 Days of AI Voice Agents — #VoiceForBharat Edition challenge. During this challenge, I built an AI voice agent named Sadie. My goal was not just to make an AI that could talk. I wanted to build a voice agent that could understand users, remember conversations, use tools, make phone calls, connect users to humans, and hand conversations to specialist agents. This journey helped me understand that building a voice agent is much more than connecting an LLM with a text-to-speech API. The Problem Many people find it easier to speak than type. This can be especially useful for people who want to: Ask questions using their voice Learn through conversation Get quick information Speak in Hindi or English Use Hindi and English together Get help without using complicated interfaces I wanted to build a voice assistant that could make learning and getting information feel more natural. Instead of typing a question, users can simply speak to Sadie. What I Built Sadie is an AI voice agent that can: Have real-time voice conversations Understand Hindi-English code-mixed conversations Follow personality and safety rules Remember information with user permission Use external tools Make outbound phone calls Escalate conversations to humans Track call information Hand conversations to specialist agents The specialist agents I built are: Grammar Specialist Maths Specialist Full Stack Development Specialist How the System Works The basic architecture of my project is: User | | Voice ↓ LiveKit | ↓ Deepgram STT | ↓ Google Gemini / | \ / | \ Memory Tools Specialists \ | / \ | / ↓ Murf Falcon | ↓ User Voice Main Components Deepgram handles Speech-to-Text. Google Gemini acts as the brain of the agent and understands the user's request. Murf Falcon converts the AI's response into natural speech. LiveKit handles real-time audio communication. I also added memory, external tools, telephony, human escalation, analytics, and specialist agents