@agent-native/core 0.98.4 → 0.98.5

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 (217) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +16 -0
  3. package/corpus/core/docs/content/durable-background-runs.mdx +37 -0
  4. package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +2 -0
  5. package/corpus/core/docs/content/locales/de-DE/tracking.mdx +2 -0
  6. package/corpus/core/docs/content/locales/es-ES/tracking.mdx +2 -0
  7. package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +4 -2
  8. package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +2 -0
  9. package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +2 -0
  10. package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +2 -0
  11. package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +2 -0
  12. package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +2 -0
  13. package/corpus/core/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
  14. package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +2 -0
  15. package/corpus/core/docs/content/tracking.mdx +2 -0
  16. package/corpus/core/package.json +1 -1
  17. package/corpus/core/src/agent/durable-background.ts +16 -16
  18. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +25 -8
  19. package/corpus/core/src/agent/engine/anthropic-engine.ts +17 -3
  20. package/corpus/core/src/agent/engine/output-tokens.ts +6 -6
  21. package/corpus/core/src/agent/production-agent.ts +200 -27
  22. package/corpus/core/src/agent/run-manager.ts +81 -1
  23. package/corpus/core/src/agent/run-store.ts +301 -41
  24. package/corpus/core/src/client/AgentPanel.tsx +6 -2
  25. package/corpus/core/src/client/AssistantChat.tsx +364 -69
  26. package/corpus/core/src/client/agent-chat-adapter.ts +169 -1
  27. package/corpus/core/src/client/chat/message-components.tsx +3 -0
  28. package/corpus/core/src/client/chat/tool-call-display.tsx +20 -36
  29. package/corpus/core/src/client/conversation/use-near-bottom-autoscroll.ts +7 -0
  30. package/corpus/core/src/client/extensions/AgentNativeExtensionFrame.tsx +2 -0
  31. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +2 -0
  32. package/corpus/core/src/client/extensions/ExtensionEditor.tsx +9 -2
  33. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +2 -0
  34. package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +2 -0
  35. package/corpus/core/src/client/extensions/portable-extension.ts +2 -0
  36. package/corpus/core/src/client/session-replay.ts +361 -29
  37. package/corpus/core/src/client/sse-event-processor.ts +43 -1
  38. package/corpus/core/src/demo/actions/toggle-demo-mode.ts +1 -1
  39. package/corpus/core/src/demo/config.ts +6 -6
  40. package/corpus/core/src/demo/fetch-interceptor.ts +13 -4
  41. package/corpus/core/src/demo/redact.ts +13 -149
  42. package/corpus/core/src/extensions/html-shell.ts +3 -0
  43. package/corpus/core/src/extensions/session-replay-iframe.ts +131 -0
  44. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -20
  45. package/corpus/core/src/session-replay-iframe-protocol.ts +58 -0
  46. package/corpus/core/src/shared/reasoning-effort.ts +35 -0
  47. package/corpus/core/src/styles/agent-conversation.css +26 -0
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  49. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +30 -21
  50. package/corpus/templates/analytics/AGENTS.md +12 -0
  51. package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
  52. package/corpus/templates/analytics/actions/get-session-replay-events.ts +1 -0
  53. package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
  54. package/corpus/templates/analytics/actions/list-error-issues.ts +1 -0
  55. package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
  56. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -1
  57. package/corpus/templates/analytics/app/global.css +2 -2
  58. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +41 -4
  59. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +52 -203
  60. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +34 -12
  61. package/corpus/templates/analytics/changelog/2026-07-12-analytics-chat-retries-before-showing-a-generic-no-data-mess.md +6 -0
  62. package/corpus/templates/analytics/changelog/2026-07-12-analytics-sessions-search-no-longer-loses-fast-keystrokes-an.md +6 -0
  63. package/corpus/templates/analytics/changelog/2026-07-12-chart-selection-respects-chat-state.md +6 -0
  64. package/corpus/templates/analytics/changelog/2026-07-12-demo-mode-anonymizes-error-reporting-emails.md +6 -0
  65. package/corpus/templates/analytics/changelog/2026-07-12-session-replays-show-iframe-content.md +6 -0
  66. package/corpus/templates/analytics/netlify.toml +0 -3
  67. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +14 -0
  68. package/corpus/templates/analytics/server/lib/error-capture.ts +59 -2
  69. package/corpus/templates/analytics/server/lib/real-data-actions.ts +24 -0
  70. package/corpus/templates/analytics/server/lib/session-replay.ts +2 -9
  71. package/corpus/templates/analytics/server/plugins/agent-chat.ts +39 -6
  72. package/corpus/templates/assets/app/global.css +1 -1
  73. package/corpus/templates/brain/app/global.css +2 -2
  74. package/corpus/templates/brain/changelog/2026-07-12-fix-long-response-progress.md +6 -0
  75. package/corpus/templates/forms/app/components/CloudUpgrade.tsx +1 -1
  76. package/corpus/templates/forms/app/components/ThemeToggle.tsx +22 -6
  77. package/corpus/templates/forms/app/components/builder/FieldPropertiesPanel.tsx +5 -5
  78. package/corpus/templates/forms/app/components/builder/FieldRenderer.tsx +3 -3
  79. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +16 -16
  80. package/corpus/templates/forms/app/global.css +110 -5
  81. package/corpus/templates/forms/app/pages/AskPage.tsx +3 -3
  82. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +134 -52
  83. package/corpus/templates/forms/app/pages/FormFillPage.tsx +44 -11
  84. package/corpus/templates/forms/app/pages/FormsListPage.tsx +42 -24
  85. package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +28 -15
  86. package/corpus/templates/forms/app/pages/ResponsesPage.tsx +38 -15
  87. package/corpus/templates/forms/app/routes/_app.settings.tsx +1 -1
  88. package/corpus/templates/forms/changelog/2026-07-12-form-builder-surfaces-are-calmer-fields-stay-stable-on-hover.md +6 -0
  89. package/corpus/templates/forms/changelog/2026-07-12-smoother-more-tactile-controls-throughout-animated-icon-and-.md +6 -0
  90. package/corpus/templates/mail/app/components/email/EmailThread.tsx +21 -13
  91. package/corpus/templates/mail/app/components/email/email-iframe-document.ts +18 -0
  92. package/dist/agent/durable-background.d.ts +10 -10
  93. package/dist/agent/durable-background.d.ts.map +1 -1
  94. package/dist/agent/durable-background.js +16 -16
  95. package/dist/agent/durable-background.js.map +1 -1
  96. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  97. package/dist/agent/engine/ai-sdk-engine.js +19 -8
  98. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  99. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  100. package/dist/agent/engine/anthropic-engine.js +11 -3
  101. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  102. package/dist/agent/engine/output-tokens.js +6 -6
  103. package/dist/agent/engine/output-tokens.js.map +1 -1
  104. package/dist/agent/production-agent.d.ts +52 -0
  105. package/dist/agent/production-agent.d.ts.map +1 -1
  106. package/dist/agent/production-agent.js +154 -26
  107. package/dist/agent/production-agent.js.map +1 -1
  108. package/dist/agent/run-manager.d.ts +9 -0
  109. package/dist/agent/run-manager.d.ts.map +1 -1
  110. package/dist/agent/run-manager.js +71 -1
  111. package/dist/agent/run-manager.js.map +1 -1
  112. package/dist/agent/run-store.d.ts +9 -0
  113. package/dist/agent/run-store.d.ts.map +1 -1
  114. package/dist/agent/run-store.js +243 -48
  115. package/dist/agent/run-store.js.map +1 -1
  116. package/dist/client/AgentPanel.d.ts.map +1 -1
  117. package/dist/client/AgentPanel.js +6 -2
  118. package/dist/client/AgentPanel.js.map +1 -1
  119. package/dist/client/AssistantChat.d.ts +21 -0
  120. package/dist/client/AssistantChat.d.ts.map +1 -1
  121. package/dist/client/AssistantChat.js +298 -67
  122. package/dist/client/AssistantChat.js.map +1 -1
  123. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  124. package/dist/client/agent-chat-adapter.js +146 -1
  125. package/dist/client/agent-chat-adapter.js.map +1 -1
  126. package/dist/client/chat/message-components.d.ts.map +1 -1
  127. package/dist/client/chat/message-components.js +2 -1
  128. package/dist/client/chat/message-components.js.map +1 -1
  129. package/dist/client/chat/tool-call-display.d.ts +3 -1
  130. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  131. package/dist/client/chat/tool-call-display.js +13 -37
  132. package/dist/client/chat/tool-call-display.js.map +1 -1
  133. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +1 -0
  134. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
  135. package/dist/client/conversation/use-near-bottom-autoscroll.js +6 -0
  136. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
  137. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -1
  138. package/dist/client/extensions/AgentNativeExtensionFrame.js +2 -1
  139. package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -1
  140. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  141. package/dist/client/extensions/EmbeddedExtension.js +2 -1
  142. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  143. package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
  144. package/dist/client/extensions/ExtensionEditor.js +5 -2
  145. package/dist/client/extensions/ExtensionEditor.js.map +1 -1
  146. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  147. package/dist/client/extensions/ExtensionViewer.js +2 -1
  148. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  149. package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
  150. package/dist/client/extensions/InlineExtensionFrame.js +2 -1
  151. package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
  152. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  153. package/dist/client/extensions/portable-extension.js +2 -0
  154. package/dist/client/extensions/portable-extension.js.map +1 -1
  155. package/dist/client/session-replay.d.ts.map +1 -1
  156. package/dist/client/session-replay.js +308 -29
  157. package/dist/client/session-replay.js.map +1 -1
  158. package/dist/client/sse-event-processor.d.ts +5 -0
  159. package/dist/client/sse-event-processor.d.ts.map +1 -1
  160. package/dist/client/sse-event-processor.js +37 -1
  161. package/dist/client/sse-event-processor.js.map +1 -1
  162. package/dist/collab/routes.d.ts +1 -1
  163. package/dist/collab/struct-routes.d.ts +1 -1
  164. package/dist/demo/actions/toggle-demo-mode.js +1 -1
  165. package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
  166. package/dist/demo/config.js +6 -6
  167. package/dist/demo/config.js.map +1 -1
  168. package/dist/demo/fetch-interceptor.d.ts.map +1 -1
  169. package/dist/demo/fetch-interceptor.js +13 -4
  170. package/dist/demo/fetch-interceptor.js.map +1 -1
  171. package/dist/demo/redact.d.ts +7 -7
  172. package/dist/demo/redact.d.ts.map +1 -1
  173. package/dist/demo/redact.js +8 -145
  174. package/dist/demo/redact.js.map +1 -1
  175. package/dist/extensions/html-shell.d.ts.map +1 -1
  176. package/dist/extensions/html-shell.js +2 -0
  177. package/dist/extensions/html-shell.js.map +1 -1
  178. package/dist/extensions/session-replay-iframe.d.ts +10 -0
  179. package/dist/extensions/session-replay-iframe.d.ts.map +1 -0
  180. package/dist/extensions/session-replay-iframe.js +121 -0
  181. package/dist/extensions/session-replay-iframe.js.map +1 -0
  182. package/dist/progress/routes.d.ts +1 -1
  183. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  184. package/dist/resources/handlers.d.ts +3 -3
  185. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  186. package/dist/scripts/agent-engines/list-agent-engines.js +1 -19
  187. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  188. package/dist/session-replay-iframe-protocol.d.ts +36 -0
  189. package/dist/session-replay-iframe-protocol.d.ts.map +1 -0
  190. package/dist/session-replay-iframe-protocol.js +24 -0
  191. package/dist/session-replay-iframe-protocol.js.map +1 -0
  192. package/dist/shared/reasoning-effort.d.ts +11 -0
  193. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  194. package/dist/shared/reasoning-effort.js +36 -0
  195. package/dist/shared/reasoning-effort.js.map +1 -1
  196. package/dist/styles/agent-conversation.css +26 -0
  197. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  198. package/docs/content/durable-background-runs.mdx +37 -0
  199. package/docs/content/locales/ar-SA/tracking.mdx +2 -0
  200. package/docs/content/locales/de-DE/tracking.mdx +2 -0
  201. package/docs/content/locales/es-ES/tracking.mdx +2 -0
  202. package/docs/content/locales/fr-FR/tracking.mdx +4 -2
  203. package/docs/content/locales/hi-IN/tracking.mdx +2 -0
  204. package/docs/content/locales/ja-JP/tracking.mdx +2 -0
  205. package/docs/content/locales/ko-KR/tracking.mdx +2 -0
  206. package/docs/content/locales/pt-BR/tracking.mdx +2 -0
  207. package/docs/content/locales/zh-CN/tracking.mdx +2 -0
  208. package/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
  209. package/docs/content/locales/zh-TW/tracking.mdx +2 -0
  210. package/docs/content/tracking.mdx +2 -0
  211. package/package.json +2 -2
  212. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  213. package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
  214. package/dist/observability/hosted-model-experiment.d.ts +0 -39
  215. package/dist/observability/hosted-model-experiment.d.ts.map +0 -1
  216. package/dist/observability/hosted-model-experiment.js +0 -90
  217. package/dist/observability/hosted-model-experiment.js.map +0 -1
@@ -28,6 +28,21 @@
28
28
  --input: 0 0% 90%;
29
29
  --ring: 0 0% 40%;
30
30
  --radius: 0.5rem;
31
+ --forms-radius-control: 0.625rem;
32
+ --forms-radius-surface: 0.75rem;
33
+ --forms-radius-floating: 1rem;
34
+ --forms-shadow-surface:
35
+ 0 0 0 1px hsl(var(--foreground) / 0.04),
36
+ 0 1px 2px -1px hsl(var(--foreground) / 0.08);
37
+ --forms-shadow-surface-hover:
38
+ 0 0 0 1px hsl(var(--foreground) / 0.08),
39
+ 0 2px 6px -3px hsl(var(--foreground) / 0.1);
40
+ --forms-shadow-control: 0 0 0 1px hsl(var(--foreground) / 0.035);
41
+ --forms-shadow-floating:
42
+ 0 0 0 1px hsl(var(--foreground) / 0.06),
43
+ 0 6px 16px -10px hsl(var(--foreground) / 0.12);
44
+ --forms-shadow-focus:
45
+ 0 0 0 3px hsl(var(--ring) / 0.18), 0 0 0 1px hsl(var(--ring) / 0.55);
31
46
 
32
47
  --sidebar-background: 0 0% 97%;
33
48
  --sidebar-foreground: 0 0% 45%;
@@ -59,6 +74,12 @@
59
74
  --border: 0 0% 24%;
60
75
  --input: 0 0% 24%;
61
76
  --ring: 0 0% 60%;
77
+ --forms-shadow-surface: 0 0 0 1px hsl(var(--foreground) / 0.08);
78
+ --forms-shadow-surface-hover: 0 0 0 1px hsl(var(--foreground) / 0.14);
79
+ --forms-shadow-control: 0 0 0 1px hsl(var(--foreground) / 0.07);
80
+ --forms-shadow-floating: 0 0 0 1px hsl(var(--foreground) / 0.1);
81
+ --forms-shadow-focus:
82
+ 0 0 0 3px hsl(var(--ring) / 0.2), 0 0 0 1px hsl(var(--ring) / 0.65);
62
83
 
63
84
  --sidebar-background: 0 0% 10%;
64
85
  --sidebar-foreground: 0 0% 60%;
@@ -94,6 +115,66 @@
94
115
  background: hsl(var(--muted-foreground) / 0.4);
95
116
  }
96
117
 
118
+ .forms-list-shell,
119
+ .forms-selection-toolbar,
120
+ .forms-settings-card {
121
+ border-radius: var(--forms-radius-surface);
122
+ box-shadow: var(--forms-shadow-surface);
123
+ }
124
+
125
+ .forms-settings-card {
126
+ border: 0;
127
+ }
128
+
129
+ .forms-list-shell {
130
+ transition-property: box-shadow;
131
+ transition-duration: 180ms;
132
+ transition-timing-function: ease-out;
133
+ }
134
+
135
+ .forms-list-shell:hover,
136
+ .forms-settings-card:hover {
137
+ box-shadow: var(--forms-shadow-surface-hover);
138
+ }
139
+
140
+ .forms-selection-toolbar {
141
+ transition-property: box-shadow;
142
+ transition-duration: 150ms;
143
+ transition-timing-function: ease-out;
144
+ }
145
+
146
+ .forms-list-row {
147
+ transition-property: background-color, box-shadow, opacity;
148
+ transition-duration: 150ms;
149
+ transition-timing-function: ease-out;
150
+ }
151
+
152
+ .forms-list-row:hover {
153
+ box-shadow: var(--forms-shadow-control);
154
+ }
155
+
156
+ .forms-list-row:focus-visible {
157
+ outline: none;
158
+ box-shadow: var(--forms-shadow-focus);
159
+ }
160
+
161
+ .forms-empty-state {
162
+ box-shadow: var(--forms-shadow-control);
163
+ }
164
+
165
+ .forms-sidebar-nav-item {
166
+ border-radius: var(--forms-radius-control);
167
+ }
168
+
169
+ .forms-sidebar-nav-item:hover {
170
+ box-shadow: var(--forms-shadow-control);
171
+ }
172
+
173
+ .forms-new-form-popover {
174
+ border: 0;
175
+ box-shadow: var(--forms-shadow-floating);
176
+ }
177
+
97
178
  .forms-ask-chat-panel {
98
179
  width: 100%;
99
180
  }
@@ -122,11 +203,12 @@
122
203
 
123
204
  @container agent-native-main (min-width: 720px) {
124
205
  .forms-list-skeleton-row {
125
- grid-template-columns: minmax(0, 1fr) 120px 120px 80px;
206
+ grid-template-columns: minmax(0, 1fr) 100px 110px 140px 88px 40px;
207
+ align-items: center;
126
208
  }
127
209
 
128
210
  .forms-list-row {
129
- grid-template-columns: minmax(0, 1fr) 110px 140px 88px 40px;
211
+ grid-template-columns: minmax(0, 1fr) 100px 110px 140px 88px 40px;
130
212
  align-items: center;
131
213
  }
132
214
  }
@@ -150,14 +232,36 @@
150
232
  }
151
233
 
152
234
  .forms-ask-chat-panel .agent-composer-root--hero {
153
- border-radius: 1.25rem;
235
+ border-radius: var(--forms-radius-floating);
154
236
  background: hsl(var(--background));
155
- box-shadow: none;
237
+ box-shadow: var(--forms-shadow-floating);
238
+ transition-property: border-color, box-shadow, transform;
239
+ transition-duration: 180ms;
240
+ transition-timing-function: ease-out;
241
+ }
242
+
243
+ .forms-ask-chat-panel .agent-composer-root--hero:hover {
244
+ box-shadow: var(--forms-shadow-surface-hover);
245
+ transform: translateY(-1px);
156
246
  }
157
247
 
158
248
  .forms-ask-chat-panel .agent-composer-root--hero:focus-within {
159
249
  border-color: hsl(var(--ring) / 0.9);
160
- box-shadow: none;
250
+ box-shadow: var(--forms-shadow-focus), var(--forms-shadow-floating);
251
+ }
252
+
253
+ @media (prefers-reduced-motion: reduce) {
254
+ .forms-list-shell,
255
+ .forms-selection-toolbar,
256
+ .forms-list-row,
257
+ .forms-sidebar-nav-item,
258
+ .forms-ask-chat-panel .agent-composer-root--hero {
259
+ transition: none;
260
+ }
261
+
262
+ .forms-ask-chat-panel .agent-composer-root--hero:hover {
263
+ transform: none;
264
+ }
161
265
  }
162
266
 
163
267
  .forms-chat-intro {
@@ -203,6 +307,7 @@
203
307
  border: 1px solid hsl(var(--border));
204
308
  border-radius: 999px;
205
309
  background: hsl(var(--background) / 0.78);
310
+ box-shadow: var(--forms-shadow-control);
206
311
  padding: 0.375rem 0.625rem;
207
312
  color: hsl(var(--muted-foreground));
208
313
  font-size: 0.75rem;
@@ -49,15 +49,15 @@ export function AskPage() {
49
49
  <h1>{t("home.heading")}</h1>
50
50
  <p>{t("home.description")}</p>
51
51
  <div className="forms-chat-pill-row" aria-hidden="true">
52
- <span>
52
+ <span className="forms-chat-pill">
53
53
  <IconDatabase className="size-3.5" />
54
54
  {t("home.pillForms")}
55
55
  </span>
56
- <span>
56
+ <span className="forms-chat-pill">
57
57
  <IconChartBar className="size-3.5" />
58
58
  {t("home.pillAnalytics")}
59
59
  </span>
60
- <span>
60
+ <span className="forms-chat-pill">
61
61
  <IconSettings className="size-3.5" />
62
62
  {t("home.pillConfiguration")}
63
63
  </span>
@@ -21,6 +21,7 @@ import {
21
21
  IconPlus,
22
22
  IconChevronDown,
23
23
  IconCopy,
24
+ IconArrowLeft,
24
25
  IconArrowUp,
25
26
  IconArrowDown,
26
27
  IconArrowsSort,
@@ -333,7 +334,21 @@ export function FormBuilderPage() {
333
334
  <div className="flex flex-col h-full">
334
335
  {/* Top bar */}
335
336
  <div className="flex items-center justify-between border-b border-border ps-12 pe-2 sm:px-4 md:ps-4 h-14 shrink-0 min-w-0">
336
- <div className="flex items-center gap-3 min-w-0 flex-1">
337
+ <div className="flex items-center gap-2 sm:gap-3 min-w-0 flex-1">
338
+ <Tooltip>
339
+ <TooltipTrigger asChild>
340
+ <Button
341
+ variant="ghost"
342
+ size="icon"
343
+ className="size-10 shrink-0 active:scale-[0.96]"
344
+ onClick={() => navigate("/forms")}
345
+ aria-label={t("builder.backToForms")}
346
+ >
347
+ <IconArrowLeft className="h-4 w-4" />
348
+ </Button>
349
+ </TooltipTrigger>
350
+ <TooltipContent>{t("builder.backToForms")}</TooltipContent>
351
+ </Tooltip>
337
352
  <Skeleton className="h-5 w-48" />
338
353
  <Skeleton className="h-4 w-14 rounded-full" />
339
354
  </div>
@@ -538,7 +553,21 @@ export function FormBuilderPage() {
538
553
  {codeRequiredDialog}
539
554
  {/* Top bar */}
540
555
  <div className="flex items-center justify-between border-b border-border ps-12 pe-2 sm:px-4 md:ps-4 h-14 shrink-0 min-w-0">
541
- <div className="flex items-center gap-2 sm:gap-3 relative min-w-0 flex-1 me-2">
556
+ <div className="flex items-center gap-1 sm:gap-2 relative min-w-0 flex-1 me-2">
557
+ <Tooltip>
558
+ <TooltipTrigger asChild>
559
+ <Button
560
+ variant="ghost"
561
+ size="icon"
562
+ className="size-10 shrink-0 active:scale-[0.96]"
563
+ onClick={() => navigate("/forms")}
564
+ aria-label={t("builder.backToForms")}
565
+ >
566
+ <IconArrowLeft className="h-4 w-4" />
567
+ </Button>
568
+ </TooltipTrigger>
569
+ <TooltipContent>{t("builder.backToForms")}</TooltipContent>
570
+ </Tooltip>
542
571
  <span
543
572
  ref={titleMeasureRef}
544
573
  aria-hidden
@@ -574,7 +603,12 @@ export function FormBuilderPage() {
574
603
  {form.status === "published" && (
575
604
  <Tooltip>
576
605
  <TooltipTrigger asChild>
577
- <Button variant="ghost" size="icon" className="h-8 w-8" asChild>
606
+ <Button
607
+ variant="ghost"
608
+ size="icon"
609
+ className="h-10 w-10 active:scale-[0.96] motion-reduce:active:scale-100"
610
+ asChild
611
+ >
578
612
  <a
579
613
  href={appPath(`/f/${form.slug}`)}
580
614
  target="_blank"
@@ -596,7 +630,7 @@ export function FormBuilderPage() {
596
630
  <Button
597
631
  variant="ghost"
598
632
  size="icon"
599
- className="h-8 w-8"
633
+ className="h-10 w-10 active:scale-[0.96] motion-reduce:active:scale-100"
600
634
  onClick={copyShareLink}
601
635
  disabled={form.status !== "published"}
602
636
  aria-label={
@@ -605,11 +639,24 @@ export function FormBuilderPage() {
605
639
  : t("builder.publishBeforeCopyPublicFormLink")
606
640
  }
607
641
  >
608
- {copied ? (
609
- <IconCheck className="h-4 w-4" />
610
- ) : (
611
- <IconCopy className="h-4 w-4" />
612
- )}
642
+ <span className="relative inline-flex h-4 w-4 items-center justify-center">
643
+ <IconCopy
644
+ className={cn(
645
+ "absolute h-4 w-4 transition-[opacity,scale] duration-200 ease-out",
646
+ copied
647
+ ? "scale-[0.25] opacity-0"
648
+ : "scale-100 opacity-100",
649
+ )}
650
+ />
651
+ <IconCheck
652
+ className={cn(
653
+ "absolute h-4 w-4 transition-[opacity,scale] duration-200 ease-out",
654
+ copied
655
+ ? "scale-100 opacity-100"
656
+ : "scale-[0.25] opacity-0",
657
+ )}
658
+ />
659
+ </span>
613
660
  </Button>
614
661
  </span>
615
662
  </TooltipTrigger>
@@ -629,7 +676,7 @@ export function FormBuilderPage() {
629
676
  resourceType="form"
630
677
  resourceId={form.id}
631
678
  resourceTitle={form.title}
632
- triggerClassName="h-9 border-input bg-transparent px-3 text-xs hover:bg-accent hover:text-accent-foreground"
679
+ triggerClassName="h-10 border-input bg-transparent px-3 text-xs active:scale-[0.96] hover:bg-accent hover:text-accent-foreground"
633
680
  shareUrl={publishedFormUrl}
634
681
  shareUrlLabel={t("builder.publicResponseLink")}
635
682
  shareUrlDescription={t(
@@ -662,7 +709,7 @@ export function FormBuilderPage() {
662
709
  {canEdit && form.status !== "published" && (
663
710
  <Button
664
711
  size="sm"
665
- className="text-xs"
712
+ className="relative text-xs before:absolute before:-inset-y-0.5 before:content-[''] active:scale-[0.96] motion-reduce:active:scale-100"
666
713
  onClick={handleTogglePublish}
667
714
  disabled={pendingStatus !== null}
668
715
  >
@@ -684,7 +731,7 @@ export function FormBuilderPage() {
684
731
  <Button
685
732
  variant="outline"
686
733
  size="icon"
687
- className="h-9 w-9 bg-transparent"
734
+ className="h-10 w-10 bg-transparent active:scale-[0.96] motion-reduce:active:scale-100"
688
735
  aria-label={t("forms.formActions")}
689
736
  >
690
737
  <IconDots className="h-4 w-4" />
@@ -728,13 +775,19 @@ export function FormBuilderPage() {
728
775
  value={activeBuilderTab}
729
776
  onValueChange={canEdit ? setBuilderTab : undefined}
730
777
  >
731
- <TabsList className="w-max sm:w-auto">
732
- <TabsTrigger value="edit" className="text-xs">
778
+ <TabsList className="w-max rounded-lg shadow-[inset_0_1px_0_hsl(var(--foreground)/0.04)] sm:w-auto">
779
+ <TabsTrigger
780
+ value="edit"
781
+ className="rounded-md text-xs transition-[color,background-color,box-shadow,transform] active:scale-[0.96]"
782
+ >
733
783
  {canEdit ? t("builder.editTab") : t("builder.previewTab")}
734
784
  </TabsTrigger>
735
785
  {canEdit && (
736
786
  <>
737
- <TabsTrigger value="responses" className="text-xs">
787
+ <TabsTrigger
788
+ value="responses"
789
+ className="rounded-md text-xs transition-[color,background-color,box-shadow,transform] active:scale-[0.96]"
790
+ >
738
791
  {t("builder.resultsTab")}
739
792
  {(form.responseCount ?? 0) > 0 && (
740
793
  <Badge
@@ -745,10 +798,16 @@ export function FormBuilderPage() {
745
798
  </Badge>
746
799
  )}
747
800
  </TabsTrigger>
748
- <TabsTrigger value="settings" className="text-xs">
801
+ <TabsTrigger
802
+ value="settings"
803
+ className="rounded-md text-xs transition-[color,background-color,box-shadow,transform] active:scale-[0.96]"
804
+ >
749
805
  {t("header.settings")}
750
806
  </TabsTrigger>
751
- <TabsTrigger value="integrations" className="text-xs">
807
+ <TabsTrigger
808
+ value="integrations"
809
+ className="rounded-md text-xs transition-[color,background-color,box-shadow,transform] active:scale-[0.96]"
810
+ >
752
811
  {t("builder.integrationsTab")}
753
812
  </TabsTrigger>
754
813
  </>
@@ -972,18 +1031,18 @@ function BuilderContent({
972
1031
  )
973
1032
  }
974
1033
  className={cn(
975
- "group relative rounded-lg border p-4 cursor-pointer",
1034
+ "group relative cursor-pointer rounded-lg border p-4 transition-[background-color,border-color,box-shadow,opacity] duration-150 ease-out",
976
1035
  selectedFieldId === field.id
977
- ? "border-primary ring-1 ring-primary/20 bg-card"
978
- : "border-border bg-card hover:border-primary/30",
1036
+ ? "border-primary bg-card shadow-[0_1px_3px_-2px_hsl(var(--foreground)/0.16)] ring-1 ring-primary/20"
1037
+ : "border-transparent bg-transparent shadow-none hover:border-border/80 hover:bg-card/70 hover:shadow-[0_1px_3px_-2px_hsl(var(--foreground)/0.12)]",
979
1038
  dragIdx === idx && "opacity-50",
980
1039
  )}
981
1040
  >
982
1041
  <div
983
- className="absolute -start-3 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 cursor-grab hidden sm:block"
1042
+ className="absolute -start-5 top-1/2 hidden size-10 -translate-y-1/2 items-center justify-center cursor-grab text-muted-foreground opacity-0 transition-[color,opacity,transform] duration-150 ease-out group-hover:opacity-100 group-focus-within:opacity-100 hover:text-foreground sm:flex"
984
1043
  aria-label={t("builder.dragToReorder")}
985
1044
  >
986
- <IconGripVertical className="h-4 w-4 text-muted-foreground" />
1045
+ <IconGripVertical className="h-4 w-4 translate-x-px" />
987
1046
  </div>
988
1047
  <FieldRenderer field={field} preview />
989
1048
  </div>
@@ -992,7 +1051,7 @@ function BuilderContent({
992
1051
  side="right"
993
1052
  align="start"
994
1053
  sideOffset={12}
995
- className="w-[calc(100vw-2rem)] sm:w-72 max-h-[70vh] sm:max-h-[520px] overflow-auto p-0"
1054
+ className="w-[calc(100vw-2rem)] max-h-[70vh] overflow-auto rounded-lg p-0 shadow-md sm:w-72 sm:max-h-[520px]"
996
1055
  onOpenAutoFocus={(e) => e.preventDefault()}
997
1056
  onInteractOutside={(e) => {
998
1057
  // Don't close when interacting with dropdowns portaled to body
@@ -1016,7 +1075,7 @@ function BuilderContent({
1016
1075
  ) : (
1017
1076
  <div
1018
1077
  key={field.id}
1019
- className="relative rounded-lg border border-border bg-card p-4"
1078
+ className="relative rounded-lg border border-transparent bg-transparent p-4 transition-[background-color,border-color] duration-150 hover:border-border/70 hover:bg-card/70"
1020
1079
  >
1021
1080
  <FieldRenderer field={field} preview />
1022
1081
  </div>
@@ -1030,10 +1089,13 @@ function BuilderContent({
1030
1089
  <div className="mt-4 flex items-center gap-2">
1031
1090
  <DropdownMenu>
1032
1091
  <DropdownMenuTrigger asChild>
1033
- <Button variant="outline" className="gap-2">
1034
- <IconPlus className="h-4 w-4" />
1092
+ <Button
1093
+ variant="outline"
1094
+ className="gap-2 active:scale-[0.96]"
1095
+ >
1096
+ <IconPlus className="h-4 w-4 shrink-0" />
1035
1097
  {t("builder.addField")}
1036
- <IconChevronDown className="h-3 w-3" />
1098
+ <IconChevronDown className="h-3.5 w-3.5 translate-y-px" />
1037
1099
  </Button>
1038
1100
  </DropdownMenuTrigger>
1039
1101
  <DropdownMenuContent align="start" className="w-48">
@@ -1056,6 +1118,7 @@ function BuilderContent({
1056
1118
  <Button
1057
1119
  variant="outline"
1058
1120
  size="icon"
1121
+ className="active:scale-[0.96]"
1059
1122
  aria-label={t("builder.editFormWithAi")}
1060
1123
  >
1061
1124
  <IconMessage className="h-4 w-4" />
@@ -1065,7 +1128,7 @@ function BuilderContent({
1065
1128
  side="top"
1066
1129
  align="end"
1067
1130
  sideOffset={8}
1068
- className="w-[calc(100vw-2rem)] sm:w-80 p-0 rounded-xl"
1131
+ className="w-[calc(100vw-2rem)] rounded-lg p-0 shadow-md sm:w-80"
1069
1132
  onOpenAutoFocus={(e) => {
1070
1133
  e.preventDefault();
1071
1134
  agentPromptRef.current?.focus();
@@ -1100,7 +1163,7 @@ function BuilderContent({
1100
1163
  <Button
1101
1164
  variant="secondary"
1102
1165
  size="icon"
1103
- className="h-7 w-7"
1166
+ className="h-10 w-10 active:scale-[0.96] motion-reduce:active:scale-100"
1104
1167
  onClick={onSubmitAgent}
1105
1168
  disabled={
1106
1169
  !agentPrompt.trim() ||
@@ -1272,7 +1335,7 @@ function ResultsContent({ formId, form }: { formId: string; form: any }) {
1272
1335
  variant="outline"
1273
1336
  size="sm"
1274
1337
  onClick={() => refetch()}
1275
- className="gap-2"
1338
+ className="gap-2 active:scale-[0.96]"
1276
1339
  >
1277
1340
  <IconRefresh className="h-3.5 w-3.5" />
1278
1341
  {t("common.retry")}
@@ -1460,18 +1523,33 @@ function ResultsSortableHeader({
1460
1523
  <button
1461
1524
  type="button"
1462
1525
  onClick={onClick}
1463
- className="inline-flex items-center gap-1 hover:text-foreground transition-colors cursor-pointer"
1526
+ className="relative inline-flex cursor-pointer items-center gap-1 transition-[color,transform] duration-150 ease-out hover:text-foreground active:scale-[0.96] motion-reduce:active:scale-100 before:absolute before:-inset-3 before:content-['']"
1464
1527
  >
1465
1528
  <span>{label}</span>
1466
- {active ? (
1467
- dir === "asc" ? (
1468
- <IconArrowUp className="h-3 w-3" />
1469
- ) : (
1470
- <IconArrowDown className="h-3 w-3" />
1471
- )
1472
- ) : (
1473
- <IconArrowsSort className="h-3 w-3 opacity-40" />
1474
- )}
1529
+ <span className="relative inline-flex h-3 w-3 items-center justify-center">
1530
+ <IconArrowUp
1531
+ className={cn(
1532
+ "absolute h-3 w-3 transition-[opacity,scale] duration-200 ease-out",
1533
+ active && dir === "asc"
1534
+ ? "scale-100 opacity-100"
1535
+ : "scale-[0.25] opacity-0",
1536
+ )}
1537
+ />
1538
+ <IconArrowDown
1539
+ className={cn(
1540
+ "absolute h-3 w-3 transition-[opacity,scale] duration-200 ease-out",
1541
+ active && dir === "desc"
1542
+ ? "scale-100 opacity-100"
1543
+ : "scale-[0.25] opacity-0",
1544
+ )}
1545
+ />
1546
+ <IconArrowsSort
1547
+ className={cn(
1548
+ "absolute h-3 w-3 transition-[opacity,scale] duration-200 ease-out",
1549
+ active ? "scale-[0.25] opacity-0" : "scale-100 opacity-40",
1550
+ )}
1551
+ />
1552
+ </span>
1475
1553
  </button>
1476
1554
  );
1477
1555
  }
@@ -1532,7 +1610,7 @@ function SettingsEditor({
1532
1610
  />
1533
1611
  </div>
1534
1612
 
1535
- <div className="flex items-start justify-between gap-4 rounded-lg border p-3">
1613
+ <div className="flex items-start justify-between gap-4 rounded-lg border border-border/60 bg-card p-3">
1536
1614
  <div className="space-y-1">
1537
1615
  <Label htmlFor="anonymous-responses" className="text-xs">
1538
1616
  {t("builder.settings.anonymousResponses")}
@@ -1549,7 +1627,11 @@ function SettingsEditor({
1549
1627
  />
1550
1628
  </div>
1551
1629
 
1552
- <Button onClick={() => onSave(settings)} className="w-full" size="sm">
1630
+ <Button
1631
+ onClick={() => onSave(settings)}
1632
+ className="w-full active:scale-[0.96]"
1633
+ size="sm"
1634
+ >
1553
1635
  {t("builder.settings.saveSettings")}
1554
1636
  </Button>
1555
1637
  </div>
@@ -1620,12 +1702,12 @@ function IntegrationBrandMark({
1620
1702
  return (
1621
1703
  <div
1622
1704
  className={cn(
1623
- "flex h-10 w-10 items-center justify-center rounded-xl border border-border/70 bg-background shadow-sm",
1705
+ "flex h-10 w-10 items-center justify-center rounded-lg border border-border/70 bg-background",
1624
1706
  className,
1625
1707
  )}
1626
1708
  >
1627
1709
  <img
1628
- src={meta.logoSrc}
1710
+ src={appPath(meta.logoSrc)}
1629
1711
  alt={t("builder.integrations.logoAlt", { label })}
1630
1712
  className="h-5 w-5 object-contain"
1631
1713
  />
@@ -1636,7 +1718,7 @@ function IntegrationBrandMark({
1636
1718
  return (
1637
1719
  <div
1638
1720
  className={cn(
1639
- "flex h-10 w-10 items-center justify-center rounded-xl border border-border/70 bg-foreground text-background shadow-sm",
1721
+ "flex h-10 w-10 items-center justify-center rounded-lg border border-border/70 bg-foreground text-background",
1640
1722
  className,
1641
1723
  )}
1642
1724
  >
@@ -1713,7 +1795,7 @@ function IntegrationsEditor({
1713
1795
  </div>
1714
1796
 
1715
1797
  {!hasIntegrations && (
1716
- <div className="rounded-xl border border-dashed border-border bg-muted/20 p-5">
1798
+ <div className="rounded-lg border border-border/60 bg-muted/20 p-5">
1717
1799
  <div className="space-y-4">
1718
1800
  <div className="space-y-2">
1719
1801
  <h3 className="text-sm font-medium">
@@ -1735,7 +1817,7 @@ function IntegrationsEditor({
1735
1817
  key={type}
1736
1818
  type="button"
1737
1819
  onClick={() => addIntegration(type)}
1738
- className="cursor-pointer rounded-lg border bg-background p-3 text-start hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring min-h-[44px]"
1820
+ className="min-h-[44px] cursor-pointer rounded-lg border border-border/60 bg-background p-3 text-start transition-[background-color,border-color,box-shadow] duration-150 ease-out hover:border-primary/30 hover:bg-muted/40 hover:shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring active:scale-[0.96] motion-reduce:active:scale-100"
1739
1821
  >
1740
1822
  <div className="flex items-center gap-3">
1741
1823
  <IntegrationBrandMark type={type} className="h-9 w-9" />
@@ -1767,7 +1849,7 @@ function IntegrationsEditor({
1767
1849
  return (
1768
1850
  <div
1769
1851
  key={integration.id}
1770
- className="rounded-xl border bg-card p-4 space-y-3"
1852
+ className="space-y-3 rounded-lg border border-border/60 bg-card p-4"
1771
1853
  >
1772
1854
  <div className="flex items-start gap-3">
1773
1855
  <IntegrationBrandMark type={integration.type} />
@@ -1801,7 +1883,7 @@ function IntegrationsEditor({
1801
1883
  <Button
1802
1884
  variant="ghost"
1803
1885
  size="icon"
1804
- className="h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive"
1886
+ className="h-10 w-10 shrink-0 text-muted-foreground hover:text-destructive active:scale-[0.96] motion-reduce:active:scale-100"
1805
1887
  onClick={() => removeIntegration(integration.id)}
1806
1888
  >
1807
1889
  <IconTrash className="h-4 w-4" />
@@ -1849,7 +1931,7 @@ function IntegrationsEditor({
1849
1931
  <Button
1850
1932
  variant="outline"
1851
1933
  size="sm"
1852
- className="h-11 w-full rounded-xl"
1934
+ className="h-11 w-full rounded-lg active:scale-[0.96]"
1853
1935
  >
1854
1936
  <IconPlus className="h-3.5 w-3.5 me-1.5" />
1855
1937
  {hasIntegrations
@@ -1869,7 +1951,7 @@ function IntegrationsEditor({
1869
1951
  key={type}
1870
1952
  onClick={() => addIntegration(type)}
1871
1953
  disabled={selectedTypes.has(type)}
1872
- className="rounded-md px-3 py-3"
1954
+ className="px-3 py-3"
1873
1955
  >
1874
1956
  <div className="flex items-center gap-3">
1875
1957
  <IntegrationBrandMark type={type} />
@@ -1900,7 +1982,7 @@ function IntegrationsEditor({
1900
1982
  <div className="space-y-2">
1901
1983
  <Button
1902
1984
  onClick={() => onSave(settings)}
1903
- className="h-10 w-full"
1985
+ className="h-10 w-full active:scale-[0.96]"
1904
1986
  size="sm"
1905
1987
  >
1906
1988
  {saveLabel}