Faces¶
Learning a name from a face, three steps at a time. A senior meets a new doctor, a new neighbor, a new aide, and wants to greet them by name next week. Faces teaches them one person at a time, walking through a memory hook for each.
The Face Quiz ("Who is this?" with the name taken away) is cut for now, so that Faces can focus on teaching. It stays built and tested behind a switch; see The Face Quiz.
The technique¶
Names are hard to remember because they are abstract: "Dr. Sanchez" has no picture. The method Faces is built on turns the name into one and ties it to the face, in three steps.
- Pick one distinctive facial feature. Something that stands out and is reasonably unique to that person: a strong jawline, thick eyebrows, a dimple, a style of glasses. Not something everyone has.
- Turn the name into a picture. Convert the abstract name into something concrete and vivid. "Sanchez" becomes "sand chess". Silly is fine; silly is more memorable.
- Merge the two into one weird, vivid image. Not "eyebrows" and "sand chess" side by side, but the eyebrows made of sand, playing chess. The interaction is what makes it stick.
The research behind the method found that the interactive image combining the facial feature and the transformed name was the essential component, and that using only pieces of the technique was less effective. That is why a card is not complete without all three parts, and why the screen never shows one without the others.
The senior-facing flow¶
Every page fits the display window without scrolling (the one-screen rule). The portrait is the elastic part; the text below it takes the height it needs at the senior's text size.
| Page | What is on it |
|---|---|
| Intro | What Faces is for, the three steps, "Then you memorize it!", and a large Start button |
| Face and Name Learn Screen | Step 1. The human photo, the Name, the Job role, and the Face description: A very wide, bright smile |
| Name to Generated Image Screen | Step 2. The picture, large, with the Name and the Generated Image description: A pier with someone on it |
| Memory Image Screen | Step 3. The memory image, large, over the memory prompt, which ends on the name: Dr. Pierron |
Then Next person, and the same three screens for someone else. The people come round in a shuffled order, everyone once before anyone repeats, and a reshuffle never opens with the person who just finished.
At the top of every page sit the app's two navigation buttons, an icon and a word each. Back turns one page back: from the memory image to the name picture, from a person's first page to the memory image of the person before, and from the first person to the introduction. From the introduction, or the empty state, it leaves Faces. Home returns to the home screen from any page.
The introduction¶
Every visit opens on the introduction, before any face appears: one line on what Faces is for ("A way to remember a name from a face."), the three steps as numbered sentences (pick one thing on the face that stands out, turn the name into a picture, put the two together in one picture), and the point of it all, "Then you memorize it!". It is shown every time rather than once, because the people this app is for may not remember having read it, and one tap on Start moves past it. A senior with nobody to practice sees the empty state instead.
Face and Name Learn Screen¶
The first page about a person, straight after the introduction. It shows the Human Photo, the real face the senior will meet, which a Loved One loads, over three pieces of text:
| On the page | Card field | Rule | Example |
|---|---|---|---|
| Name | name |
A single name, and it must be the last name. No first name, no "Dr." | Pierron |
| Job role | relationship |
Who they are, said to the senior, so it opens with "Your" | Your primary care provider |
| Face description | feature |
The one thing on this face that stands out, that most people do not have | A very wide, bright smile, a full row of teeth |
No step instruction is shown: the name, the job role and the face description speak for themselves, and the picture gets the height. "Step 1. Find one thing that stands out." is still announced to assistive technology as the page appears. Next moves on to step 2.
This phase of Faces holds doctors only, which is why the second line is a
job role. The last name is the one the memory hook is built on ("Pierron"
is a pier with someone on it), so it is the one name the senior is shown.
tests/faces-cards.test.ts holds every card to the single-name rule and to
the "Your" voice.
Name to Generated Image Screen¶
Step 2 turns the name into a picture. Under the picture there is only the
Name, the label "Sounds like:", and the Generated Image description (the
card's soundsLike): "A pier with someone on it: pier on". The job role and
the full step instruction stay behind on step 1, so the picture gets the
height the text gives up; the instruction is still announced to assistive
technology.
Memory Image Screen¶
Step 3 puts the two together. The memory image takes as much of the screen as it can, and under it sits the memory prompt, which uses the Face description and the Generated Image description and leads to the name:
| Line | Comes from | Example |
|---|---|---|
| What to remember | the card's remember |
Remember her smile! |
| The merged image | the card's link |
Her smile is a pier, a person walks ON the pier. |
| The name | "Dr." and the card's name |
Dr. Pierron |
The name comes last because it is where the prompt is meant to lead. A card
holds the last name alone; the "Dr." is added here, since this phase holds
doctors only (titledName in cards.ts). Next person moves on.
The pictures¶
A person can carry two pictures. The photo is the real face the senior will meet: the Face and Name Learn Screen shows it. The memory image is the hook drawn as a scene, with the feature and the name picture merged into one (Dr. Callan's wavy hair as the coiled cord of a ringing telephone): the Name to Generated Image Screen and the Memory Image Screen show it. A person with only a photo shows it on every page; a person with neither gets a plain portrait placeholder.
Every Faces picture is a 1:1 square, photo and drawing alike. The
portrait frame shows a picture whole, never cropped, so a drawing keeps the
part that does the remembering, and it takes the height the text leaves. A
tall picture in that frame stands as a narrow strip between two bands; a
square one runs the full width of every supported iPhone at both text sizes,
and most of the width of an iPad, where the height runs out first. New
drawings are made square, a photo is cropped to a square before it is added,
and tests/faces-pictures.test.ts fails the build on one that is not.
The Face Quiz (cut for now)¶
The quiz is switched off: FacesScreen takes a quiz prop that defaults to
off, and the route does not set it. It stays built, and its tests still run,
for the day it comes back. With it on, two more pages follow step 3:
| Page | What is on it |
|---|---|
| The check | The face without the name. "Who is this?" over three names, all people the senior has met |
| The answer | "Yes! That is Sanchez." or "This is Sanchez." and the image once more, then Next person |
The check takes two taps, like every other quiz in the app: the first tap arms a name (shown filled, read aloud under Self-Voicing, and exposed as selected to assistive technology), the second submits it. A stray touch never answers.
A miss is met with the name and the linking image again, so it becomes one more rehearsal. There is no wrong-answer message, no red, and no score.
The answers for a check are the card's own name and two other names from the same senior's cards, so every name on screen is someone they have actually met, and a Loved One never has to author wrong answers. With only one person on file there is nobody to confuse them with, so the check is skipped.
Accessibility¶
- Each step is announced to assistive technology as it appears, instruction and cue together, since the page changes under a button that keeps its label. The Memory Image Screen is heard the way it is read: "Step 3. Now put the two together. Remember her smile! Her smile is a pier, a person walks ON the pier. Dr. Pierron."
- While the name is on screen the portrait is described as the picture it is (the catalog description of the photo or the memory image), or as "No photo of Sanchez yet" when there is none. During the quiz's check it must not give the name away, so the photo is described by the feature instead: "Someone with thick, dark eyebrows", the same cue a sighted senior gets from the face. The memory image is never shown during the check, since a drawing of the hook would hand over the name.
- A photo appears only once it has a description, the same Born Accessible gate every other screen uses (media catalog).
- The screen header "Faces" is kept for screen readers and clipped from sight, as on the Music Quiz, so the face carries the screen visually.
Where the code lives¶
src/features/faces/types.ts:FaceCard, one person with all three parts of the hook and up to two pictures, andRecallChoice.src/features/faces/cards.ts: the seed cards,faceCardsFor(one senior's people),recallChoices(the check's names, with injectable randomness), and the three steps with their instructions.src/features/faces/faces-intro.tsxandintro.ts: the introduction and its words, kept apart so the one-screen test budgets the real copy.src/features/faces/faces-screen.tsx: the screen.app/faces.tsx: the route, wrapped in the shared Pane with its Back and Home buttons;useBackHandlerinfaces-screen.tsxis what makes Back turn one page at a time. Reached from the Faces button on the home screen.
Content¶
Tom's people are real: eight of his doctors, with the hooks his family wrote for them, each with a real photo and a memory image drawn from it. Nyna's are invented, so the default senior has a deck to try. In production a Loved One writes every card from the senior's real life, the way they author Stories questions.
A card, from src/features/faces/cards.ts:
{
id: 'tom-dr-lauren-callan',
seniorId: '1',
name: 'Callan',
relationship: 'Your dentist',
photoId: 'dr-lauren-callan',
hookImageId: 'tom-dr-lauren-callan-hook',
feature: 'Long blonde hair in loose, rolling waves',
soundsLike: 'An old rotary phone ringing: call in',
remember: 'Remember her wavy hair!',
link: 'Her hair waves are phone cords; a rotary phone rings.',
scene:
'Each rolling wave of her long blonde hair is a coiled telephone cord. An old black rotary phone is tangled in the waves on one side and is ringing loudly, and she lifts a wave of hair to her ear like a receiver while the cord waves on the other side bounce and stretch.',
}
scene is the merged image in full. It is never shown on screen, so it has
no budget: link is the short version the senior reads, and scene is what
the drawing is made from (pnpm faces:image --scene), kept on the card so
the drawing can be made again.
Cards are scoped per senior like every other piece of content
(multiple seniors): seniorId matches the roster,
and the screen reads faceCardsFor(seniorId), never the whole list. Tom (1)
carries his eight doctors and Nyna (2) four invented people; Thomas (3) and Lisa (4) carry none and
see the empty state.
To give a person a photo, add it to the media catalog with a description
(media catalog) and set photoId on the card. The face is what
the technique is about, so add one whenever the family has a picture; the
card still works from the feature description without it.
The memory image is the hook itself, drawn. Nyna's dentist, Dr. Lauren
Callan, has her long wavy hair drawn as the coiled cord of a ringing
telephone, because "Callan" sounds like "callin'". To add one, drop the file
in apps/mobile/assets/<seniorId>/photos/, register it in photoAssets
with a description written for someone who cannot see it, and set the
card's hookImageId.
One person at a time¶
The workflow for building a deck of real people, each with a real photo and a generated memory image:
- Say who they are. Their name (the card keeps the last name only), what
kind of doctor they are, and their real photo: a file
path, or drop it in
apps/mobile/assets/<seniorId>/photos/. The photo is cropped to a 1:1 square around the head before it is registered. - The card gets written from the photo. The feature comes from looking at the face (something this person has and most people do not), then the sound picture for the last name alone, then the link that merges the two. Every string is checked against its budget.
- The memory image gets drawn. The backend turns the card into a
prompt and asks OpenAI's image model to draw it, with the real photo as
the reference so the drawing is recognizably them. One command writes the
PNG beside the photo as
<card-id>-hook.png:
pnpm faces:image --senior 2 --card nyna-dr-lauren-callan \
--name "Dr. Lauren Callan" \
--feature "Long, wavy blonde hair" \
--sounds-like "Calling on the telephone" \
--link "Her long wavy hair is a curly phone cord, ringing." \
--photo apps/mobile/assets/2/photos/dr-lauren-callan.jpg
It needs OPENAI_API_KEY in backend/.env, and each image is billed.
--dry-run prints the prompt first; --prompt replaces it with your own
when the generated one needs a nudge. Look at the result: if the face is
not them or the scene is wrong, run it again.
- Both pictures are registered in the media catalog with descriptions,
the card gets its
photoIdandhookImageId, and the tests run over the new content.
The prompt is built in backend/app/services/memory_image_service.py, from
the shared style in backend/app/memory_image_style.txt (a very simple flat
cartoon from plain shapes with no outlines, dot eyes and a curved smile, a
calm sand-and-teal palette, a 1:1 square that is one single picture and
never a strip of panels, and no text of any kind, since a
drawn name would hand the answer to the check; edit that file to change the
look of every drawing) and the card itself:
draw the person in the photo, smiling, face clear and central; the feature
that stands out; what the name sounds like; and "draw exactly this scene,
with the feature and the sound picture interacting", followed by the link
sentence. The same service is POST /faces/memory-image on the backend, for
the day the Loved One web app authors cards; POST /faces/memory-image/prompt
previews the prompt without spending on an image.
Character budgets¶
Every string on a card is held to a budget by tests/one-screen-fit.test.ts
(the one-screen rule):
| Field | Role | Characters | Why |
|---|---|---|---|
name |
faceName |
20 | One line under the portrait; also an answer button (choiceLabel) |
relationship |
faceRelationship |
45 | Two lines |
feature |
faceCue |
59 | Four lines, the same as a question prompt |
soundsLike |
faceCue |
59 | |
remember |
faceRemember |
45 | Two lines; opens with "Remember her", "his" or "their" |
link |
faceCue |
59 |
Writing tips for the cues, from the technique itself: the feature should be something this person has and most people do not; the sound picture should be concrete and a little silly; the link should have the two doing something together, not sitting side by side.
Last name only¶
The hook is built from the last name and nothing else. The sound picture is
what the last name sounds like: "Rodriguez-Homs" is a fishing rod hooking
little homes, "Jamison" is a boy with a jar of jam. It never carries the
first name (no seagull for Miguel, no cave-in for Kevin) and never the
specialty (no heart for a cardiologist, no lungs for a pulmonologist). The
last name is the only name the senior is shown, so anything else in the
drawing points at a word they never see, and a picture with three things
to decode is harder to hold than one with two. The link and the scene
merge the face feature with that one name picture, and they describe one
moment: a scene with two states (breathing in, then out) comes back from
the image model as a strip of panels, each half too small for a phone. Tom's
eight cards were rewritten to this rule and all eight drawings made again on
2026-09-17.
Stats¶
While the Face Quiz is cut, Faces saves nothing: the learning steps are not
answers, and they are not timed. With the quiz on, every answered check
saves one row to the on-device stats database (stats) as quiz
faces, format name-recall, with the response time from the moment the
check appeared.
Follow-ups¶
- Bring the Face Quiz back (the
quizprop onFacesScreen), once teaching one person at a time has settled. - Author cards in the Loved One web app and serve them from the memory bank,
so the seed stops being the source. The web app would call
POST /faces/memory-imageand store the drawing in R2. - Voice answering in the check, as in the video quiz.
- Spaced repetition: bring back the people the senior missed sooner than the ones they got right.