Contents Purpose Anatomy Variants States Tokens Used Accessibility Behavior Platform Notes Component: spinner Purpose Indicate loading state with a rotating animation. Anatomy Single element — a spinning circle Variants Class Visual Usage spinner 32px circle, 2px border, accent-colored arc Default loading indicator spinner-sm 16px circle, 1.5px border Inline or compact contexts States Always animating (spin). Respects prefers-reduced-motion — opacity pulse instead of rotation. Tokens Used --space-4, --space-8 --color-accent-base --color-border-default --duration-normal Accessibility Use role="status" on the spinner element Add aria-label="Loading" (or context-appropriate label) Screen readers announce the loading state without seeing the animation Behavior Default size: 32px (--space-8) width and height Small size: 16px (--space-4) width and height Border: var(--color-border-default) with border-top-color: var(--color-accent-base) Border-radius: 50% — sanctioned exception (like skeleton-circle) Animation: 0.6s linear infinite rotation prefers-reduced-motion: reduce: opacity pulse (1s ease-in-out infinite, 1.0 to 0.4) instead of rotation No interactivity — purely visual indicator Inline display — can sit alongside text Platform Notes Web: CSS in @layer components. One file: spinner.css. Pure CSS animation — no JS needed. macOS: Map to SwiftUI ProgressView() or NSProgressIndicator (indeterminate, spinning style).