Breed Whisperer — know any dog with Google AI (and pure CSS)
A dog breed identifier for the DEV Weekend Challenge: Dog Days Edition. Upload a photo of any dog and Google AI (Gemini) whispers back its breed, confidence, personality and care tips — in seconds. The dog on this page isn't a photo: it's drawn entirely in pure CSS, no images, no SVG.
🔗 Live demo: https://dog.bmops.tech
The story
Every dog has a story. The Elkhound that guarded Viking hunts. The lab who's "just a good boy" (very rare breed). The park stranger who absolutely deserves a treat.
Breed Whisperer is my tiny contribution to understanding them: point your camera at a dog and ask Google's newest vision model. It tells you who they are, what they're like, and how to take care of them. Three seconds, no signup, nothing stored.
What I built
-
🐶 Pure-CSS dog — the hero illustration is hand-drawn with divs, layered
box-shadowand gradients (the cyanHarlow technique): floppy ears, a wagging tail, a panting tongue, a collar with a shiny tag. The tail and tongue animate with CSS keyframes (disabled forprefers-reduced-motion) - 📷 Drag-and-drop upload — click or drop a photo, see a live preview, and Gemini reads it
-
🧠 Google AI identification — the photo goes to
gemini-3-flash-previewvia the Gemini API, which returns breed, confidence, a personality read, a care tip, and a "did you know?" fact -
♿ Accessible by default — skip link, semantic landmarks, keyboard-operable upload (Enter/Space),
role="status"live regions, visible focus, 0 axe-core violations, responsive from 360px to desktop
How it works
- Snap it — any camera, any dog, any park
- Gemini sees — one private request to Google AI's vision model; nothing is stored
- Whisper back — breed + personality + care tips in under ten seconds
The Google AI bit (and a 2026 gotcha)
I chased a 401 for a while before realising the API key format changed: new keys are AQ... and must be sent with the x-goog-api-key header, not ?key=. And gemini-2.5-flash is retired for new accounts — gemini-3-flash-preview is the current workhorse. Once I switched both, the first real photo (a very majestic Norwegian Elkhound) came back perfectly:
Elkhound Noruego · confidence: alta
— national dog of Norway, used by Vikings to hunt moose.
Care: frequent brushing (dense double coat) + lots of daily exercise.
Why pure CSS for the dog
The challenge is about dogs, and dogs are character. I wanted the page itself to have a personality — not a stock photo, but a hand-drawn companion rendered by the browser. Every shadow on its fur is an inset box-shadow; every ear is a rotated border-radius ellipse. The whole illustration is ~200 lines of CSS. No <img>, no <svg>, no canvas — one file, ~17 KB.
What I learned / enjoyed
- The new Google AI key format (
AQ...+x-goog-api-keyheader) — documented for the next dev who hits the same wall - Layered inset shadows make CSS fur feel soft (same trick as clay pots in my previous challenge entry 😄)
- Gemini's vision model handles messy real-world photos (park dogs, dark fur, motion blur) surprisingly well
- An accessible upload widget is easier than it looks: one input, two drag events, three ARIA attributes
Tech
HTML5 · CSS3 (pure-CSS illustration, keyframes, prefers-reduced-motion) · Vanilla JS (fetch, drag & drop, live regions) · Google AI — Gemini 3 Flash Preview (vision) · FastAPI backend · Zero images · Zero dependencies · 0 axe violations
Built for the DEV Weekend Challenge: Dog Days Edition · submitted in the **Best use of Google AI* category · all illustrations are pure CSS · no dogs were emotionally manipulated (much).*
Top comments (0)