Building a flat white for pickup, on a phone, on the morning the shop has run out of the milk your saved drink is made with.
The fourth brand specimen, and the warm one. It is also the only page in this portfolio whose canvas is not white or near-black.
Where the style comes from
Transcribed from awesome-design-md/design-md/starbucks/DESIGN.md, read 2026-09-16, and emitted by:
python3 tools/brand_tokens.py starbucks-brand > systems/starbucks-brand/tokens.css
python3 tools/brand_tokens.py starbucks-brand --check
python3 tools/brand_tokens.py --self-test
| Decision | Transcribed |
|---|---|
| Canvas | #f2f0eb, a cream — white is what a card is made of |
| Greens | brand #006241, accent #00754a, house #1e3932, uplift #2b5148, light #d4e9e2 |
| Gold | #cba258, "never a general-purpose brand color" — reserved for rewards |
| Semantics | error #c82014, warning #fbbc05 |
| Type | 80 · 58 · 45 · 24 · 19 · 16 · 14 · 13 px |
| Tracking | default negative, -0.01em, even at body size |
| Weights | 400 and 600 |
| Radii | 12px cards, 50px full pill on every button |
| Motion | published: 0.2s / 0.3s / 0.4s, ease-out, plus an overshoot curve |
| Press | scale(0.95) — the signature micro-interaction |
| Depth | whispered; 0.14 and 0.24 alpha, one assertive floating button |
The finding that shaped the generator's ramp. Two of this brand's text values are published as ALPHA blacks — rgba(0,0,0,0.87) and rgba(0,0,0,0.58) — and a translucent value cannot go in a ramp the solver walks, because it has no fixed contrast until you know what is behind it. Both are composited against this brand's own cream canvas and the solid result is what the ramp carries. The derivation is stated in the generator rather than the composited numbers being presented as published values.
Two measured pairs worth naming. White on the green action reads 5.76:1, so the reference's own filled CTA is legal as published. The same green as a WORD on the cream canvas reads 4.71:1 and on the recessed band 4.51:1, so accent-text is a shade deeper than the fill — the same split the other three brands here needed, arrived at independently each time.
The direction
- Archetype. Wizard.
- Data stance. Tile-first.
- Density. Comfortable, touch — every target at least 44px, pills at 48.
- The one bold decision. The shortage is stated where the choice is made, not at checkout. Most ordering apps let somebody build the whole drink and then refuse it at the till, which wastes the order and the walk. The unavailable option stays on the screen, disabled, saying why — removing it would leave somebody hunting for the thing they always choose — and the two ways out sit above the tiles: another milk, or another shop with the extra distance stated.
The second state
The out-of-stock ingredient, which is the state a mobile order actually breaks on and the one every demo of one leaves out. It is the hardest state a wizard has, because a wizard's whole promise is that the steps are answerable.
Deviations from CONTRACT.md
- §2, the typeface. SoDoSans is proprietary. Nunito Sans is substituted — the closest open-licensed humanist sans at 400 and 600 with the rounded terminals this language pairs with its pill geometry.
- §5, motion. No deviation, unusually: the reference publishes its durations and the 0.2s rung is already inside the 250ms exit cap, so nothing had to be chosen. The
scale(0.95)press is switched OFF rather than shortened underprefers-reduced-motion, which is the one place this portfolio's "shorten, never delete" rule does not apply — a transform is exactly what that setting is about, and there is notransitionendwaiting on it. - §1, one composited value family. The two alpha text values, as above.
Findings kept, with reasons
slop_scan·overshoot-easing— the reference's owncubic-bezier(0.32, 2.32, 0.61, 0.27). It is emitted because the generator carries a brand's published motion vocabulary whole, the way the other generators here carry a published ramp whole; the page itself does not use it, and leaving it out would have made this the one brand quietly edited for taste.slop_scan·default-ai-palette— a deep green and a cream. The rule allows it where the brief asked for it, and the brief is the brand.craft_lint·disabled-unstyled— the rule looks for utility-class variants; the disabled control is styled by.pill[disabled]and carriesaria-describedbynaming what would make it live.audit_page·apple-touch-icon-missing,manifest-missing— portfolio-wide.copy_lint·name-drift— seecopy-lint.ignore.
What the gates changed
craft_lint's no-primary-action caught the two recovery buttons drawn at the same weight. One of them finishes the order here and now; the other costs a nine-minute walk to a different shop. Drawing them identically made the reader decide twice, so the first is now the filled pill.