Skip to content

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.

  1. 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.
  2. 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.
  3. 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, and RecallChoice.
  • 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.tsx and intro.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; useBackHandler in faces-screen.tsx is 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:

  1. 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.
  2. 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.
  3. 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.

  1. Both pictures are registered in the media catalog with descriptions, the card gets its photoId and hookImageId, 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 quiz prop on FacesScreen), 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-image and 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.