@burdenoff/website-sdk 2026.921.1 → 2026.922.2

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.
@@ -23,8 +23,8 @@ function isRtlLocale(locale) {
23
23
  }
24
24
  var EN = {
25
25
  badge: "AI answers, grounded in our documentation",
26
- welcomeTitle: "Ask anything about our products",
27
- welcomeBody: "Describe what you are trying to do and I will point you at the product, the page and the next step.",
26
+ welcomeTitle: "What problem are you trying to solve?",
27
+ welcomeBody: "Describe the problem you're facing, in your own words. You can also ask about a specific product or compare a few. Every answer comes straight from our documentation.",
28
28
  tryAsking: "Try asking",
29
29
  focusProduct: "Focus on a product",
30
30
  allProducts: "All products",
@@ -32,8 +32,8 @@ var EN = {
32
32
  showLess: "Show less",
33
33
  sources: "Sources",
34
34
  nextYouCouldAsk: "Next you could ask",
35
- placeholder: "Ask anything about our products\u2026",
36
- placeholderProduct: "Ask about {product}\u2026",
35
+ placeholder: "Describe the problem you're facing\u2026",
36
+ placeholderProduct: "Describe a problem, or ask about {product}\u2026",
37
37
  send: "Send",
38
38
  stop: "Stop",
39
39
  newChat: "New chat",
@@ -66,16 +66,16 @@ var EN = {
66
66
  "Straight to the right page"
67
67
  ],
68
68
  prompts: [
69
- "What does this product actually do?",
70
- "Which product fits my team?",
71
- "How do I get started, step by step?",
72
- "How much does it cost?"
69
+ "Every course we run lives in a different spreadsheet.",
70
+ "We only hear a machine is down after the line has stopped.",
71
+ "Members quietly stop showing up and we never know why.",
72
+ "Which of your products fits a problem like mine?"
73
73
  ]
74
74
  };
75
75
  var ZH = {
76
76
  badge: "\u57FA\u4E8E\u6211\u4EEC\u6587\u6863\u7684 AI \u56DE\u7B54",
77
- welcomeTitle: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE",
78
- welcomeBody: "\u63CF\u8FF0\u4F60\u60F3\u505A\u7684\u4E8B\uFF0C\u6211\u4F1A\u4E3A\u4F60\u6307\u51FA\u5BF9\u5E94\u7684\u4EA7\u54C1\u3001\u9875\u9762\u548C\u4E0B\u4E00\u6B65\u3002",
77
+ welcomeTitle: "\u4F60\u60F3\u89E3\u51B3\u4EC0\u4E48\u95EE\u9898\uFF1F",
78
+ welcomeBody: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u4F60\u9047\u5230\u7684\u95EE\u9898\u3002\u4F60\u4E5F\u53EF\u4EE5\u8BE2\u95EE\u67D0\u4E00\u6B3E\u4EA7\u54C1\uFF0C\u6216\u6BD4\u8F83\u51E0\u6B3E\u4EA7\u54C1\u3002\u6240\u6709\u56DE\u7B54\u90FD\u76F4\u63A5\u6765\u81EA\u6211\u4EEC\u7684\u6587\u6863\u3002",
79
79
  tryAsking: "\u8BD5\u7740\u95EE",
80
80
  focusProduct: "\u805A\u7126\u67D0\u4E2A\u4EA7\u54C1",
81
81
  allProducts: "\u5168\u90E8\u4EA7\u54C1",
@@ -83,8 +83,8 @@ var ZH = {
83
83
  showLess: "\u6536\u8D77",
84
84
  sources: "\u6765\u6E90",
85
85
  nextYouCouldAsk: "\u4F60\u8FD8\u53EF\u4EE5\u95EE",
86
- placeholder: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE\u2026",
87
- placeholderProduct: "\u8BE2\u95EE\u5173\u4E8E {product} \u7684\u95EE\u9898\u2026",
86
+ placeholder: "\u63CF\u8FF0\u4F60\u9047\u5230\u7684\u95EE\u9898\u2026",
87
+ placeholderProduct: "\u63CF\u8FF0\u95EE\u9898\uFF0C\u6216\u8BE2\u95EE {product}\u2026",
88
88
  send: "\u53D1\u9001",
89
89
  stop: "\u505C\u6B62",
90
90
  newChat: "\u65B0\u5BF9\u8BDD",
@@ -113,16 +113,16 @@ var ZH = {
113
113
  opensInNewTab: "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00",
114
114
  capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
115
115
  prompts: [
116
- "\u8FD9\u4E2A\u4EA7\u54C1\u5230\u5E95\u80FD\u505A\u4EC0\u4E48\uFF1F",
117
- "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u7684\u56E2\u961F\uFF1F",
118
- "\u5982\u4F55\u4E00\u6B65\u6B65\u5F00\u59CB\u4F7F\u7528\uFF1F",
119
- "\u4EF7\u683C\u662F\u591A\u5C11\uFF1F"
116
+ "\u6BCF\u95E8\u8BFE\u7A0B\u90FD\u8BB0\u5728\u4E0D\u540C\u7684\u8868\u683C\u91CC\u3002",
117
+ "\u673A\u5668\u505C\u4E86\uFF0C\u8981\u7B49\u6574\u6761\u7EBF\u505C\u4E0B\u6765\u624D\u77E5\u9053\u3002",
118
+ "\u4F1A\u5458\u6162\u6162\u5C31\u4E0D\u6765\u4E86\uFF0C\u6211\u4EEC\u4E5F\u4E0D\u77E5\u9053\u4E3A\u4EC0\u4E48\u3002",
119
+ "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u8FD9\u6837\u7684\u95EE\u9898\uFF1F"
120
120
  ]
121
121
  };
122
122
  var HI = {
123
123
  badge: "\u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 AI \u0909\u0924\u094D\u0924\u0930",
124
- welcomeTitle: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902",
125
- welcomeBody: "\u092C\u0924\u093E\u0907\u090F \u0906\u092A \u0915\u094D\u092F\u093E \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902, \u0914\u0930 \u092E\u0948\u0902 \u0906\u092A\u0915\u094B \u0938\u0939\u0940 \u0909\u0924\u094D\u092A\u093E\u0926, \u092A\u0947\u091C \u0914\u0930 \u0905\u0917\u0932\u093E \u0915\u0926\u092E \u092C\u0924\u093E\u090A\u0901\u0917\u093E\u0964",
124
+ welcomeTitle: "\u0906\u092A \u0915\u094C\u0928 \u0938\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0939\u0932 \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902?",
125
+ welcomeBody: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902\u0964 \u0906\u092A \u0915\u093F\u0938\u0940 \u090F\u0915 \u0909\u0924\u094D\u092A\u093E\u0926 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092D\u0940 \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902 \u092F\u093E \u0915\u0941\u091B \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930 \u0938\u0915\u0924\u0947 \u0939\u0948\u0902\u0964 \u0939\u0930 \u0909\u0924\u094D\u0924\u0930 \u0938\u0940\u0927\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C \u0938\u0947 \u0906\u0924\u093E \u0939\u0948\u0964",
126
126
  tryAsking: "\u092F\u0939 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902",
127
127
  focusProduct: "\u0915\u093F\u0938\u0940 \u0909\u0924\u094D\u092A\u093E\u0926 \u092A\u0930 \u0927\u094D\u092F\u093E\u0928 \u0926\u0947\u0902",
128
128
  allProducts: "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926",
@@ -130,8 +130,8 @@ var HI = {
130
130
  showLess: "\u0915\u092E \u0926\u093F\u0916\u093E\u090F\u0901",
131
131
  sources: "\u0938\u094D\u0930\u094B\u0924",
132
132
  nextYouCouldAsk: "\u0906\u0917\u0947 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902",
133
- placeholder: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902\u2026",
134
- placeholderProduct: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
133
+ placeholder: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u092F\u0939\u093E\u0901 \u092C\u0924\u093E\u090F\u0902\u2026",
134
+ placeholderProduct: "\u0938\u092E\u0938\u094D\u092F\u093E \u092C\u0924\u093E\u090F\u0902, \u092F\u093E {product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
135
135
  send: "\u092D\u0947\u091C\u0947\u0902",
136
136
  stop: "\u0930\u094B\u0915\u0947\u0902",
137
137
  newChat: "\u0928\u0908 \u092C\u093E\u0924\u091A\u0940\u0924",
@@ -164,16 +164,16 @@ var HI = {
164
164
  "\u0938\u0940\u0927\u0947 \u0938\u0939\u0940 \u092A\u0947\u091C \u092A\u0930"
165
165
  ],
166
166
  prompts: [
167
- "\u092F\u0939 \u0909\u0924\u094D\u092A\u093E\u0926 \u0905\u0938\u0932 \u092E\u0947\u0902 \u0915\u094D\u092F\u093E \u0915\u0930\u0924\u093E \u0939\u0948?",
168
- "\u092E\u0947\u0930\u0940 \u091F\u0940\u092E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?",
169
- "\u0936\u0941\u0930\u0941\u0906\u0924 \u0915\u0948\u0938\u0947 \u0915\u0930\u0947\u0902, \u091A\u0930\u0923 \u0926\u0930 \u091A\u0930\u0923?",
170
- "\u0907\u0938\u0915\u0940 \u0915\u0940\u092E\u0924 \u0915\u093F\u0924\u0928\u0940 \u0939\u0948?"
167
+ "\u0939\u0930 \u0915\u094B\u0930\u094D\u0938 \u0915\u093E \u0939\u093F\u0938\u093E\u092C \u0905\u0932\u0917 \u0936\u0940\u091F \u092E\u0947\u0902 \u0930\u0916\u093E \u091C\u093E\u0924\u093E \u0939\u0948\u0964",
168
+ "\u092E\u0936\u0940\u0928 \u092C\u0902\u0926 \u0939\u094B\u0928\u0947 \u0915\u093E \u092A\u0924\u093E \u0924\u092D\u0940 \u091A\u0932\u0924\u093E \u0939\u0948 \u091C\u092C \u0932\u093E\u0907\u0928 \u0930\u0941\u0915 \u091C\u093E\u090F\u0964",
169
+ "\u0938\u0926\u0938\u094D\u092F \u0927\u0940\u0930\u0947-\u0927\u0940\u0930\u0947 \u0906\u0928\u093E \u092C\u0902\u0926 \u0915\u0930 \u0926\u0947\u0924\u0947 \u0939\u0948\u0902, \u0935\u091C\u0939 \u092A\u0924\u093E \u0928\u0939\u0940\u0902 \u091A\u0932\u0924\u0940\u0964",
170
+ "\u092E\u0947\u0930\u0940 \u091C\u0948\u0938\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?"
171
171
  ]
172
172
  };
173
173
  var ES = {
174
174
  badge: "Respuestas de IA basadas en nuestra documentaci\xF3n",
175
- welcomeTitle: "Pregunta lo que quieras sobre nuestros productos",
176
- welcomeBody: "Cu\xE9ntame qu\xE9 necesitas hacer y te indicar\xE9 el producto, la p\xE1gina y el siguiente paso.",
175
+ welcomeTitle: "\xBFQu\xE9 problema quieres resolver?",
176
+ welcomeBody: "Describe el problema que tienes con tus propias palabras. Tambi\xE9n puedes preguntar por un producto concreto o comparar varios. Cada respuesta procede directamente de nuestra documentaci\xF3n.",
177
177
  tryAsking: "Prueba a preguntar",
178
178
  focusProduct: "Centrarse en un producto",
179
179
  allProducts: "Todos los productos",
@@ -181,8 +181,8 @@ var ES = {
181
181
  showLess: "Ver menos",
182
182
  sources: "Fuentes",
183
183
  nextYouCouldAsk: "Tambi\xE9n puedes preguntar",
184
- placeholder: "Pregunta lo que quieras sobre nuestros productos\u2026",
185
- placeholderProduct: "Pregunta sobre {product}\u2026",
184
+ placeholder: "Describe el problema que tienes\u2026",
185
+ placeholderProduct: "Describe un problema o pregunta por {product}\u2026",
186
186
  send: "Enviar",
187
187
  stop: "Detener",
188
188
  newChat: "Nueva conversaci\xF3n",
@@ -215,16 +215,16 @@ var ES = {
215
215
  "Directo a la p\xE1gina correcta"
216
216
  ],
217
217
  prompts: [
218
- "\xBFQu\xE9 hace realmente este producto?",
219
- "\xBFQu\xE9 producto encaja con mi equipo?",
220
- "\xBFC\xF3mo empiezo, paso a paso?",
221
- "\xBFCu\xE1nto cuesta?"
218
+ "Cada curso que damos est\xE1 en una hoja de c\xE1lculo distinta.",
219
+ "Nos enteramos de que una m\xE1quina falla cuando para la l\xEDnea.",
220
+ "Los socios dejan de venir poco a poco y nunca sabemos por qu\xE9.",
221
+ "\xBFQu\xE9 producto encaja con un problema como el m\xEDo?"
222
222
  ]
223
223
  };
224
224
  var AR = {
225
225
  badge: "\u0625\u062C\u0627\u0628\u0627\u062A \u0630\u0643\u0627\u0621 \u0627\u0635\u0637\u0646\u0627\u0639\u064A \u0645\u0628\u0646\u064A\u0629 \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
226
- welcomeTitle: "\u0627\u0633\u0623\u0644 \u0623\u064A \u0634\u064A\u0621 \u0639\u0646 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627",
227
- welcomeBody: "\u0635\u0650\u0641 \u0645\u0627 \u062A\u0631\u064A\u062F \u0625\u0646\u062C\u0627\u0632\u0647 \u0648\u0633\u0623\u062F\u0644\u0651\u0643 \u0639\u0644\u0649 \u0627\u0644\u0645\u0646\u062A\u062C \u0648\u0627\u0644\u0635\u0641\u062D\u0629 \u0648\u0627\u0644\u062E\u0637\u0648\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629.",
226
+ welcomeTitle: "\u0645\u0627 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u062D\u0627\u0648\u0644 \u062D\u0644\u0647\u0627\u061F",
227
+ welcomeBody: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u0648\u0627\u062C\u0647\u0647\u0627 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0623\u0646\u062A. \u064A\u0645\u0643\u0646\u0643 \u0623\u064A\u0636\u064B\u0627 \u0627\u0644\u0633\u0624\u0627\u0644 \u0639\u0646 \u0645\u0646\u062A\u062C \u0628\u0639\u064A\u0646\u0647 \u0623\u0648 \u0627\u0644\u0645\u0642\u0627\u0631\u0646\u0629 \u0628\u064A\u0646 \u0639\u062F\u0629 \u0645\u0646\u062A\u062C\u0627\u062A. \u062A\u0623\u062A\u064A \u0643\u0644 \u0625\u062C\u0627\u0628\u0629 \u0645\u0628\u0627\u0634\u0631\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642\u0646\u0627.",
228
228
  tryAsking: "\u062C\u0631\u0651\u0628 \u0623\u0646 \u062A\u0633\u0623\u0644",
229
229
  focusProduct: "\u0627\u0644\u062A\u0631\u0643\u064A\u0632 \u0639\u0644\u0649 \u0645\u0646\u062A\u062C",
230
230
  allProducts: "\u0643\u0644 \u0627\u0644\u0645\u0646\u062A\u062C\u0627\u062A",
@@ -232,8 +232,8 @@ var AR = {
232
232
  showLess: "\u0639\u0631\u0636 \u0623\u0642\u0644",
233
233
  sources: "\u0627\u0644\u0645\u0635\u0627\u062F\u0631",
234
234
  nextYouCouldAsk: "\u064A\u0645\u0643\u0646\u0643 \u0623\u0646 \u062A\u0633\u0623\u0644 \u0628\u0639\u062F \u0630\u0644\u0643",
235
- placeholder: "\u0627\u0633\u0623\u0644 \u0623\u064A \u0634\u064A\u0621 \u0639\u0646 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627\u2026",
236
- placeholderProduct: "\u0627\u0633\u0623\u0644 \u0639\u0646 {product}\u2026",
235
+ placeholder: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u0648\u0627\u062C\u0647\u0647\u0627\u2026",
236
+ placeholderProduct: "\u0635\u0641 \u0645\u0634\u0643\u0644\u062A\u0643 \u0623\u0648 \u0627\u0633\u0623\u0644 \u0639\u0646 {product}\u2026",
237
237
  send: "\u0625\u0631\u0633\u0627\u0644",
238
238
  stop: "\u0625\u064A\u0642\u0627\u0641",
239
239
  newChat: "\u0645\u062D\u0627\u062F\u062B\u0629 \u062C\u062F\u064A\u062F\u0629",
@@ -266,16 +266,16 @@ var AR = {
266
266
  "\u0645\u0628\u0627\u0634\u0631\u0629\u064B \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0629 \u0627\u0644\u0635\u062D\u064A\u062D\u0629"
267
267
  ],
268
268
  prompts: [
269
- "\u0645\u0627 \u0627\u0644\u0630\u064A \u064A\u0641\u0639\u0644\u0647 \u0647\u0630\u0627 \u0627\u0644\u0645\u0646\u062A\u062C \u0641\u0639\u0644\u064A\u064B\u0627\u061F",
270
- "\u0623\u064A \u0645\u0646\u062A\u062C \u064A\u0646\u0627\u0633\u0628 \u0641\u0631\u064A\u0642\u064A\u061F",
271
- "\u0643\u064A\u0641 \u0623\u0628\u062F\u0623 \u062E\u0637\u0648\u0629 \u0628\u062E\u0637\u0648\u0629\u061F",
272
- "\u0643\u0645 \u062A\u0628\u0644\u063A \u0627\u0644\u062A\u0643\u0644\u0641\u0629\u061F"
269
+ "\u0643\u0644 \u062F\u0648\u0631\u0629 \u062A\u062F\u0631\u064A\u0628\u064A\u0629 \u0644\u062F\u064A\u0646\u0627 \u0641\u064A \u062C\u062F\u0648\u0644 \u0628\u064A\u0627\u0646\u0627\u062A \u0645\u062E\u062A\u0644\u0641.",
270
+ "\u0644\u0627 \u0646\u0639\u0644\u0645 \u0628\u062A\u0639\u0637\u0644 \u0627\u0644\u0645\u0627\u0643\u064A\u0646\u0629 \u0625\u0644\u0627 \u0628\u0639\u062F \u062A\u0648\u0642\u0641 \u062E\u0637 \u0627\u0644\u0625\u0646\u062A\u0627\u062C.",
271
+ "\u0623\u0639\u0636\u0627\u0624\u0646\u0627 \u064A\u062A\u0648\u0642\u0641\u0648\u0646 \u0639\u0646 \u0627\u0644\u062D\u0636\u0648\u0631 \u062A\u062F\u0631\u064A\u062C\u064A\u064B\u0627 \u062F\u0648\u0646 \u0623\u0646 \u0646\u0639\u0631\u0641 \u0627\u0644\u0633\u0628\u0628.",
272
+ "\u0623\u064A \u0645\u0646\u062A\u062C \u064A\u0646\u0627\u0633\u0628 \u0645\u0634\u0643\u0644\u0629 \u0645\u062B\u0644 \u0645\u0634\u0643\u0644\u062A\u064A\u061F"
273
273
  ]
274
274
  };
275
275
  var TA = {
276
276
  badge: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BC8 \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F AI \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BCD",
277
- welcomeTitle: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF \u0B8E\u0BA4\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
278
- welcomeBody: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA9\u0BCD\u0BA9 \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF \u0BB5\u0BBF\u0BB0\u0BC1\u0BAE\u0BCD\u0BAA\u0BC1\u0B95\u0BBF\u0BB1\u0BC0\u0BB0\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA9\u0BCD\u0BB1\u0BC1 \u0B9A\u0BCA\u0BB2\u0BCD\u0BB2\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD; \u0B9A\u0BB0\u0BBF\u0BAF\u0BBE\u0BA9 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1, \u0BAA\u0B95\u0BCD\u0B95\u0BAE\u0BCD, \u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4 \u0BAA\u0B9F\u0BBF \u0B86\u0B95\u0BBF\u0BAF\u0BB5\u0BB1\u0BCD\u0BB1\u0BC8\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1\u0B95\u0BBF\u0BB1\u0BC7\u0BA9\u0BCD.",
277
+ welcomeTitle: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA8\u0BCD\u0BA4\u0B9A\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8\u0BA4\u0BCD \u0BA4\u0BC0\u0BB0\u0BCD\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0BAF\u0BB2\u0BCD\u0B95\u0BBF\u0BB1\u0BC0\u0BB0\u0BCD\u0B95\u0BB3\u0BCD?",
278
+ welcomeBody: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0BAE\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD. \u0B92\u0BB0\u0BC1 \u0B95\u0BC1\u0BB1\u0BBF\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BCD\u0B9F \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0BAF\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD, \u0B9A\u0BBF\u0BB2\u0BB5\u0BB1\u0BCD\u0BB1\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BB5\u0BC1\u0BAE\u0BCD \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BB2\u0BBE\u0BAE\u0BCD. \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BB2\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC7\u0BB0\u0B9F\u0BBF\u0BAF\u0BBE\u0B95 \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
279
279
  tryAsking: "\u0B87\u0BA4\u0BC8\u0B95\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
280
280
  focusProduct: "\u0B92\u0BB0\u0BC1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BBF\u0BB2\u0BCD \u0B95\u0BB5\u0BA9\u0BAE\u0BCD",
281
281
  allProducts: "\u0B85\u0BA9\u0BC8\u0BA4\u0BCD\u0BA4\u0BC1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD",
@@ -283,8 +283,8 @@ var TA = {
283
283
  showLess: "\u0B95\u0BC1\u0BB1\u0BC8\u0BB5\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9F\u0BC1",
284
284
  sources: "\u0BAE\u0BC2\u0BB2\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
285
285
  nextYouCouldAsk: "\u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD",
286
- placeholder: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF \u0B8E\u0BA4\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
287
- placeholderProduct: "{product} \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
286
+ placeholder: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0BAE\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
287
+ placeholderProduct: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1 {product} \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
288
288
  send: "\u0B85\u0BA9\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1",
289
289
  stop: "\u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
290
290
  newChat: "\u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B89\u0BB0\u0BC8\u0BAF\u0BBE\u0B9F\u0BB2\u0BCD",
@@ -317,10 +317,10 @@ var TA = {
317
317
  "\u0BA8\u0BC7\u0BB0\u0BBE\u0B95 \u0B9A\u0BB0\u0BBF\u0BAF\u0BBE\u0BA9 \u0BAA\u0B95\u0BCD\u0B95\u0BA4\u0BCD\u0BA4\u0BBF\u0BB1\u0BCD\u0B95\u0BC1"
318
318
  ],
319
319
  prompts: [
320
- "\u0B87\u0BA8\u0BCD\u0BA4\u0BA4\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0B89\u0BA3\u0BCD\u0BAE\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B8E\u0BA9\u0BCD\u0BA9 \u0B9A\u0BC6\u0BAF\u0BCD\u0B95\u0BBF\u0BB1\u0BA4\u0BC1?",
321
- "\u0B8E\u0BA9\u0BCD \u0B95\u0BC1\u0BB4\u0BC1\u0BB5\u0BBF\u0BB1\u0BCD\u0B95\u0BC1 \u0B8E\u0BA8\u0BCD\u0BA4\u0BA4\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD?",
322
- "\u0BAA\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BBF\u0BAF\u0BBE\u0B95 \u0B8E\u0BAA\u0BCD\u0BAA\u0B9F\u0BBF\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0B99\u0BCD\u0B95\u0BC1\u0BB5\u0BA4\u0BC1?",
323
- "\u0B87\u0BA4\u0BA9\u0BCD \u0BB5\u0BBF\u0BB2\u0BC8 \u0B8E\u0BA9\u0BCD\u0BA9?"
320
+ "\u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BAF\u0BBF\u0BB1\u0BCD\u0B9A\u0BBF \u0BB5\u0B95\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0BAE\u0BCD \u0BB5\u0BC6\u0BB5\u0BCD\u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0BBF\u0BB0\u0BBF\u0BA4\u0BBE\u0BB3\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
321
+ "\u0B87\u0BAF\u0BA8\u0BCD\u0BA4\u0BBF\u0BB0\u0BAE\u0BCD \u0BA8\u0BBF\u0BA9\u0BCD\u0BB1\u0BA4\u0BC1 \u0BB2\u0BC8\u0BA9\u0BCD \u0BA8\u0BBF\u0BB1\u0BCD\u0B95\u0BC1\u0BAE\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1\u0BA4\u0BBE\u0BA9\u0BCD \u0BA4\u0BC6\u0BB0\u0BBF\u0BAF \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
322
+ "\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BBF\u0BA9\u0BB0\u0BCD\u0B95\u0BB3\u0BCD \u0BAE\u0BC6\u0BB2\u0BCD\u0BB2 \u0BB5\u0BB0\u0BC1\u0BB5\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BBF\u0BB1\u0BBE\u0BB0\u0BCD\u0B95\u0BB3\u0BCD, \u0B95\u0BBE\u0BB0\u0BA3\u0BAE\u0BCD \u0BA4\u0BC6\u0BB0\u0BBF\u0BAF\u0BBE\u0BA4\u0BC1.",
323
+ "\u0B8E\u0BA9\u0BCD \u0BAA\u0BBF\u0BB0\u0B9A\u0BCD\u0B9A\u0BBF\u0BA9\u0BC8\u0B95\u0BCD\u0B95\u0BC1 \u0B8E\u0BA8\u0BCD\u0BA4\u0BA4\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD?"
324
324
  ]
325
325
  };
326
326
  var STRINGS = {
@@ -1181,13 +1181,13 @@ var FALLBACK_EXPLORE_LIMITS = {
1181
1181
  historyTurns: 6
1182
1182
  };
1183
1183
  var DEFAULT_EXPLORE_EXAMPLE_PROMPTS = [
1184
- "What does this product actually do?",
1185
- "Which Burdenoff product fits my team?",
1186
- "How do I get started, step by step?",
1187
- "What does it integrate with?"
1184
+ "Every course we run lives in a different spreadsheet.",
1185
+ "We only hear a machine is down after the line has stopped.",
1186
+ "Members quietly stop showing up and we never know why.",
1187
+ "Which of your products fits a problem like mine?"
1188
1188
  ];
1189
- var FALLBACK_WELCOME_TITLE = "Ask anything about our products";
1190
- var FALLBACK_WELCOME_BODY = "Get straight answers drawn from our product documentation and public pages \u2014 with links back to the exact page each answer came from.";
1189
+ var FALLBACK_WELCOME_TITLE = "What problem are you trying to solve?";
1190
+ var FALLBACK_WELCOME_BODY = "Describe the problem you're facing, in your own words. You can also ask about a specific product or compare a few. Every answer comes straight from our documentation.";
1191
1191
  function buildFallbackCatalog(examplePrompts, welcome) {
1192
1192
  return {
1193
1193
  enabled: true,
@@ -2492,6 +2492,7 @@ function toPayload(staged) {
2492
2492
  textContent
2493
2493
  }));
2494
2494
  }
2495
+ var SHORT_VIEWPORT_PX = 420;
2495
2496
  var EXPLORE_CSS = `
2496
2497
  @keyframes boff-explore-pulse {
2497
2498
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
@@ -2526,6 +2527,12 @@ var EXPLORE_CSS = `
2526
2527
  .boff-explore-scroll {
2527
2528
  scrollbar-width: thin;
2528
2529
  scrollbar-color: hsl(var(--border)) transparent;
2530
+ /* Stop the transcript handing its scroll to the page. Without this, the first
2531
+ swipe that exhausts the transcript chains to the document \u2014 and on a host site
2532
+ that is 65-70% footer, which is how a phone ends up showing nothing but the
2533
+ footer. Engines that do not support this property ignore the line and keep
2534
+ today's behaviour; the scroll correction above covers them. */
2535
+ overscroll-behavior: contain;
2529
2536
  }
2530
2537
  .boff-explore-scroll::-webkit-scrollbar { width: 10px; }
2531
2538
  .boff-explore-scroll::-webkit-scrollbar-track { background: transparent; }
@@ -2643,6 +2650,68 @@ var EXPLORE_CSS = `
2643
2650
  .boff-explore-busy::after { animation: none; }
2644
2651
  .boff-explore-rise { animation: none; opacity: 1; transform: none; }
2645
2652
  }
2653
+
2654
+ /* ---- Pane height ----------------------------------------------------------------------
2655
+ This used to be one inline declaration, \`height: calc(100dvh - 64px)\`, and it carried two
2656
+ defects. An inline style cannot carry a fallback, so every engine without \`dvh\` (iOS
2657
+ Safari < 15.4, Chrome/WebView < 108, Samsung Internet < 21, Firefox < 101) dropped it
2658
+ whole; and the 64px came from a prop hard-coded to 64 on all 41 host pages that matches
2659
+ none of them \u2014 the burdenoff/algoshred chrome is 80px, the sticky-header sites are 65.
2660
+
2661
+ A class plus custom properties lets the cascade do the work: \`vh\` is the floor and \`dvh\`
2662
+ an upgrade where it exists, while the two measured values stay *lengths*, never a height.
2663
+ That distinction is the whole prerender contract. The host sites snapshot \`/explore\` by
2664
+ loading the built SPA in headless Chromium and writing the POST-HYDRATION DOM to
2665
+ dist/explore/index.html, so every attribute and inline value this component sets after
2666
+ mount IS the static HTML CloudFront serves. A measured pixel *height* would therefore
2667
+ hand every phone the prerender viewport's height until the bundle executes; a measured
2668
+ *offset* is a site-header height, which is the same on every device to within a few
2669
+ pixels, and the height built from it stays viewport-relative on the visitor's own screen.
2670
+
2671
+ --boff-explore-offset chrome above the pane (measured root top; the prop pre-measure)
2672
+ --boff-explore-inset the slice of the layout viewport hidden below the visible area \u2014
2673
+ the on-screen keyboard, which \`dvh\` does not track. Zero unless
2674
+ something is actually covering the bottom, so a snapshot taken
2675
+ with no keyboard open never carries it. */
2676
+ .boff-explore-viewport {
2677
+ height: calc(100vh - var(--boff-explore-offset, 0px) - var(--boff-explore-inset, 0px));
2678
+ }
2679
+ @supports (height: 100dvh) {
2680
+ .boff-explore-viewport {
2681
+ height: calc(100dvh - var(--boff-explore-offset, 0px) - var(--boff-explore-inset, 0px));
2682
+ }
2683
+ }
2684
+
2685
+ /* Landscape phones and other short viewports: a one-screen pane leaves a ~124px transcript
2686
+ sliver under ~610px of chrome and content. At or below the threshold the pane stops
2687
+ pretending to be a window and lets the page's own scrolling carry the transcript. The
2688
+ min-height is the available height rather than a fixed rem value, so the fallback can
2689
+ never be taller than the screen it is rescuing. */
2690
+ @media (max-height: ${SHORT_VIEWPORT_PX}px) {
2691
+ .boff-explore-viewport {
2692
+ height: auto;
2693
+ min-height: calc(100vh - var(--boff-explore-offset, 0px));
2694
+ }
2695
+ }
2696
+ @supports (height: 100dvh) {
2697
+ @media (max-height: ${SHORT_VIEWPORT_PX}px) {
2698
+ .boff-explore-viewport {
2699
+ min-height: calc(100dvh - var(--boff-explore-offset, 0px));
2700
+ }
2701
+ }
2702
+ }
2703
+
2704
+ /* ---- Composer dock --------------------------------------------------------------------
2705
+ Three declarations, each the fallback for the one after it: a plain 1rem where \`max()\`
2706
+ is unknown, then the measured overlap of any FOREIGN fixed chrome sitting over the
2707
+ composer (the host sites' cookie banner is 229px tall and lands exactly there), then the
2708
+ same plus the home-indicator inset. \`--boff-explore-chrome\` is set on the root only once
2709
+ an overlap has actually been measured, so everywhere else this collapses to 1rem. */
2710
+ .boff-explore-composer {
2711
+ padding-bottom: 1rem;
2712
+ padding-bottom: max(1rem, var(--boff-explore-chrome, 0px));
2713
+ padding-bottom: max(1rem, env(safe-area-inset-bottom), var(--boff-explore-chrome, 0px));
2714
+ }
2646
2715
  `;
2647
2716
  function ExploreStyles() {
2648
2717
  return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: EXPLORE_CSS } });
@@ -2664,6 +2733,8 @@ var CAPABILITIES = [
2664
2733
  body: "Get the sources and next steps \u2014 pricing, docs, a demo \u2014 without hunting."
2665
2734
  }
2666
2735
  ];
2736
+ var MIN_VISIBLE_FRACTION = 0.25;
2737
+ var SDK_OVERLAY_SELECTOR = "[data-boff-explore]";
2667
2738
  var CTA_VARIANTS = {
2668
2739
  CONTACT: "default",
2669
2740
  WAITLIST: "default",
@@ -2679,6 +2750,28 @@ function normalizeOffset(offset) {
2679
2750
  if (offset === void 0) return "0px";
2680
2751
  return typeof offset === "number" ? `${offset}px` : offset;
2681
2752
  }
2753
+ function isOwnElement(el, root) {
2754
+ if (el === document.body || el === document.documentElement) return true;
2755
+ if (root.contains(el)) return true;
2756
+ return el.closest(SDK_OVERLAY_SELECTOR) !== null;
2757
+ }
2758
+ function visualViewportHeight() {
2759
+ return window.visualViewport?.height ?? window.innerHeight;
2760
+ }
2761
+ function clamp(value, min, max) {
2762
+ return Math.min(Math.max(value, min), max);
2763
+ }
2764
+ function isRestoredNavigation() {
2765
+ const entries = window.performance?.getEntriesByType?.("navigation");
2766
+ const entry = entries?.[0];
2767
+ if (!entry) return true;
2768
+ const navigation = entry;
2769
+ return navigation.type === "reload" || navigation.type === "back_forward";
2770
+ }
2771
+ function pageOwnsScrolling(el) {
2772
+ if (window.innerHeight > SHORT_VIEWPORT_PX) return false;
2773
+ return el.scrollHeight - el.clientHeight <= 1;
2774
+ }
2682
2775
  function isInternalPath(url) {
2683
2776
  return url.startsWith("/") && !url.startsWith("//");
2684
2777
  }
@@ -3527,6 +3620,8 @@ function ExplorePage({
3527
3620
  const pickQueueRef = useRef(Promise.resolve());
3528
3621
  const [shareLabel, setShareLabel] = useState(T.share);
3529
3622
  const [shareUrl, setShareUrl] = useState(null);
3623
+ const rootRef = useRef(null);
3624
+ const composerRef = useRef(null);
3530
3625
  const scrollRef = useRef(null);
3531
3626
  const latestAssistantRef = useRef(null);
3532
3627
  const alignedForRef = useRef(null);
@@ -3554,11 +3649,196 @@ function ExplorePage({
3554
3649
  el.style.height = "auto";
3555
3650
  el.style.height = `${Math.min(el.scrollHeight, 200)}px`;
3556
3651
  }, [draft]);
3652
+ const [paneOffset, setPaneOffset] = useState(null);
3653
+ const [bottomInset, setBottomInset] = useState(0);
3654
+ const paneOffsetRef = useRef(0);
3655
+ const measurePane = useCallback(() => {
3656
+ if (heightMode !== "viewport") return;
3657
+ const el = rootRef.current;
3658
+ if (!el) return;
3659
+ const layoutHeight = window.innerHeight;
3660
+ if (layoutHeight === 0) return;
3661
+ const top = Math.round(
3662
+ clamp(el.getBoundingClientRect().top, 0, layoutHeight)
3663
+ );
3664
+ const viewport = window.visualViewport;
3665
+ const inset = viewport ? Math.round(
3666
+ clamp(
3667
+ layoutHeight - viewport.height - viewport.offsetTop,
3668
+ 0,
3669
+ layoutHeight
3670
+ )
3671
+ ) : 0;
3672
+ paneOffsetRef.current = top;
3673
+ setPaneOffset((current) => current === top ? current : top);
3674
+ setBottomInset((current) => current === inset ? current : inset);
3675
+ }, [heightMode]);
3676
+ const [chromeOverlap, setChromeOverlap] = useState(0);
3677
+ const measureChrome = useCallback(() => {
3678
+ const root = rootRef.current;
3679
+ const dock = composerRef.current;
3680
+ if (!root || !dock) return;
3681
+ if (typeof document.elementFromPoint !== "function") return;
3682
+ const viewportHeight = visualViewportHeight();
3683
+ const rect = dock.getBoundingClientRect();
3684
+ if (rect.width === 0 || viewportHeight === 0) return;
3685
+ if (rect.bottom <= 0 || rect.top >= viewportHeight) return;
3686
+ const edge = Math.min(rect.bottom, viewportHeight);
3687
+ const hit = document.elementFromPoint(rect.left + rect.width / 2, edge - 1);
3688
+ if (!hit || isOwnElement(hit, root)) {
3689
+ setChromeOverlap(0);
3690
+ return;
3691
+ }
3692
+ const overlap = Math.round(edge - hit.getBoundingClientRect().top);
3693
+ setChromeOverlap(overlap > 0 && overlap < viewportHeight ? overlap : 0);
3694
+ }, []);
3695
+ const remeasure = useCallback(() => {
3696
+ measurePane();
3697
+ measureChrome();
3698
+ }, [measurePane, measureChrome]);
3699
+ useEffect(() => {
3700
+ if (typeof window === "undefined") return;
3701
+ let frame = 0;
3702
+ const run = () => {
3703
+ frame = 0;
3704
+ remeasure();
3705
+ };
3706
+ const schedule = () => {
3707
+ if (frame) return;
3708
+ if (typeof window.requestAnimationFrame !== "function") {
3709
+ remeasure();
3710
+ return;
3711
+ }
3712
+ frame = window.requestAnimationFrame(run);
3713
+ };
3714
+ remeasure();
3715
+ const viewport = window.visualViewport;
3716
+ window.addEventListener("resize", schedule);
3717
+ window.addEventListener("orientationchange", schedule);
3718
+ viewport?.addEventListener("resize", schedule);
3719
+ viewport?.addEventListener("scroll", schedule);
3720
+ const observer = typeof MutationObserver === "function" ? new MutationObserver((records) => {
3721
+ const el = rootRef.current;
3722
+ if (el && records.every((record) => el.contains(record.target)))
3723
+ return;
3724
+ schedule();
3725
+ }) : null;
3726
+ observer?.observe(document.body, { childList: true, subtree: true });
3727
+ return () => {
3728
+ if (frame) window.cancelAnimationFrame(frame);
3729
+ window.removeEventListener("resize", schedule);
3730
+ window.removeEventListener("orientationchange", schedule);
3731
+ viewport?.removeEventListener("resize", schedule);
3732
+ viewport?.removeEventListener("scroll", schedule);
3733
+ observer?.disconnect();
3734
+ setPaneOffset(null);
3735
+ setBottomInset(0);
3736
+ setChromeOverlap(0);
3737
+ };
3738
+ }, [remeasure]);
3739
+ useEffect(() => {
3740
+ measureChrome();
3741
+ }, [measureChrome, paneOffset, bottomInset]);
3742
+ useEffect(() => {
3743
+ if (heightMode !== "viewport" || typeof window === "undefined") return;
3744
+ const { history: browserHistory } = window;
3745
+ const previousRestoration = "scrollRestoration" in browserHistory ? browserHistory.scrollRestoration : null;
3746
+ if (previousRestoration !== null)
3747
+ browserHistory.scrollRestoration = "manual";
3748
+ let frame = 0;
3749
+ let visitorMoved = false;
3750
+ const onVisitorMove = () => {
3751
+ visitorMoved = true;
3752
+ };
3753
+ const align = () => {
3754
+ if (visitorMoved) return;
3755
+ const el = rootRef.current;
3756
+ if (!el) return;
3757
+ const viewportHeight = visualViewportHeight();
3758
+ const rect = el.getBoundingClientRect();
3759
+ if (rect.height === 0 || viewportHeight === 0) return;
3760
+ const visible = Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0);
3761
+ const reachable = Math.min(rect.height, viewportHeight);
3762
+ if (visible >= reachable * MIN_VISIBLE_FRACTION) return;
3763
+ window.scrollTo({
3764
+ top: Math.max(0, window.scrollY + rect.top),
3765
+ left: window.scrollX,
3766
+ behavior: "auto"
3767
+ });
3768
+ if (typeof document.elementFromPoint === "function") {
3769
+ const probe = document.elementFromPoint(
3770
+ Math.max(0, rect.left + rect.width / 2),
3771
+ 1
3772
+ );
3773
+ if (probe && !isOwnElement(probe, el)) {
3774
+ const chrome = probe.getBoundingClientRect().bottom;
3775
+ if (chrome > 0 && chrome < viewportHeight / 2) {
3776
+ window.scrollBy({ top: -chrome, left: 0, behavior: "auto" });
3777
+ }
3778
+ }
3779
+ }
3780
+ remeasure();
3781
+ };
3782
+ const alignIfRestored = () => {
3783
+ if (!isRestoredNavigation()) return;
3784
+ align();
3785
+ };
3786
+ alignIfRestored();
3787
+ if (typeof window.requestAnimationFrame === "function") {
3788
+ frame = window.requestAnimationFrame(alignIfRestored);
3789
+ }
3790
+ const onPageShow = (event) => {
3791
+ if (!event.persisted) {
3792
+ alignIfRestored();
3793
+ return;
3794
+ }
3795
+ visitorMoved = false;
3796
+ align();
3797
+ };
3798
+ window.addEventListener("pageshow", onPageShow);
3799
+ window.addEventListener("wheel", onVisitorMove, { passive: true });
3800
+ window.addEventListener("touchmove", onVisitorMove, { passive: true });
3801
+ window.addEventListener("keydown", onVisitorMove, { passive: true });
3802
+ return () => {
3803
+ if (frame) window.cancelAnimationFrame(frame);
3804
+ window.removeEventListener("pageshow", onPageShow);
3805
+ window.removeEventListener("wheel", onVisitorMove);
3806
+ window.removeEventListener("touchmove", onVisitorMove);
3807
+ window.removeEventListener("keydown", onVisitorMove);
3808
+ if (previousRestoration !== null)
3809
+ browserHistory.scrollRestoration = previousRestoration;
3810
+ };
3811
+ }, [heightMode, remeasure]);
3557
3812
  const handleScroll = useCallback(() => {
3558
3813
  const el = scrollRef.current;
3559
3814
  if (!el) return;
3560
3815
  stickToBottomRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
3561
3816
  }, []);
3817
+ useEffect(() => {
3818
+ if (typeof window === "undefined") return;
3819
+ let frame = 0;
3820
+ const run = () => {
3821
+ frame = 0;
3822
+ const el = scrollRef.current;
3823
+ const dock = composerRef.current;
3824
+ if (!el || !dock) return;
3825
+ if (!pageOwnsScrolling(el)) return;
3826
+ stickToBottomRef.current = dock.getBoundingClientRect().bottom - visualViewportHeight() < 80;
3827
+ };
3828
+ const schedule = () => {
3829
+ if (frame) return;
3830
+ if (typeof window.requestAnimationFrame !== "function") {
3831
+ run();
3832
+ return;
3833
+ }
3834
+ frame = window.requestAnimationFrame(run);
3835
+ };
3836
+ window.addEventListener("scroll", schedule, { passive: true });
3837
+ return () => {
3838
+ if (frame) window.cancelAnimationFrame(frame);
3839
+ window.removeEventListener("scroll", schedule);
3840
+ };
3841
+ }, []);
3562
3842
  const latestAssistantId = useMemo(() => {
3563
3843
  for (let i = messages.length - 1; i >= 0; i -= 1) {
3564
3844
  const message = messages[i];
@@ -3574,16 +3854,32 @@ function ExplorePage({
3574
3854
  if (!stickToBottomRef.current) return;
3575
3855
  if (anchor.offsetHeight === 0) return;
3576
3856
  alignedForRef.current = latestAssistantId;
3577
- const delta = anchor.getBoundingClientRect().top - el.getBoundingClientRect().top;
3578
- el.scrollTop = Math.max(0, el.scrollTop + delta - 12);
3857
+ if (!pageOwnsScrolling(el)) {
3858
+ const delta2 = anchor.getBoundingClientRect().top - el.getBoundingClientRect().top;
3859
+ el.scrollTop = Math.max(0, el.scrollTop + delta2 - 12);
3860
+ return;
3861
+ }
3862
+ const delta = Math.round(
3863
+ anchor.getBoundingClientRect().top - paneOffsetRef.current - 12
3864
+ );
3865
+ if (delta !== 0) window.scrollBy({ top: delta, left: 0, behavior: "auto" });
3579
3866
  }, [latestAssistantId, messages]);
3580
3867
  useEffect(() => {
3868
+ if (messages.length === 0) return;
3581
3869
  if (!stickToBottomRef.current) return;
3582
3870
  if (latestAssistantId && alignedForRef.current === latestAssistantId)
3583
3871
  return;
3584
3872
  const el = scrollRef.current;
3585
3873
  if (!el) return;
3586
- el.scrollTop = el.scrollHeight;
3874
+ if (!pageOwnsScrolling(el)) {
3875
+ el.scrollTop = el.scrollHeight;
3876
+ return;
3877
+ }
3878
+ const dock = composerRef.current ?? el;
3879
+ const delta = Math.round(
3880
+ dock.getBoundingClientRect().bottom - visualViewportHeight()
3881
+ );
3882
+ if (delta > 0) window.scrollBy({ top: delta, left: 0, behavior: "auto" });
3587
3883
  }, [activity, latestAssistantId, messages]);
3588
3884
  const handleShare = useCallback(async () => {
3589
3885
  setShareLabel(T.copying);
@@ -3681,16 +3977,27 @@ function ExplorePage({
3681
3977
  const captchaOn = Boolean(
3682
3978
  catalog.captchaRequired && catalog.recaptchaSiteKey
3683
3979
  );
3684
- const rootStyle = heightMode === "viewport" ? { height: `calc(100dvh - ${normalizeOffset(viewportOffset)})` } : void 0;
3980
+ const rootStyle = {};
3981
+ if (heightMode === "viewport") {
3982
+ rootStyle["--boff-explore-offset"] = paneOffset === null ? normalizeOffset(viewportOffset) : `${paneOffset}px`;
3983
+ if (bottomInset > 0) {
3984
+ rootStyle["--boff-explore-inset"] = `${bottomInset}px`;
3985
+ }
3986
+ }
3987
+ if (chromeOverlap > 0) {
3988
+ rootStyle["--boff-explore-chrome"] = `${chromeOverlap}px`;
3989
+ }
3685
3990
  return /* @__PURE__ */ jsxs(
3686
3991
  "div",
3687
3992
  {
3993
+ ref: rootRef,
3688
3994
  "data-boff-explore": "page",
3689
3995
  "data-phase": phase,
3690
3996
  "data-locale": activeLocale,
3691
3997
  dir: rtl ? "rtl" : void 0,
3692
3998
  className: cn(
3693
3999
  "flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground",
4000
+ heightMode === "viewport" && "boff-explore-viewport",
3694
4001
  heightMode === "auto" && "min-h-[70vh]",
3695
4002
  className
3696
4003
  ),
@@ -3924,249 +4231,257 @@ function ExplorePage({
3924
4231
  ]
3925
4232
  }
3926
4233
  ) : null,
3927
- /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md", children: /* @__PURE__ */ jsxs(
3928
- "form",
4234
+ /* @__PURE__ */ jsx(
4235
+ "div",
3929
4236
  {
3930
- "data-boff-explore": "composer",
3931
- className: "mx-auto w-full max-w-3xl",
3932
- onSubmit: (event) => {
3933
- event.preventDefault();
3934
- submitDraft();
3935
- },
3936
- children: [
3937
- error ? /* @__PURE__ */ jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
3938
- staged.length > 0 ? /* @__PURE__ */ jsx(
3939
- "ul",
3940
- {
3941
- "data-boff-explore": "attachments",
3942
- className: "mb-2 flex flex-wrap gap-1.5",
3943
- "aria-label": T.attach,
3944
- children: staged.map((entry) => /* @__PURE__ */ jsxs(
3945
- "li",
4237
+ ref: composerRef,
4238
+ "data-boff-explore": "composer-dock",
4239
+ className: "boff-explore-composer border-t border-border bg-background/85 px-4 pt-3 backdrop-blur-md",
4240
+ children: /* @__PURE__ */ jsxs(
4241
+ "form",
4242
+ {
4243
+ "data-boff-explore": "composer",
4244
+ className: "mx-auto w-full max-w-3xl",
4245
+ onSubmit: (event) => {
4246
+ event.preventDefault();
4247
+ submitDraft();
4248
+ },
4249
+ children: [
4250
+ error ? /* @__PURE__ */ jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
4251
+ staged.length > 0 ? /* @__PURE__ */ jsx(
4252
+ "ul",
4253
+ {
4254
+ "data-boff-explore": "attachments",
4255
+ className: "mb-2 flex flex-wrap gap-1.5",
4256
+ "aria-label": T.attach,
4257
+ children: staged.map((entry) => /* @__PURE__ */ jsxs(
4258
+ "li",
4259
+ {
4260
+ "data-boff-explore": "attachment",
4261
+ "data-text-extracted": entry.textExtracted ? "true" : "false",
4262
+ className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 py-1 pl-2.5 pr-1 text-xs",
4263
+ children: [
4264
+ /* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0 text-muted-foreground" }),
4265
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: entry.name, children: entry.name }),
4266
+ /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
4267
+ formatBytes(entry.size),
4268
+ entry.textExtracted ? "" : ` \xB7 ${T.attachmentNameOnly}`
4269
+ ] }),
4270
+ /* @__PURE__ */ jsx(
4271
+ "button",
4272
+ {
4273
+ type: "button",
4274
+ "data-boff-explore": "attachment-remove",
4275
+ onClick: () => removeAttachment(entry.id),
4276
+ "aria-label": fill(T.removeAttachment, { name: entry.name }),
4277
+ className: "ml-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-background hover:text-foreground",
4278
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
4279
+ }
4280
+ )
4281
+ ]
4282
+ },
4283
+ entry.id
4284
+ ))
4285
+ }
4286
+ ) : null,
4287
+ attachmentNotice !== null ? /* @__PURE__ */ jsx(
4288
+ "p",
3946
4289
  {
3947
- "data-boff-explore": "attachment",
3948
- "data-text-extracted": entry.textExtracted ? "true" : "false",
3949
- className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 py-1 pl-2.5 pr-1 text-xs",
4290
+ "data-boff-explore": "attachment-notice",
4291
+ role: "status",
4292
+ className: "mb-2 text-xs text-destructive",
4293
+ children: attachmentNotice
4294
+ }
4295
+ ) : null,
4296
+ /* @__PURE__ */ jsxs(
4297
+ "div",
4298
+ {
4299
+ className: cn(
4300
+ "flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all",
4301
+ busy && "boff-explore-busy",
4302
+ overLimit ? "border-destructive/60" : "border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring"
4303
+ ),
3950
4304
  children: [
3951
- /* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0 text-muted-foreground" }),
3952
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: entry.name, children: entry.name }),
3953
- /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
3954
- formatBytes(entry.size),
3955
- entry.textExtracted ? "" : ` \xB7 ${T.attachmentNameOnly}`
3956
- ] }),
3957
4305
  /* @__PURE__ */ jsx(
3958
- "button",
4306
+ Textarea,
4307
+ {
4308
+ ref: textareaRef,
4309
+ value: draft,
4310
+ rows: 1,
4311
+ disabled: composerDisabled,
4312
+ onChange: (event) => setDraft(event.target.value),
4313
+ onKeyDown: handleKeyDown,
4314
+ onCompositionStart: () => {
4315
+ composingRef.current = true;
4316
+ },
4317
+ onCompositionEnd: () => {
4318
+ composingRef.current = false;
4319
+ },
4320
+ "aria-label": "Ask a question",
4321
+ placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
4322
+ product: focusedProductName
4323
+ }) : T.placeholder,
4324
+ className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-base shadow-none focus-visible:ring-0 sm:text-sm"
4325
+ }
4326
+ ),
4327
+ /* @__PURE__ */ jsx(
4328
+ "input",
4329
+ {
4330
+ ref: fileInputRef,
4331
+ type: "file",
4332
+ multiple: true,
4333
+ className: "hidden",
4334
+ onChange: (event) => {
4335
+ void handleFilesPicked(event.target.files);
4336
+ event.target.value = "";
4337
+ }
4338
+ }
4339
+ ),
4340
+ /* @__PURE__ */ jsx(
4341
+ Button,
4342
+ {
4343
+ "data-boff-explore": "attach",
4344
+ type: "button",
4345
+ size: "icon",
4346
+ variant: "ghost",
4347
+ disabled: composerDisabled || staged.length >= MAX_ATTACHMENTS,
4348
+ "aria-label": T.attach,
4349
+ title: `${T.attach} \u2014 ${fill(T.attachHint, {
4350
+ max: String(MAX_ATTACHMENTS),
4351
+ size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
4352
+ })}`,
4353
+ onClick: () => fileInputRef.current?.click(),
4354
+ children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
4355
+ }
4356
+ ),
4357
+ speech.supported ? /* @__PURE__ */ jsx(
4358
+ Button,
4359
+ {
4360
+ "data-boff-explore": "mic",
4361
+ "data-listening": speech.listening ? "true" : "false",
4362
+ type: "button",
4363
+ size: "icon",
4364
+ variant: speech.listening ? "default" : "ghost",
4365
+ disabled: composerDisabled,
4366
+ "aria-label": speech.listening ? T.stopDictating : T.dictate,
4367
+ "aria-pressed": speech.listening,
4368
+ title: speech.listening ? T.stopDictating : T.dictate,
4369
+ onClick: speech.toggle,
4370
+ className: cn(speech.listening && "animate-pulse"),
4371
+ children: /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" })
4372
+ }
4373
+ ) : null,
4374
+ busy ? /* @__PURE__ */ jsx(
4375
+ Button,
3959
4376
  {
4377
+ "data-boff-explore": "stop",
3960
4378
  type: "button",
3961
- "data-boff-explore": "attachment-remove",
3962
- onClick: () => removeAttachment(entry.id),
3963
- "aria-label": fill(T.removeAttachment, { name: entry.name }),
3964
- className: "ml-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-background hover:text-foreground",
3965
- children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
4379
+ size: "icon",
4380
+ variant: "secondary",
4381
+ "aria-label": T.stop,
4382
+ onClick: stop,
4383
+ children: /* @__PURE__ */ jsx(Square, { className: "h-4 w-4" })
4384
+ }
4385
+ ) : /* @__PURE__ */ jsx(
4386
+ Button,
4387
+ {
4388
+ "data-boff-explore": "send",
4389
+ type: "submit",
4390
+ size: "icon",
4391
+ disabled: !canSubmit,
4392
+ "aria-label": T.send,
4393
+ children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4" })
3966
4394
  }
3967
4395
  )
3968
4396
  ]
3969
- },
3970
- entry.id
3971
- ))
3972
- }
3973
- ) : null,
3974
- attachmentNotice !== null ? /* @__PURE__ */ jsx(
3975
- "p",
3976
- {
3977
- "data-boff-explore": "attachment-notice",
3978
- role: "status",
3979
- className: "mb-2 text-xs text-destructive",
3980
- children: attachmentNotice
3981
- }
3982
- ) : null,
3983
- /* @__PURE__ */ jsxs(
3984
- "div",
3985
- {
3986
- className: cn(
3987
- "flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all",
3988
- busy && "boff-explore-busy",
3989
- overLimit ? "border-destructive/60" : "border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring"
4397
+ }
3990
4398
  ),
3991
- children: [
3992
- /* @__PURE__ */ jsx(
3993
- Textarea,
4399
+ speech.listening || speech.interim !== "" ? /* @__PURE__ */ jsxs(
4400
+ "p",
4401
+ {
4402
+ "data-boff-explore": "dictation",
4403
+ className: "mt-2 flex items-center gap-2 text-xs text-muted-foreground",
4404
+ "aria-live": "polite",
4405
+ children: [
4406
+ /* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2 shrink-0", children: [
4407
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75" }),
4408
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-primary" })
4409
+ ] }),
4410
+ /* @__PURE__ */ jsx("span", { className: "italic", children: speech.interim !== "" ? speech.interim : "Listening\u2026" })
4411
+ ]
4412
+ }
4413
+ ) : null,
4414
+ speech.error !== null ? /* @__PURE__ */ jsx(
4415
+ "p",
4416
+ {
4417
+ "data-boff-explore": "dictation-error",
4418
+ className: "mt-2 text-xs text-destructive",
4419
+ children: speech.error
4420
+ }
4421
+ ) : null,
4422
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
4423
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Enter to send \xB7 Shift + Enter for a new line" }),
4424
+ remainingToday !== null ? /* @__PURE__ */ jsxs("span", { "data-boff-explore": "remaining", children: [
4425
+ remainingToday,
4426
+ " message",
4427
+ remainingToday === 1 ? "" : "s",
4428
+ " left today"
4429
+ ] }) : null,
4430
+ /* @__PURE__ */ jsxs(
4431
+ "span",
3994
4432
  {
3995
- ref: textareaRef,
3996
- value: draft,
3997
- rows: 1,
3998
- disabled: composerDisabled,
3999
- onChange: (event) => setDraft(event.target.value),
4000
- onKeyDown: handleKeyDown,
4001
- onCompositionStart: () => {
4002
- composingRef.current = true;
4003
- },
4004
- onCompositionEnd: () => {
4005
- composingRef.current = false;
4006
- },
4007
- "aria-label": "Ask a question",
4008
- placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
4009
- product: focusedProductName
4010
- }) : T.placeholder,
4011
- className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-base shadow-none focus-visible:ring-0 sm:text-sm"
4433
+ className: cn(
4434
+ "ml-auto tabular-nums",
4435
+ overLimit && "font-medium text-destructive"
4436
+ ),
4437
+ children: [
4438
+ draft.length.toLocaleString(),
4439
+ " / ",
4440
+ maxLength.toLocaleString()
4441
+ ]
4012
4442
  }
4013
- ),
4443
+ )
4444
+ ] }),
4445
+ shareUrl ? /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
4014
4446
  /* @__PURE__ */ jsx(
4015
4447
  "input",
4016
4448
  {
4017
- ref: fileInputRef,
4018
- type: "file",
4019
- multiple: true,
4020
- className: "hidden",
4021
- onChange: (event) => {
4022
- void handleFilesPicked(event.target.files);
4023
- event.target.value = "";
4024
- }
4449
+ "data-boff-explore": "share-url",
4450
+ readOnly: true,
4451
+ value: shareUrl,
4452
+ "aria-label": "Read-only link to this conversation",
4453
+ onFocus: (event) => event.currentTarget.select(),
4454
+ className: "min-w-0 flex-1 rounded-md border border-border bg-muted px-2 py-1 text-xs text-muted-foreground"
4025
4455
  }
4026
4456
  ),
4027
4457
  /* @__PURE__ */ jsx(
4028
- Button,
4029
- {
4030
- "data-boff-explore": "attach",
4031
- type: "button",
4032
- size: "icon",
4033
- variant: "ghost",
4034
- disabled: composerDisabled || staged.length >= MAX_ATTACHMENTS,
4035
- "aria-label": T.attach,
4036
- title: `${T.attach} \u2014 ${fill(T.attachHint, {
4037
- max: String(MAX_ATTACHMENTS),
4038
- size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
4039
- })}`,
4040
- onClick: () => fileInputRef.current?.click(),
4041
- children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
4042
- }
4043
- ),
4044
- speech.supported ? /* @__PURE__ */ jsx(
4045
- Button,
4458
+ "button",
4046
4459
  {
4047
- "data-boff-explore": "mic",
4048
- "data-listening": speech.listening ? "true" : "false",
4049
4460
  type: "button",
4050
- size: "icon",
4051
- variant: speech.listening ? "default" : "ghost",
4052
- disabled: composerDisabled,
4053
- "aria-label": speech.listening ? T.stopDictating : T.dictate,
4054
- "aria-pressed": speech.listening,
4055
- title: speech.listening ? T.stopDictating : T.dictate,
4056
- onClick: speech.toggle,
4057
- className: cn(speech.listening && "animate-pulse"),
4058
- children: /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" })
4461
+ className: "shrink-0 text-xs underline underline-offset-2",
4462
+ onClick: () => setShareUrl(null),
4463
+ children: "Done"
4059
4464
  }
4060
- ) : null,
4061
- busy ? /* @__PURE__ */ jsx(
4062
- Button,
4465
+ )
4466
+ ] }) : null,
4467
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
4468
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: T.disclaimerShort }),
4469
+ /* @__PURE__ */ jsx(
4470
+ "button",
4063
4471
  {
4064
- "data-boff-explore": "stop",
4065
4472
  type: "button",
4066
- size: "icon",
4067
- variant: "secondary",
4068
- "aria-label": T.stop,
4069
- onClick: stop,
4070
- children: /* @__PURE__ */ jsx(Square, { className: "h-4 w-4" })
4071
- }
4072
- ) : /* @__PURE__ */ jsx(
4073
- Button,
4074
- {
4075
- "data-boff-explore": "send",
4076
- type: "submit",
4077
- size: "icon",
4078
- disabled: !canSubmit,
4079
- "aria-label": T.send,
4080
- children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4" })
4473
+ "data-boff-explore": "disclaimer",
4474
+ onClick: () => setDisclaimerOpen(true),
4475
+ className: "shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
4476
+ children: T.disclaimer
4081
4477
  }
4082
4478
  )
4083
- ]
4084
- }
4085
- ),
4086
- speech.listening || speech.interim !== "" ? /* @__PURE__ */ jsxs(
4087
- "p",
4088
- {
4089
- "data-boff-explore": "dictation",
4090
- className: "mt-2 flex items-center gap-2 text-xs text-muted-foreground",
4091
- "aria-live": "polite",
4092
- children: [
4093
- /* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2 shrink-0", children: [
4094
- /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75" }),
4095
- /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-primary" })
4096
- ] }),
4097
- /* @__PURE__ */ jsx("span", { className: "italic", children: speech.interim !== "" ? speech.interim : "Listening\u2026" })
4098
- ]
4099
- }
4100
- ) : null,
4101
- speech.error !== null ? /* @__PURE__ */ jsx(
4102
- "p",
4103
- {
4104
- "data-boff-explore": "dictation-error",
4105
- className: "mt-2 text-xs text-destructive",
4106
- children: speech.error
4107
- }
4108
- ) : null,
4109
- /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
4110
- /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Enter to send \xB7 Shift + Enter for a new line" }),
4111
- remainingToday !== null ? /* @__PURE__ */ jsxs("span", { "data-boff-explore": "remaining", children: [
4112
- remainingToday,
4113
- " message",
4114
- remainingToday === 1 ? "" : "s",
4115
- " left today"
4116
- ] }) : null,
4117
- /* @__PURE__ */ jsxs(
4118
- "span",
4119
- {
4120
- className: cn(
4121
- "ml-auto tabular-nums",
4122
- overLimit && "font-medium text-destructive"
4123
- ),
4124
- children: [
4125
- draft.length.toLocaleString(),
4126
- " / ",
4127
- maxLength.toLocaleString()
4128
- ]
4129
- }
4130
- )
4131
- ] }),
4132
- shareUrl ? /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
4133
- /* @__PURE__ */ jsx(
4134
- "input",
4135
- {
4136
- "data-boff-explore": "share-url",
4137
- readOnly: true,
4138
- value: shareUrl,
4139
- "aria-label": "Read-only link to this conversation",
4140
- onFocus: (event) => event.currentTarget.select(),
4141
- className: "min-w-0 flex-1 rounded-md border border-border bg-muted px-2 py-1 text-xs text-muted-foreground"
4142
- }
4143
- ),
4144
- /* @__PURE__ */ jsx(
4145
- "button",
4146
- {
4147
- type: "button",
4148
- className: "shrink-0 text-xs underline underline-offset-2",
4149
- onClick: () => setShareUrl(null),
4150
- children: "Done"
4151
- }
4152
- )
4153
- ] }) : null,
4154
- /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
4155
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: T.disclaimerShort }),
4156
- /* @__PURE__ */ jsx(
4157
- "button",
4158
- {
4159
- type: "button",
4160
- "data-boff-explore": "disclaimer",
4161
- onClick: () => setDisclaimerOpen(true),
4162
- className: "shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
4163
- children: T.disclaimer
4164
- }
4165
- )
4166
- ] })
4167
- ]
4479
+ ] })
4480
+ ]
4481
+ }
4482
+ )
4168
4483
  }
4169
- ) })
4484
+ )
4170
4485
  ]
4171
4486
  }
4172
4487
  );