Every screen measured against the Apple design skill and the researched industry standards. What changed, what rule it broke, and why it is better.
apple-design §15 · hierarchy from weight + size + leading — not from repeating one style
Space Mono caps was on 113 places plus all 44 buttons — weekdays, durations, ticket counts, statuses, every button in both apps. theme.ts already said “use sparingly… section labels only”; the code did the opposite. A strong texture repeated everywhere stops reading as character and starts reading as a template. It is now on 54 places, all of them genuine section headings.
Winter concert
Winter concert
dataviz · a boxed tile grid is the stock dashboard look; rows let values line up
Four bordered tiles in a 2×2 all fight for attention, so nothing reads as more important than anything else. As rows, the labels line up in one column and the figures in another, so they can actually be compared — and the money section now leads with one headline figure instead of four of equal weight.
Money
Money
apple-design §16.4 familiarity · iOS marks a choice, it does not repaint it
The selected row inverted to solid ink. On a list of seven branches that is a full-width black bar shouting at you — and an inverted row is a spreadsheet highlight, not a considered choice. iOS picks with a checkmark and leaves the row alone; the weight change on the label carries the rest.
Teacher rate
Teacher rate
apple-design §16.6 simplicity · burying everything in one place looks minimal but is not simple
The staff Me tab was your profile and the console for running a music academy: identity, a wall of 41 permission words, then sixteen admin rows under three headings. Splitting them is the fix; restyling the same pile would not have been. Sixteen rows moved to their own screen, in five short groups — a group stops being scannable past about six rows.
Me.
Run the academy
Money
Me.
The academy
Account
apple-design §16.4 familiarity · things that look the same must behave the same
Photos & clips had three parallel sections — but two were wrapped in a card and one was a bare button. It also never said whether you had any clips, so it failed wayfinding: a screen must answer “what’s there?”. And every heading repeated the button beneath it (YOUR PHOTO over Add a photo), which is the weak-mapping smell. It is a list of three things you can add, each with a state — so it is rows.
Your photo
Playing video
Performance clips
A short video of you playing helps a teacher put you at the right level before your first lesson.
WCAG 2.2 · 4.5:1 for body text — measured against every surface, not the easiest one
Contrast was calculated for every text colour against paper, card and paperDeep. Three failed: the grey under every name and hint at 3.25:1, the warning colour carrying “4 unpriced” at 3.54:1, and the yellow accent at 2.98:1 — failing even the large-text bar, so the word we chose to highlight was the least legible thing on screen. All now clear 4.5:1.
3.25:1 · 2.98:1 · 3.54:1 — all under the bar
4.50:1 · 4.51:1 · 4.55:1 — all clear
smaller fixes, same rules
Button now, one height, variants named by importance not colour.Card = content, Note = us talking about the content.two research passes, ~300 cited rules
_DESIGN/. Every rule is tagged
[EVIDENCE] / [CONVENTION] / [OPINION] and cited, and
both files are explicit about what could not be verified.
honest limits
theme.ts at build time so they cannot drift, but they are re-creations.
simctl takes real screenshots. It is blocked on
one command that needs your password:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
simctl has no input support,
AppleScript is unavailable here, and CocoaPods is not installed so a native dev build cannot
be made. Expo Go puts a first-run dev-menu sheet over the app that needs exactly one tap to
dismiss; I tried five ways to suppress it and none worked. Run that one line and the next
pass can screenshot and click through every screen for real.
_DESIGN/SIMULATOR_BLOCKER.md.RESEARCH_STANDARDS E14/E24 · loading must never be mistakable for empty
CLAUDE.md §7 records that this
API resets roughly one request in three. So a desk person would have turned a parent
away, or a parent would have chased the academy about a problem that did not exist. Both now
say which of the three states they are actually in.Time
…said after a failed request
Time
…and “no times” only when there genuinely are none
from RESEARCH_STANDARDS.md
| 1 · Contrast | every text colour now ≥4.5:1 against all three surfaces |
| 2 · Targets | every tappable thing ≥44pt — verified by brace-matching each style block |
| 3 · Dynamic Type | ⚠️ needs a device — but nothing disables font scaling anywhere |
| 4 · Grouping | 3:1 between/within rhythm, now the same on tabs and pushed screens |
| 5 · Hierarchy | one filled button visible per screen (8 flagged, all mutually-exclusive states) |
| 6 · States | 2 real bugs fixed — failure rendered as fact |
| 7 · Latency | nothing under 1s, per NN/g |
| 8 · Motion | 120 / 200 / 320ms — all inside the researched bands |
| 9 · Forms | validation moved into the field; 2 placeholder-as-label fixed |
| 10 · Semantics | icon-only controls labelled — both back buttons had none |