1import type { UsageProviderKind } from "@t3tools/contracts";
2import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider";
3
4/**
5 * Series and table order. The chart stacks providers from the bottom in this
6 * order, so it also fixes which band sits on top of the bars.
7 */
8export const PROVIDER_ORDER: readonly UsageProviderKind[] = [
9 "codex",
10 "claude",
11 "grok",
12 "cursor",
13 "opencode",
14 "antigravity",
15 "pi",
16];
17
18export const PROVIDER_LABEL: Record<UsageProviderKind, string> = {
19 claude: "Claude Code",
20 codex: "Codex",
21 grok: "Grok Build",
22 cursor: "Cursor",
23 opencode: "OpenCode",
24 antigravity: "Antigravity",
25 pi: "Pi",
26};
27
28/**
29 * Claude's brand orange holds in both themes; Codex and Grok are neutrals and
30 * must flip with the theme or their bars vanish against the matching background.
31 */
32export function useProviderColors(): Record<UsageProviderKind, string> {
33 const { themeAppearance: scheme } = useAppearancePreferences();
34 return {
35 claude: "#d97757",
36 codex: scheme === "dark" ? "#e6e6e6" : "#3c3c43",
37 grok: scheme === "dark" ? "#a1a1aa" : "#52525b",
38 cursor: "#8b8b8b",
39 opencode: "#5b9bbd",
40 antigravity: "#8c7bd1",
41 pi: "#4d9f8a",
42 };
43}
44
45/**
46 * Neutral steps for cost and token mixes, so they never borrow a provider's
47 * color. Matches the web steps: oklab mixes of the codex ink into the
48 * background, above the 15 ΔE separation floor for adjacent segments.
49 */
50export function useUsageMixColors() {
51 const { themeAppearance: scheme } = useAppearancePreferences();
52 const dark = scheme === "dark";
53 return {
54 input: dark ? "#737373" : "#848484",
55 cacheRead: dark ? "#282828" : "#c0c0c0",
56 cacheWrite: dark ? "#949494" : "#6d6d6d",
57 output: dark ? "#e6e6e6" : "#3c3c43",
58 other: dark ? "#494949" : "#a3a3a3",
59 standard: dark ? "#313131" : "#b8b8b8",
60 fast: dark ? "#838383" : "#797979",
61 ultrafast: dark ? "#e6e6e6" : "#3c3c43",
62 };
63}