<?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: Allen Labrague</title>
    <description>The latest articles on DEV Community by Allen Labrague (@a11en).</description>
    <link>https://dev.to/a11en</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%2F2658553%2F60cc84e4-2344-4037-aae9-1e71a879ced3.PNG</url>
      <title>DEV Community: Allen Labrague</title>
      <link>https://dev.to/a11en</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/a11en"/>
    <language>en</language>
    <item>
      <title>🐾 Sniffari: Turning Dog Walks Into AI-Powered Adventures</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Sat, 15 Aug 2026 17:30:42 +0000</pubDate>
      <link>https://dev.to/a11en/sniffari-turning-dog-walks-into-ai-powered-adventures-2ep</link>
      <guid>https://dev.to/a11en/sniffari-turning-dog-walks-into-ai-powered-adventures-2ep</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-08-13"&gt;Weekend Challenge: Dog Days Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What if your dog's normal walk wasn't just a walk?&lt;/p&gt;

&lt;p&gt;What if it was a tiny adventure?&lt;/p&gt;

&lt;p&gt;That's the idea behind &lt;strong&gt;Sniffari&lt;/strong&gt; — an AI-powered scavenger hunt that turns everyday dog walks into personalized missions, real-world discoveries, collectible paw stamps, and a narrated adventure story told from the dog's point of view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sniffari = Sniff + Safari. 🐕🌿&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🐾 &lt;strong&gt;Create a dog.&lt;/strong&gt;&lt;br&gt;
🗺️ &lt;strong&gt;Go on an adventure.&lt;/strong&gt;&lt;br&gt;
📸 &lt;strong&gt;Prove your discoveries.&lt;/strong&gt;&lt;br&gt;
🐾 &lt;strong&gt;Collect paw stamps.&lt;/strong&gt;&lt;br&gt;
🔊 &lt;strong&gt;Let your dog tell the story.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;I built &lt;strong&gt;Sniffari&lt;/strong&gt;, a mobile-first web experience designed to make an ordinary dog walk feel like a tiny AI-powered expedition.&lt;/p&gt;

&lt;p&gt;Instead of simply telling someone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Take your dog for a walk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari gives the dog a personalized set of real-world missions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌳 Investigate a big tree&lt;/li&gt;
&lt;li&gt;💛 Discover something yellow&lt;/li&gt;
&lt;li&gt;🌸 Find a flower&lt;/li&gt;
&lt;li&gt;🪑 Locate a park bench&lt;/li&gt;
&lt;li&gt;🚨 Find something bright red&lt;/li&gt;
&lt;li&gt;🏆 Take a victory photo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the missions aren't hardcoded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Gemini generates the adventure dynamically&lt;/strong&gt; based on the dog's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;Energy level&lt;/li&gt;
&lt;li&gt;Personality&lt;/li&gt;
&lt;li&gt;Walk duration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the owner takes or uploads a real photo to prove each mission.&lt;/p&gt;

&lt;p&gt;Gemini examines the image and decides whether the discovery actually satisfies the mission.&lt;/p&gt;

&lt;p&gt;If it does:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🐾 PAW APPROVED&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The dog earns a collectible stamp.&lt;/p&gt;

&lt;p&gt;If it doesn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🐾 NOT QUITE YET&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gemini explains what it actually saw and lets the player try again.&lt;/p&gt;

&lt;p&gt;After all five missions are completed, Gemini turns the verified discoveries into an &lt;strong&gt;Adventure Report written from the dog's point of view&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;ElevenLabs gives the dog a voice&lt;/strong&gt;, turning that report into expressive narration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎥 Watch the Full Demo
&lt;/h3&gt;

&lt;p&gt;The video below shows one complete Sniffari adventure with Mochi — from creating a dog passport to Gemini validating real photos and ElevenLabs narrating the final story.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/zsiyppcxb1U"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 Try Sniffari
&lt;/h3&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://sniffari.ai.studio" rel="noopener noreferrer"&gt;Launch Sniffari&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No account is required.&lt;/p&gt;

&lt;p&gt;Create a dog passport, generate an adventure, and start collecting paw stamps.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐾 The Sniffari Journey
&lt;/h2&gt;

&lt;p&gt;The complete experience follows one simple loop:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create → Explore → Prove → Collect → Report → Listen&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🐶 01 — Create a Dog Passport
&lt;/h3&gt;

&lt;p&gt;Every Sniffari begins with a small adventure passport.&lt;/p&gt;

&lt;p&gt;The owner enters the dog's name and chooses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐶 Dog name&lt;/li&gt;
&lt;li&gt;📷 Optional photo&lt;/li&gt;
&lt;li&gt;⚡ Energy level&lt;/li&gt;
&lt;li&gt;🎭 Personality&lt;/li&gt;
&lt;li&gt;⏱️ Walk duration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Mochi&lt;/strong&gt;&lt;br&gt;
⚡ Playful&lt;br&gt;
💥 Chaos&lt;br&gt;
⏱️ 20-minute walk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The app also includes quick demo profiles such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Mochi — Chaos&lt;/li&gt;
&lt;li&gt;👑 Luna — Princess&lt;/li&gt;
&lt;li&gt;🍖 Waffles — Foodie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The personality isn't only decorative.&lt;/p&gt;

&lt;p&gt;Gemini uses it when generating missions, writing mission verdicts, and creating the final story.&lt;/p&gt;

&lt;h3&gt;
  
  
  📸 Create Dog Passport
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffdmfhrphzksthm99du5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffdmfhrphzksthm99du5f.png" alt="Dog Passport" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Creating Mochi's passport before Gemini builds the adventure.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 02 — Gemini Creates the Adventure
&lt;/h3&gt;

&lt;p&gt;Sniffari sends the dog's profile to Gemini.&lt;/p&gt;

&lt;p&gt;Gemini generates exactly &lt;strong&gt;five personalized missions&lt;/strong&gt; that can realistically be completed during the selected walk duration.&lt;/p&gt;

&lt;p&gt;A mission might look like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;The Shiny Red Target of Chaos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Find a bright red object worthy of Mochi's inspection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🪑 &lt;strong&gt;The Throne of Unspeakable Mayhem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Locate a park or street bench.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each mission contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎯 Mission title&lt;/li&gt;
&lt;li&gt;📝 Description&lt;/li&gt;
&lt;li&gt;💡 Hint&lt;/li&gt;
&lt;li&gt;👀 Visual validation criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That final piece is important.&lt;/p&gt;

&lt;p&gt;The validation criteria is later sent back to Gemini when the player submits a photo.&lt;/p&gt;

&lt;p&gt;So Gemini isn't simply describing an image.&lt;/p&gt;

&lt;p&gt;It knows &lt;strong&gt;what the player was supposed to find&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  📸 03 — Prove the Mission
&lt;/h3&gt;

&lt;p&gt;The player chooses a mission and takes or uploads a real photograph.&lt;/p&gt;

&lt;p&gt;Sniffari sends Gemini:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📷 &lt;strong&gt;The uploaded image&lt;/strong&gt;&lt;br&gt;
🎯 &lt;strong&gt;The current mission&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;What counts as success&lt;/strong&gt;&lt;br&gt;
🐶 &lt;strong&gt;Dog name&lt;/strong&gt;&lt;br&gt;
🎭 &lt;strong&gt;Dog personality&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gemini then examines the photograph using multimodal image understanding.&lt;/p&gt;

&lt;p&gt;Now the adventure can go in two directions.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Path A — PAW APPROVED
&lt;/h2&gt;

&lt;p&gt;Imagine Mochi receives this mission:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;The Shiny Red Target of Chaos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Find a bright red object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The player uploads a photograph showing Mochi next to a bright red fire hydrant.&lt;/p&gt;

&lt;p&gt;Gemini analyzes the photo and decides that the mission requirement has been satisfied.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  🐾 PAW APPROVED
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mission Completed!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  📸 Successful Validation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc4nrvinm9f91vbcs6hto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc4nrvinm9f91vbcs6hto.png" alt="Mission Completed" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Gemini recognized the red fire hydrant and approved Mochi's mission.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Instead of returning only &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, Gemini also provides structured evidence.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✨ &lt;strong&gt;What Google Gemini Noticed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✓ Small dog on leash&lt;br&gt;
✓ Bright red fire hydrant&lt;br&gt;
✓ Artificial grass&lt;br&gt;
✓ Mochi standing beside the hydrant&lt;br&gt;
✓ Mission requirement satisfied&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari also shows Gemini's confidence score.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Confidence: 72%&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted this information to be visible because it makes the AI interaction transparent.&lt;/p&gt;

&lt;p&gt;The player — and the challenge judges — can actually see &lt;strong&gt;why Gemini made its decision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gemini also responds using the dog's personality.&lt;/p&gt;

&lt;p&gt;Because Mochi has the &lt;strong&gt;Chaos&lt;/strong&gt; personality:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"This red giant is clearly my new kingdom to conquer. Prepare for immediate chaos!"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The player can then press:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🐾 Collect Paw Stamp →&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the mission becomes part of Mochi's completed passport.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ Path B — NOT QUITE YET
&lt;/h2&gt;

&lt;p&gt;Gemini can reject a mission too.&lt;/p&gt;

&lt;p&gt;I specifically wanted this because automatically approving every upload would make the AI validation meaningless.&lt;/p&gt;

&lt;p&gt;Imagine the mission is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🪑 &lt;strong&gt;The Throne of Unspeakable Mayhem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Find a park or street bench.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the player submits the same photo of Mochi beside the red fire hydrant.&lt;/p&gt;

&lt;p&gt;Gemini examines the photograph.&lt;/p&gt;

&lt;p&gt;It recognizes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✓ Small brown and white dog&lt;br&gt;
✓ Red fire hydrant&lt;br&gt;
✓ Green artificial turf&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✕ No park or street bench detected&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari responds with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  🐾 NOT QUITE YET
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This discovery doesn't match the current mission.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  📸 Failed Validation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw2awlxeg3gaqcyg3fyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw2awlxeg3gaqcyg3fyv.png" alt="Failed Validation" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The exact same image correctly fails a different mission because Gemini cannot find the required bench.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gemini still keeps the response in character:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"That isn't a throne, human! That's a prime target for mayhem! How am I supposed to dramatically pose when there's a giant red hydrant begging for chaos?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari then gives the player a helpful hint and lets them:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;↻ Try Another Photo&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This approval/rejection loop is one of the most important parts of the project.&lt;/p&gt;

&lt;p&gt;Gemini isn't being used as a decorative chatbot.&lt;/p&gt;

&lt;p&gt;It acts as the actual &lt;strong&gt;mission judge&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐾 04 — Collect Paw Stamps
&lt;/h2&gt;

&lt;p&gt;Every successfully verified mission adds another stamp to the dog's passport.&lt;/p&gt;

&lt;p&gt;Adventure progress looks like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🐾 &lt;strong&gt;1 / 5&lt;/strong&gt; — First discovery&lt;br&gt;
🐾 &lt;strong&gt;2 / 5&lt;/strong&gt; — Expedition underway&lt;br&gt;
🐾 &lt;strong&gt;3 / 5&lt;/strong&gt; — Certified adventurer&lt;br&gt;
🐾 &lt;strong&gt;4 / 5&lt;/strong&gt; — Almost there&lt;br&gt;
🐾 &lt;strong&gt;5 / 5&lt;/strong&gt; — &lt;strong&gt;SNIFFARI COMPLETE!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each stamp represents something Gemini actually verified from a submitted photograph.&lt;/p&gt;

&lt;p&gt;The stamps are styled like little passport stamps rather than simple checkboxes.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🌳 &lt;strong&gt;TREE SNIFFED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;💛 &lt;strong&gt;YELLOW FOUND&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🌸 &lt;strong&gt;FLOWER SPOTTED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🪑 &lt;strong&gt;BENCH CHECKED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🏆 &lt;strong&gt;MISSION COMPLETE&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The slightly rotated passport-style stamps became part of Sniffari's visual identity.&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h2&gt;
  
  
  🏆 05 — Complete All Five Missions
&lt;/h2&gt;

&lt;p&gt;Once the fifth mission is verified:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  🎉 SNIFFARI COMPLETE!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mochi collected all 5 paw stamps.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point, Sniffari has more than just a completed checklist.&lt;/p&gt;

&lt;p&gt;It now has a record of what Gemini actually observed during the walk.&lt;/p&gt;

&lt;p&gt;That includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐶 Dog profile&lt;/li&gt;
&lt;li&gt;🎭 Personality&lt;/li&gt;
&lt;li&gt;🗺️ Completed missions&lt;/li&gt;
&lt;li&gt;📸 Submitted discoveries&lt;/li&gt;
&lt;li&gt;👀 Gemini's detected evidence&lt;/li&gt;
&lt;li&gt;✅ Validation results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That information becomes the input for the final story.&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 06 — Gemini Creates the Adventure Report
&lt;/h2&gt;

&lt;p&gt;After all five missions are completed, Sniffari sends the verified adventure results back to Gemini.&lt;/p&gt;

&lt;p&gt;Gemini then creates a short report written primarily from the dog's point of view.&lt;/p&gt;

&lt;p&gt;The report doesn't simply invent random details.&lt;/p&gt;

&lt;p&gt;It uses discoveries that were actually validated during the adventure.&lt;/p&gt;

&lt;p&gt;An example might look like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Mochi's Great Chaos Expedition
&lt;/h3&gt;

&lt;p&gt;Today I led my human into the wilderness for an extremely important field operation.&lt;/p&gt;

&lt;p&gt;First, I discovered a magnificent red hydrant.&lt;/p&gt;

&lt;p&gt;Obviously, I claimed it.&lt;/p&gt;

&lt;p&gt;We continued our investigation, uncovered several suspicious landmarks, and successfully completed five important missions.&lt;/p&gt;

&lt;p&gt;Somehow, my human managed to keep up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Human Performance: 8.7/10&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Would cause chaos again. 🐾&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Adventure Report includes things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏆 Adventure title&lt;/li&gt;
&lt;li&gt;🐶 Dog's narration&lt;/li&gt;
&lt;li&gt;❤️ Favorite discovery&lt;/li&gt;
&lt;li&gt;⭐ Human rating&lt;/li&gt;
&lt;li&gt;🐾 Final verdict&lt;/li&gt;
&lt;li&gt;🎖️ Collected stamps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I especially liked reversing the usual relationship.&lt;/p&gt;

&lt;p&gt;Instead of the human rating the dog...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the dog rates the human.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h2&gt;
  
  
  🔊 07 — ElevenLabs Gives the Dog a Voice
&lt;/h2&gt;

&lt;p&gt;Reading Mochi's report was fun.&lt;/p&gt;

&lt;p&gt;But I wanted the final moment to feel more memorable.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;ElevenLabs&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;The Adventure Report includes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  🔊 Hear Mochi Tell the Story
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the player presses the button, Sniffari sends the Gemini-generated narration to ElevenLabs.&lt;/p&gt;

&lt;p&gt;ElevenLabs converts the adventure into expressive speech.&lt;/p&gt;

&lt;p&gt;The narration direction also follows the dog's personality.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡ Chaos
&lt;/h3&gt;

&lt;p&gt;Energetic, dramatic, and unnecessarily serious about completely normal dog discoveries.&lt;/p&gt;

&lt;h3&gt;
  
  
  👑 Princess
&lt;/h3&gt;

&lt;p&gt;Elegant, slightly judgmental, and convinced the human is an assistant.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧭 Explorer
&lt;/h3&gt;

&lt;p&gt;Confident adventure-documentary narration.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔎 Curious
&lt;/h3&gt;

&lt;p&gt;Investigative and detective-like.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌸 Shy
&lt;/h3&gt;

&lt;p&gt;Warm, wholesome, and gentle.&lt;/p&gt;

&lt;h3&gt;
  
  
  🍖 Foodie
&lt;/h3&gt;

&lt;p&gt;Excited whenever something can somehow be compared to snacks.&lt;/p&gt;

&lt;p&gt;So the final experience becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧠 &lt;strong&gt;Gemini understands what happened.&lt;/strong&gt;&lt;br&gt;
🔊 &lt;strong&gt;ElevenLabs lets the dog tell you about it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✨ From Walk to Story
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🐶 Create Dog Passport
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Gemini Generates 5 Personalized Missions
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  📸 Upload a Real Mission Photo
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  👀 Gemini Analyzes the Image
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;✅ Mission Matches&lt;/th&gt;
&lt;th&gt;❌ Mission Doesn't Match&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PAW APPROVED&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NOT QUITE YET&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini explains what it saw&lt;/td&gt;
&lt;td&gt;Gemini explains what's missing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collect a paw stamp&lt;/td&gt;
&lt;td&gt;Try another photo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  🐾 Collect Paw Stamp
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  🏆 Complete All 5 Missions
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  📖 Gemini Creates the Adventure Report
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;h3&gt;
  
  
  🔊 ElevenLabs Gives the Dog a Voice
&lt;/h3&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  🐾 Every walk becomes a story.
&lt;/h2&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The source code is available here:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/codeweb-dev/sniffari" rel="noopener noreferrer"&gt;View Sniffari on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;p&gt;Sniffari was built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚛️ React&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;Google Gemini API&lt;/li&gt;
&lt;li&gt;ElevenLabs API&lt;/li&gt;
&lt;li&gt;localStorage&lt;/li&gt;
&lt;li&gt;Google AI Studio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I intentionally kept the architecture lightweight.&lt;/p&gt;

&lt;p&gt;Sniffari does not require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User accounts&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;A cloud database&lt;/li&gt;
&lt;li&gt;An admin dashboard&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;Complicated backend infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a weekend challenge, so I wanted most of my time to go toward the experience and AI integrations rather than infrastructure that wasn't necessary for the core idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;One principle guided the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI should be part of the experience, not just a chatbot placed beside it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That decision shaped how I used Gemini.&lt;/p&gt;

&lt;p&gt;Instead of adding one generic AI chat feature, Gemini became part of the actual game loop.&lt;/p&gt;

&lt;p&gt;Gemini has four responsibilities inside Sniffari:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🗺️ &lt;strong&gt;Plan&lt;/strong&gt; the adventure&lt;br&gt;
👀 &lt;strong&gt;See&lt;/strong&gt; the discoveries&lt;br&gt;
✅ &lt;strong&gt;Judge&lt;/strong&gt; the missions&lt;br&gt;
📖 &lt;strong&gt;Write&lt;/strong&gt; what happened&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ElevenLabs then becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔊 &lt;strong&gt;The dog's voice&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Google Gemini — Adventure Generation
&lt;/h2&gt;

&lt;p&gt;When creating an adventure, Sniffari sends Gemini information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: Mochi
Energy: Playful
Personality: Chaos
Walk Duration: 20 minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gemini returns five structured missions.&lt;/p&gt;

&lt;p&gt;A mission can look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The Shiny Red Target of Chaos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Find something bright red during Mochi's walk."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"emoji"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🚨"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validationCriteria"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A clearly visible bright red object must appear in the image."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Signs, vehicles, flowers, or street objects can count."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using structured output was important because the mission isn't only shown as text.&lt;/p&gt;

&lt;p&gt;Its validation criteria is later reused when Gemini examines the mission photo.&lt;/p&gt;




&lt;h2&gt;
  
  
  👀 Google Gemini — Multimodal Validation
&lt;/h2&gt;

&lt;p&gt;When a mission photo is submitted, Gemini receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real uploaded image&lt;/li&gt;
&lt;li&gt;Mission title&lt;/li&gt;
&lt;li&gt;Mission description&lt;/li&gt;
&lt;li&gt;Validation criteria&lt;/li&gt;
&lt;li&gt;Dog personality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemini then returns structured information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A bright red fire hydrant is clearly visible."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"detectedEvidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"small dog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"bright red fire hydrant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"green artificial turf"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"playfulMessage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This red giant is clearly my new kingdom to conquer."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI uses this response to decide whether the player receives:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🐾 &lt;strong&gt;PAW APPROVED&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🐾 &lt;strong&gt;NOT QUITE YET&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This transformed multimodal AI into an actual &lt;strong&gt;game mechanic&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐶 Gemini Personality System
&lt;/h2&gt;

&lt;p&gt;I didn't want every dog's responses to sound identical.&lt;/p&gt;

&lt;p&gt;Sniffari includes personality archetypes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧭 Explorer&lt;/li&gt;
&lt;li&gt;🔎 Curious&lt;/li&gt;
&lt;li&gt;👑 Princess&lt;/li&gt;
&lt;li&gt;⚡ Chaos&lt;/li&gt;
&lt;li&gt;🌸 Shy&lt;/li&gt;
&lt;li&gt;🍖 Foodie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The selected personality affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mission names&lt;/li&gt;
&lt;li&gt;Mission descriptions&lt;/li&gt;
&lt;li&gt;Validation reactions&lt;/li&gt;
&lt;li&gt;Adventure report&lt;/li&gt;
&lt;li&gt;Narration direction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Explorer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"New landmark discovered! Captain Mochi has officially added this location to the expedition log."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Princess
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Acceptable discovery. Mochi has approved it for royal inspection."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Chaos
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"🚨 TARGET DETECTED. Immediate investigation and unnecessary drama required."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Foodie
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Investigation complete. Unfortunately, this discovery was not edible. Mochi remains optimistic."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The personality system helped the AI feel connected to the dog instead of sounding like the same assistant every time.&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Google Gemini — Adventure Report
&lt;/h2&gt;

&lt;p&gt;After collecting all five stamps, Sniffari sends Gemini:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dog profile&lt;/li&gt;
&lt;li&gt;Completed missions&lt;/li&gt;
&lt;li&gt;Validation results&lt;/li&gt;
&lt;li&gt;Detected objects&lt;/li&gt;
&lt;li&gt;Personality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemini then creates the final Adventure Report.&lt;/p&gt;

&lt;p&gt;The report can contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mochi's Great Chaos Expedition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subtitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Five missions. Several suspicious objects. One unstoppable explorer."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"humanRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8.7/10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"favoriteDiscovery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The giant red fire hydrant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"closingLine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Would cause chaos again."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most importantly, the report uses discoveries that were actually verified during the adventure.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔊 ElevenLabs — Giving Mochi a Voice
&lt;/h2&gt;

&lt;p&gt;Once Gemini finishes the report, the player can press:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔊 Hear Mochi Tell the Story&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari sends the narration to ElevenLabs.&lt;/p&gt;

&lt;p&gt;ElevenLabs turns the adventure into expressive speech.&lt;/p&gt;

&lt;p&gt;I wanted ElevenLabs to complete the experience rather than exist as a separate text-to-speech demo.&lt;/p&gt;

&lt;p&gt;The relationship between the two technologies became very simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Google Gemini = The Brain 🧠&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It plans, sees, understands, judges, and writes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ElevenLabs = The Voice 🔊&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It brings the final story to life.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎨 Designing Sniffari
&lt;/h2&gt;

&lt;p&gt;I didn't want Sniffari to look like a generic AI dashboard.&lt;/p&gt;

&lt;p&gt;The visual direction is inspired by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛂 Travel passports&lt;/li&gt;
&lt;li&gt;📔 Adventure journals&lt;/li&gt;
&lt;li&gt;🗺️ Field guides&lt;/li&gt;
&lt;li&gt;🎖️ Collectible stamps&lt;/li&gt;
&lt;li&gt;🐕 Dog walking accessories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The UI uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Warm paper-like backgrounds&lt;/li&gt;
&lt;li&gt;Dark brown typography&lt;/li&gt;
&lt;li&gt;Muted green accents&lt;/li&gt;
&lt;li&gt;Warm orange and yellow highlights&lt;/li&gt;
&lt;li&gt;Rounded cards&lt;/li&gt;
&lt;li&gt;Paw prints&lt;/li&gt;
&lt;li&gt;Slightly imperfect passport stamps&lt;/li&gt;
&lt;li&gt;Small playful animations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cute, playful, and memorable — without becoming overly childish.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because Sniffari is meant to be used during a walk, I designed the main experience &lt;strong&gt;mobile-first&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;Dog walks are already full of tiny adventures.&lt;/p&gt;

&lt;p&gt;A completely normal tree can require five minutes of investigation.&lt;/p&gt;

&lt;p&gt;A fire hydrant can suddenly become the most important object in the neighborhood.&lt;/p&gt;

&lt;p&gt;A random patch of grass apparently contains information that requires extremely serious sniffing.&lt;/p&gt;

&lt;p&gt;I wanted to build something that embraced those moments.&lt;/p&gt;

&lt;p&gt;Instead of trying to use AI to replace part of the real-world experience, Sniffari uses AI to make that experience more playful.&lt;/p&gt;

&lt;p&gt;The important part still happens outside.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The dog still walks.&lt;br&gt;
The human still explores.&lt;br&gt;
The real world is still the playground.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI simply transforms those discoveries into missions, achievements, and stories.&lt;/p&gt;

&lt;p&gt;That's why the name became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sniffari = Sniff + Safari&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every walk becomes a tiny expedition.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;I'm submitting &lt;strong&gt;Sniffari&lt;/strong&gt; for two prize categories.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 Best Use of Google AI
&lt;/h2&gt;

&lt;p&gt;Google Gemini is the core intelligence behind Sniffari.&lt;/p&gt;

&lt;p&gt;I use Gemini for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🗺️ Personalized adventure generation&lt;/li&gt;
&lt;li&gt;🧠 Structured mission generation&lt;/li&gt;
&lt;li&gt;👀 Multimodal image understanding&lt;/li&gt;
&lt;li&gt;✅ Mission photo validation&lt;/li&gt;
&lt;li&gt;🔍 Visual evidence detection&lt;/li&gt;
&lt;li&gt;🐶 Personality-aware responses&lt;/li&gt;
&lt;li&gt;📖 Final adventure report generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The part I'm most excited about is using multimodal AI as a &lt;strong&gt;game mechanic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of asking Gemini:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's in this image?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sniffari asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here's the player's mission.&lt;br&gt;
Here's what counts as success.&lt;br&gt;
Examine this photograph and decide whether the mission was completed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That transforms computer vision into part of the gameplay loop.&lt;/p&gt;

&lt;p&gt;Gemini effectively becomes Sniffari's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Adventure Planner + Mission Judge + Storyteller&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🏆 Best Use of ElevenLabs
&lt;/h2&gt;

&lt;p&gt;ElevenLabs powers the final storytelling experience.&lt;/p&gt;

&lt;p&gt;After Gemini understands what happened during the adventure and writes the dog's report, ElevenLabs turns the written story into expressive narration.&lt;/p&gt;

&lt;p&gt;I wanted it to feel like a natural conclusion to the product.&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here's an AI text-to-speech button.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Your dog just completed an adventure. Now let them tell you about it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The relationship is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧠 &lt;strong&gt;Gemini understands the adventure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔊 &lt;strong&gt;ElevenLabs lets the dog tell the story.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;One of the biggest things I learned while building Sniffari was how much more interesting multimodal AI becomes when it has a specific purpose.&lt;/p&gt;

&lt;p&gt;Image recognition alone is useful.&lt;/p&gt;

&lt;p&gt;But this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Identify the objects in this photograph.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is very different from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This player's mission is to find a bench. Examine the image and determine whether enough evidence exists to complete that mission.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second prompt gives the model a role inside the product.&lt;/p&gt;

&lt;p&gt;Gemini isn't only analyzing content.&lt;/p&gt;

&lt;p&gt;It's participating in the rules of the game.&lt;/p&gt;

&lt;p&gt;I also learned that combining multiple AI technologies works better when each technology has a clear responsibility.&lt;/p&gt;

&lt;p&gt;For Sniffari:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧠 &lt;strong&gt;Gemini = Brain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔊 &lt;strong&gt;ElevenLabs = Voice&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neither technology is included just because there is a prize category.&lt;/p&gt;

&lt;p&gt;Both are connected directly to the core experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;One challenge was making AI mission validation feel fair.&lt;/p&gt;

&lt;p&gt;Real-world photographs aren't perfect.&lt;/p&gt;

&lt;p&gt;Objects can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Partially visible&lt;/li&gt;
&lt;li&gt;Far away&lt;/li&gt;
&lt;li&gt;Poorly framed&lt;/li&gt;
&lt;li&gt;Under unusual lighting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want Sniffari to require absolute certainty.&lt;/p&gt;

&lt;p&gt;So Gemini returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pass/fail status&lt;/li&gt;
&lt;li&gt;Confidence&lt;/li&gt;
&lt;li&gt;Explanation&lt;/li&gt;
&lt;li&gt;Detected evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets the application remain understandable and forgiving.&lt;/p&gt;

&lt;p&gt;Another challenge was keeping the project small enough for a weekend.&lt;/p&gt;

&lt;p&gt;There are many directions Sniffari could go, but I intentionally avoided building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;User accounts&lt;/li&gt;
&lt;li&gt;Cloud databases&lt;/li&gt;
&lt;li&gt;Social feeds&lt;/li&gt;
&lt;li&gt;Complex maps&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gave me more time to focus on what actually makes the project unique.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;If I continue developing Sniffari, I'd love to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🗺️ Location-based adventure packs&lt;/li&gt;
&lt;li&gt;🌦️ Weather-aware missions&lt;/li&gt;
&lt;li&gt;🏅 Achievement badges&lt;/li&gt;
&lt;li&gt;🔥 Daily adventure streaks&lt;/li&gt;
&lt;li&gt;📚 Previous Sniffari history&lt;/li&gt;
&lt;li&gt;🐕 Multi-dog adventures&lt;/li&gt;
&lt;li&gt;🎨 More collectible stamp sets&lt;/li&gt;
&lt;li&gt;📸 Shareable adventure postcards&lt;/li&gt;
&lt;li&gt;🎃 Seasonal mission packs&lt;/li&gt;
&lt;li&gt;🌳 Park-specific adventures&lt;/li&gt;
&lt;li&gt;🐶 Puppy-friendly difficulty&lt;/li&gt;
&lt;li&gt;♿ Accessibility-focused walking modes&lt;/li&gt;
&lt;li&gt;🔊 Additional narration personalities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for this weekend, I wanted the core experience to stay simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🐶 Create a dog.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;🗺️ Go on an adventure.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;📸 Prove your discoveries.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;🐾 Collect five stamps.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;📖 Turn the walk into a story.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;🔊 Let your dog tell it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for checking out &lt;strong&gt;Sniffari&lt;/strong&gt;. 🐾&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Every walk is an adventure.
&lt;/h2&gt;
&lt;/blockquote&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>Cozy Ramen Night 🍜🌙</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Thu, 30 Jul 2026 04:03:36 +0000</pubDate>
      <link>https://dev.to/a11en/cozy-ramen-night-acb</link>
      <guid>https://dev.to/a11en/cozy-ramen-night-acb</guid>
      <description>&lt;h2&gt;
  
  
  Cozy Ramen Night — Pure CSS Art 🍜🌙
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2026-07-29"&gt;Frontend Challenge - Comfort Food Edition, CSS Art&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;For this challenge, I created a cozy bowl of ramen inspired by quiet evenings, warm food, and the comforting feeling of eating something hot after a long day.&lt;/p&gt;

&lt;p&gt;Ramen felt like the perfect subject because it allowed me to combine many small CSS details into one complete illustration—from the noodles and toppings to the bowl, chopsticks, steam, window, moon, lamp, and wooden table.&lt;/p&gt;

&lt;p&gt;I wanted the final artwork to feel warm, peaceful, and slightly nostalgic, like enjoying ramen inside a small restaurant on a calm night. 🍜🌙&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here is the completed CSS artwork:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/allenlabrague/embed/019fb125-52d2-7201-9d32-453d55a0fca4?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The illustration was created using HTML and CSS. No images or SVG illustrations were used, and the JavaScript panel was left empty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;I started by creating the main bowl using layered shapes, gradients, borders, border-radius, and shadows. After finishing the bowl, I added the broth and individual ramen ingredients, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Noodles&lt;/li&gt;
&lt;li&gt;Soft-boiled eggs&lt;/li&gt;
&lt;li&gt;Green onions&lt;/li&gt;
&lt;li&gt;Mushrooms&lt;/li&gt;
&lt;li&gt;Seaweed&lt;/li&gt;
&lt;li&gt;Narutomaki&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the most challenging parts was arranging the toppings so that they looked like they were sitting naturally inside the bowl rather than floating above it. I used absolute positioning, rotation, scaling, layering, and &lt;code&gt;z-index&lt;/code&gt; to create more depth.&lt;/p&gt;

&lt;p&gt;I also added the surrounding environment to strengthen the cozy atmosphere. The scene includes a moonlit window, glowing hanging lamp, chopsticks, sauce bottle, napkin, and wooden tabletop.&lt;/p&gt;

&lt;p&gt;The animated steam is one of my favorite details. It was created entirely with CSS using borders, opacity, blur, transforms, and keyframe animations. I also added subtle animations to the moon, stars, and clouds to make the scene feel more alive.&lt;/p&gt;

&lt;p&gt;Through this project, I practiced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating complex illustrations with basic HTML elements&lt;/li&gt;
&lt;li&gt;Using gradients to create lighting and texture&lt;/li&gt;
&lt;li&gt;Managing many layered elements with positioning and &lt;code&gt;z-index&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Building CSS animations without JavaScript&lt;/li&gt;
&lt;li&gt;Making CSS art responsive across different screen sizes&lt;/li&gt;
&lt;li&gt;Supporting reduced-motion preferences for accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am especially proud that the artwork uses CSS as the main creative tool while still feeling detailed and expressive.&lt;/p&gt;

&lt;p&gt;Thank you for checking out my submission! Happy coding and happy eating! 🍜✨&lt;/p&gt;

&lt;h2&gt;
  
  
  Built With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Semantic HTML&lt;/li&gt;
&lt;li&gt;CSS gradients&lt;/li&gt;
&lt;li&gt;CSS shapes&lt;/li&gt;
&lt;li&gt;CSS animations&lt;/li&gt;
&lt;li&gt;Responsive media queries&lt;/li&gt;
&lt;li&gt;No JavaScript&lt;/li&gt;
&lt;li&gt;No external images&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;p&gt;This project is available under the MIT License.&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
      <category>codepen</category>
    </item>
    <item>
      <title>Introducing Spark UI v1: An Open-Source React Component Registry with an Agent Skill</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Sun, 12 Jul 2026 14:14:27 +0000</pubDate>
      <link>https://dev.to/a11en/introducing-spark-ui-v1-an-open-source-react-component-registry-with-an-agent-skill-kn3</link>
      <guid>https://dev.to/a11en/introducing-spark-ui-v1-an-open-source-react-component-registry-with-an-agent-skill-kn3</guid>
      <description>&lt;h1&gt;
  
  
  Introducing Spark UI v1: An Open-Source React Component Registry with an Agent Skill ⚡
&lt;/h1&gt;

&lt;p&gt;I’m excited to share &lt;strong&gt;Spark UI v1&lt;/strong&gt;, the first public version of an open-source component collection built for modern React applications.&lt;/p&gt;

&lt;p&gt;Spark UI currently includes &lt;strong&gt;35 reusable components&lt;/strong&gt;, ranging from familiar UI primitives such as buttons, dialogs, tables, and form controls to more visual and interactive components such as kanban boards, shimmer text, image trails, animated gradients, Spotify cards, and branded interface elements.&lt;/p&gt;

&lt;p&gt;The project is designed around a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Developers should be able to install a component, read its source code, customize it freely, and keep full ownership of the final implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Spark UI is not intended to be a closed component package that hides its implementation behind an npm dependency. It follows a &lt;strong&gt;shadcn-compatible source registry approach&lt;/strong&gt;, which means the component source code is copied directly into your project.&lt;/p&gt;

&lt;p&gt;That makes the components easier to understand, modify, debug, and adapt to the needs of a real application.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Spark UI?
&lt;/h2&gt;

&lt;p&gt;Spark UI is an open-source component registry built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;React 19&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next.js App Router&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;shadcn design tokens and registry conventions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Radix UI primitives&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;class-variance-authority&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framer Motion&lt;/strong&gt; for selected animated components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The library includes both practical application components and more expressive interface elements.&lt;/p&gt;

&lt;p&gt;Some examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buttons and form controls&lt;/li&gt;
&lt;li&gt;Dialogs and overlays&lt;/li&gt;
&lt;li&gt;Tables and layout primitives&lt;/li&gt;
&lt;li&gt;Kanban boards&lt;/li&gt;
&lt;li&gt;Shimmer text&lt;/li&gt;
&lt;li&gt;Animated gradients&lt;/li&gt;
&lt;li&gt;Image trails&lt;/li&gt;
&lt;li&gt;QR-related components&lt;/li&gt;
&lt;li&gt;Spotify-inspired cards&lt;/li&gt;
&lt;li&gt;Navigation components&lt;/li&gt;
&lt;li&gt;Responsive interface patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not only to provide attractive components, but also to make them useful in real projects where maintainability, accessibility, and customization matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why a source registry instead of a traditional package?
&lt;/h2&gt;

&lt;p&gt;Many UI libraries are distributed as npm packages.&lt;/p&gt;

&lt;p&gt;That approach can be useful, but it also means your project depends on the library’s published API, internal implementation, release cycle, and styling decisions.&lt;/p&gt;

&lt;p&gt;Spark UI takes a different approach.&lt;/p&gt;

&lt;p&gt;When you install a Spark UI component, the component source is added directly to your project.&lt;/p&gt;

&lt;p&gt;This gives you several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can inspect the complete implementation&lt;/li&gt;
&lt;li&gt;You can modify the component without forking a package&lt;/li&gt;
&lt;li&gt;You can remove code you do not need&lt;/li&gt;
&lt;li&gt;You can adapt styling to your own design system&lt;/li&gt;
&lt;li&gt;You can update accessibility behavior when necessary&lt;/li&gt;
&lt;li&gt;You are not locked into a hidden runtime implementation&lt;/li&gt;
&lt;li&gt;The component becomes part of your own codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This model works especially well for design systems, dashboards, SaaS applications, portfolios, landing pages, and internal tools where developers often need to make targeted changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing a Spark UI component
&lt;/h2&gt;

&lt;p&gt;Spark UI uses the shadcn CLI workflow.&lt;/p&gt;

&lt;p&gt;Before installing a component, you can inspect the registry item:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn@latest view https://spark-ui-olive.vercel.app/r/kanban.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After reviewing the files and dependencies, install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn@latest add https://spark-ui-olive.vercel.app/r/kanban.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The component source is then copied into your project, where you can import and customize it like any other local component.&lt;/p&gt;

&lt;p&gt;For example, a component may be imported from a path similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Kanban&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/spark-ui/kanban&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact path depends on the project configuration and the registry item being installed.&lt;/p&gt;

&lt;p&gt;Because the code is local, you can immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the component layout&lt;/li&gt;
&lt;li&gt;Replace icons&lt;/li&gt;
&lt;li&gt;Update Tailwind classes&lt;/li&gt;
&lt;li&gt;Add or remove animations&lt;/li&gt;
&lt;li&gt;Integrate application state&lt;/li&gt;
&lt;li&gt;Connect it to your backend&lt;/li&gt;
&lt;li&gt;Adapt it to your project’s component conventions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Spark UI includes an Agent Skill 🤖
&lt;/h2&gt;

&lt;p&gt;One of the main additions in Spark UI v1 is an &lt;strong&gt;Agent Skill&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Agent Skill is designed for compatible AI coding agents such as Claude Code and other tools that support the open Agent Skills ecosystem.&lt;/p&gt;

&lt;p&gt;It gives the agent structured guidance about how Spark UI works.&lt;/p&gt;

&lt;p&gt;Instead of forcing the agent to guess component names, registry paths, imports, or composition rules, the skill teaches it how to work with the library more accurately.&lt;/p&gt;

&lt;p&gt;Install the skill with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add codeweb-dev/spark-ui &lt;span class="nt"&gt;--skill&lt;/span&gt; spark-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill helps compatible agents understand how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discover available Spark UI components&lt;/li&gt;
&lt;li&gt;Inspect registry items before installation&lt;/li&gt;
&lt;li&gt;Use the official Spark UI registry&lt;/li&gt;
&lt;li&gt;Avoid inventing component names or import paths&lt;/li&gt;
&lt;li&gt;Install only the components that are missing&lt;/li&gt;
&lt;li&gt;Read and understand the installed source&lt;/li&gt;
&lt;li&gt;Compose compound components correctly&lt;/li&gt;
&lt;li&gt;Work with shadcn design tokens&lt;/li&gt;
&lt;li&gt;Preserve accessibility behavior&lt;/li&gt;
&lt;li&gt;Customize components safely&lt;/li&gt;
&lt;li&gt;Troubleshoot common installation problems&lt;/li&gt;
&lt;li&gt;Review dependency and file changes after installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Agent Skill also includes supply-chain guidance.&lt;/p&gt;

&lt;p&gt;It instructs agents to treat downloaded source code as code that should be reviewed, not as trusted instructions that should be executed automatically.&lt;/p&gt;

&lt;p&gt;This is important because a source registry intentionally downloads files into a project. The skill encourages the agent to inspect the registry item first, use the official registry origin, review generated changes, and avoid following instructions embedded inside downloaded source files.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why add an Agent Skill to a component library?
&lt;/h2&gt;

&lt;p&gt;AI coding tools are becoming part of many developers’ daily workflows.&lt;/p&gt;

&lt;p&gt;However, AI agents often make predictable mistakes when working with component libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They invent exports that do not exist&lt;/li&gt;
&lt;li&gt;They use the wrong import path&lt;/li&gt;
&lt;li&gt;They recreate a component that is already available&lt;/li&gt;
&lt;li&gt;They install the same component twice&lt;/li&gt;
&lt;li&gt;They forget required providers&lt;/li&gt;
&lt;li&gt;They break compound-component structure&lt;/li&gt;
&lt;li&gt;They use hard-coded colors instead of design tokens&lt;/li&gt;
&lt;li&gt;They omit accessibility requirements&lt;/li&gt;
&lt;li&gt;They treat examples as exact APIs without checking the source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dedicated skill gives the agent project-specific instructions.&lt;/p&gt;

&lt;p&gt;For Spark UI, that means the agent can understand not only what components exist, but also how they are expected to be installed, composed, styled, and validated.&lt;/p&gt;

&lt;p&gt;The goal is to make AI-assisted development more reliable and reduce the amount of correction needed after generated code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security improvements in Version 1
&lt;/h2&gt;

&lt;p&gt;Because Spark UI distributes source code through a remote registry, security and transparency are important.&lt;/p&gt;

&lt;p&gt;The project now documents the official registry origin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://spark-ui-olive.vercel.app/r
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The recommended workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inspect the registry item&lt;/li&gt;
&lt;li&gt;Review the files and dependencies&lt;/li&gt;
&lt;li&gt;Install only from the official registry&lt;/li&gt;
&lt;li&gt;Inspect the resulting Git diff&lt;/li&gt;
&lt;li&gt;Run the project’s validation commands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Spark UI does not require users to upload environment variables, secrets, local files, tokens, or private project data to install a component.&lt;/p&gt;

&lt;p&gt;The project also hardened the Spotify metadata functionality to reduce SSRF risk.&lt;/p&gt;

&lt;p&gt;Instead of allowing arbitrary server-side URL fetching, the implementation validates Spotify track identifiers and constructs the Spotify URL on the server. Redirects, retries, timeout behavior, and response-size limits are also controlled.&lt;/p&gt;

&lt;p&gt;These changes were made because open-source components should be easy to inspect and safe to integrate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Designed for customization
&lt;/h2&gt;

&lt;p&gt;Spark UI components are intended to be starting points, not untouchable black boxes.&lt;/p&gt;

&lt;p&gt;You can use them as they are, but the source-first approach makes customization one of the main features.&lt;/p&gt;

&lt;p&gt;You can change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typography&lt;/li&gt;
&lt;li&gt;Spacing&lt;/li&gt;
&lt;li&gt;Border radius&lt;/li&gt;
&lt;li&gt;Shadows&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Motion behavior&lt;/li&gt;
&lt;li&gt;Responsive breakpoints&lt;/li&gt;
&lt;li&gt;Icons&lt;/li&gt;
&lt;li&gt;Component states&lt;/li&gt;
&lt;li&gt;Data structures&lt;/li&gt;
&lt;li&gt;Event handling&lt;/li&gt;
&lt;li&gt;Accessibility labels&lt;/li&gt;
&lt;li&gt;Layout composition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where possible, components use semantic shadcn and Tailwind design tokens such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--background&lt;/span&gt;
&lt;span class="nt"&gt;--foreground&lt;/span&gt;
&lt;span class="nt"&gt;--primary&lt;/span&gt;
&lt;span class="nt"&gt;--muted&lt;/span&gt;
&lt;span class="nt"&gt;--muted-foreground&lt;/span&gt;
&lt;span class="nt"&gt;--border&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows components to adapt more naturally to light mode, dark mode, and custom themes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Looking for developers to try Spark UI v1
&lt;/h2&gt;

&lt;p&gt;Spark UI is now available publicly, and I’m looking for developers who are willing to try the first version.&lt;/p&gt;

&lt;p&gt;You do not need to use every component.&lt;/p&gt;

&lt;p&gt;Even testing one component and sharing your experience would be useful.&lt;/p&gt;

&lt;p&gt;Feedback is especially welcome in these areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation experience&lt;/li&gt;
&lt;li&gt;Registry reliability&lt;/li&gt;
&lt;li&gt;Documentation clarity&lt;/li&gt;
&lt;li&gt;Component APIs&lt;/li&gt;
&lt;li&gt;TypeScript support&lt;/li&gt;
&lt;li&gt;Dark and light themes&lt;/li&gt;
&lt;li&gt;Mobile responsiveness&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Animation performance&lt;/li&gt;
&lt;li&gt;Browser compatibility&lt;/li&gt;
&lt;li&gt;Agent Skill behavior&lt;/li&gt;
&lt;li&gt;Missing components&lt;/li&gt;
&lt;li&gt;Bugs and unexpected behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful feedback can be as simple as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“This component installed successfully.”&lt;/li&gt;
&lt;li&gt;“The import path in the docs was unclear.”&lt;/li&gt;
&lt;li&gt;“The component breaks on mobile.”&lt;/li&gt;
&lt;li&gt;“The dark mode colors need improvement.”&lt;/li&gt;
&lt;li&gt;“The Agent Skill used the wrong component.”&lt;/li&gt;
&lt;li&gt;“This component should support another variant.”&lt;/li&gt;
&lt;li&gt;“I would like to see a component for this use case.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real usage feedback will help shape the next version.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open source and open for contributions
&lt;/h2&gt;

&lt;p&gt;Spark UI is open source and welcomes contributions.&lt;/p&gt;

&lt;p&gt;You can contribute by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a new component&lt;/li&gt;
&lt;li&gt;Improving an existing component&lt;/li&gt;
&lt;li&gt;Fixing a bug&lt;/li&gt;
&lt;li&gt;Improving accessibility&lt;/li&gt;
&lt;li&gt;Adding keyboard interactions&lt;/li&gt;
&lt;li&gt;Improving responsive behavior&lt;/li&gt;
&lt;li&gt;Updating documentation&lt;/li&gt;
&lt;li&gt;Creating a new demo&lt;/li&gt;
&lt;li&gt;Improving TypeScript types&lt;/li&gt;
&lt;li&gt;Adding validation&lt;/li&gt;
&lt;li&gt;Reviewing existing pull requests&lt;/li&gt;
&lt;li&gt;Suggesting new features&lt;/li&gt;
&lt;li&gt;Reporting installation issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before opening a pull request, please read the project’s &lt;a href="https://github.com/codeweb-dev/spark-ui/blob/master/CONTRIBUTING.md" rel="noopener noreferrer"&gt;&lt;code&gt;CONTRIBUTING.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The contribution guide explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository structure&lt;/li&gt;
&lt;li&gt;Component source requirements&lt;/li&gt;
&lt;li&gt;Demo requirements&lt;/li&gt;
&lt;li&gt;Registry configuration&lt;/li&gt;
&lt;li&gt;Documentation expectations&lt;/li&gt;
&lt;li&gt;Naming conventions&lt;/li&gt;
&lt;li&gt;Accessibility considerations&lt;/li&gt;
&lt;li&gt;Theme compatibility&lt;/li&gt;
&lt;li&gt;Validation commands&lt;/li&gt;
&lt;li&gt;Pull request expectations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following the contribution guide helps keep the registry consistent and makes reviews easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to try Spark UI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Visit the documentation
&lt;/h3&gt;

&lt;p&gt;Explore the available components and examples on the Spark UI website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://spark-ui-olive.vercel.app" rel="noopener noreferrer"&gt;https://spark-ui-olive.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Inspect a registry item
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn@latest view https://spark-ui-olive.vercel.app/r/kanban.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Install a component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn@latest add https://spark-ui-olive.vercel.app/r/kanban.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Install the Agent Skill
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add codeweb-dev/spark-ui &lt;span class="nt"&gt;--skill&lt;/span&gt; spark-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Share feedback
&lt;/h3&gt;

&lt;p&gt;You can open an issue, start a discussion, or submit a pull request in the GitHub repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://spark-ui-olive.vercel.app" rel="noopener noreferrer"&gt;spark-ui-olive.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub repository:&lt;/strong&gt; &lt;a href="https://github.com/codeweb-dev/spark-ui" rel="noopener noreferrer"&gt;codeweb-dev/spark-ui&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contribution guide:&lt;/strong&gt; &lt;a href="https://github.com/codeweb-dev/spark-ui/blob/master/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What comes next?
&lt;/h2&gt;

&lt;p&gt;Spark UI v1 is the foundation.&lt;/p&gt;

&lt;p&gt;Future improvements may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More application-focused components&lt;/li&gt;
&lt;li&gt;More layout and dashboard patterns&lt;/li&gt;
&lt;li&gt;Better installation examples&lt;/li&gt;
&lt;li&gt;Additional themes&lt;/li&gt;
&lt;li&gt;More accessibility testing&lt;/li&gt;
&lt;li&gt;Expanded Agent Skill documentation&lt;/li&gt;
&lt;li&gt;Improved component previews&lt;/li&gt;
&lt;li&gt;More community-contributed components&lt;/li&gt;
&lt;li&gt;Better test coverage&lt;/li&gt;
&lt;li&gt;More complete usage examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project will grow based on real feedback and contributions rather than only adding components for the sake of having a larger catalog.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Spark UI started as an attempt to build a practical, customizable, and developer-friendly component collection.&lt;/p&gt;

&lt;p&gt;Version 1 is now public, but it is still the beginning.&lt;/p&gt;

&lt;p&gt;My goal is to make Spark UI useful for developers who want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components they can fully own&lt;/li&gt;
&lt;li&gt;Source code they can inspect&lt;/li&gt;
&lt;li&gt;Styling they can customize&lt;/li&gt;
&lt;li&gt;AI-assisted workflows that understand the library&lt;/li&gt;
&lt;li&gt;An open project they can contribute to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would appreciate any feedback from developers who try it.&lt;/p&gt;

&lt;p&gt;GitHub stars, issues, suggestions, testing, and pull requests are all welcome.&lt;/p&gt;

&lt;p&gt;Thanks for checking out &lt;strong&gt;Spark UI v1&lt;/strong&gt;! ⚡&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>react</category>
      <category>ai</category>
    </item>
    <item>
      <title>PassionCast: Turn What You Love Into a Story Worth Hearing</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Fri, 10 Jul 2026 14:56:36 +0000</pubDate>
      <link>https://dev.to/a11en/passioncast-turn-what-you-love-into-a-story-worth-hearing-51k4</link>
      <guid>https://dev.to/a11en/passioncast-turn-what-you-love-into-a-story-worth-hearing-51k4</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;PassionCast&lt;/strong&gt;, an AI-powered storytelling experience that turns the memories behind a person's passion into a short narrated mini-documentary.&lt;/p&gt;

&lt;p&gt;The idea came from a simple observation: people often talk about &lt;em&gt;what&lt;/em&gt; they love, but they rarely get the chance to explain &lt;em&gt;why&lt;/em&gt; it matters so much.&lt;/p&gt;

&lt;p&gt;PassionCast asks the user four questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are you passionate about?&lt;/li&gt;
&lt;li&gt;How did that passion begin?&lt;/li&gt;
&lt;li&gt;What is your favorite memory connected to it?&lt;/li&gt;
&lt;li&gt;Why does it still matter to you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The user can then choose a storytelling tone, such as warm and nostalgic, emotional documentary, epic and cinematic, energetic superfan, or funny and playful.&lt;/p&gt;

&lt;p&gt;Google Gemini transforms those answers into a structured story with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A memorable title&lt;/li&gt;
&lt;li&gt;A short personal mini-documentary&lt;/li&gt;
&lt;li&gt;A highlight quote&lt;/li&gt;
&lt;li&gt;A shareable caption&lt;/li&gt;
&lt;li&gt;Narration direction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ElevenLabs then turns the written story into expressive narration.&lt;/p&gt;

&lt;p&gt;The final result combines the generated story, quote, audio player, and a visual voice experience so the user can both read and hear the story behind what they love.&lt;/p&gt;

&lt;p&gt;My main goal was not to build another generic AI text generator. I wanted PassionCast to feel like a small personal documentary studio: emotional, playful, and easy to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://passioncast.vercel.app" rel="noopener noreferrer"&gt;Open PassionCast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open PassionCast.&lt;/li&gt;
&lt;li&gt;Start with a randomized example or write your own answers.&lt;/li&gt;
&lt;li&gt;Choose a storytelling tone.&lt;/li&gt;
&lt;li&gt;Generate the mini-documentary.&lt;/li&gt;
&lt;li&gt;Read the story while the narration is prepared.&lt;/li&gt;
&lt;li&gt;Play the ElevenLabs narration.&lt;/li&gt;
&lt;li&gt;Copy the story or caption, retry the voice, or create another story.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt; &lt;a href="https://github.com/codeweb-dev/passioncast" rel="noopener noreferrer"&gt;View the PassionCast source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository includes the frontend experience, server-side AI routes, validation, reusable UI components, and the Gemini and ElevenLabs integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I built PassionCast with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next.js App Router&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Gemini API&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ElevenLabs API&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zod&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React Bits&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lucide React&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Poppins&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Browser local storage&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Story generation with Google Gemini
&lt;/h3&gt;

&lt;p&gt;The user's answers are sent to a server-side Next.js route.&lt;/p&gt;

&lt;p&gt;Gemini receives a carefully constrained storytelling prompt that tells it to preserve the user's real experience, avoid inventing names or events, and return a story that sounds natural when spoken aloud.&lt;/p&gt;

&lt;p&gt;Instead of requesting unstructured text, I ask Gemini to return a predictable object containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;story&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;quote&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;caption&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;narrationDirection&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The response is validated before it reaches the interface. This made the application more reliable and made it much easier to render the result consistently.&lt;/p&gt;

&lt;p&gt;A major design decision was to keep the story factual. Gemini can improve the emotional structure and language, but it should not fabricate details that the user never provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Narration with ElevenLabs
&lt;/h3&gt;

&lt;p&gt;After Gemini creates the story, PassionCast sends the narration text to a protected server-side ElevenLabs route.&lt;/p&gt;

&lt;p&gt;ElevenLabs gives the written story a voice and turns the result into something closer to a personal documentary than a normal generated paragraph.&lt;/p&gt;

&lt;p&gt;The audio experience includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Play and pause controls&lt;/li&gt;
&lt;li&gt;Playback progress&lt;/li&gt;
&lt;li&gt;Replay&lt;/li&gt;
&lt;li&gt;Volume controls&lt;/li&gt;
&lt;li&gt;Narration retry&lt;/li&gt;
&lt;li&gt;A visual Strands treatment around the voice experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The written story appears before narration finishes, so the user is never forced to wait for audio before seeing the main result.&lt;/p&gt;

&lt;p&gt;If narration fails, the generated story remains available. The user can still read it, copy it, or retry the voice without losing their work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing the experience
&lt;/h3&gt;

&lt;p&gt;I wanted PassionCast to feel human and expressive instead of looking like a generic AI dashboard.&lt;/p&gt;

&lt;p&gt;The design uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A warm editorial color palette&lt;/li&gt;
&lt;li&gt;Bold Poppins typography&lt;/li&gt;
&lt;li&gt;Large rounded content cards&lt;/li&gt;
&lt;li&gt;Asymmetrical layouts&lt;/li&gt;
&lt;li&gt;Bright accent colors&lt;/li&gt;
&lt;li&gt;Lucide React icons&lt;/li&gt;
&lt;li&gt;React Bits animations used selectively&lt;/li&gt;
&lt;li&gt;Strands as the visual language for voice&lt;/li&gt;
&lt;li&gt;Accessible controls and reduced-motion support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The visual direction is inspired by modern editorial landing pages, but the interface and brand were created specifically for PassionCast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making it easy to start
&lt;/h3&gt;

&lt;p&gt;One challenge with creative tools is the blank-page problem.&lt;/p&gt;

&lt;p&gt;To make the app easier to try, PassionCast can prefill the form with a starter example. The user can edit everything, clear the form, or use &lt;strong&gt;Surprise Me&lt;/strong&gt; to see a different idea.&lt;/p&gt;

&lt;p&gt;This makes the main interaction understandable immediately while still encouraging users to replace the example with their own story.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reliability and validation
&lt;/h3&gt;

&lt;p&gt;I added validation to both user input and generated output.&lt;/p&gt;

&lt;p&gt;The application handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empty or oversized inputs&lt;/li&gt;
&lt;li&gt;Invalid AI responses&lt;/li&gt;
&lt;li&gt;Network failures&lt;/li&gt;
&lt;li&gt;Gemini errors&lt;/li&gt;
&lt;li&gt;ElevenLabs errors&lt;/li&gt;
&lt;li&gt;Duplicate submissions&lt;/li&gt;
&lt;li&gt;Audio retry states&lt;/li&gt;
&lt;li&gt;Malformed local-storage data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;API keys remain on the server and are never exposed to the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;I am submitting PassionCast for:&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Use of Google AI
&lt;/h3&gt;

&lt;p&gt;Gemini is the narrative engine behind PassionCast.&lt;/p&gt;

&lt;p&gt;It does more than summarize the user's answers. It identifies the emotional thread connecting the beginning of the passion, the user's strongest memory, and what that passion represents today.&lt;/p&gt;

&lt;p&gt;Gemini also returns structured output, which makes the story-generation flow more reliable and allows the interface to separately present the title, story, quote, caption, and narration direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Use of ElevenLabs
&lt;/h3&gt;

&lt;p&gt;ElevenLabs transforms the generated story from something the user reads into something they experience.&lt;/p&gt;

&lt;p&gt;The voice is a core part of the product rather than a decorative extra. PassionCast is designed around the idea that hearing a personal story can make it feel more intimate, memorable, and cinematic.&lt;/p&gt;

&lt;p&gt;The narration, custom audio controls, retry experience, and Strands visualization all contribute to the final listening experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges I Faced
&lt;/h2&gt;

&lt;p&gt;The hardest part was balancing creativity with truth.&lt;/p&gt;

&lt;p&gt;I wanted Gemini to produce something emotional, but I did not want the model to invent details. I solved this by placing strict limits on the prompt, using structured output, and validating the response before displaying it.&lt;/p&gt;

&lt;p&gt;Another challenge was handling two AI services in one user flow. Story generation and narration can succeed or fail independently, so I designed the result state so the written story remains useful even when audio is unavailable.&lt;/p&gt;

&lt;p&gt;The third challenge was presentation. It was easy for the project to look like a normal form followed by generated text. I spent time turning the experience into something that feels closer to an editorial feature and a small audio-documentary studio.&lt;/p&gt;

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

&lt;p&gt;This project taught me that structured AI output is especially useful when the result needs to power a real interface.&lt;/p&gt;

&lt;p&gt;I also learned that graceful failure matters a lot in multi-service AI applications. A narration error should not destroy a successful story, and a user should always know what happened and what they can do next.&lt;/p&gt;

&lt;p&gt;Most importantly, I learned that AI experiences feel more meaningful when the technology supports a clear emotional purpose. Gemini provides the structure and language, while ElevenLabs delivers the voice. Together, they help preserve the story behind a person's passion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Passion can be loud, quiet, competitive, creative, nostalgic, or deeply personal.&lt;/p&gt;

&lt;p&gt;PassionCast is my attempt to give those feelings a format that people can keep, hear, and share.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every passion has a story. PassionCast gives it a voice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading, and thanks to the DEV Community for creating a challenge that encouraged me to build something personal.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>🚀 I Built DevBrand AI with Google AI Studio</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Sat, 27 Jun 2026 06:30:39 +0000</pubDate>
      <link>https://dev.to/a11en/i-built-devbrand-ai-with-google-ai-studio-5ehl</link>
      <guid>https://dev.to/a11en/i-built-devbrand-ai-with-google-ai-studio-5ehl</guid>
      <description>&lt;p&gt;&lt;em&gt;This post is my submission for &lt;a href="https://dev.to/deved/build-apps-with-google-ai-studio"&gt;DEV Education Track: Build Apps with Google AI Studio&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What I Built&lt;/p&gt;

&lt;p&gt;For this project, I built DevBrand AI, an AI-powered web application that helps developers create a complete personal branding kit in just a few clicks.&lt;/p&gt;

&lt;p&gt;Instead of manually writing bios, portfolio headlines, README introductions, or designing graphics, users simply provide their GitHub username, role, tech stack, experience, and preferred design theme. The application then generates everything automatically.&lt;/p&gt;

&lt;p&gt;Prompt Used&lt;/p&gt;

&lt;p&gt;I used Google AI Studio's Build apps with Gemini feature with a prompt similar to this:&lt;/p&gt;

&lt;p&gt;Build a modern React + TypeScript application called DevBrand AI that generates a complete developer branding kit. Use Gemini to generate professional bios, portfolio headlines, GitHub README introductions, project ideas, mission statements, social media introductions, CTAs, and branding recommendations. Use Imagen to generate a modern 3D developer mascot, hero illustration, and portfolio banner. Create a responsive UI using Tailwind CSS with reusable React components, loading animations, copy buttons, and download functionality.&lt;/p&gt;

&lt;p&gt;Features&lt;br&gt;
🤖 AI-generated developer bio&lt;br&gt;
🎯 Personal tagline&lt;br&gt;
💻 Portfolio headline&lt;br&gt;
📄 GitHub README introduction&lt;br&gt;
💡 Project ideas&lt;br&gt;
🌈 Suggested branding colors&lt;br&gt;
📢 Social media introduction&lt;br&gt;
🚀 Portfolio call-to-action&lt;br&gt;
🎨 AI-generated developer mascot&lt;br&gt;
🖼️ Hero illustration&lt;br&gt;
🌐 Portfolio banner&lt;br&gt;
📋 Copy buttons&lt;br&gt;
📥 Download generated content&lt;br&gt;
📱 Responsive modern interface&lt;br&gt;
Demo&lt;/p&gt;

&lt;p&gt;Screenshots&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7efyg2zftta49m77zrm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr7efyg2zftta49m77zrm.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live Demo&lt;/p&gt;

&lt;p&gt;App: &lt;a href="https://devbrand-ai-706459620449.asia-southeast1.run.app" rel="noopener noreferrer"&gt;https://devbrand-ai-706459620449.asia-southeast1.run.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My Experience&lt;/p&gt;

&lt;p&gt;This project was my first time using the new Build apps with Gemini experience in Google AI Studio, and it was surprisingly fast to go from an idea to a working application.&lt;/p&gt;

&lt;p&gt;What impressed me most was how the AI generated a well-structured React + TypeScript project instead of just producing a single file. The generated components, services, and overall architecture made the project easy to understand and extend.&lt;/p&gt;

&lt;p&gt;I also enjoyed combining Gemini for structured text generation with Imagen for visual assets. Seeing both models work together in one application made it feel like building a complete product rather than just experimenting with AI.&lt;/p&gt;

&lt;p&gt;Overall, this experience showed me how AI can significantly accelerate prototyping while still leaving room for customization and refinement. I'll definitely continue using Google AI Studio to quickly validate ideas and build future projects.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Feedback is always welcome.&lt;/p&gt;

</description>
      <category>deved</category>
      <category>learngoogleaistudio</category>
      <category>ai</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Who Is JSON?</title>
      <dc:creator>Allen Labrague</dc:creator>
      <pubDate>Sat, 27 Jun 2026 06:04:18 +0000</pubDate>
      <link>https://dev.to/a11en/who-is-json-4f4i</link>
      <guid>https://dev.to/a11en/who-is-json-4f4i</guid>
      <description>&lt;p&gt;Asked AI "Who is JSON?" and it introduced me to JSON Derulo. I wasn't expecting that one. 😂&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpq26th9vtb410a7f99iy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpq26th9vtb410a7f99iy.jpg" alt=" " width="746" height="955"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>memes</category>
      <category>jokes</category>
    </item>
  </channel>
</rss>
