Theming

The token system the styled components paint against, and the CSS to copy.

The styled components paint against a small set of semantic tokens. Copy the token CSS into your global stylesheet once and every component reads it. The headless package has no styling of its own, so this only matters if you use the styled components.

The token model

Four seeds drive everything:

:root {
  --bg: #ffffff;   /* canvas */
  --fg: #1a1a1a;   /* ink */
  --acc: #0169cc;  /* accent */
  --con: 0.3;      /* contrast — how far surfaces and states step from bg */
}

Every other token derives from those with oklch(from … calc(…)): the surface tiers (--primary, --tertiary, --base), their -hover/-active/-border states, the accent chain, and the ink tiers. Because the derivations reference the seeds, dark mode is just a different set of seeds — the .dark block re-seeds --bg/--fg/--acc and flips the state-delta signs, and every derived value recomputes. Tune the whole system by changing four values.

Copy the tokens

Paste this into your globals.css (after @import "tailwindcss"). It defines the seeds, the derived tokens, the @theme inline mappings, and the .dark overrides:

app/globals.css
@custom-variant dark (&:is(.dark *));

:root {
  font-feature-settings:
    "liga" 1,
    "calt" 1;

  --bg: #ffffff;
  --fg: #1a1a1a;
  --acc: #0169cc;
  --con: 0.35;

  --mix-hover: calc(16% * var(--con));
  --mix-active: calc(20% * var(--con));
  --mix-border: calc(24% * var(--con));

  /* Border states stack from the border token so a hovered border keeps its
     separation from the hovered background. */
  --base-bg: color-mix(in oklch, var(--bg), var(--fg) calc(10% * var(--con)));
  --base-bg-hover: color-mix(in oklch, var(--base-bg), var(--fg) var(--mix-hover));
  --base-bg-active: color-mix(in oklch, var(--base-bg), var(--fg) var(--mix-active));
  --base-border: color-mix(in oklch, var(--base-bg), var(--fg) var(--mix-border));
  --base-border-hover: color-mix(in oklch, var(--base-border), var(--fg) var(--mix-hover));
  --base-border-active: color-mix(in oklch, var(--base-border), var(--fg) var(--mix-active));

  --secondary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(4% * var(--con)));
  --secondary-bg-hover: color-mix(in oklch, var(--secondary-bg), var(--fg) var(--mix-hover));
  --secondary-bg-active: color-mix(in oklch, var(--secondary-bg), var(--fg) var(--mix-active));
  --secondary-border: color-mix(in oklch, var(--secondary-bg), var(--fg) var(--mix-border));
  --secondary-border-hover: color-mix(in oklch, var(--secondary-border), var(--fg) var(--mix-hover));
  --secondary-border-active: color-mix(
    in oklch,
    var(--secondary-border),
    var(--fg) var(--mix-active)
  );

  --primary-bg: var(--bg);
  --primary-bg-hover: color-mix(in oklch, var(--primary-bg), var(--fg) var(--mix-hover));
  --primary-bg-active: color-mix(in oklch, var(--primary-bg), var(--fg) var(--mix-active));
  --primary-border: color-mix(in oklch, var(--primary-bg), var(--fg) var(--mix-border));
  --primary-border-hover: color-mix(in oklch, var(--primary-border), var(--fg) var(--mix-hover));
  --primary-border-active: color-mix(in oklch, var(--primary-border), var(--fg) var(--mix-active));

  --tertiary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(2% * var(--con)));
  --tertiary-bg-hover: color-mix(in oklch, var(--tertiary-bg), var(--fg) var(--mix-hover));
  --tertiary-bg-active: color-mix(in oklch, var(--tertiary-bg), var(--fg) var(--mix-active));
  --tertiary-border: color-mix(in oklch, var(--tertiary-bg), var(--fg) var(--mix-border));
  --tertiary-border-hover: color-mix(in oklch, var(--tertiary-border), var(--fg) var(--mix-hover));
  --tertiary-border-active: color-mix(in oklch, var(--tertiary-border), var(--fg) var(--mix-active));

  --quaternary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(24% * var(--con)));
  --quaternary-bg-hover: color-mix(in oklch, var(--quaternary-bg), var(--fg) var(--mix-hover));
  --quaternary-bg-active: color-mix(in oklch, var(--quaternary-bg), var(--fg) var(--mix-active));
  --quaternary-border: color-mix(in oklch, var(--quaternary-bg), var(--fg) var(--mix-border));
  --quaternary-border-hover: color-mix(
    in oklch,
    var(--quaternary-border),
    var(--fg) var(--mix-hover)
  );
  --quaternary-border-active: color-mix(
    in oklch,
    var(--quaternary-border),
    var(--fg) var(--mix-active)
  );

  --accent-bg: color-mix(in oklch, var(--acc), var(--fg) calc(28% * var(--con)));
  --accent-bg-hover: color-mix(in oklch, var(--acc), var(--fg) var(--mix-hover));
  --accent-bg-active: color-mix(in oklch, var(--acc), var(--fg) var(--mix-active));
  --accent-border: color-mix(in oklch, var(--acc), var(--fg) var(--mix-border));
  --accent-border-hover: color-mix(in oklch, var(--accent-border), var(--fg) var(--mix-hover));
  --accent-border-active: color-mix(in oklch, var(--accent-border), var(--fg) var(--mix-active));

  --text-primary: color-mix(in oklch, var(--bg), var(--fg) 85%);
  --text-secondary: color-mix(in oklch, var(--bg), var(--fg) 58%);
  --text-tertiary: color-mix(in oklch, var(--bg), var(--fg) 40%);

  --radius: 8px;
  --sidebar-width: 224px;
  --thread-width: 672px;
  --artifacts-panel-width: 512px;
}

.dark {
  --bg: #111111;
  --fg: #fcfcfc;
  --acc: #4a9eed;

  --base-bg: var(--bg);
  --primary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(12% * var(--con)));
  --secondary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(3% * var(--con)));
  --tertiary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(20% * var(--con)));
  --quaternary-bg: color-mix(in oklch, var(--bg), var(--fg) calc(56% * var(--con)));

  --mix-hover: calc(16% * var(--con));
  --mix-active: calc(18% * var(--con));
  --mix-border: calc(20% * var(--con));
}

@theme inline {
  --color-base-bg: var(--base-bg);
  --color-base-bg-hover: var(--base-bg-hover);
  --color-base-bg-active: var(--base-bg-active);
  --color-base-border: var(--base-border);
  --color-base-border-hover: var(--base-border-hover);
  --color-base-border-active: var(--base-border-active);
  --color-secondary-bg: var(--secondary-bg);
  --color-secondary-bg-hover: var(--secondary-bg-hover);
  --color-secondary-bg-active: var(--secondary-bg-active);
  --color-secondary-border: var(--secondary-border);
  --color-secondary-border-hover: var(--secondary-border-hover);
  --color-secondary-border-active: var(--secondary-border-active);
  --color-primary-bg: var(--primary-bg);
  --color-primary-bg-hover: var(--primary-bg-hover);
  --color-primary-bg-active: var(--primary-bg-active);
  --color-primary-border: var(--primary-border);
  --color-primary-border-hover: var(--primary-border-hover);
  --color-primary-border-active: var(--primary-border-active);
  --color-tertiary-bg: var(--tertiary-bg);
  --color-tertiary-bg-hover: var(--tertiary-bg-hover);
  --color-tertiary-bg-active: var(--tertiary-bg-active);
  --color-tertiary-border: var(--tertiary-border);
  --color-tertiary-border-hover: var(--tertiary-border-hover);
  --color-tertiary-border-active: var(--tertiary-border-active);
  --color-quaternary-bg: var(--quaternary-bg);
  --color-quaternary-bg-hover: var(--quaternary-bg-hover);
  --color-quaternary-bg-active: var(--quaternary-bg-active);
  --color-quaternary-border: var(--quaternary-border);
  --color-quaternary-border-hover: var(--quaternary-border-hover);
  --color-quaternary-border-active: var(--quaternary-border-active);
  --color-accent-bg: var(--accent-bg);
  --color-accent-bg-hover: var(--accent-bg-hover);
  --color-accent-bg-active: var(--accent-bg-active);
  --color-accent-border: var(--accent-border);
  --color-accent-border-hover: var(--accent-border-hover);
  --color-accent-border-active: var(--accent-border-active);
  --color-ink-primary: var(--text-primary);
  --color-ink-secondary: var(--text-secondary);
  --color-ink-tertiary: var(--text-tertiary);
  --radius-xs: calc(var(--radius) - 4px);
  --radius-sm: calc(var(--radius) - 2px);
  --radius-md: var(--radius);
  --radius-lg: calc(var(--radius) + 2px);
  --radius-xl: calc(var(--radius) + 4px);
  --radius-2xl: calc(var(--radius) + 8px);
  --radius-3xl: calc(var(--radius) + 12px);
  --radius-4xl: calc(var(--radius) + 16px);
  --text-2xs: 11px;
  --text-xs: 12px;
  --text-sm: 13px;
  --text-md: 14px;
  --text-lg: 15px;
  --text-xl: 16px;
}

The @source line keeps Tailwind scanning the streamdown package for classes; drop it if you don't render markdown. Adjust the four seeds to rebrand.