Browse all of Kata

Imagery

Source docs/design/foundations/imagery.mdMarkdown

On this page

Photos, avatars, thumbnails, the mascot — and what each looks like when it fails.

Part of the Konjo design language. The laws in the spine apply here unless this chapter contradicts them.

Chrome carries no imagery. No photographic headers, no textured backgrounds, no image behind a nav bar. This was a deliberate calibration decision and it has a practical reason: the hero block has to work for a dojo that has never uploaded a picture, and most of them never will. A design that only looks good with photography is a design that looks broken for your first hundred customers.

Imagery appears in exactly four places: user content, avatars, event and dojo pages, and onboarding.

The failure case is the design

Every image in Konjo is remote, and remote means slow, missing, or 404. Decide what the absence looks like before the presence, because the absence is what a new dojo sees.

Loading Missing / failed
Avatar The initials fallback — never a spinner The initials fallback, permanently
Thumbnail surface.tag block at the final aspect ratio Same block with an inline glyph, no error text
Event / dojo photo Reserved space at the final ratio The section renders without it; nothing collapses

Reserve the space at the final aspect ratio before the image arrives. Content that jumps when a picture loads is the most common way a list feels cheap, and it is entirely avoidable.

Use CachedImage rather than a bare Image, and MediaThumbnail for anything in a grid or feed — it already carries the radius, the ratio and the play overlay.

Avatars

Avatar is the only way a person is pictured.

  • Sizes are fixed: 32 in a row and in the header, 88 on a profile. The header's carries a 1px hairline ring so it separates from whatever it sits on.
  • Circular, always. A squared avatar reads as a logo.
  • The fallback is initials on a flat fill, not a silhouette glyph. A generic person icon makes eleven students look like the same student; "AT" does not. The fill is surface.muted with a 1px border.subtle ring and text.secondary initials — named here because "a flat fill" was the whole specification and the next person to build an avatar somewhere new would have picked one.
  • Never tint an avatar by belt. Rank is carried by the belt dot beside it. Two encodings of the same fact is one too many, and a coloured ring around a photo fights the photo.

User photos and video

  • Posts and coaching clips keep their own aspect ratio, capped so one tall image cannot own the screen.
  • Video routes to Mux, never to Storage — see the video pipeline. A video thumbnail is a MediaThumbnail with the play overlay; it never autoplays in a feed.
  • All uploads go through the upload queue, never Storage directly from a screen.

Text on a photograph

The short version: don't. If you must —

  • A scrim between the photo and the text, dark enough that the text clears 4.5:1 against the lightest pixel it covers, not the average.
  • The text must still be legible if the image fails to load, which means the scrim is a solid-enough fill on its own.
  • Never accent.red or any red on a photograph. Red is a role; on top of an unpredictable background it is just a colour that vanishes.

This is why the hero block is a solid surface carrying type, never a photograph.

The mascot

The Konjo ninja is the brand's mark and its mascot: one character, silent, always a black belt (Kata interview). Canon, construction and the pose list are in the ninja prompt pack; the vector masters are in assets/brand/ninja/, and the app renders the PNGs that scripts/brand/icons.mjs generates from them.

Where the ninja may appear:

  • Onboarding and the auth screens, inline with the wordmark in KonjoWordmark.
  • Marketing, emails and social.
  • Empty states and error states, in the pose that matches the moment: point for "start here", seiza for nothing today, oops for something that failed.
  • Celebrations and milestones: promotion for a belt, jump for a streak or badge.

Where it never appears:

  • Chrome: tab bars, headers, navigation. The screen title does that job.
  • Billing, waivers, safety flags and anything with legal or money consequences. Those moments are serious; a cartoon undercuts them.
  • As a speaker. The ninja is silent: no speech bubbles, no first-person lines, no copy written "in its voice". The words on the screen stay in the app's plain voice.
  • Recoloured, redrawn by hand, or holding a weapon.

In an empty or error state the ninja accompanies the message and the one way in; it never replaces them. A screen that shows the ninja and no action is still an empty state with no way in.

Never

  • A stock photo of martial arts. Konjo shows this dojo or it shows type.
  • A gradient standing in for an image.
  • An image that is load-bearing for comprehension with no text alternative.
  • A decorative image without accessibilityElementsHidden — see accessibility.
  • Text baked into an image. It cannot scale, cannot be read aloud, and cannot be translated.