Jump to a component
Core · Content
CastAvatar
CastAvatar shows a person: a character (a round portrait from their identity sheet), or a creator (an initial until they add a picture), with their name and a one-line role.
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Coming soon
CastAvatar for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
Android
Coming soon
CastAvatar for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
- Use it for
- A person with their name and a one-line role: a character's round portrait from their identity sheet, or a creator's initial until they add a picture.
- Not for
- A cast member on the cast page, with what they have and what is happening to themCastCard
- Who or what a panel holds, with its @ or # mark and a noteMentionChip
- A character as one card with stats and traitsCharacterCard
- A character named inside proseMention
- Several people at a glance, overlappingCastStack
Guidelines
size="lg"(104px) on the desktop series page,md(72px) on phone and in the player.- The role is a few words a viewer understands ("Leads the E.R.A.", "Power of wind"), never internal production data.
- The portrait is decorative; the name is the label.
- Without an
imageit shows theinitialin the same circle, until a portrait is approved. selected(true or false) makes it a choice: a ring and a check say it is chosen (who wears a look).muteddims the face: the character is no longer in the story at that moment (dead, gone).- Under a small face (
sm,xs) in a column, the name reads at 12 px and the name and role are cut to the cell, so a panel grid of four stays tidy; larger faces wrap their names. layout="row"puts a small portrait beside the name and role (the people in a character's life).sizeislg,md,sm(44),xs(36) or a number of pixels.
import { CastAvatar } from '@anicanon/sakuga/ui';
export default function CastAvatarExample() {
return (
<>
<CastAvatar
image="/art/eba-cast-the-professor.webp"
name="The Professor"
role="Arthur Penhaligon"
width={120}
href="#"
/>
<CastAvatar
image="/art/eba-cast-kiko.webp"
name="Kiko"
role="Leads the E.R.A."
width={120}
href="#"
/>
<CastAvatar
size="md"
image="/art/eba-cast-kiko.webp"
name="Kiko"
width={84}
href="#"
/>
</>
);
}PropsCastAvatarProps
imagestringinitialstringnamestringrolestringsize'xs' | 'sm' | 'md' | 'lg' | numberlayout'row'selectedbooleanmutedbooleanonClickMouseEventHandlerlabelstringhrefstringwidthnumber | stringclassNamestringEach token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
cast-avatar-nameCastAvatar: character name.text-primaryneutral-925#0b0a10text-primaryneutral-0#ffffffcast-avatar-roleCastAvatar: role line.text-mutedneutral-600#5c5b67text-mutedneutral-400#a3a3a7cast-avatar-placeholderCastAvatar: portrait frame while it loads.bg-surface-raisedneutral-100#ececf0bg-surface-raisedneutral-875#1a1a21Space and shape
cast-avatar-gapgap-mdcast-avatar-img-size-lgcast-avatar-img-size-mdcast-avatar-role-margin-topcast-avatar-check-icon-sizeicon-size-xscast-avatar-img-active-scalescale-press-smcast-avatar-face-size-lgcast-avatar-face-size-mdcast-avatar-face-size-smcast-avatar-face-size-xscast-avatar-check-insetcast-avatar-check-sizeicon-size-mdcast-avatar-check-ring-widthline-strongcast-avatar-selected-ring-widthline-strongcast-avatar-selected-outer-ring-widthring-outercast-avatar-row-gapgap-mdcast-avatar-row-padding-yinset-xscast-avatar-row-padding-rightinset-mdcast-avatar-row-padding-leftinset-xscast-avatar-row-radiusradius-xlcast-avatar-row-inset-ring-widthline-hairlinecast-avatar-face-muted-opacityopacity-disabledcast-avatar-forced-selected-widthline-strongType
cast-avatar-font-familyfont-sanscast-avatar-name-font-sizetext-label-sizecast-avatar-name-line-heighttext-label-line-heightcast-avatar-name-font-weighttext-label-weightcast-avatar-role-font-sizetext-small-sizecast-avatar-role-line-heighttext-small-line-heightcast-avatar-face-font-size-lgtext-title-1-sizecast-avatar-face-font-size-mdtext-subtitle-sizecast-avatar-face-font-size-smtext-lead-sizecast-avatar-face-font-size-xstext-body-sizecast-avatar-initial-fontcast-avatar-row-name-font-sizetext-caption-sizecast-avatar-row-name-line-heighttext-caption-line-heightcast-avatar-row-role-font-sizetext-small-sizecast-avatar-row-role-line-heighttext-small-line-heightcast-avatar-name-font-size-xs-smtext-small-sizecast-avatar-name-line-height-xs-smtext-small-line-heightMotion
cast-avatar-img-develop-animationmotion-developcast-avatar-img-active-durationmotion-instantcast-avatar-img-durationmotion-fastcast-avatar-img-easingease-standardChecked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- With
selectedset it is a toggle button, "pressed" when selected; withhrefa link; with onlyonClicka button; otherwise plain text, and Tab reaches each of the three controls, Enter or Space pressing the buttons. Its name and role are read,mutedadds "not in the story at this point", and the portrait, initial and check are hidden; withoutnameit is named bylabel. - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.