rift-ds 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +28 -5
  2. package/bin/rift-ds.mjs +142 -29
  3. package/bin/templates/chat/.env.chat.example +21 -0
  4. package/bin/templates/chat/app/api/chat/feedback/route.ts +12 -0
  5. package/bin/templates/chat/app/api/chat/followups/route.ts +23 -0
  6. package/bin/templates/chat/app/api/chat/guardrails.ts +18 -0
  7. package/bin/templates/chat/app/api/chat/route.ts +31 -0
  8. package/bin/templates/chat/components/chat/ChatMount.tsx +52 -0
  9. package/bin/templates/chat/components/chat/models.ts +29 -0
  10. package/chat/AssistantTurn.d.ts +5 -0
  11. package/chat/AssistantTurn.js +82 -0
  12. package/chat/ChatAgentPane.css +56 -0
  13. package/chat/ChatAgentPane.d.ts +21 -0
  14. package/chat/ChatAgentPane.js +25 -0
  15. package/chat/ChatLauncher.d.ts +64 -0
  16. package/chat/ChatLauncher.js +347 -0
  17. package/chat/ChatProvider.d.ts +53 -0
  18. package/chat/ChatProvider.js +181 -0
  19. package/chat/ChatTabs.d.ts +13 -0
  20. package/chat/ChatTabs.js +24 -0
  21. package/chat/ChatThreads.d.ts +26 -0
  22. package/chat/ChatThreads.js +55 -0
  23. package/chat/ChatWidget.css +1072 -0
  24. package/chat/ChatWidget.d.ts +113 -0
  25. package/chat/ChatWidget.js +495 -0
  26. package/chat/DemoWelcome.d.ts +13 -0
  27. package/chat/DemoWelcome.js +131 -0
  28. package/chat/FollowupSuggestions.d.ts +23 -0
  29. package/chat/FollowupSuggestions.js +34 -0
  30. package/chat/ResponseActions.d.ts +18 -0
  31. package/chat/ResponseActions.js +79 -0
  32. package/chat/TurnContent.d.ts +9 -0
  33. package/chat/TurnContent.js +12 -0
  34. package/chat/context.d.ts +65 -0
  35. package/chat/context.js +27 -0
  36. package/chat/demo-agent-panes.d.ts +5 -0
  37. package/chat/demo-agent-panes.js +49 -0
  38. package/chat/demo-agent.d.ts +3 -0
  39. package/chat/demo-agent.js +28 -0
  40. package/chat/demo-card-components.d.ts +46 -0
  41. package/chat/demo-card-components.js +59 -0
  42. package/chat/demo-cards.d.ts +32 -0
  43. package/chat/demo-cards.js +59 -0
  44. package/chat/demo-fixtures.d.ts +20 -0
  45. package/chat/demo-fixtures.js +113 -0
  46. package/chat/demo-script.d.ts +6 -0
  47. package/chat/demo-script.js +215 -0
  48. package/chat/demo.css +46 -0
  49. package/chat/demo.d.ts +9 -0
  50. package/chat/demo.js +24 -0
  51. package/chat/followups.d.ts +41 -0
  52. package/chat/followups.js +55 -0
  53. package/chat/greeting.d.ts +11 -0
  54. package/chat/greeting.js +21 -0
  55. package/chat/index.d.ts +34 -0
  56. package/chat/index.js +80 -0
  57. package/chat/placement.d.ts +48 -0
  58. package/chat/placement.js +39 -0
  59. package/chat/queries.d.ts +9 -0
  60. package/chat/queries.js +22 -0
  61. package/chat/registry.d.ts +25 -0
  62. package/chat/registry.js +9 -0
  63. package/chat/registry.json.d.ts +69 -0
  64. package/chat/registry.json.js +11 -0
  65. package/chat/server.d.ts +217 -0
  66. package/chat/server.js +488 -0
  67. package/chat/sim.d.ts +71 -0
  68. package/chat/sim.js +125 -0
  69. package/chat/starters.d.ts +15 -0
  70. package/chat/starters.js +38 -0
  71. package/chat/suggestions.d.ts +22 -0
  72. package/chat/suggestions.js +9 -0
  73. package/chat/threads.d.ts +73 -0
  74. package/chat/threads.js +270 -0
  75. package/chat/transport.d.ts +49 -0
  76. package/chat/transport.js +105 -0
  77. package/chat/types.d.ts +210 -0
  78. package/chat/types.js +16 -0
  79. package/chat/upstash.d.ts +63 -0
  80. package/chat/upstash.js +147 -0
  81. package/chat/useChat.d.ts +64 -0
  82. package/chat/useChat.js +241 -0
  83. package/cli/templates/chat/app/api/chat/feedback/route.d.ts +3 -0
  84. package/cli/templates/chat/app/api/chat/followups/route.d.ts +3 -0
  85. package/cli/templates/chat/app/api/chat/guardrails.d.ts +10 -0
  86. package/cli/templates/chat/app/api/chat/route.d.ts +4 -0
  87. package/cli/templates/chat/components/chat/ChatMount.d.ts +1 -0
  88. package/cli/templates/chat/components/chat/models.d.ts +11 -0
  89. package/components/ShaderField/ShaderField.d.ts +3 -2
  90. package/components/ShaderField/useShaderField.d.ts +2 -1
  91. package/components/ShaderField/useShaderField.js +6 -6
  92. package/fonts/material-symbols.css +2 -1
  93. package/package.json +39 -2
  94. package/tokens/presets/coral.css +18 -2
  95. package/tokens/presets/forest.css +18 -2
  96. package/tokens/presets/gold.css +18 -2
  97. package/tokens/presets/mono.css +18 -2
  98. package/tokens/presets/pink.css +18 -2
  99. package/tokens/presets/terminal.css +18 -2
  100. package/tokens/presets/violet.css +18 -2
  101. package/tokens/presets/warm.css +18 -2
  102. package/tokens/presets/zest.css +18 -2
  103. package/tokens/registry.json +6 -0
  104. package/tokens/registry.json.d.ts +6 -0
  105. package/tokens/registry.json.js +1 -1
  106. package/tokens/tokens-dark.css +10 -0
  107. package/tokens/tokens-light.css +10 -0
@@ -0,0 +1,241 @@
1
+ "use client";
2
+ import { useState, useRef, useEffect, useCallback } from "react";
3
+ import { revokeAttachmentUrls } from "../components/Attachment/useAttachments.js";
4
+ import { createStreamReveal } from "../components/StreamingText/useStreamReveal.js";
5
+ let nextId = 0;
6
+ const makeId = () => `turn-${++nextId}`;
7
+ const DEFAULT_PLACEHOLDER_COPY = {
8
+ empty: "The reply came back empty. Try sending that again.",
9
+ stopped: "Stopped before a reply arrived.",
10
+ failed: "Something went wrong while replying. Try sending that again."
11
+ };
12
+ function useChat(transport, placeholders = DEFAULT_PLACEHOLDER_COPY) {
13
+ const [turns, setTurns] = useState([]);
14
+ const [live, setLive] = useState(null);
15
+ const [modelLabel, setModelLabel] = useState(null);
16
+ const [modelPolicy, setModelPolicy] = useState(null);
17
+ const abortRef = useRef(null);
18
+ const busyRef = useRef(false);
19
+ const historyRef = useRef([]);
20
+ const generationRef = useRef(0);
21
+ useEffect(() => () => abortRef.current?.abort(), []);
22
+ const turnsRef = useRef(turns);
23
+ useEffect(() => {
24
+ turnsRef.current = turns;
25
+ }, [turns]);
26
+ const releaseAttachments = useCallback(() => {
27
+ for (const turn of turnsRef.current) {
28
+ if (turn.attachments) revokeAttachmentUrls(turn.attachments);
29
+ }
30
+ }, []);
31
+ useEffect(() => releaseAttachments, [releaseAttachments]);
32
+ const streaming = live !== null;
33
+ const commit = useCallback(
34
+ (finished, startedAt, historyText) => {
35
+ if (historyText !== null && historyText !== "") {
36
+ historyRef.current = [
37
+ ...historyRef.current,
38
+ { role: "assistant", content: historyText }
39
+ ];
40
+ }
41
+ setLive(null);
42
+ setTurns((prev) => [
43
+ ...prev,
44
+ {
45
+ id: finished.id,
46
+ role: "assistant",
47
+ text: finished.text,
48
+ tracePoints: finished.tracePoints,
49
+ exchangeId: finished.exchangeId,
50
+ followups: finished.followups,
51
+ content: finished.content,
52
+ card: finished.card,
53
+ durationSeconds: finished.durationSeconds ?? Math.max(1, Math.round((Date.now() - startedAt) / 1e3))
54
+ }
55
+ ]);
56
+ },
57
+ []
58
+ );
59
+ const send = useCallback(
60
+ (text, options) => {
61
+ const trimmed = text.trim();
62
+ const attachments = options?.attachments?.length ? options.attachments : void 0;
63
+ if (trimmed === "" && !attachments || busyRef.current) return false;
64
+ busyRef.current = true;
65
+ const controller = new AbortController();
66
+ abortRef.current = controller;
67
+ const generation = generationRef.current;
68
+ const startedAt = Date.now();
69
+ const history = [
70
+ ...historyRef.current,
71
+ {
72
+ role: "user",
73
+ content: trimmed,
74
+ attachments: attachments?.map(({ name, kind, size }) => ({ name, kind, size }))
75
+ }
76
+ ];
77
+ historyRef.current = history;
78
+ const userTurnId = makeId();
79
+ setTurns((prev) => [
80
+ ...prev,
81
+ {
82
+ id: userTurnId,
83
+ role: "user",
84
+ text: trimmed,
85
+ content: options?.content,
86
+ attachments
87
+ }
88
+ ]);
89
+ let current = {
90
+ id: makeId(),
91
+ phase: "thinking",
92
+ statusLabel: "Thinking",
93
+ tracePoints: [],
94
+ text: ""
95
+ };
96
+ setLive(current);
97
+ const update = (next) => {
98
+ current = next;
99
+ setLive(next);
100
+ };
101
+ const reveal = createStreamReveal({
102
+ onUpdate: (visible) => update({ ...current, text: visible }),
103
+ /* Someone who has asked for less motion is asking for less of this. */
104
+ paced: !window.matchMedia("(prefers-reduced-motion: reduce)").matches
105
+ });
106
+ const run = async () => {
107
+ try {
108
+ for await (const event of transport(history, controller.signal)) {
109
+ if (generation !== generationRef.current || controller.signal.aborted) break;
110
+ switch (event.type) {
111
+ case "model":
112
+ setModelLabel(event.label);
113
+ break;
114
+ case "models":
115
+ setModelPolicy({ default: event.default, locked: event.locked });
116
+ break;
117
+ case "exchange":
118
+ current = { ...current, exchangeId: event.id };
119
+ break;
120
+ case "followups":
121
+ current = { ...current, followups: event.items };
122
+ break;
123
+ case "content":
124
+ current = { ...current, content: event.node };
125
+ break;
126
+ case "card":
127
+ current = { ...current, card: event.card };
128
+ break;
129
+ case "status":
130
+ update({
131
+ ...current,
132
+ statusLabel: event.label,
133
+ tracePoints: event.point ? [...current.tracePoints, event.point] : current.tracePoints
134
+ });
135
+ break;
136
+ case "delta":
137
+ current = {
138
+ ...current,
139
+ phase: "streaming",
140
+ // Thinking ends at the first delta; freeze the duration then.
141
+ durationSeconds: current.durationSeconds ?? Math.max(1, Math.round((Date.now() - startedAt) / 1e3))
142
+ };
143
+ reveal.append(event.text);
144
+ break;
145
+ /* A guardrail line and a failure are not the model speaking, so
146
+ they are not paced like it: they appear whole. */
147
+ case "notice":
148
+ case "error":
149
+ current = {
150
+ ...current,
151
+ phase: "streaming",
152
+ durationSeconds: current.durationSeconds ?? 1
153
+ };
154
+ reveal.showWhole(event.type === "notice" ? event.text : event.message);
155
+ break;
156
+ case "done":
157
+ break;
158
+ }
159
+ if (event.type === "done") break;
160
+ }
161
+ if (controller.signal.aborted || generation !== generationRef.current) {
162
+ reveal.flush();
163
+ } else {
164
+ await reveal.drained();
165
+ }
166
+ reveal.cancel();
167
+ if (generation !== generationRef.current) return;
168
+ if (current.text === "") {
169
+ commit({ ...current, text: placeholders.empty }, startedAt, null);
170
+ } else {
171
+ commit(current, startedAt, current.text);
172
+ }
173
+ } catch (err) {
174
+ reveal.flush();
175
+ if (generation !== generationRef.current) ;
176
+ else if (controller.signal.aborted) {
177
+ if (current.text === "") {
178
+ commit({ ...current, text: placeholders.stopped }, startedAt, null);
179
+ } else {
180
+ commit(current, startedAt, current.text);
181
+ }
182
+ } else {
183
+ if (current.text === "") {
184
+ commit({ ...current, text: placeholders.failed }, startedAt, null);
185
+ } else {
186
+ commit(current, startedAt, current.text);
187
+ }
188
+ console.error(err);
189
+ }
190
+ } finally {
191
+ if (generation === generationRef.current) busyRef.current = false;
192
+ }
193
+ };
194
+ void run();
195
+ return true;
196
+ },
197
+ [transport, commit, placeholders]
198
+ );
199
+ const setTurnFeedback = useCallback((turnId, feedback) => {
200
+ setTurns(
201
+ (prev) => prev.map((turn) => turn.id === turnId ? { ...turn, feedback } : turn)
202
+ );
203
+ }, []);
204
+ const setTurnFollowups = useCallback((turnId, followups) => {
205
+ setTurns(
206
+ (prev) => prev.map((turn) => turn.id === turnId ? { ...turn, followups } : turn)
207
+ );
208
+ }, []);
209
+ const injectTurn = useCallback((turn) => {
210
+ setTurns((prev) => [...prev, { ...turn, id: makeId() }]);
211
+ }, []);
212
+ const stop = useCallback(() => {
213
+ abortRef.current?.abort();
214
+ }, []);
215
+ const reset = useCallback(() => {
216
+ generationRef.current += 1;
217
+ abortRef.current?.abort();
218
+ busyRef.current = false;
219
+ historyRef.current = [];
220
+ releaseAttachments();
221
+ setTurns([]);
222
+ setLive(null);
223
+ }, [releaseAttachments]);
224
+ return {
225
+ turns,
226
+ live,
227
+ streaming,
228
+ modelLabel,
229
+ modelPolicy,
230
+ send,
231
+ stop,
232
+ reset,
233
+ injectTurn,
234
+ setTurnFeedback,
235
+ setTurnFollowups
236
+ };
237
+ }
238
+ export {
239
+ DEFAULT_PLACEHOLDER_COPY,
240
+ useChat
241
+ };
@@ -0,0 +1,3 @@
1
+ export declare const runtime = "nodejs";
2
+ export declare const dynamic = "force-dynamic";
3
+ export declare function POST(request: Request): Promise<Response>;
@@ -0,0 +1,3 @@
1
+ export declare const runtime = "nodejs";
2
+ export declare const dynamic = "force-dynamic";
3
+ export declare function POST(request: Request): Promise<Response>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Rate limits, a daily budget with model tiers, the exchange log and the
3
+ * feedback store, over Upstash Redis. Shared by the three chat routes.
4
+ *
5
+ * Fails open: with KV_REST_API_URL and KV_REST_API_TOKEN unset, every
6
+ * request is allowed and nothing is logged, so the chat works on day one
7
+ * and the limits arrive when you add the two variables. Set CHAT_VISITOR_SALT
8
+ * too: it salts the hashed visitor address the limits key on.
9
+ */
10
+ export declare const guardrails: import('../../../../../../chat/server').ChatGuardrails;
@@ -0,0 +1,4 @@
1
+ export declare const runtime = "nodejs";
2
+ export declare const maxDuration = 60;
3
+ export declare const dynamic = "force-dynamic";
4
+ export declare function POST(request: Request): Promise<Response>;
@@ -0,0 +1 @@
1
+ export declare function ChatMount(): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { ChatModelOption } from 'rift-ds/chat';
2
+ /**
3
+ * The models your chat offers. The widget's picker shows `label` and
4
+ * `description`; the client sends `value`; the server calls `id`. Shared by
5
+ * the route and the mount so the two can never disagree. Edit freely.
6
+ */
7
+ export declare const CHAT_MODELS: ChatModelOption[];
8
+ /** What serves when the visitor has not chosen. */
9
+ export declare const DEFAULT_CHAT_MODEL: string;
10
+ /** The model that writes the three follow-up questions under an answer. */
11
+ export declare const FOLLOWUP_MODEL = "claude-haiku-5-5";
@@ -17,8 +17,9 @@ type ShaderFieldOwnProps = {
17
17
  */
18
18
  params?: Partial<ShaderParams>;
19
19
  /**
20
- * The light sources. Defaults to an eight-source composition on the core
21
- * accent tokens. Fewer than `BLOB_COUNT` entries is fine — unused slots park
20
+ * The light sources. Defaults to an eight-source composition: six on the
21
+ * ambient tokens (`--color-ambient-*`, which follow the core accents unless a
22
+ * theme re-points them) and two on surface tokens. Fewer than `BLOB_COUNT` entries is fine — unused slots park
22
23
  * off-field; more are ignored, because the shader's uniform arrays are
23
24
  * fixed-size.
24
25
  */
@@ -74,7 +74,8 @@ export interface ShaderBlob {
74
74
  */
75
75
  export declare const DEFAULT_SHADER_PARAMS: ShaderParams;
76
76
  /**
77
- * The default composition: eight sources on core accent tokens, filling
77
+ * The default composition: eight sources, six on the ambient tokens and two
78
+ * on surface tokens, filling
78
79
  * BLOB_COUNT exactly.
79
80
  *
80
81
  * `--color-action-primary-bg` is deliberately absent. The action colour is
@@ -12,13 +12,13 @@ const DEFAULT_SHADER_PARAMS = {
12
12
  crop: 0.5
13
13
  };
14
14
  const DEFAULT_SHADER_BLOBS = [
15
- { token: "--color-core-accent-gold", size: 0.45, cx: 0.175, cy: 0.125, period: 18, phase: 0, weight: 1 },
16
- { token: "--color-core-accent-mint", size: 0.55, cx: 0.125, cy: 0.125, period: 16, phase: 1, weight: 1 },
17
- { token: "--color-core-accent-violet", size: 0.9, cx: 0.35, cy: 0.25, period: 22, phase: 0.5, weight: 1 },
15
+ { token: "--color-ambient-1", size: 0.45, cx: 0.175, cy: 0.125, period: 18, phase: 0, weight: 1 },
16
+ { token: "--color-ambient-2", size: 0.55, cx: 0.125, cy: 0.125, period: 16, phase: 1, weight: 1 },
17
+ { token: "--color-ambient-3", size: 0.9, cx: 0.35, cy: 0.25, period: 22, phase: 0.5, weight: 1 },
18
18
  { token: "--color-bg-container-secondary", size: 0.55, cx: 0.025, cy: 0.075, period: 14, phase: 1.5, weight: 1 },
19
- { token: "--color-core-accent-cobalt", size: 0.55, cx: -0.125, cy: 0.475, period: 17, phase: 0.8, weight: 1 },
20
- { token: "--color-core-accent-coral", size: 0.48, cx: 0.39, cy: -0.26, period: 19, phase: 0.3, weight: 1 },
21
- { token: "--color-core-accent-amber", size: 0.3, cx: 0.35, cy: 0.3, period: 15, phase: 1.2, weight: 1 },
19
+ { token: "--color-ambient-4", size: 0.55, cx: -0.125, cy: 0.475, period: 17, phase: 0.8, weight: 1 },
20
+ { token: "--color-ambient-5", size: 0.48, cx: 0.39, cy: -0.26, period: 19, phase: 0.3, weight: 1 },
21
+ { token: "--color-ambient-6", size: 0.3, cx: 0.35, cy: 0.3, period: 15, phase: 1.2, weight: 1 },
22
22
  { token: "--color-core-ui-secondary", size: 0.75, cx: -0.125, cy: -0.025, period: 20, phase: 0.7, weight: 1 }
23
23
  ];
24
24
  const RENDER_SCALE = 0.5;
@@ -26,7 +26,8 @@
26
26
  specificity with every single-class component rule and — being imported
27
27
  later — won, rendering 24px glyphs inside 20px boxes.
28
28
 
29
- Use one of the semantic steps: --icon-size-500 | -md | -lg | -xl.
29
+ Use one of the semantic steps on the --icon-size-* scale
30
+ (tokens-light.css defines them).
30
31
  */
31
32
  .material-symbols-rounded {
32
33
  font-family: 'Material Symbols Rounded';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rift-ds",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "An AI-ready React design system: accessible components on composable tokens, light/dark theming, and CSS-variable overrides.",
5
5
  "author": {
6
6
  "name": "Robert Ritacca",
@@ -73,6 +73,23 @@
73
73
  "types": "./behaviors/useScrollLock.d.ts",
74
74
  "import": "./behaviors/useScrollLock.js"
75
75
  },
76
+ "./chat": {
77
+ "types": "./chat/index.d.ts",
78
+ "import": "./chat/index.js"
79
+ },
80
+ "./chat/server": {
81
+ "types": "./chat/server.d.ts",
82
+ "import": "./chat/server.js"
83
+ },
84
+ "./chat/upstash": {
85
+ "types": "./chat/upstash.d.ts",
86
+ "import": "./chat/upstash.js"
87
+ },
88
+ "./chat/demo": {
89
+ "types": "./chat/demo.d.ts",
90
+ "import": "./chat/demo.js"
91
+ },
92
+ "./chat/chat.css": "./chat/ChatWidget.css",
76
93
  "./tokens/registry": {
77
94
  "types": "./tokens/registry.d.ts",
78
95
  "import": "./tokens/registry.js"
@@ -91,13 +108,33 @@
91
108
  "./package.json": "./package.json"
92
109
  },
93
110
  "peerDependencies": {
111
+ "@anthropic-ai/sdk": "^0.116.0",
112
+ "@upstash/ratelimit": "^2.0.8",
113
+ "@upstash/redis": "^1.38.2",
94
114
  "react": "^19.0.0",
95
115
  "react-dom": "^19.0.0",
96
- "recharts": "^3.0.0"
116
+ "react-markdown": "^10.1.0",
117
+ "recharts": "^3.0.0",
118
+ "remark-gfm": "^4.0.1"
97
119
  },
98
120
  "peerDependenciesMeta": {
121
+ "@anthropic-ai/sdk": {
122
+ "optional": true
123
+ },
124
+ "@upstash/ratelimit": {
125
+ "optional": true
126
+ },
127
+ "@upstash/redis": {
128
+ "optional": true
129
+ },
130
+ "react-markdown": {
131
+ "optional": true
132
+ },
99
133
  "recharts": {
100
134
  "optional": true
135
+ },
136
+ "remark-gfm": {
137
+ "optional": true
101
138
  }
102
139
  }
103
140
  }
@@ -124,7 +124,15 @@ html[data-brand="coral"] {
124
124
  --color-action-primary-text: var(--primitive-neutral-00);
125
125
  --color-action-primary-text-secondary: var(--primitive-red-10);
126
126
  --color-action-primary-text-tertiary: var(--primitive-red-08);
127
- --color-ai-gradient-end: var(--primitive-red-07);
127
+ --color-ai-gradient-end: var(--primitive-red-09);
128
+ --color-ai-gradient-mid: var(--primitive-red-07);
129
+ --color-ai-gradient-start: var(--primitive-red-03);
130
+ --color-ambient-1: #FFC24B;
131
+ --color-ambient-2: #2EBFA5;
132
+ --color-ambient-3: #C86B98;
133
+ --color-ambient-4: #5E7BD0;
134
+ --color-ambient-5: #E6708C;
135
+ --color-ambient-6: #F0A7B8;
128
136
  --color-core-accent-amber: #FF8E3C;
129
137
  --color-core-accent-cobalt: #5E7BD0;
130
138
  --color-core-accent-coral: #FF5A5F;
@@ -244,7 +252,15 @@ html[data-brand="coral"][data-theme="dark"] {
244
252
  --color-action-primary-text-active: var(--primitive-red-01);
245
253
  --color-action-primary-text-secondary: var(--primitive-red-10);
246
254
  --color-action-primary-text-tertiary: var(--primitive-red-07);
247
- --color-ai-gradient-end: var(--primitive-red-08);
255
+ --color-ai-gradient-end: var(--primitive-red-09);
256
+ --color-ai-gradient-mid: var(--primitive-red-07);
257
+ --color-ai-gradient-start: var(--primitive-red-03);
258
+ --color-ambient-1: #FFC24B;
259
+ --color-ambient-2: #2EBFA5;
260
+ --color-ambient-3: #C86B98;
261
+ --color-ambient-4: #5E7BD0;
262
+ --color-ambient-5: #E6708C;
263
+ --color-ambient-6: #F0A7B8;
248
264
  --color-core-accent-amber: #FF8E3C;
249
265
  --color-core-accent-cobalt: #5E7BD0;
250
266
  --color-core-accent-coral: #FF5A5F;
@@ -52,7 +52,15 @@ html[data-brand="forest"] {
52
52
  --color-action-primary-text: var(--primitive-green-02);
53
53
  --color-action-primary-text-secondary: var(--primitive-green-10);
54
54
  --color-action-primary-text-tertiary: var(--primitive-green-08);
55
- --color-ai-gradient-end: var(--primitive-green-07);
55
+ --color-ai-gradient-end: var(--primitive-green-09);
56
+ --color-ai-gradient-mid: var(--primitive-green-07);
57
+ --color-ai-gradient-start: var(--primitive-green-03);
58
+ --color-ambient-1: #C2A147;
59
+ --color-ambient-2: #4E9A6C;
60
+ --color-ambient-3: #7E6899;
61
+ --color-ambient-4: #446E93;
62
+ --color-ambient-5: #709282;
63
+ --color-ambient-6: #A7BCB2;
56
64
  --color-core-accent-amber: #C97F3F;
57
65
  --color-core-accent-cobalt: #446E93;
58
66
  --color-core-accent-coral: #B45E4A;
@@ -197,7 +205,15 @@ html[data-brand="forest"][data-theme="dark"] {
197
205
  --color-action-primary-text-active: var(--primitive-green-02);
198
206
  --color-action-primary-text-secondary: var(--primitive-green-10);
199
207
  --color-action-primary-text-tertiary: var(--primitive-green-07);
200
- --color-ai-gradient-end: var(--primitive-green-08);
208
+ --color-ai-gradient-end: var(--primitive-green-09);
209
+ --color-ai-gradient-mid: var(--primitive-green-07);
210
+ --color-ai-gradient-start: var(--primitive-green-03);
211
+ --color-ambient-1: #C2A147;
212
+ --color-ambient-2: #4E9A6C;
213
+ --color-ambient-3: #7E6899;
214
+ --color-ambient-4: #446E93;
215
+ --color-ambient-5: #709282;
216
+ --color-ambient-6: #A7BCB2;
201
217
  --color-core-accent-amber: #C97F3F;
202
218
  --color-core-accent-cobalt: #446E93;
203
219
  --color-core-accent-coral: #B45E4A;
@@ -53,7 +53,15 @@ html[data-brand="gold"] {
53
53
  --color-action-primary-text-active: var(--primitive-yellow-07);
54
54
  --color-action-primary-text-secondary: var(--primitive-yellow-10);
55
55
  --color-action-primary-text-tertiary: var(--primitive-yellow-08);
56
- --color-ai-gradient-end: var(--primitive-yellow-07);
56
+ --color-ai-gradient-end: var(--primitive-yellow-09);
57
+ --color-ai-gradient-mid: var(--primitive-yellow-07);
58
+ --color-ai-gradient-start: var(--primitive-yellow-03);
59
+ --color-ambient-1: #FFD166;
60
+ --color-ambient-2: #7FC9A0;
61
+ --color-ambient-3: #B78AD9;
62
+ --color-ambient-4: #6E7FD9;
63
+ --color-ambient-5: #FFE19C;
64
+ --color-ambient-6: #FFEDC2;
57
65
  --color-core-accent-amber: #FFAE4F;
58
66
  --color-core-accent-cobalt: #6E7FD9;
59
67
  --color-core-accent-coral: #F58B5B;
@@ -237,7 +245,15 @@ html[data-brand="gold"][data-theme="dark"] {
237
245
  --color-action-primary-text-active: var(--primitive-yellow-11);
238
246
  --color-action-primary-text-secondary: var(--primitive-yellow-10);
239
247
  --color-action-primary-text-tertiary: var(--primitive-yellow-07);
240
- --color-ai-gradient-end: var(--primitive-yellow-08);
248
+ --color-ai-gradient-end: var(--primitive-yellow-09);
249
+ --color-ai-gradient-mid: var(--primitive-yellow-07);
250
+ --color-ai-gradient-start: var(--primitive-yellow-03);
251
+ --color-ambient-1: #FFD166;
252
+ --color-ambient-2: #7FC9A0;
253
+ --color-ambient-3: #B78AD9;
254
+ --color-ambient-4: #6E7FD9;
255
+ --color-ambient-5: #FFE19C;
256
+ --color-ambient-6: #FFEDC2;
241
257
  --color-core-accent-amber: #FFAE4F;
242
258
  --color-core-accent-cobalt: #6E7FD9;
243
259
  --color-core-accent-coral: #F58B5B;
@@ -52,7 +52,15 @@ html[data-brand="mono"] {
52
52
  --color-action-primary-text: var(--primitive-neutral-02);
53
53
  --color-action-primary-text-secondary: var(--primitive-neutral-09);
54
54
  --color-action-primary-text-tertiary: var(--primitive-neutral-08);
55
- --color-ai-gradient-end: var(--primitive-neutral-08);
55
+ --color-ai-gradient-end: var(--primitive-neutral-10);
56
+ --color-ai-gradient-mid: var(--primitive-neutral-08);
57
+ --color-ai-gradient-start: var(--primitive-neutral-04);
58
+ --color-ambient-1: #C9C9C9;
59
+ --color-ambient-2: #ADADAD;
60
+ --color-ambient-3: #8F8F8F;
61
+ --color-ambient-4: #5C5C5C;
62
+ --color-ambient-5: #707070;
63
+ --color-ambient-6: #A7A7A7;
56
64
  --color-core-accent-amber: #B8B8B8;
57
65
  --color-core-accent-cobalt: #5C5C5C;
58
66
  --color-core-accent-coral: #A3A3A3;
@@ -173,7 +181,15 @@ html[data-brand="mono"][data-theme="dark"] {
173
181
  --color-action-primary-text-active: var(--primitive-neutral-07);
174
182
  --color-action-primary-text-secondary: var(--primitive-neutral-06);
175
183
  --color-action-primary-text-tertiary: var(--primitive-neutral-01);
176
- --color-ai-gradient-end: var(--primitive-neutral-03);
184
+ --color-ai-gradient-end: var(--primitive-neutral-06);
185
+ --color-ai-gradient-mid: var(--primitive-neutral-01);
186
+ --color-ai-gradient-start: var(--primitive-neutral-00);
187
+ --color-ambient-1: #C9C9C9;
188
+ --color-ambient-2: #ADADAD;
189
+ --color-ambient-3: #8F8F8F;
190
+ --color-ambient-4: #5C5C5C;
191
+ --color-ambient-5: #F6F6F6;
192
+ --color-ambient-6: #F9F9F9;
177
193
  --color-core-accent-amber: #B8B8B8;
178
194
  --color-core-accent-cobalt: #5C5C5C;
179
195
  --color-core-accent-coral: #A3A3A3;
@@ -53,7 +53,15 @@ html[data-brand="pink"] {
53
53
  --color-action-primary-text-active: var(--primitive-neutral-00);
54
54
  --color-action-primary-text-secondary: var(--primitive-red-10);
55
55
  --color-action-primary-text-tertiary: var(--primitive-red-08);
56
- --color-ai-gradient-end: var(--primitive-red-07);
56
+ --color-ai-gradient-end: var(--primitive-red-09);
57
+ --color-ai-gradient-mid: var(--primitive-red-07);
58
+ --color-ai-gradient-start: var(--primitive-red-03);
59
+ --color-ambient-1: #FFD34D;
60
+ --color-ambient-2: #3DDCB8;
61
+ --color-ambient-3: #C45CFF;
62
+ --color-ambient-4: #5C7CFF;
63
+ --color-ambient-5: #E064AB;
64
+ --color-ambient-6: #ECA0CB;
57
65
  --color-core-accent-amber: #FF9A4D;
58
66
  --color-core-accent-cobalt: #5C7CFF;
59
67
  --color-core-accent-coral: #FF5A8A;
@@ -246,7 +254,15 @@ html[data-brand="pink"][data-theme="dark"] {
246
254
  --color-action-primary-text-active: var(--primitive-neutral-00);
247
255
  --color-action-primary-text-secondary: var(--primitive-red-10);
248
256
  --color-action-primary-text-tertiary: var(--primitive-red-07);
249
- --color-ai-gradient-end: var(--primitive-red-08);
257
+ --color-ai-gradient-end: var(--primitive-red-09);
258
+ --color-ai-gradient-mid: var(--primitive-red-07);
259
+ --color-ai-gradient-start: var(--primitive-red-03);
260
+ --color-ambient-1: #FFD34D;
261
+ --color-ambient-2: #3DDCB8;
262
+ --color-ambient-3: #C45CFF;
263
+ --color-ambient-4: #5C7CFF;
264
+ --color-ambient-5: #E064AB;
265
+ --color-ambient-6: #ECA0CB;
250
266
  --color-core-accent-amber: #FF9A4D;
251
267
  --color-core-accent-cobalt: #5C7CFF;
252
268
  --color-core-accent-coral: #FF5A8A;
@@ -107,7 +107,15 @@ html[data-brand="terminal"] {
107
107
  --color-action-primary-text-active: var(--primitive-green-11);
108
108
  --color-action-primary-text-secondary: var(--primitive-green-10);
109
109
  --color-action-primary-text-tertiary: var(--primitive-green-08);
110
- --color-ai-gradient-end: var(--primitive-green-07);
110
+ --color-ai-gradient-end: var(--primitive-green-09);
111
+ --color-ai-gradient-mid: var(--primitive-green-07);
112
+ --color-ai-gradient-start: var(--primitive-green-03);
113
+ --color-ambient-1: #7CE8C2;
114
+ --color-ambient-2: #06D6A0;
115
+ --color-ambient-3: #3DBFA8;
116
+ --color-ambient-4: #2FA98F;
117
+ --color-ambient-5: #5DE4C1;
118
+ --color-ambient-6: #9BEFD9;
111
119
  --color-core-accent-amber: #57E0B0;
112
120
  --color-core-accent-cobalt: #2FA98F;
113
121
  --color-core-accent-coral: #35D6A0;
@@ -248,7 +256,15 @@ html[data-brand="terminal"][data-theme="dark"] {
248
256
  --color-action-primary-text-active: var(--primitive-green-11);
249
257
  --color-action-primary-text-secondary: var(--primitive-green-10);
250
258
  --color-action-primary-text-tertiary: var(--primitive-green-07);
251
- --color-ai-gradient-end: var(--primitive-green-08);
259
+ --color-ai-gradient-end: var(--primitive-green-09);
260
+ --color-ai-gradient-mid: var(--primitive-green-07);
261
+ --color-ai-gradient-start: var(--primitive-green-03);
262
+ --color-ambient-1: #7CE8C2;
263
+ --color-ambient-2: #06D6A0;
264
+ --color-ambient-3: #3DBFA8;
265
+ --color-ambient-4: #2FA98F;
266
+ --color-ambient-5: #5DE4C1;
267
+ --color-ambient-6: #9BEFD9;
252
268
  --color-core-accent-amber: #57E0B0;
253
269
  --color-core-accent-cobalt: #2FA98F;
254
270
  --color-core-accent-coral: #35D6A0;
@@ -52,7 +52,15 @@ html[data-brand="violet"] {
52
52
  --color-action-primary-text: var(--primitive-purple-02);
53
53
  --color-action-primary-text-secondary: var(--primitive-purple-11);
54
54
  --color-action-primary-text-tertiary: var(--primitive-purple-09);
55
- --color-ai-gradient-end: var(--primitive-purple-08);
55
+ --color-ai-gradient-end: var(--primitive-purple-10);
56
+ --color-ai-gradient-mid: var(--primitive-purple-08);
57
+ --color-ai-gradient-start: var(--primitive-purple-04);
58
+ --color-ambient-1: #D9BE7A;
59
+ --color-ambient-2: #6BAE9E;
60
+ --color-ambient-3: #9E47EF;
61
+ --color-ambient-4: #6A5BE0;
62
+ --color-ambient-5: #A57BCE;
63
+ --color-ambient-6: #C7AEE1;
56
64
  --color-core-accent-amber: #D9915E;
57
65
  --color-core-accent-cobalt: #6A5BE0;
58
66
  --color-core-accent-coral: #D96BA8;
@@ -231,7 +239,15 @@ html[data-brand="violet"][data-theme="dark"] {
231
239
  --color-action-primary-text-active: var(--primitive-purple-02);
232
240
  --color-action-primary-text-secondary: var(--primitive-purple-11);
233
241
  --color-action-primary-text-tertiary: var(--primitive-purple-08);
234
- --color-ai-gradient-end: var(--primitive-purple-09);
242
+ --color-ai-gradient-end: var(--primitive-purple-10);
243
+ --color-ai-gradient-mid: var(--primitive-purple-08);
244
+ --color-ai-gradient-start: var(--primitive-purple-04);
245
+ --color-ambient-1: #D9BE7A;
246
+ --color-ambient-2: #6BAE9E;
247
+ --color-ambient-3: #9E47EF;
248
+ --color-ambient-4: #6A5BE0;
249
+ --color-ambient-5: #A57BCE;
250
+ --color-ambient-6: #C7AEE1;
235
251
  --color-core-accent-amber: #D9915E;
236
252
  --color-core-accent-cobalt: #6A5BE0;
237
253
  --color-core-accent-coral: #D96BA8;