Lab · exploring · May 5, 2026
KuKi - a pattern-tracking health companion for chronically ill pets
Hypothesis
A pet parent managing a chronic condition needs a tool that lets them ask questions of their logs, not just record them - and a solo builder with rigorous specs and AI coding tools can ship that in under a month.
Outcome
Working alpha, invite-only with 6-15 pet parents. Confirmed the core bet - data separation has to be a query-level rule, not a UI filter, and a single wellness score can alarm the exact caregiver it's meant to help.
My wife and I have two chihuahuas. In late 2023 one of them, Kingini, started having seizures from an undiagnosed neurological condition. We tracked everything by hand for three years - WhatsApp for notes, Google Calendar for reminders, Excel for the pattern analysis - across three tools that were never built to talk to each other. KuKi is my answer to a gap I lived through personally, then validated with other pet parents.
The gap
WhatsApp and notes apps are easy to log into and impossible to search. Google Calendar handles reminders but has no room for symptoms. Spreadsheets can do the analysis but ask for more effort than most pet parents have to give. Paper vet records sit scattered, rarely cross-referenced with what’s actually happening at home. No consumer tool lets you log pet health data and then actually ask questions of it - the way you’d want to for a condition you’re living with day to day.
There’s no direct competitor in pet health built for chronic condition tracking specifically. The closest reference point was human health-tracking apps - symptom trackers, chronic illness tools - borrowed for patterns like baseline-relative scoring and longitudinal trend views, then adapted for a pet-parent-as-proxy-reporter context. Everything else - the taxonomy, the illness-specific tools, the adaptive Home screen - came from three years of our own trial and error, not from copying an existing app.
The method: data, then design, then code
The research base was unusually deep going in: three years of first-party data - WhatsApp logs, Excel timelines, vet and neurology reports, ongoing input from a veterinary neurologist. An early invite-only alpha checked this wasn’t a “just us” problem - several alpha testers manage chronic conditions in their own pets too.
Design took a year in Figma before any code got written, reworked multiple times. The biggest rework: splitting one flat “care focus” list into separate goals, watchlist, and condition layers once it was clear they were different mental models for a pet parent. Every implementation brief followed a strict format - non-negotiable rules first (data separation, dummy-data conventions, required UI states), then feature specs - so AI tools couldn’t quietly violate an established constraint while building something new. Specs used a confidence-marker system (certain / likely / assumption / unknown) so ambiguity was visible in the doc, not discovered mid-build.
Execution ran on Google Antigravity as the primary build environment (using the Firebase MCP to scaffold auth, Firestore, and storage) and Claude Code for structured build tasks. Design and the portfolio case study were built in parallel with the app, not after. The first working build came together in under a month.
Key decisions
- Health and Daily are split into separate tabs, not folded into one “Logs” view - diagnostic history and day-to-day routine are different mental categories for a pet parent, and the split is enforced at the query level after an early build let seizure events leak into the Daily tab.
- Profile shows the pet, not the user - every other tab is scoped to the active pet, so Profile follows the same pattern instead of switching to “account mode.” It also solves multi-caregiver sharing for free.
- Home is adaptive, not fixed - independent modules reordered per pet based on their goals, conditions, and usage. A watchlist symptom starts as a one-tap quick-log chip; log it three or more times in fourteen days and it auto-promotes to a full tracker with its own trend graph.
- The wellness score baselines against the pet’s own history, never a breed average, and deductions decay instead of resetting. Chronic-illness pets get a Symptom-Free Streak instead of a single score - a dropping number tested as alarming, not informative, for a caregiver already managing a hard condition.
- The AI chatbot has three scoped jobs only: food toxicity Q&A against a closed, curated list (never an improvised safety judgment), health summaries over pre-aggregated data, and natural-language queries where real Dart functions run the Firestore queries - not a custom-trained model reasoning freely.
Designing the Health tab’s charts
This round of chart selection ran the same way as the rest of the build - fast mockup comparisons in chat, checked against the actual data, before anything went into Figma. The Health tab’s job is analysis, not action, so every chart type got tested against the data it was supposed to represent, not picked for how it looked. That meant a first pass that used the wrong chart for more than one metric, and some back and forth to fix it before design work started.
Seizures started as a bubble chart, and bubbles lost the readability test. Duration, seizure type (grand mal, focal), and time of day all needed to show up in one place, and a bubble’s size is genuinely hard to compare at a glance across a week or month of data. Three alternatives got mocked up side by side: a lollipop/stem chart (stem height for duration, colour for type), a type-stacked bar (colour for type, no duration), and a plain coloured dot strip (simplest to build, but duration invisible entirely).

Lollipop won. Stem length reads faster than bubble area, and duration on its own is clinically the thing you want to catch at a glance - a 60 second seizure and a 1 second one look nothing alike as stems, everything alike bucketed into the same bar. The stem height uses a log scale, not linear, fixed to a 5 minute (300 second) ceiling - a linear scale flattens anything under a minute to nothing next to a five-minute event, so the scale itself had to be picked for the data’s actual range, not for looking clean.

Seizure Frequency, Weekly. Stem height on a log scale, colour for Grand Mal versus Focal, exact duration printed on every dot.

Seizure Frequency, Monthly. Same data, zoomed out - a heatmap trades type detail for a full month’s pattern at a glance.
Crying got the same chart, once the data caught up with the question. The first version used a zigzag line for episodes per day and minutes per day - and a connected line implies interpolation between points that doesn’t exist for a discrete event like a cry. The right shape already existed on the same screen set: a heatmap calendar, already built for the generic symptom watchlist, correct for anything that’s frequency-only. Once crying moved from “did it happen” to “how long did it last” - start and end time, not just a flag - it needed the same duration treatment as seizures: lollipop for day and week, heatmap for the month overview. One catch surfaced before this could ship: the logging as built only captured a boolean “observed” flag, not an actual duration - so the build order became fix the data model, then draw the chart, not the other way round.
Weight got one line added: a target. A dashed reference line marks the goal weight set at onboarding, for any pet on a weight management goal - not just ones trying to lose weight, since a healthy pet can have a maintenance target too. If no target is on file, the line simply does not render. A baseline invented for a pet that never set one would be worse than no baseline at all.

Weight, with a target. The only addition to an existing chart - a dashed line for the goal set at onboarding, shown only when one exists.
Sleep, water, and food kept their bar charts, and fixed a labelling bug hiding underneath them. The x-axis was unreadable in month view - every date was trying to render at once. The fix was not just “show fewer labels.” It surfaced that “Monthly” was not a calendar month at all - it was a rolling 30-day window mislabelled with a month name. Once that got corrected to a true calendar month, the axis fix became simple: label only the 1st, 8th, 15th, 22nd, and 29th.

Sleep Patterns, Monthly. The same bar-chart shape is reused for water and food - only sleep is shown here since the other two are visually identical.
The pattern that held across all four: one chart shape per kind of data, reused everywhere that data type shows up, rather than a bespoke chart per symptom. Duration-based events (seizures, crying) get lollipop plus heatmap. Frequency-only symptoms get heatmap alone. Cumulative daily totals (sleep, water, food) get bar charts. Slow, continuous trends (weight) get a line. Four shapes cover the entire Health tab.
What it looks like
The Symptom-Free Streak in the four states a caregiver actually sees it in, from an active alert through two clear weeks. Same screen, same score logic, deliberately different colour and tone at each end.

Kingini needs attention. A red alert card after 2 grand mal seizures logged today, the streak reset to 0 days.

Kingini had a mild episode. An amber card after 1 focal seizure, streak still at 0 days.

Kingini had a quiet week. A light green card marking a 5 day symptom-free streak.

Kingini is doing well! A dark green card at 14 symptom-free days.
The Daily tab: one running timeline instead of the WhatsApp and Excel split from before, shown in both themes.

Daily Logs, light theme. A timestamped timeline of activity, food, water, and bathroom entries.

Daily Logs, dark theme. The same timeline.
Health records, X-rays, prescriptions, vaccination history, live in one searchable place instead of scattered across paper and photo albums.

Files, light theme. A chest X-ray and a prescription under the pet’s health records.

Files, dark theme. The same records.
What I learned
- Data separation is an architecture rule, not a display concern. The seizure-data leak taught me this needs enforcing at the query level, every time - not patched with UI filtering after the fact.
- A single wellness score can hurt the exact user it’s meant to help. For a chronic-illness caregiver, a dropping number reads as a crisis signal, not a data point. The Symptom-Free Streak came directly from that.
- Safety-critical AI features need closed data, not clever prompting. For anything like food toxicity, the model should retrieve from a curated list, never reason its way to a safety judgment.
- Solo-with-AI still needs team-level rigor. Writing non-negotiable rules before every feature brief is what kept the build from drifting or reintroducing old bugs.
- The hardest UX problem wasn’t a screen, it was a taxonomy. Splitting one flat list into goals, watchlist, and conditions took several iterations - and unlocked most of the adaptive Home logic downstream.
What’s next
An iOS release after Android. Moving the AI features to a paid tier or Vertex AI before wider rollout, since the free tier carries data-privacy tradeoffs for sensitive pet health data. Pattern detection and proactive vet-visit recommendations - deliberately deferred, extending the existing rule-based promotion logic before reaching for ML. Expanding the alpha group, and vet-sharing for care-team collaboration.