Voice Studio · the mascot · 2026-08-10

Mai. A girl who
teaches you
the language.

The app-premise embodied. She is drawn only in the design tokens on the tokens page, ships static, and appears on a closed list of surfaces — possession of an asset is not permission to deploy it. Her canon is the accepted-image corpus plus its prompt manifests in product/mascot/assets/mai/; the ruling ledger is DESIGN.md §5.4c and it wins any disagreement with this page. Read it →

The copy still speaks as MaiSay, not as Mai — "MaiSay's voice", MaiSay Pro. She is a face the app wears on her surfaces, never a narrator, and never the grader. An open question is with the product team: the pitch to open the lesson-loop surfaces →

Mai — canonical

The character, and the two laws she lives by

Chibi glasses girl: big round glasses, warm smile, long ink-black hair, lilac vest, white collar, peach skin — flat geometric register, solid fills, no gradients. Every pixel of her is an existing token; she never introduces a colour.

Scene backgrounds must contrast her wardrobe, solved within the surface's own pastel. Her lilac vest dissolved into a lilac panel on the door's first pass; the fix was rose — the door is a speaking claim — never a pastel reassigned for contrast's sake.

A surface that has earned her may be redesigned around her — she is layout, not a sticker — but the complete figure stays inside its semantic container, respects the content grid, and never straddles two regions.

Statics — usable

Every gated still in the corpus, each regenerable from its prompt manifest. The note says what it is for; where it says marketing-only the asset exists but no v1 screen may carry it — possession is not permission, and the closed list below is the permission. The register table in the mascot README rules what may be drawn next: raised-arms is marketing-only, and the thumbs-up is the in-app celebration gesture of record.

canonical
mai-canonical · the door

The idle every other asset is generated from. Vector; usable as the idle on any approved surface.

listening
mai-listening · onboarding mic

Hand cupped behind the ear, head tilted. The hearing pose — also the say-from-memory gloss band.

encouraging
mai-encouraging · paywall recap

Thumbs-up — the in-app celebration gesture of record. Celebrates the completed fact, never the limit.

thinking
mai-thinking · empty states

Genuine zero-result only, never a failure. An error surface carries no character at all.

greeting
mai-greeting · path arrival

One warm wave serves all four time states — the hour is carried by the copy, not by a second drawing.

studying
mai-studying · path pm · sets Popular

Cross-legged over an open book. The quiet rooms, and the shelf head where she reads. Floor line at y995.

writing
mai-writing · sets My sets

The studying seat redrawn with a pencil — same floor, same register, different verb. Left page ruled, right page blank.

lofi study
mai-lofi-study · path am

The desk, deep focus. The home-path header's daytime pose at 132px.

music
mai-music · path evening

Headphones on, eyes drawn closed. This is the headphones pose — mai-listening is the ear-cup, and they get confused.

sleepy
mai-sleepy · path night

The home-path header past about ten. Drowsy, never guilty.

phone browse
mai-phone-browse · sets-empty

The library with no result. Centred at 178px, no crop.

resting
mai-resting · end of day

Never-guilt is the law here: it must read “good stopping point”, never “you stopped”.

path companion
mai-path-companion · unseated

A pose at ease. The path header took mai-lofi-study instead — a companion should carry a verb. Kept as the identity input most edits start from.

walking
mai-walking · transitions

The companion in motion, for journey and transition moments.

calm wait
mai-calm-wait · EXPERIMENTAL

The scoring-wait companion. Dies the moment it reads as worry — a character waiting beside a verdict is the risk.

presenting
mai-presenting · teaching rooms

Open palm, her eyes on her own hand — teach-before-test puts the word where she is looking.

tone hand
mai-tone-hand · tone rooms

The contour gesture. Framed left on purpose: the canvas keeps ~250px of clear air for the contour to be drawn into.

brush character
mai-brush-character · decomposition

Forming the character, not taking notes. A scene — wants 190px, not a bust seat.

bridge delight
mai-bridge-delight · Hán-Việt bridge

“You already knew this.” Recognition shared, not victory celebrated — the open-mouthed cut was rejected for crossing into cheering.

counting
mai-counting · teaching rooms

Three on the hand — a teacher's count, not a cheer. Took four rounds; the model drew a peace sign three times.

role greeting
mai-role-greeting · conversation · 美玲

The first meeting. Role-play cannot use wardrobe — the wardrobe is the character — so formality lives in the bowed head and folded hands.

role tea
mai-role-tea · conversation · 美玲

Over tea — goal 1's scene. Full body at master framing; the layout does the cut.

role asking
mai-role-asking · conversation · 美玲

Her turn. On screen while TTS plays 你是哪国人?— which is why the closed mouth is a gate, not a style note.

role shopping
mai-role-shopping · conversation · candidate

The price scene — 多少钱. Anchored on role-tea, not on greeting: a scene pose inherits its outline weight from the scene pose beside it. The cast stops at four.

flashcards
mai-flashcards · candidate · study-set drilling

The raised card breaks the silhouette above the lap where studying and writing are all lap-and-floor; the deck on the floor is what makes it flashcards and not a note.

checklist
mai-checklist · candidate · nothing-due only

Every box is ticked, so it says done — right for a zero-state, wrong beside "here's what's due". A due-today twin needs unticked boxes and is a different asset.

headphones
mai-headphones · candidate · audio review

Listening with you, not waiting on a verdict. Same expression as mai-music by design — the difference is the bust framing, which crops into a panel where a floor scene cannot.

sharing phone
mai-sharing-phone · candidate · share a set

First cut read as a selfie at 288px and was killed. Phone at chest, face square to the viewer, screen paper-white — the corpus had only ever drawn the phone's back.

cue bust
mai-cue-bust · cue panels

The one deliberate exception to the long-hair canon: a compact bob, because the hair-mass law wins at an edge seat.

speaking frame closed
mai-speaking-frame-closed · fallback A

Half of the no-Lottie speaking pair. Pixel-registered against its twin — the diff between the two files is the mouth and nothing else.

speaking frame open
mai-speaking-frame-open · fallback B

The other half. Swap the two on a timer where Lottie is unavailable.

mark
mai-mark · 24–40px chips

The companion mark for chips, rows and rail headers. Gated at 24px — it has to survive being tiny.

mark wink
mai-mark-wink · rare delight

The same mark, winking. Rare-delight moments only — routine use spends the effect.

happy win
mai-happy-win · marketing-only

Raised arms. Marketing-only in v1 by ruling — in-app celebration is the thumbs-up.

pointing
mai-pointing · marketing-only

Pointing right, for store and ad compositions.

pointing left
mai-pointing-left · marketing-only

The mirrored twin, so a composition never has to flip her and break the parting.

speaking
mai-speaking · marketing-only

Open mouth. In-app she is drawn beside TTS audio, never producing it, so this stays out of the app.

surprised oops
mai-surprised-oops · marketing-only

Never in-app: a surprised face next to a learner's result reads as the grader's reaction.

eyes up
mai-eyes-up · icon / marketing

Looking up out of frame — for bubble-acknowledgment icon compositions.

Lotties — usable, playing live

All programmatic — no animator, no Rive; every one is built by tools/make_motion.py and regenerable. Two rules hold across the whole set. Frame 0 renders identical to the shipped still, so reduced-motion and first paint resolve with no pop — checked by tools/check_frame0.py at each loop's walked size, not asserted. And the rig transforms the whole image, never a cut-out part: a moving cutout either tears at its seam or ghosts against the static copy beneath, and the artifact is as large as the motion. Where a loop is marked unseated the file is ready and the surface is a §5.4c decision — motion never expands the surface list, and never touches a lesson or score surface.

mai-lofi-loop · path am · 98KB

The desk. Breath and two blinks on an irregular beat — a metronome blink is what catches peripheral vision.

mai-studying-loop · path pm · sets Popular · 91KB

She reads. One page turn (not two — a second in ten seconds reads as skimming), two blinks, breath. The turn is cut from the drawing's own page silhouettes.

mai-writing-loop · sets My sets · 88KB

She writes. Three grey marks draw onto the blank right page on a trim path, then clear. Same 10s, breath and blink beat as its sibling — deliberately no page turn.

mai-thinking-loop · empty states · 81KB

Three dots pop in along her drawn up-gaze and fade together. A dot appearing against empty canvas is the strongest contrast change available — the pupil glance was declined, because moving a pupil means redrawing one without its highlight crescent.

mai-phone-browse-loop · sets-empty · 91KB

The screen lights in bands down the handset's own axis — measured at 14.06° by least squares, because PCA answers 10.1° once the fingers eat the lower half. Nothing translates; only opacity moves.

mai-greeting-loop · path arrival · 83KB

Breath and two blinks, and nothing else — this drawing has no contrast beat in it. The raised hand rises with her because it is one transform on one image; that is the breath, not a wave.

mai-encouraging-loop · paywall recap · 67KB

Shallower than the house breath on purpose: a deep breath at a paywall reads as a sigh, and a sigh beside an offer is a comment on the learner's decision. One −1.3° lean, tilting toward the completed facts and away from the purchase.

mai-resting-loop · end of day · 90KB

The slowest in the library: 8.6 breaths/min against the clock loops' 12, plus one lean. No blink — her eyes are drawn closed. Steam was declined; the 160px above the mug is all chin and collar.

mai-music-loop · path evening · 86KB

A slow sway, one movement per ~4s. Nodding in time, not bouncing. No blinks — her eyes are drawn closed.

mai-sleepy-loop · path night · 76KB

Breath at bust amplitude plus a drowsy lean. The one-shot yawn was cut — a beat that happens once and never again reads as a glitch.

mai-presenting-loop · teaching rooms · 59KB

Breath and two blinks while the learner reads. The hand settle is the breath — one transform on one image, so the hand stays registered to her body.

mai-tone-hand-loop · tone rooms · EXPERIMENTAL · 61KB

Four tones as labelled markers in one file — goToAndPlay('tone3', true). The hand holds and the contour draws out of her fingertip; the shape is what a learner needs, not the travel.

mai-speaking-loop · unseated · 39KB

The cue card's speaking state — mouth cycle only, nothing else moves.

mai-listening-loop · unseated · 72KB

Breath and a measured blink over the ear-cup pose, hand held.

mai-goal-settle · one-shot · unseated · 66KB

The goal-complete arrival: settles after the coin's moment and ends on the static frame.

mai-calm-breath · EXPERIMENTAL · 73KB

The scoring wait — a slow rise anchored at the flat crop edge, nothing else. Dies if it reads as worry.

mai-jump-win · EXPERIMENTAL · 65KB

A little hop landing on the encouraging stance — the gesture of record. Raised-arms is discouraged in-app, so it lands on the thumbs-up.

mai-idle · tier 1 · 24KB

Breath + blink on the embedded canonical. The cheapest possible sign of life; the door's minimal idle.

mai-alive · tier 2 · 42KB

Pure shape layers, no raster at all — pupils and brows become animatable, so she breathes, blinks and glances with a brow lift.

Archive — do not seat

Kept because deleting them loses the reason they exist, and because someone will otherwise draw them again. Nothing here goes on a screen. Each note says what replaced it.

canonical bust
mai-canonical-bust · deprecated

A base drawn into the artwork is a second, softer edge floating near the panel's real one, and it lines up only at the offset it was authored for. Crops live in the container — use the master.

listening bust
mai-listening-bust · deprecated

Same ruling. Seat mai-listening and let the panel make a straight horizontal cut.

mai-nod-yes · UNSEATED · 34KB

Drawn as inventory. The intended beat is after a correct recognition tap — whether that is close enough to a verdict surface is an open adjudication, and not the mascot seat's to make.

mai-thinking-idle · demo-grade · 1.0MB

Thought dots along her gaze, on a verbatim uncompressed embed — nine times the 110KB ceiling. Kept as a taste test only; a shippable cut would need re-quantizing.

mai-listening-idle · demo-grade · 1.0MB

Sound arcs beside the cupped hand, same uncompressed embed. Superseded for real use by mai-listening-loop at 72KB.

mai-glad · superseded · 40KB

An early reaction one-shot from the first motion ladder. Never seated; mai-goal-settle is the shipped arrival beat.

mai-shake · superseded · 38KB

The negative twin of the above — and the reason it will not ship: she is never the one who tells a learner they were wrong.

Where she appears — the list is the permission, and it is closed

Four surfaces, each with its one mapped expression. Each card links the built mock. Expressions not mapped here exist in the corpus and are marketing-only in v1.

Where she never appears: lesson, recording-result and score surfaces — a character beside a verdict reads as the grader's mood — and the paywall's offer row. On any money or streak surface she is never sad, disappointed, pleading, alarmed, or gesturing toward the purchase. Marketing, store and ad compositions obey this same list.

Where she comes from

There is no illustrator. Every asset is generated from the canonical by an identity-preserving edit model, gated at ~15% of a 1080×1920 frame, and promoted only with a manifest recording its prompt, seed, hashes and permitted surfaces — the corpus plus the manifests is the character sheet. The copies under src/mai/ here derive from product/mascot/assets/mai/; pipeline, playground and plan of record live in product/mascot/. One file in the corpus is not a card above and never will be: mai-canonical-source.svg is the un-flattened source the shipped mai-canonical.svg is exported from — a build input, not an asset.