Cast Forecast

See a mineral sunscreen's predicted white cast on your own selfie before you buy it. Live: https://cast-forecast.vercel.app · Code: https://github.com/StephenSook/cast-forecast · No login, no install.

The problem

A mineral sunscreen's label tells you how much zinc is in it. It does not tell you how white it will look on your face. In a 2024 dermatology survey, 25% of respondents with skin of color reported concerns about white cast (7% of non-Hispanic White respondents), and 41% reported not knowing how to find suitable products (Wang et al., J Drugs Dermatol 2024). Today you find out after you buy the bottle.

What it does

  1. Take a selfie or upload one.
  2. Tap Suggest my tone: YouCam reads your skin type and the site suggests a starting tone. You can change it.
  3. Tap a bottle, or search any of 687 FDA-listed mineral sunscreens. YouCam paints an approximation of that bottle's predicted cast on your face. Drag the slider for before and after.

No selfie handy? Tap Use a sample face to see recorded results without uploading anything.

Why you can trust the number

  • It starts from the bottle's FDA label (the zinc oxide percent), linked on DailyMed.
  • My model, fitted to a 2025 study of 13 volunteers, turns that into lightening for your tone. Tested on data it never saw: it misses by 1.61 L* on average (1.80 on darker skin). Every result shows its range.
  • It refuses instead of guessing: skin deeper than the study, or zinc outside 5 to 30%, gets no number and a sentence saying why.
  • Check it yourself: curl -s https://cast-forecast.vercel.app/api/label-model returns the 1.61, computed by the shipped code from the study's raw data.

Who it helps

  • Shoppers with medium to deep skin: compare mineral sunscreens on their own face before buying. The same bottle is predicted to leave more cast on deeper skin (+5.3 to +8.3 L* across five tones), and the app shows it.
  • Stores and brands: it runs from labels they already have. It already covers 687 zinc-only sunscreen labels from the FDA's database, each with its own page, so it can sit next to the zinc sunscreens a store sells, online or on a shelf.
  • AI shopping agents: the same predictions are callable tools over MCP: search the 687 labels, predict a cast for any of them.

How it is built (the tech, in depth)

Cast Forecast uses two Perfect Corp YouCam APIs, each for the job it is best at. YouCam AI Fitzpatrick Skin Type Analysis (Skin category) reads the selfie and suggests a starting tone from five study-range tones; I map each type to a tone by skin-tone class (Del Bino 2006), taking the deeper tone inside a class so a cast is never understated; type VI maps to Deeper, which gets no number. The shopper can always change it. YouCam Makeup VTO (Beauty category) renders the cast: a foundation effect in the bottle's white, where I control how strong it looks. To set the try-on strength from the number, I ran 16 renders of my own selfie across the full strength range, measured the lightening each produced, and fitted the curve (R² 0.98); the app inverts that curve to pick the strength for each bottle and tone. Both APIs are called server side through Perfect Corp's REST flow (upload, create task, poll), so the key never reaches the browser, with per-session and per-IP limits and a credit floor so judges' try-ons cannot drain the account. The bottle data comes from the FDA: openFDA's drug label API, filtered to labels whose only active ingredient is zinc oxide: of 4,034 zinc records, 687 sunscreen labels are kept after leaving out tinted, powder, lip, unreadable and duplicate labels (each reason counted), each pinned to its DailyMed label. The model is fitted on the raw data of Maldonado Lopez et al., PLOS ONE 2025 (CC BY 4.0) in Python and ported to TypeScript, and tests pin the port to the Python's published numbers (the endpoint serves the 1.61 the shipped code computes from the raw data). The web app is Next.js on Vercel; GitHub Actions runs lint, type checks, tests, the build and a bundle scan for leaked keys on every push, and a daily job checks the live site and the credit balance. For agents, /api/mcp is a Model Context Protocol server (search the labels, predict a cast for any of them, get the held-out error) and /llms.txt explains it in plain text.

Honest limits

Every cast is a prediction from the label, not a measurement on a person, and the render was calibrated on one person. It shows how a sunscreen looks, not how well it works.

Built solo by Stephen Sookra, a student at Kennesaw State University ([email protected]).

Built With

Share this project:

Updates

Submission history