Sakuga Back to Sakuga
Theme
Sound
Jump to a component

Core · Content

Thumb

Thumb is a picture in a frame: cover-cropped, 6 px corners, selected adds the accent ring, muted greys a rejected take. Give it width and height, or leave them out for a full-width 16:9 frame (ratio changes it).

@anicanon/sakuga/uiv1.0Used onWeb · iOS · Android

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Coming soon

Thumb 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

Thumb 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 picture in a frame: a take (selected, or muted when rejected), a library item, a panel to pick, a frame not made yet.
Not for
  • An episode, short or manga issue a viewer opensMediaCard
  • A person's portrait with their name and roleCastAvatar
  • A manga page at its trimMangaPage
  • One look on white with its occasionLookPlate
  • The place or backdrop being made, on the left of its flowPlaceCard
  • A whole page or list with nothing in it yetEmptyState

Guidelines

  • imageStyle moves the crop (object-position:30% 40%).
  • figure lays a cut-out over the picture (a character on a place). Prefer a real render.
  • lightMap gives the picture light on art, as on MediaCard: its own highlights glow where the pointer is. It is on wherever there is a map and never on muted; light={false} turns it off. ListRow and PlaceCard pass lightMap to their picture. A player's poster is a Thumb with its map before play, and light={false} the moment the video plays.
  • onClick makes it a toggle button (aria-pressed follows selected) that sinks on press; the accent ring grows in on motion-fast.
  • title and meta caption it under the picture (a library item, a panel to pick).
  • placeholder is a frame that is not made yet: an empty frame naming what will fill it ("Board drawn when you approve the cut"). Never fake a picture.
  • radius="none" sits it flush inside other art (a split view, a loupe of frames); radius="lg" for a cover.
  • Mount it; never draw .sk-thumb by hand.
  • fit="contain" shows the whole picture (a sheet); paper sets it on the white a sheet is drawn on, in either theme. radius is none, md, lg, xl or full (a round crop of a face). Every picture develops in once as it arrives (motion-develop), so develop adds nothing; it stays so older pages that pass it still work.
ThumbExample.jsxReact
import { useState } from 'react';
import { Thumb } from '@anicanon/sakuga/ui';

export default function ThumbExample() {
  const [value, setValue] = useState(1);
  return (
    <div style={{ display: 'flex', gap: 10 }}>
      {[0, 1, 2].map((i) => (
        <Thumb
          key={i}
          image="/art/eba-cinema.webp"
          lightMap="/art/eba-cinema.light.webp"
          width={128}
          height={72}
          muted={i === 2}
          selected={value === i}
          label={'Take ' + (i + 1)}
          onClick={() => setValue(i)}
        />
      ))}
    </div>
  );
}

PropsThumbProps

title
string
Caption under the picture.
meta
string
placeholder
string
A frame not made yet, naming what will fill it.
radius
'none' | 'md' | 'lg' | 'xl' | 'full'
fit
'cover' | 'contain'
contain: the whole picture, e.g. a sheet.
paper
boolean
The white a character sheet is drawn on.
develop
boolean
Kept so older pages still work: every picture already develops in once as it arrives.
image
string
imageStyle
string
CSS, e.g. "object-position:30% 40%".
lightMap
string
The picture's baked light map: it glows with its own highlights under the pointer (light on art). Never on muted.
light
boolean
On wherever there is a lightMap; false turns it off (a poster the moment its video plays).
figure
string
figureStyle
string
width
number | string
height
number | string
ratio
string
selected
boolean
muted
boolean
alt
string
onClick
MouseEventHandler
Makes it a toggle button; aria-pressed follows selected.
label
string
The button's name when the picture's alt does not say it.
children
ReactNode
className
string
ThumbExample.swiftiOS · coming soon
ThumbExample.ktAndroid · coming soon

Each 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

thumbnail-ring-activePage strip: ring around the current page.
accentcamellia-600#c2335f
accentcamellia-400#f4779f
thumbnail-ringPage strip: ring around the other pages.
border-glass-mediawhite-a16rgba(255,255,255,0.16)
border-glass-mediawhite-a16rgba(255,255,255,0.16)
thumb-captionThumb: a caption's title.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
thumb-caption-metaThumb: a caption's quiet line.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
thumb-placeholder-edgeThumb: the edge of a frame that is not made yet.
border-placeholdershade-a24rgba(11,10,16,0.24)
border-placeholderwhite-a22rgba(255,255,255,0.22)
thumb-placeholder-fgThumb: what the empty frame will hold.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
thumb-paperThumb: the white a character or face sheet is drawn on, in either theme.
neutral-0#ffffff
neutral-0#ffffff

Space and shape

thumb-radius
radius-xs
4px
thumb-active-scale
scale-press
.97
thumb-selected-ring-width
line-strong
2px
thumb-img-muted-filter
its own value
grayscale(1) brightness(.6)
thumb-fig-gap
gap-xs
4px
thumb-placeholder-padding-x
inset-md
12px
thumb-placeholder-inset-ring-width
line-strong
2px
thumb-radius-lg-radius
radius-lg
16px
thumb-radius-md-radius
radius-md
12px
thumb-radius-xl-radius
radius-xl
24px

Type

thumb-fig-figcaption-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
thumb-fig-figcaption-span-font-weight
weight-medium
500
thumb-placeholder-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif

Motion

thumb-duration
motion-fast
160ms
thumb-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
thumb-active-duration
motion-instant
100ms
thumb-img-develop-animation
motion-develop
sk-develop 560ms cubic-bezier(0, 0, 0, 1)
thumb-img-filter-duration
motion-base
240ms
thumb-img-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
thumb-img-transform-duration
motion-slower
560ms
thumb-light-duration
motion-slower
560ms
thumb-light-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)

Checked 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
A picture whose alt is alt (empty, so hidden, by default), with "selected" and "rejected" (muted) said after it, and with title or meta a figure captioned by them. With onClick it is a toggle button that Tab reaches and Enter or Space presses, "pressed" when selected: name it with label (or alt), since without one it has no name. In forced colours a selected frame keeps its ring, in Highlight.
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.