Sakuga Back to Sakuga
Theme
Sound
Jump to a component

AniCanonKit · Productions

ProgramBar

ProgramBar is the whole cut at a glance: sections in planned proportion (cut, partial with gaps, missing), the window the Timeline shows, the playhead, and numbered note marks from screening. A mark sits on its own rail above the bar, its number centred in its badge, with a hairline down to its exact point, as Timeline's markers do, so it never covers a section's label.

@anicanon/sakuga/anicanonkitv1.0Used onWebFrom AniCanon™

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Web only

ProgramBar is made for the web, and isn’t part of Sakuga for iOS yet.

Android

Web only

ProgramBar is made for the web, and isn’t part of Sakuga for Android yet.

Use it for
The whole cut at a glance: its sections in planned proportion, the window the Timeline shows, the playhead and numbered notes from screening.
Not for
  • The cut's tracks to editTimeline
  • The playhead of an episode or a short being watchedScrubber
  • How far something being made has comeProgress
  • Moving through the story in story orderStoryScrubber
ProgramBarExample.jsxReact
import { ProgramBar } from '@anicanon/sakuga/anicanonkit';

export default function ProgramBarExample() {
  return (
    <ProgramBar
      duration={400}
      planned={660}
      total="6:40 of 11:00"
      window={{ start: 140, length: 40 }}
      playhead={161}
      marks={[
        { at: 96, label: '1', done: true },
        { at: 402, label: '2' },
      ]}
      sections={[
        { label: '#1', start: 0, length: 110 },
        { label: '#2 The roof', start: 110, length: 160, state: 'partial' },
        { label: '#3', start: 270, length: 90 },
        { label: '#4', start: 360, length: 120, state: 'partial' },
        { label: '#5 Red Line', start: 480, length: 180, state: 'missing' },
      ]}
    />
  );
}

PropsProgramBarProps

durationrequired
number
planned
number
total
string
playhead
number
window
{ start: number; length: number; }
sections
{ label: string; start: number; length: number; state?: 'cut' | 'partial' | 'missing'; }[]
marks
{ at: number; label: string; done?: boolean; }[]
label
string
Names the group; "The whole cut" without it.
className
string
ProgramBarExample.swiftiOS · coming soon
ProgramBarExample.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

pbar-bgProgramBar: the track.
bg-fill-subtleshade-a06rgba(11,10,16,0.06)
bg-fill-subtlewhite-a08rgba(255,255,255,0.08)
pbar-borderProgramBar: track edge.
border-hairlineshade-a08rgba(11,10,16,0.08)
border-hairlinewhite-a06rgba(255,255,255,0.06)
pbar-cutProgramBar: a section in the cut.
bg-surface-raisedneutral-100#ececf0
bg-surface-raisedneutral-875#1a1a21
pbar-partialProgramBar: dashed edge on a section with gaps.
border-controlshade-a52rgba(11,10,16,0.52)
border-controlwhite-a45rgba(255,255,255,0.45)
pbar-missingProgramBar: a planned section not cut yet.
border-placeholdershade-a24rgba(11,10,16,0.24)
border-placeholderwhite-a22rgba(255,255,255,0.22)
pbar-labelProgramBar: section label.
text-secondaryneutral-800#2e2d36
text-secondaryneutral-200#dcdcde
pbar-metaProgramBar: total and missing labels.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
pbar-windowProgramBar: the part the timeline shows, the playhead and open notes.
accentcamellia-600#c2335f
accentcamellia-400#f4779f
pbar-mark-fgProgramBar: note number.
on-accentneutral-0#ffffff
on-accentneutral-925#0b0a10

Space and shape

pbar-gap
gap-md
8px
pbar-track-height
its own value
24px
pbar-track-radius
radius-sm
8px
pbar-track-inset-ring-width
line-hairline
1px
pbar-sec-inset
inset-2xs
2px
pbar-sec-padding-x
inset-xs
4px
pbar-sec-radius
radius-xs
4px
pbar-sec-border-right-width
line-hairline
1px
pbar-sec-partial-outline-width
line-strong
2px
pbar-sec-partial-outline-offset
its own value
calc(-1 * 2px)
pbar-sec-missing-outline-width
line-strong
2px
pbar-sec-missing-outline-offset
its own value
calc(-1 * 2px)
pbar-window-radius
radius-sm
8px
pbar-window-inset-ring-width
line-strong
2px
pbar-playhead-inset
its own value
calc(-1 * 2px)
pbar-playhead-border-left-width
line-strong
2px
pbar-mark-top
its own value
calc(-1 * 8px)
pbar-mark-min-width
icon-size-md
20px
pbar-mark-height
icon-size-md
20px
pbar-mark-padding-x
inset-xs
4px
pbar-mark-radius
radius-full
9999px
pbar-mark-gap
gap-xs
4px
pbar-mark-line-width
line-hairline
1px

Type

pbar-sec-b-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
pbar-mark-font
text-micro
700 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
pbar-total-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif

Motion

pbar-sec-duration
motion-base
240ms
pbar-sec-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
Not focusable; a group named by label (default "The whole cut") whose section labels (with "partly cut" or "missing"), mark labels (with "done"), the window ("Timeline shows 0:30 to 1:00"), the playhead ("Playhead at 0:42") and the total read as text.
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.