AI Layer

Primitives and semantic tokens for AI-powered states. Aurora, Halo, and Dots share a consistent OKLCH color identity that does not flip with theme.

AI is drafting a response…

Hue anchors (primitives)

Six OKLCH values. Identical in dark and light — AI identity does not flip with theme.

--ai-hue-1
magenta
--ai-hue-2
warm red
--ai-hue-3
emerald
--ai-hue-4
cyan
--ai-hue-5
blue
--ai-hue-6
violet

Semantic tokens

Composed from hue anchors. Consumed by components — do not use raw hue vars in component code.

--ai-glow-colorAmbient glow color used for AI-tinted box-shadows
--ai-aurora-fromAurora left blob color (magenta anchor)
--ai-aurora-viaAurora center blob color (emerald anchor)
--ai-aurora-toAurora right blob color (violet anchor)

Component vars

Override any --ds-ai-* var on a parent element to adjust a single instance without touching the component source.

--ds-ai-halo-width1px
--ds-ai-halo-speed3s
--ds-ai-halo-bloom-size10px
--ds-ai-halo-bloom-opacity0.55
--ds-ai-dots-size8px
--ds-ai-dots-gap6px
--ds-ai-dots-speed1.2s
--ds-ai-aurora-blur40px
--ds-ai-aurora-opacity0.45
--ds-ai-aurora-speed12s
--ds-ai-aurora-blendauto

Usage guidelines

When to use

  • Active generation — spinner / dots while the model streams
  • AI-powered UI surfaces — panels, sidebars, chat windows
  • Contextual AI entry points — buttons that trigger a model call
  • Onboarding moments that introduce AI capability

Do not use

  • Decorative polish on non-AI features — the iridescent palette carries meaning
  • Error or destructive states — use status red instead
  • Always-on ambient decoration — reserve for transient AI states
  • Dense data tables or form-heavy screens where motion distracts

How to apply to existing components

Three common patterns: a loading button, an AI response panel, and a thinking row.

Loading button

// Loading button with Halo + Dots
function AiButton({ loading }: { loading: boolean }) {
  return (
    <Halo tone="iridescent" active={loading}>
      <Button disabled={loading}>
        {loading ? (
          <>
            Generating
            <Dots size="sm" className="ml-2" />
          </>
        ) : (
          "Ask AI"
        )}
      </Button>
    </Halo>
  );
}

AI panel

// AI response panel with Aurora background
function AiPanel({ children }: { children: React.ReactNode }) {
  return (
    <div className="relative rounded-[var(--ds-radius-card)] border border-edge-subtle bg-surface-card overflow-hidden p-6">
      <Aurora intensity="subtle" />
      <div className="relative">{children}</div>
    </div>
  );
}

Thinking row

// Thinking row in a message list
function ThinkingRow() {
  return (
    <div className="flex items-center gap-3 py-3 px-4 rounded-[var(--ds-radius-card)] bg-surface-elevated">
      <Dots size="md" tone="iridescent" />
      <span className="text-sm text-fg-muted">AI is thinking…</span>
    </div>
  );
}

Motion

All AI animations — halo spin, dots bounce, aurora drift — are wrapped in @media (prefers-reduced-motion: reduce) guards in the token CSS. When reduced motion is active, animations are set to none and the halo renders as a static iridescent border. Dots remain visible but stationary. Aurora opacity is halved to reduce visual noise.