Sakuga Back to Sakuga
Theme
Sound
Jump to a component

AniCanonKit · AniCanon™

SpendButton

An action that spends fragments: Sakuga's Button with AniCanon™'s price after the label, behind the hairline, with the fragment mark. It takes every Button prop except trailing, plus cost. The core Button knows nothing of fragments; its trailing slot is neutral, and this is the part that fills it.

@anicanon/sakuga/anicanonkitv1.0Used onWeb · iOS · AndroidFrom AniCanon™

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Coming soon

SpendButton 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

SpendButton 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
An action that spends fragments: Generate, Draw it again, Make the clip, Plan scene 5.
Not for
  • An action that costs nothingButton
  • A fragment amount inside a sentenceFragmentBalance variant="inline"
  • A price on a choice cardSpendTiles

Guidelines

  • Keep the label a plain verb ("Generate", "Start", "Retake"); never write the price into the label.
  • The mark is drawn at the button's icon size, so it grows with size="lg".
SpendButtonExample.jsxReact
import { SpendButton } from '@anicanon/sakuga/anicanonkit';

export default function SpendButtonExample() {
  return (
    <>
      <SpendButton variant="primary" size="lg" cost="~12">
        Generate
      </SpendButton>
      <SpendButton variant="secondary" cost="~12">
        Draw it again
      </SpendButton>
      <SpendButton variant="primary" shape="pill" size="lg" cost="~120">
        Make the clip
      </SpendButton>
    </>
  );
}

PropsSpendButtonProps

cost
string
What the action is expected to cost in fragments, e.g. "~100" or "~10 a second": shown after the label with the fragment mark.
SpendButtonExample.swiftiOS · coming soon
SpendButtonExample.ktAndroid · coming soon

It has no tokens of its own: it draws with Button’s, listed here.

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

button-primary-bgButton primary: fill.
action-primaryneutral-925#0b0a10
action-primaryneutral-0#ffffff
button-primary-fgButton primary: label and icon.
text-inverseneutral-0#ffffff
text-inverseneutral-925#0b0a10
button-secondary-bgButton secondary: fill.
action-secondaryshade-a12rgba(11,10,16,0.12)
action-secondarywhite-a14rgba(255,255,255,0.14)
button-secondary-fgButton secondary: label and icon.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
button-outline-borderButton outline: edge.
border-controlshade-a52rgba(11,10,16,0.52)
border-controlwhite-a45rgba(255,255,255,0.45)
button-outline-fgButton outline: label and icon.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff
button-ghost-fgButton ghost: label and icon.
text-secondaryneutral-800#2e2d36
text-secondaryneutral-200#dcdcde
button-ghost-hover-bgButton ghost: hover fill.
bg-fill-subtleshade-a06rgba(11,10,16,0.06)
bg-fill-subtlewhite-a08rgba(255,255,255,0.08)
button-disabled-bgButton primary or media while it can't be used yet: a quiet fill, never a faded white.
bg-fill-subtleshade-a06rgba(11,10,16,0.06)
bg-fill-subtlewhite-a08rgba(255,255,255,0.08)
button-disabled-fgButton label while disabled.
text-mutedneutral-600#5c5b67
text-mutedneutral-400#a3a3a7
button-media-bgButton media: fill over video or artwork.
action-medianeutral-0#ffffff
action-medianeutral-0#ffffff
button-media-fgButton media: label and icon.
text-on-action-medianeutral-925#0b0a10
text-on-action-medianeutral-925#0b0a10
button-media-secondary-bgButton media-secondary: glass fill over video or artwork.
action-media-secondaryglass-dark-a42rgba(28,28,34,0.42)
action-media-secondaryglass-dark-a42rgba(28,28,34,0.42)
button-media-secondary-fgButton media-secondary: label and icon.
text-on-medianeutral-0#ffffff
text-on-medianeutral-0#ffffff
button-media-secondary-borderButton media-secondary: edge.
border-glass-mediawhite-a16rgba(255,255,255,0.16)
border-glass-mediawhite-a16rgba(255,255,255,0.16)
button-destructive-bgButton destructive: the fill of the action that confirms a deletion or takes access away.
dangervermilion-600#c8321e
dangervermilion-600#c8321e
button-destructive-fgButton destructive: its label and icon.
on-dangerneutral-0#ffffff
on-dangerneutral-0#ffffff

Space and shape

button-radius
radius-md
12px
button-pill-radius
radius-full
9999px
button-height-sm
size-control-sm
36px
button-height-md
size-control-md
44px
button-height-lg
size-control-lg
52px
button-gap
gap-md
8px
button-active-scale
scale-press
.97
button-padding-x-sm
inset-md
12px
button-padding-x-md
inset-lg
16px
button-padding-x-lg
inset-xl
24px
button-outline-inset-ring-width
line-hairline
1px
button-media-secondary-blur
blur-glass
blur(22px) saturate(1.8)
button-media-secondary-inset-ring-width
line-hairline
1px
button-disabled-opacity
opacity-disabled
0.35
button-icon-size-lg
icon-size-sm
16px
button-icon-size
icon-size-sm
16px
button-cost-gap
gap-xs
4px
button-cost-margin-left
gap-2xs
2px
button-cost-padding-left
inset-md
12px
button-cost-border-left-width
line-hairline
1px
button-cost-padding-left-sm-md
inset-sm
8px
button-forced-edge-width
line-hairline
1px

Type

button-font-family
font-sans
Funnel Sans
button-font-weight
weight-bold
700
button-font-size-sm
text-label-bold-size
14px
Aa
button-line-height-sm
text-label-bold-line-height
18px
button-font-size-md
text-label-bold-size
14px
Aa
button-line-height-md
text-label-bold-line-height
18px
button-font-size-lg
its own value
16px
Aa
button-line-height-lg
its own value
20px
button-secondary-font-weight
weight-strong
600
button-outline-font-weight
weight-strong
600
button-ghost-font-weight
weight-strong
600
button-media-secondary-font-weight
weight-strong
600
button-cost-font-weight
weight-strong
600

Motion

button-duration
motion-fast
160ms
button-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
button-active-duration
motion-instant
100ms

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
Button's own: a native button (a link with href), so Tab reaches it, Enter activates it, and Space does too on a button. A screen reader hears its label, then the price as "~100 fragments"; the mark and icons are hidden. With href and disabled it is a disabled button, out of the tab order, so a price can't be spent through a disabled link.
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.