@uplifted/react 0.22.6

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 (221) hide show
  1. package/dist/AddClientSheet.d.ts +39 -0
  2. package/dist/AddClientSheet.d.ts.map +1 -0
  3. package/dist/AddClientSheet.js +108 -0
  4. package/dist/AddClientSheet.js.map +1 -0
  5. package/dist/AiSettingsSheet.d.ts +20 -0
  6. package/dist/AiSettingsSheet.d.ts.map +1 -0
  7. package/dist/AiSettingsSheet.js +274 -0
  8. package/dist/AiSettingsSheet.js.map +1 -0
  9. package/dist/AssistantGrid.d.ts +30 -0
  10. package/dist/AssistantGrid.d.ts.map +1 -0
  11. package/dist/AssistantGrid.js +68 -0
  12. package/dist/AssistantGrid.js.map +1 -0
  13. package/dist/AttachmentPicker.d.ts +38 -0
  14. package/dist/AttachmentPicker.d.ts.map +1 -0
  15. package/dist/AttachmentPicker.js +173 -0
  16. package/dist/AttachmentPicker.js.map +1 -0
  17. package/dist/BulkGenerateSheet.d.ts +25 -0
  18. package/dist/BulkGenerateSheet.d.ts.map +1 -0
  19. package/dist/BulkGenerateSheet.js +65 -0
  20. package/dist/BulkGenerateSheet.js.map +1 -0
  21. package/dist/ChannelBadge.d.ts +16 -0
  22. package/dist/ChannelBadge.d.ts.map +1 -0
  23. package/dist/ChannelBadge.js +19 -0
  24. package/dist/ChannelBadge.js.map +1 -0
  25. package/dist/ChannelExplainer.d.ts +17 -0
  26. package/dist/ChannelExplainer.d.ts.map +1 -0
  27. package/dist/ChannelExplainer.js +25 -0
  28. package/dist/ChannelExplainer.js.map +1 -0
  29. package/dist/ClientList.d.ts +43 -0
  30. package/dist/ClientList.d.ts.map +1 -0
  31. package/dist/ClientList.js +76 -0
  32. package/dist/ClientList.js.map +1 -0
  33. package/dist/ClosedWindowBanner.d.ts +12 -0
  34. package/dist/ClosedWindowBanner.d.ts.map +1 -0
  35. package/dist/ClosedWindowBanner.js +15 -0
  36. package/dist/ClosedWindowBanner.js.map +1 -0
  37. package/dist/Composer.d.ts +49 -0
  38. package/dist/Composer.d.ts.map +1 -0
  39. package/dist/Composer.js +99 -0
  40. package/dist/Composer.js.map +1 -0
  41. package/dist/ComposerExtras.d.ts +15 -0
  42. package/dist/ComposerExtras.d.ts.map +1 -0
  43. package/dist/ComposerExtras.js +14 -0
  44. package/dist/ComposerExtras.js.map +1 -0
  45. package/dist/ConversationPane.d.ts +33 -0
  46. package/dist/ConversationPane.d.ts.map +1 -0
  47. package/dist/ConversationPane.js +126 -0
  48. package/dist/ConversationPane.js.map +1 -0
  49. package/dist/DeliveryReceipt.d.ts +7 -0
  50. package/dist/DeliveryReceipt.d.ts.map +1 -0
  51. package/dist/DeliveryReceipt.js +13 -0
  52. package/dist/DeliveryReceipt.js.map +1 -0
  53. package/dist/DraftGrid.d.ts +17 -0
  54. package/dist/DraftGrid.d.ts.map +1 -0
  55. package/dist/DraftGrid.js +43 -0
  56. package/dist/DraftGrid.js.map +1 -0
  57. package/dist/HostPreviewPane.d.ts +37 -0
  58. package/dist/HostPreviewPane.d.ts.map +1 -0
  59. package/dist/HostPreviewPane.js +106 -0
  60. package/dist/HostPreviewPane.js.map +1 -0
  61. package/dist/InlineDrafts.d.ts +14 -0
  62. package/dist/InlineDrafts.d.ts.map +1 -0
  63. package/dist/InlineDrafts.js +19 -0
  64. package/dist/InlineDrafts.js.map +1 -0
  65. package/dist/ItemActions.d.ts +23 -0
  66. package/dist/ItemActions.d.ts.map +1 -0
  67. package/dist/ItemActions.js +83 -0
  68. package/dist/ItemActions.js.map +1 -0
  69. package/dist/MediaAttachment.d.ts +7 -0
  70. package/dist/MediaAttachment.d.ts.map +1 -0
  71. package/dist/MediaAttachment.js +37 -0
  72. package/dist/MediaAttachment.js.map +1 -0
  73. package/dist/OfferSheet.d.ts +32 -0
  74. package/dist/OfferSheet.d.ts.map +1 -0
  75. package/dist/OfferSheet.js +84 -0
  76. package/dist/OfferSheet.js.map +1 -0
  77. package/dist/ProactiveOptionsSheet.d.ts +14 -0
  78. package/dist/ProactiveOptionsSheet.d.ts.map +1 -0
  79. package/dist/ProactiveOptionsSheet.js +58 -0
  80. package/dist/ProactiveOptionsSheet.js.map +1 -0
  81. package/dist/QuickSend.d.ts +15 -0
  82. package/dist/QuickSend.d.ts.map +1 -0
  83. package/dist/QuickSend.js +90 -0
  84. package/dist/QuickSend.js.map +1 -0
  85. package/dist/SegmentEditor.d.ts +25 -0
  86. package/dist/SegmentEditor.d.ts.map +1 -0
  87. package/dist/SegmentEditor.js +95 -0
  88. package/dist/SegmentEditor.js.map +1 -0
  89. package/dist/Sheet.d.ts +13 -0
  90. package/dist/Sheet.d.ts.map +1 -0
  91. package/dist/Sheet.js +64 -0
  92. package/dist/Sheet.js.map +1 -0
  93. package/dist/ThreadFeed.d.ts +27 -0
  94. package/dist/ThreadFeed.d.ts.map +1 -0
  95. package/dist/ThreadFeed.js +42 -0
  96. package/dist/ThreadFeed.js.map +1 -0
  97. package/dist/UpliftPanel.d.ts +40 -0
  98. package/dist/UpliftPanel.d.ts.map +1 -0
  99. package/dist/UpliftPanel.js +219 -0
  100. package/dist/UpliftPanel.js.map +1 -0
  101. package/dist/UpliftProvider.d.ts +15 -0
  102. package/dist/UpliftProvider.d.ts.map +1 -0
  103. package/dist/UpliftProvider.js +19 -0
  104. package/dist/UpliftProvider.js.map +1 -0
  105. package/dist/WaitingTemplateGhost.d.ts +12 -0
  106. package/dist/WaitingTemplateGhost.d.ts.map +1 -0
  107. package/dist/WaitingTemplateGhost.js +16 -0
  108. package/dist/WaitingTemplateGhost.js.map +1 -0
  109. package/dist/channels.d.ts +22 -0
  110. package/dist/channels.d.ts.map +1 -0
  111. package/dist/channels.js +31 -0
  112. package/dist/channels.js.map +1 -0
  113. package/dist/errors.d.ts +6 -0
  114. package/dist/errors.d.ts.map +1 -0
  115. package/dist/errors.js +20 -0
  116. package/dist/errors.js.map +1 -0
  117. package/dist/host.d.ts +45 -0
  118. package/dist/host.d.ts.map +1 -0
  119. package/dist/host.js +35 -0
  120. package/dist/host.js.map +1 -0
  121. package/dist/icons.d.ts +48 -0
  122. package/dist/icons.d.ts.map +1 -0
  123. package/dist/icons.js +71 -0
  124. package/dist/icons.js.map +1 -0
  125. package/dist/index.d.ts +58 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +36 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/labels.d.ts +58 -0
  130. package/dist/labels.d.ts.map +1 -0
  131. package/dist/labels.js +86 -0
  132. package/dist/labels.js.map +1 -0
  133. package/dist/phone.d.ts +18 -0
  134. package/dist/phone.d.ts.map +1 -0
  135. package/dist/phone.js +27 -0
  136. package/dist/phone.js.map +1 -0
  137. package/dist/proactiveIcons.d.ts +6 -0
  138. package/dist/proactiveIcons.d.ts.map +1 -0
  139. package/dist/proactiveIcons.js +39 -0
  140. package/dist/proactiveIcons.js.map +1 -0
  141. package/dist/purposes.d.ts +19 -0
  142. package/dist/purposes.d.ts.map +1 -0
  143. package/dist/purposes.js +20 -0
  144. package/dist/purposes.js.map +1 -0
  145. package/dist/segments.d.ts +29 -0
  146. package/dist/segments.d.ts.map +1 -0
  147. package/dist/segments.js +75 -0
  148. package/dist/segments.js.map +1 -0
  149. package/dist/smsSegments.d.ts +28 -0
  150. package/dist/smsSegments.d.ts.map +1 -0
  151. package/dist/smsSegments.js +100 -0
  152. package/dist/smsSegments.js.map +1 -0
  153. package/dist/styles.d.ts +15 -0
  154. package/dist/styles.d.ts.map +1 -0
  155. package/dist/styles.js +545 -0
  156. package/dist/styles.js.map +1 -0
  157. package/dist/time.d.ts +14 -0
  158. package/dist/time.d.ts.map +1 -0
  159. package/dist/time.js +80 -0
  160. package/dist/time.js.map +1 -0
  161. package/dist/useAiSettings.d.ts +11 -0
  162. package/dist/useAiSettings.d.ts.map +1 -0
  163. package/dist/useAiSettings.js +21 -0
  164. package/dist/useAiSettings.js.map +1 -0
  165. package/dist/useBilling.d.ts +40 -0
  166. package/dist/useBilling.d.ts.map +1 -0
  167. package/dist/useBilling.js +155 -0
  168. package/dist/useBilling.js.map +1 -0
  169. package/dist/useBulkDrafts.d.ts +41 -0
  170. package/dist/useBulkDrafts.d.ts.map +1 -0
  171. package/dist/useBulkDrafts.js +112 -0
  172. package/dist/useBulkDrafts.js.map +1 -0
  173. package/dist/useClients.d.ts +16 -0
  174. package/dist/useClients.d.ts.map +1 -0
  175. package/dist/useClients.js +22 -0
  176. package/dist/useClients.js.map +1 -0
  177. package/dist/useDeliveryStatus.d.ts +7 -0
  178. package/dist/useDeliveryStatus.d.ts.map +1 -0
  179. package/dist/useDeliveryStatus.js +39 -0
  180. package/dist/useDeliveryStatus.js.map +1 -0
  181. package/dist/useDrafts.d.ts +19 -0
  182. package/dist/useDrafts.d.ts.map +1 -0
  183. package/dist/useDrafts.js +60 -0
  184. package/dist/useDrafts.js.map +1 -0
  185. package/dist/useInstructions.d.ts +9 -0
  186. package/dist/useInstructions.d.ts.map +1 -0
  187. package/dist/useInstructions.js +20 -0
  188. package/dist/useInstructions.js.map +1 -0
  189. package/dist/useLiveUpdates.d.ts +9 -0
  190. package/dist/useLiveUpdates.d.ts.map +1 -0
  191. package/dist/useLiveUpdates.js +48 -0
  192. package/dist/useLiveUpdates.js.map +1 -0
  193. package/dist/usePolling.d.ts +6 -0
  194. package/dist/usePolling.d.ts.map +1 -0
  195. package/dist/usePolling.js +31 -0
  196. package/dist/usePolling.js.map +1 -0
  197. package/dist/usePreviewDrafts.d.ts +15 -0
  198. package/dist/usePreviewDrafts.d.ts.map +1 -0
  199. package/dist/usePreviewDrafts.js +77 -0
  200. package/dist/usePreviewDrafts.js.map +1 -0
  201. package/dist/useProactiveOptions.d.ts +15 -0
  202. package/dist/useProactiveOptions.d.ts.map +1 -0
  203. package/dist/useProactiveOptions.js +39 -0
  204. package/dist/useProactiveOptions.js.map +1 -0
  205. package/dist/useSend.d.ts +16 -0
  206. package/dist/useSend.d.ts.map +1 -0
  207. package/dist/useSend.js +50 -0
  208. package/dist/useSend.js.map +1 -0
  209. package/dist/useStickToBottom.d.ts +12 -0
  210. package/dist/useStickToBottom.d.ts.map +1 -0
  211. package/dist/useStickToBottom.js +71 -0
  212. package/dist/useStickToBottom.js.map +1 -0
  213. package/dist/useThread.d.ts +26 -0
  214. package/dist/useThread.d.ts.map +1 -0
  215. package/dist/useThread.js +76 -0
  216. package/dist/useThread.js.map +1 -0
  217. package/dist/useWhatsAppWindow.d.ts +8 -0
  218. package/dist/useWhatsAppWindow.d.ts.map +1 -0
  219. package/dist/useWhatsAppWindow.js +22 -0
  220. package/dist/useWhatsAppWindow.js.map +1 -0
  221. package/package.json +36 -0
@@ -0,0 +1,20 @@
1
+ import { proactiveIcon } from "./proactiveIcons.js";
2
+ export function hydratePurposes(options) {
3
+ if (!options || options.length === 0)
4
+ return null;
5
+ return options.map((o) => ({ id: o.id, label: o.label, icon: o.icon, prompt: o.prompt || "", cannedText: o.cannedText || null, Icon: proactiveIcon(o.icon) }));
6
+ }
7
+ /** What a picked purpose sends to a drafts endpoint: canned text as a message to personalise, else the prompt as a hint. */
8
+ export function purposeToDraftsInput(p) {
9
+ return p.cannedText ? { purpose: p.cannedText, purposeMode: "message" } : { purpose: p.prompt };
10
+ }
11
+ /** Native DEFAULT_PROACTIVE_OPTIONS, used until the coach's own list arrives. */
12
+ export const PURPOSES = hydratePurposes([
13
+ { id: "check_in", label: "Check In", icon: "timer", prompt: "Check in with client depending on the time of day" },
14
+ { id: "game_plan", label: "Game Plan", icon: "target", prompt: "Invite the client to articulate their plan for the day or to achieve their weekly goals" },
15
+ { id: "status", label: "Status Review", icon: "bar-chart", prompt: "Share details with the client regarding their goals and engagement and progress report" },
16
+ { id: "call_out", label: "Call Out", icon: "flame", prompt: "Inspire the client to action with a tough love callout" },
17
+ { id: "schedule", label: "Schedule", icon: "calendar", prompt: "Remind the client to book a video call" },
18
+ { id: "follow_up", label: "Follow Up", icon: "refresh", prompt: "Follow up on last sent message" },
19
+ ]);
20
+ //# sourceMappingURL=purposes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purposes.js","sourceRoot":"","sources":["../src/purposes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcpD,MAAM,UAAU,eAAe,CAAC,OAA0D;IACxF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACjK,CAAC;AAED,4HAA4H;AAC5H,MAAM,UAAU,oBAAoB,CAAC,CAAU;IAC7C,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAClG,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAAuB,eAAe,CAAC;IAC1D,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,mDAAmD,EAAE;IACjH,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,yFAAyF,EAAE;IAC1J,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,wFAAwF,EAAE;IAC7J,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,wDAAwD,EAAE;IACtH,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,wCAAwC,EAAE;IACzG,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,gCAAgC,EAAE;CACnG,CAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Segment editing, ported from native Uplift's RichTextEditor (uplift_coach,
3
+ * client/src/components/ui/RichTextEditor.jsx) so the two behave identically: a picked draft
4
+ * is split into clause-sized "pills" the coach can drop one at a time, and sending reconstructs
5
+ * exact plain text from what is left. The split and reconstruct rules here are the native ones
6
+ * verbatim; do not "improve" them without changing native too.
7
+ */
8
+ /** Stable hue for a chunk of text: the same phrase is always the same colour. */
9
+ export declare function hueFor(text: string): number;
10
+ /**
11
+ * Split only at clause/sentence punctuation that is FOLLOWED BY whitespace, keeping that
12
+ * punctuation and whitespace attached to the preceding segment. Never splits inside URLs or
13
+ * decimals (their dots and slashes are not followed by a space), and preserves the original
14
+ * spacing exactly so reconstruction never injects an extra space.
15
+ */
16
+ export declare function splitIntoSegments(text: string): string[];
17
+ export declare const SEG_CLASS = "u-seg";
18
+ export declare const SEG_DELETE_CLASS = "u-seg-x";
19
+ /** Pill markup for one draft. Each pill carries its hue and a delete control that is not editable. */
20
+ export declare function toPillHtml(text: string, nonce: number): string;
21
+ /**
22
+ * One locked pill for text the coach cannot change: Uplift's stock intro, which goes out on its
23
+ * own before the first message (on WhatsApp as the approved template). No × and not editable;
24
+ * it still counts as message text so Send is live.
25
+ */
26
+ export declare function toLockedPillHtml(text: string, nonce: number): string;
27
+ /** Plain text back from editor HTML. Walks nodes verbatim so spacing inside pills, URLs and decimals survives. */
28
+ export declare function reconstructMessage(html: string): string;
29
+ //# sourceMappingURL=segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../src/segments.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,iFAAiF;AACjF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI3C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxD;AAED,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAM1C,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGpE;AAQD,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWvD"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Segment editing, ported from native Uplift's RichTextEditor (uplift_coach,
3
+ * client/src/components/ui/RichTextEditor.jsx) so the two behave identically: a picked draft
4
+ * is split into clause-sized "pills" the coach can drop one at a time, and sending reconstructs
5
+ * exact plain text from what is left. The split and reconstruct rules here are the native ones
6
+ * verbatim; do not "improve" them without changing native too.
7
+ */
8
+ /** Stable hue for a chunk of text: the same phrase is always the same colour. */
9
+ export function hueFor(text) {
10
+ let hash = 0;
11
+ for (let i = 0; i < text.length; i++)
12
+ hash = text.charCodeAt(i) + ((hash << 5) - hash);
13
+ return Math.abs(hash) % 360;
14
+ }
15
+ /**
16
+ * Split only at clause/sentence punctuation that is FOLLOWED BY whitespace, keeping that
17
+ * punctuation and whitespace attached to the preceding segment. Never splits inside URLs or
18
+ * decimals (their dots and slashes are not followed by a space), and preserves the original
19
+ * spacing exactly so reconstruction never injects an extra space.
20
+ */
21
+ export function splitIntoSegments(text) {
22
+ const parts = text.split(/([.,;—?!]+\s+)/);
23
+ const result = [];
24
+ for (let i = 0; i < parts.length; i += 2) {
25
+ const combined = (parts[i] ?? "") + (parts[i + 1] ?? "");
26
+ if (combined.trim())
27
+ result.push(combined);
28
+ }
29
+ return result.length ? result : (text.trim() ? [text] : []);
30
+ }
31
+ export const SEG_CLASS = "u-seg";
32
+ export const SEG_DELETE_CLASS = "u-seg-x";
33
+ function escapeHtml(s) {
34
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
35
+ }
36
+ /** Pill markup for one draft. Each pill carries its hue and a delete control that is not editable. */
37
+ export function toPillHtml(text, nonce) {
38
+ return splitIntoSegments(text).map((segment, index) => {
39
+ const id = `seg-${nonce}-${index}`;
40
+ const label = escapeHtml(`Remove "${segment.trim()}"`);
41
+ const x = `<span class="${SEG_DELETE_CLASS}" role="button" tabindex="0" contenteditable="false" aria-label="${label}" data-seg="${id}">×</span>`;
42
+ return `<span class="${SEG_CLASS}" data-seg="${id}" style="--u-seg-h:${hueFor(segment.trim())}">${escapeHtml(segment)}${x}</span>`;
43
+ }).join("");
44
+ }
45
+ /**
46
+ * One locked pill for text the coach cannot change: Uplift's stock intro, which goes out on its
47
+ * own before the first message (on WhatsApp as the approved template). No × and not editable;
48
+ * it still counts as message text so Send is live.
49
+ */
50
+ export function toLockedPillHtml(text, nonce) {
51
+ const id = `seg-${nonce}-lock`;
52
+ return `<span class="${SEG_CLASS} u-seg-lock" data-seg="${id}" contenteditable="false" title="Uplift sends this intro itself; it can't be edited" style="--u-seg-h:${hueFor(text.trim())}">${escapeHtml(text)}</span> `;
53
+ }
54
+ function extractPlainText(html) {
55
+ const tmp = document.createElement("div");
56
+ tmp.innerHTML = html;
57
+ return (tmp.textContent || "").replace(/\s+/g, " ").trim();
58
+ }
59
+ /** Plain text back from editor HTML. Walks nodes verbatim so spacing inside pills, URLs and decimals survives. */
60
+ export function reconstructMessage(html) {
61
+ const tmp = document.createElement("div");
62
+ tmp.innerHTML = html;
63
+ if (tmp.querySelectorAll(`.${SEG_CLASS}`).length === 0)
64
+ return extractPlainText(html);
65
+ tmp.querySelectorAll(`.${SEG_DELETE_CLASS}`).forEach((el) => el.remove());
66
+ let out = "";
67
+ tmp.childNodes.forEach((node) => {
68
+ if (node.nodeType === Node.TEXT_NODE)
69
+ out += node.textContent ?? "";
70
+ else if (node.nodeType === Node.ELEMENT_NODE)
71
+ out += (node.textContent ?? "").replace(/🗑️/g, "");
72
+ });
73
+ return out.replace(/[ \t]{2,}/g, " ").trim();
74
+ }
75
+ //# sourceMappingURL=segments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segments.js","sourceRoot":"","sources":["../src/segments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SMS segment maths, a mirror of native Uplift's client/src/chat/normalizers/smsSegments.js (which
3
+ * itself mirrors server/utils/smsSegments.js). The composer warns what a message will actually cost
4
+ * in SMS parts before it is sent. SMS holds 160 characters only in the GSM-7 alphabet; one character
5
+ * outside it (a curly apostrophe is the usual culprit) drops the whole message to 70, and carriers
6
+ * reject concatenated SMS past ~10 parts. SMS only: WhatsApp has no segmentation.
7
+ */
8
+ export declare const MAX_SEGMENTS = 10;
9
+ export declare function isGsm7(text: string): boolean;
10
+ export interface SmsMeasure {
11
+ encoding: "GSM-7" | "UCS-2";
12
+ length: number;
13
+ segments: number;
14
+ perSegment: number;
15
+ }
16
+ export declare function measure(text: string): SmsMeasure;
17
+ export declare function normalizeForSms(text: string): string;
18
+ export declare function splitForSms(text: string, maxSegments?: number): string[];
19
+ export interface SmsCost {
20
+ segments: number;
21
+ encoding: "GSM-7" | "UCS-2";
22
+ parts: number;
23
+ willSplit: boolean;
24
+ normalized: boolean;
25
+ }
26
+ /** What the composer needs in one call: how this message will actually go out. `parts > 1` means several texts. */
27
+ export declare function previewSmsCost(text: string): SmsCost;
28
+ //# sourceMappingURL=smsSegments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smsSegments.d.ts","sourceRoot":"","sources":["../src/smsSegments.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG5C;AAWD,MAAM,WAAW,UAAU;IAAG,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAEjH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAQhD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAAe,GAAG,MAAM,EAAE,CA0B9E;AAED,MAAM,WAAW,OAAO;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE;AAElI,mHAAmH;AACnH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpD"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * SMS segment maths, a mirror of native Uplift's client/src/chat/normalizers/smsSegments.js (which
3
+ * itself mirrors server/utils/smsSegments.js). The composer warns what a message will actually cost
4
+ * in SMS parts before it is sent. SMS holds 160 characters only in the GSM-7 alphabet; one character
5
+ * outside it (a curly apostrophe is the usual culprit) drops the whole message to 70, and carriers
6
+ * reject concatenated SMS past ~10 parts. SMS only: WhatsApp has no segmentation.
7
+ */
8
+ const GSM_BASIC = "@£$¥èéùìòÇ\nØø\rÅå"
9
+ + "Δ_ΦΓΛΩΠΨΣΘΞÆæßÉ"
10
+ + " !\"#¤%&'()*+,-./0123456789:;<=>?¡"
11
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿"
12
+ + "abcdefghijklmnopqrstuvwxyzäöñüà";
13
+ const GSM_EXTENDED = "^{}\\[~]|€";
14
+ const BASIC = new Set([...GSM_BASIC]);
15
+ const EXTENDED = new Set([...GSM_EXTENDED]);
16
+ const GSM_SINGLE = 160;
17
+ const GSM_CONCAT = 153;
18
+ const UCS2_SINGLE = 70;
19
+ const UCS2_CONCAT = 67;
20
+ export const MAX_SEGMENTS = 10;
21
+ export function isGsm7(text) {
22
+ for (const ch of String(text ?? ""))
23
+ if (!BASIC.has(ch) && !EXTENDED.has(ch))
24
+ return false;
25
+ return true;
26
+ }
27
+ function billableLength(text, gsm) {
28
+ let n = 0;
29
+ for (const ch of String(text ?? "")) {
30
+ if (gsm)
31
+ n += EXTENDED.has(ch) ? 2 : 1;
32
+ else
33
+ n += (ch.codePointAt(0) ?? 0) > 0xffff ? 2 : 1;
34
+ }
35
+ return n;
36
+ }
37
+ export function measure(text) {
38
+ const t = String(text ?? "");
39
+ const gsm = isGsm7(t);
40
+ const length = billableLength(t, gsm);
41
+ const single = gsm ? GSM_SINGLE : UCS2_SINGLE;
42
+ const concat = gsm ? GSM_CONCAT : UCS2_CONCAT;
43
+ const segments = length === 0 ? 0 : (length <= single ? 1 : Math.ceil(length / concat));
44
+ return { encoding: gsm ? "GSM-7" : "UCS-2", length, segments, perSegment: segments > 1 ? concat : single };
45
+ }
46
+ export function normalizeForSms(text) {
47
+ return String(text ?? "")
48
+ .replace(/[‘’‛′]/g, "'")
49
+ .replace(/[“”‟″]/g, '"')
50
+ .replace(/[–—―]/g, "-")
51
+ .replace(/…/g, "...")
52
+ .replace(/ /g, " ")
53
+ .replace(/[•·]/g, "-")
54
+ .replace(/™/g, "TM")
55
+ .replace(/[←-⇿]/g, "->");
56
+ }
57
+ export function splitForSms(text, maxSegments = MAX_SEGMENTS) {
58
+ const t = String(text ?? "");
59
+ if (!t)
60
+ return [];
61
+ if (measure(t).segments <= maxSegments)
62
+ return [t];
63
+ const { encoding } = measure(t);
64
+ const perPart = (encoding === "GSM-7" ? GSM_CONCAT : UCS2_CONCAT) * maxSegments;
65
+ const parts = [];
66
+ let rest = t;
67
+ while (rest) {
68
+ if (measure(rest).segments <= maxSegments) {
69
+ parts.push(rest);
70
+ break;
71
+ }
72
+ const window = rest.slice(0, perPart);
73
+ let cut = -1;
74
+ const BOUNDARIES = [
75
+ [/\n\n(?![\s\S]*\n\n)/, 0],
76
+ [/(?:[.!?])\s(?![\s\S]*[.!?]\s)/, 0.3],
77
+ [/\s(?!\S*\s)/, 0.5],
78
+ ];
79
+ for (const [boundary, minFill] of BOUNDARIES) {
80
+ const m = window.match(boundary);
81
+ if (m && m.index !== undefined && m.index >= perPart * minFill) {
82
+ cut = m.index + m[0].length;
83
+ break;
84
+ }
85
+ }
86
+ if (cut <= 0)
87
+ cut = perPart;
88
+ parts.push(rest.slice(0, cut).trim());
89
+ rest = rest.slice(cut).trim();
90
+ }
91
+ return parts.filter(Boolean);
92
+ }
93
+ /** What the composer needs in one call: how this message will actually go out. `parts > 1` means several texts. */
94
+ export function previewSmsCost(text) {
95
+ const cleaned = normalizeForSms(text);
96
+ const after = measure(cleaned);
97
+ const parts = splitForSms(cleaned);
98
+ return { segments: after.segments, encoding: after.encoding, parts: parts.length, willSplit: parts.length > 1, normalized: cleaned !== String(text ?? "") };
99
+ }
100
+ //# sourceMappingURL=smsSegments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smsSegments.js","sourceRoot":"","sources":["../src/smsSegments.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,SAAS,GACb,oBAAoB;MAClB,iBAAiB;MACjB,oCAAoC;MACpC,kCAAkC;MAClC,iCAAiC,CAAC;AACtC,MAAM,YAAY,GAAG,YAAY,CAAC;AAClC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;AACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;AAC5C,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;IAC3F,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,GAAY;IAChD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;QACpC,IAAI,GAAG;YAAE,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;YAClC,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAID,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9C,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACxF,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;SACtB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,WAAW,GAAG,YAAY;IAClE,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,WAAW;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IAChF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,MAAM;QAAC,CAAC;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;QACb,MAAM,UAAU,GAA4B;YAC1C,CAAC,qBAAqB,EAAE,CAAC,CAAC;YAC1B,CAAC,+BAA+B,EAAE,GAAG,CAAC;YACtC,CAAC,aAAa,EAAE,GAAG,CAAC;SACrB,CAAC;QACF,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,UAAU,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;gBAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAC,MAAM;YAAC,CAAC;QACzG,CAAC;QACD,IAAI,GAAG,IAAI,CAAC;YAAE,GAAG,GAAG,OAAO,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAID,mHAAmH;AACnH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,UAAU,EAAE,OAAO,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;AAC9J,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Panel styles, injected once into the document by <UpliftPanel>. Scoped under `.uplift`.
3
+ * D15: every colour, font and radius is a `--u-*` custom property. Defaults below sit at
4
+ * zero specificity (`:where`) so a host overrides them with any ordinary rule, e.g.
5
+ * `.uplift { --u-bg: var(--card); --u-text: var(--foreground); }`.
6
+ * `--u-accent`/`--u-accent-ink` paint primary buttons (Send, Add client); `--u-highlight`/`--u-highlight-soft`
7
+ * paint emphasis (sparkle, draft labels, selected ring, focus, purpose icons) and default to the accent, so a
8
+ * host whose buttons are neutral and whose brand is a colour (PulseKit) can split them.
9
+ * D16: layout answers to the panel's own width through a container query, never the viewport.
10
+ */
11
+ export declare const STYLE_ELEMENT_ID = "uplifted-react-styles";
12
+ export declare const upliftStyles = "\n:where(.uplift){\n --u-bg:#ffffff;--u-surface:#ffffff;--u-surface-2:#fafafa;--u-surface-3:#f4f4f5;\n --u-text:#262626;--u-muted:#666666;--u-border:rgba(0,0,0,.08);\n --u-accent:#0f8a63;--u-accent-soft:#e3f5ee;--u-accent-ink:#ffffff;--u-link:#0b6b4c;\n --u-highlight:var(--u-accent);--u-highlight-soft:var(--u-accent-soft);\n --u-gold:#c9971c;--u-gold-hi:#f7e2a0;--u-gold-ink:#8a6410;--u-gold-ink-hi:#c9971c;\n --u-seg-l:88%;\n --u-danger:#c10007;--u-warn:#bb4d00;--u-out:#eaf1ff;--u-out-ink:#12244d;\n --u-font:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Inter,sans-serif;--u-radius:10px;\n}\n:where(.uplift[data-theme=\"dark\"],[data-theme=\"dark\"] .uplift){\n --u-bg:#111111;--u-surface:#111111;--u-surface-2:#0a0a0a;--u-surface-3:#1a1a1a;\n --u-text:#f5f5f5;--u-muted:#9a9a9a;--u-border:rgba(255,255,255,.08);\n --u-accent:#70d7b0;--u-accent-soft:#17342a;--u-accent-ink:#062a1e;--u-link:#70d7b0;\n --u-gold:#d9a830;--u-gold-hi:#fff1b8;--u-gold-ink:#d9a830;--u-gold-ink-hi:#f3d47a;\n --u-seg-l:26%;\n --u-danger:#ff6467;--u-warn:#ffb900;--u-out:#1d2b4a;--u-out-ink:#e3ebff;\n}\n.uplift,.uplift *,.uplift *::before,.uplift *::after{box-sizing:border-box}\n.uplift{font:15px/1.45 var(--u-font);color:var(--u-text);background:var(--u-bg);border:1px solid var(--u-border);border-radius:14px;overflow:hidden;container-type:inline-size;container-name:panel;position:relative;-webkit-font-smoothing:antialiased}\n:where(.uplift) button{font:inherit;color:inherit;cursor:pointer}\n:where(.uplift) button:disabled{cursor:not-allowed}\n.uplift :focus-visible{outline:2px solid var(--u-highlight);outline-offset:2px;border-radius:6px}\n.uplift h2,.uplift h3,.uplift h4,.uplift p{margin:0}\n.u-sp{flex:1}\n.u-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n.u-pill{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--u-border);background:var(--u-surface-2);border-radius:999px;padding:4px 10px;font-size:13px;color:var(--u-muted)}\n.u-pill b{color:var(--u-text);font-weight:600}\n.u-linkbtn{background:none;border:0;padding:4px 2px;color:var(--u-link);font-weight:600;text-decoration:underline;text-underline-offset:3px}\n.u-split{display:grid;grid-template-columns:320px minmax(0,1fr);height:min(max(520px,62.5cqw),86vh)}\n.u-split>*{min-height:0}\n.u-list{overflow:hidden}\n.u-pane{overflow:hidden}\n.u-iconbtn{display:inline-grid;place-items:center;width:34px;height:34px;border:1px solid var(--u-border);background:var(--u-bg);border-radius:8px;color:var(--u-muted);padding:0}\n.u-iconbtn:hover{color:var(--u-text)}\n.u-iconbtn-pair{width:auto;padding:0 9px;display:inline-flex;align-items:center;gap:4px}\n.u-ai-spark{display:inline-flex;color:var(--u-highlight)}\n.u-iconbtn .u-ai-spark svg{width:14px;height:14px}\n.u-iconbtn svg{width:16px;height:16px}\n.u-iconbtn[aria-pressed=\"true\"]{color:var(--u-text);background:var(--u-surface-2)}\n.u-bulkbtn svg{width:14px;height:14px}\n.uplift.u-full{position:fixed;inset:0;z-index:2147483000;border-radius:0;border:0;display:flex;flex-direction:column}\n.uplift.u-full .u-split{flex:1;height:auto;min-height:0}\n.u-back{display:none;border:1px solid var(--u-border);background:var(--u-bg);border-radius:8px;padding:6px 10px;font-size:16px;min-height:36px;align-items:center;flex:none}\n.u-list{border-right:1px solid var(--u-border);display:flex;flex-direction:column;min-width:0}\n/* inbox toolbar: native Uplift's collapsed search + segmented sort + Bulk generate */\n.u-toolbar{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--u-border)}\n.u-search{position:relative;flex:0 1 32px;min-width:32px;display:flex;align-items:center;cursor:pointer;transition:flex-basis .2s ease,flex-grow .2s ease}\n.u-search-open{flex:1 1 140px;cursor:auto}\n.u-search svg{position:absolute;left:9px;width:14px;height:14px;color:var(--u-muted);pointer-events:none}\n.u-search input{width:100%;min-height:32px;padding:6px 10px 6px 30px;border-radius:999px;border:1px solid var(--u-border);background:var(--u-surface-2);font:inherit;font-size:13px;color:var(--u-text)}\n.u-search:not(.u-search-open) input{cursor:pointer;padding-right:0}\n.u-search:not(.u-search-open) input::placeholder{opacity:0}\n.u-search input:focus{outline:none;border-color:var(--u-accent);background:var(--u-bg)}\n.u-search input::-webkit-search-cancel-button{cursor:pointer}\n.u-sortgroup{display:inline-flex;align-items:center;padding:2px;border-radius:999px;background:var(--u-surface-2);flex:none}\n.u-sortgroup button{border:0;background:none;border-radius:999px;padding:4px 9px;font-size:12px;font-weight:600;color:var(--u-muted);min-height:28px;white-space:nowrap}\n.u-sortgroup button:hover{color:var(--u-text)}\n.u-sortgroup button[aria-pressed=\"true\"]{background:var(--u-bg);color:var(--u-text);box-shadow:0 1px 2px rgba(0,0,0,.08),0 0 0 1px var(--u-border)}\n.u-toolbar button.u-bulkbtn{margin-left:auto;display:inline-flex;align-items:center;gap:1px;border:0;border-radius:999px;background:none;color:var(--u-muted);padding:0 6px;min-height:32px;flex:none}\n.u-toolbar button.u-bulkbtn:hover:not(:disabled){color:var(--u-accent);background:var(--u-surface-2)}\n.u-toolbar button.u-bulkbtn:disabled{opacity:.45}\n.u-rows{list-style:none;margin:0;padding:0;overflow:auto;flex:1;min-height:0}\n.u-rows li{display:flex;flex-wrap:wrap;align-items:stretch;border-bottom:1px solid var(--u-border)}\n.u-row-open{flex:1;min-width:0;text-align:left;border:0;background:transparent;padding:11px 12px;display:grid;grid-template-columns:36px minmax(0,1fr);gap:2px 10px;min-height:64px}\n.u-av{grid-row:span 3;width:36px;height:36px;border-radius:999px;display:grid;place-items:center;font-size:13px;font-weight:700;color:#fff}\n.u-av.u-av-sm{grid-row:auto;width:32px;height:32px}\n.u-r-top{display:flex;gap:6px;align-items:baseline;min-width:0}\n.u-r-name{font-weight:600;font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.u-r-time{margin-left:auto;font-size:12.5px;color:var(--u-muted);flex:none}\n.u-r-line{font-size:13.5px;color:var(--u-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.u-r-tags{display:flex;flex-wrap:wrap;gap:4px}\n.u-tag{font-size:12px;font-weight:600;border-radius:999px;padding:1px 8px;border:1px solid var(--u-border);color:var(--u-muted);background:var(--u-surface-2)}\n.u-tag.u-need{color:var(--u-danger);border-color:color-mix(in srgb,var(--u-danger) 35%,transparent)}\n.u-tag.u-ok{color:var(--u-link);border-color:color-mix(in srgb,var(--u-highlight) 35%,transparent)}\n.u-tag.u-warn{color:var(--u-warn);border-color:color-mix(in srgb,var(--u-warn) 35%,transparent)}\n.u-list-foot{padding:10px 12px;font-size:13px;color:var(--u-muted)}\n.u-skel{height:12px;border-radius:6px;background:var(--u-surface-3);margin:6px 0}\n.u-skel-row{padding:14px 12px;border-bottom:1px solid var(--u-border)}\n.u-state{padding:22px 16px;display:flex;flex-direction:column;gap:8px;align-items:flex-start;font-size:14.5px;color:var(--u-muted)}\n.u-state h3{font-size:16px;color:var(--u-text)}\n.u-state p{max-width:52ch}\n.u-pane{display:flex;flex-direction:column;min-width:0}\n.u-pane-head{display:flex;align-items:center;gap:10px;padding:11px 16px;border-bottom:1px solid var(--u-border)}\n.u-who{display:flex;flex-direction:column;min-width:0}\n.u-who strong{font-size:15px}\n.u-who small{font-size:13px;color:var(--u-muted)}\n.u-chan{margin-left:auto;font-size:13px;color:var(--u-muted)}\n.u-feed{flex:1;overflow:auto;padding:14px 16px;display:flex;flex-direction:column;gap:8px;background:var(--u-surface-2);min-height:200px}\n.u-tpl-chip{display:inline-flex;align-items:center;gap:4px;margin-left:6px;border:1px solid var(--u-border);border-radius:999px;padding:0 7px;font-size:11px;color:var(--u-muted);background:var(--u-bg);min-height:18px}\n.u-bub.u-tpl-shown{opacity:.85;border:1px dashed color-mix(in srgb,var(--u-out-ink) 50%,transparent)}\n.u-day{align-self:center;font-size:12px;color:var(--u-muted);background:var(--u-bg);border:1px solid var(--u-border);padding:2px 10px;border-radius:999px}\n.u-older{align-self:center;border:1px solid var(--u-border);background:var(--u-bg);border-radius:999px;padding:5px 12px;font-size:13px;color:var(--u-muted);min-height:32px}\n.u-ev{align-self:center;max-width:92%;display:flex;gap:8px;align-items:flex-start;font-size:13.5px;background:var(--u-bg);border:1px solid var(--u-border);border-radius:10px;padding:8px 11px}\n.u-ev svg{width:16px;height:16px;flex:none;margin-top:2px;color:var(--u-muted)}\n.u-ev b{font-weight:600}\n.u-ev .u-meta{color:var(--u-muted);font-size:12.5px}\n.u-bub{max-width:78%;padding:8px 12px;border-radius:14px;font-size:14.5px;white-space:pre-wrap;overflow-wrap:anywhere}\n.u-bub.u-in{align-self:flex-start;background:var(--u-bg);border:1px solid var(--u-border);border-bottom-left-radius:4px}\n.u-bub.u-out{align-self:flex-end;background:var(--u-out);color:var(--u-out-ink);border-bottom-right-radius:4px}\n.u-bmeta{font-size:12px;color:var(--u-muted)}\n.u-bmeta.u-r{align-self:flex-end}\n/* ---- Composer footer (port of native ChatPage footer) ---- */\n.u-composer{display:flex;flex-direction:column;gap:8px;padding:10px 16px 12px;background:var(--u-surface-2);border-top:1px solid var(--u-border)}\n.u-composer>*:empty{display:none}\n.u-rail{align-self:center;display:inline-flex;align-items:center;gap:6px;border:0;background:transparent;color:var(--u-muted);font-size:12px;padding:2px 10px;border-radius:999px;min-height:24px}\n.u-rail:hover{color:var(--u-text);background:var(--u-surface-3)}\n.u-rail svg{width:14px;height:14px}\n.u-extras-wrap{position:relative;display:flex;flex-direction:column}\n.u-extras-wrap>.u-rail{align-self:flex-end}\n.u-extras-wrap>.u-rail[aria-expanded=\"true\"]{position:absolute;top:0;right:0;z-index:1}\n.u-extras-wrap:has(>.u-rail[aria-expanded=\"true\"]) .u-ag-h{padding-right:34px}\n.u-extras{display:contents}\n.u-extras-off{display:none}\n/* draft grid (ComposerAssistant) */\n.u-ag{display:flex;flex-direction:column;gap:6px}\n.u-ag-h{display:flex;align-items:center;gap:2px}\n.u-ag-toggle{display:inline-flex;align-items:center;gap:8px;padding:4px 8px;border:0;background:transparent;color:var(--u-muted);font-size:12px;font-weight:600;border-radius:6px;min-height:28px}\n.u-ag-toggle:hover{background:var(--u-surface-3);color:var(--u-text)}\n.u-ag-spark{display:inline-flex;color:var(--u-highlight)}.u-ag-spark svg{width:12px;height:12px}\n.u-ag-label{letter-spacing:.02em}\n.u-ag-chev{display:inline-flex;color:var(--u-muted);transition:transform .15s}.u-ag-chev svg{width:14px;height:14px}\n.u-ag-chev-open{transform:rotate(180deg)}\n.u-ag-by{font-size:12px;color:var(--u-muted);margin-left:6px}\n.u-ag-regen{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:0;background:transparent;color:var(--u-muted);border-radius:6px;min-width:24px;min-height:24px}\n.u-ag-regen svg{width:11px;height:11px}\n.u-ag-regen:hover:not(:disabled){color:var(--u-highlight);background:var(--u-surface-3)}\n.u-ag-regen:disabled{opacity:.5}\n.u-ag-spinning svg{animation:u-spin 1s linear infinite}\n@keyframes u-spin{to{transform:rotate(360deg)}}\n.u-ag-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}\n.u-ag-cell{position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;min-height:56px;padding:10px 12px;background:var(--u-surface-2);border:1px solid transparent;border-radius:var(--u-radius);color:var(--u-text);text-align:left;transition:background .15s,transform .15s}\n.u-ag-cell:hover:not(:disabled){background:var(--u-bg)}\n/* Gold shimmer ring on finished drafts (Ian, 2026-10-11): a gradient pseudo-element masked to the edge. Reduced motion leaves a still ring. */\n.u-ag-cell:not(.u-ag-loading)::before{content:\"\";position:absolute;inset:-1px;border-radius:calc(var(--u-radius) + 1px);padding:1.5px;pointer-events:none;background:linear-gradient(110deg,var(--u-gold) 0%,var(--u-gold-hi) 25%,var(--u-gold) 50%,var(--u-gold-hi) 75%,var(--u-gold) 100%);background-size:250% 100%;animation:u-shimmer 3.2s linear infinite;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude}\n@keyframes u-shimmer{from{background-position:0% 50%}to{background-position:250% 50%}}\n.u-ag-cell[aria-checked=\"true\"]{box-shadow:0 0 0 2px var(--u-highlight)}\n.u-ag-cell[aria-checked=\"true\"]::before{display:none}\n.u-ag-lab{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;color:var(--u-highlight);text-transform:uppercase;letter-spacing:.04em}\n.u-ag-pencil{display:inline-flex;opacity:.6}.u-ag-pencil svg{width:10px;height:10px}\n.u-ag-txt{font-size:14px;line-height:1.35;color:var(--u-text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}\n.u-ag-loading{overflow:hidden;cursor:default;pointer-events:none;justify-content:center;align-items:center;border-color:var(--u-border)}\n.u-ag-loading-txt{position:relative;z-index:1;font-size:12px;color:var(--u-muted)}\n.u-ag-shimmer{position:absolute;inset:0;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.55) 50%,transparent 100%);animation:u-ag-sheen 1.4s infinite;transform:translateX(-100%)}\n@keyframes u-ag-sheen{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}\n.u-ag-empty{font-size:12.5px;color:var(--u-muted);padding:6px 0;display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n.u-ag-foot{font-size:12.5px;color:var(--u-muted);margin:0}\n/* attachments */\n.u-attach-row{align-items:center;gap:8px;flex-wrap:wrap}\n.u-limits{font-size:12px;color:var(--u-muted)}\n.u-limits-warn{color:var(--u-warn)}\n.u-chips{display:flex;flex-wrap:wrap;gap:8px;padding:4px 0}\n.u-chip{display:inline-flex;align-items:center;gap:6px;max-width:240px;padding:4px 8px;border-radius:999px;background:var(--u-bg);border:1px solid var(--u-border);font-size:12px;color:var(--u-muted)}\n.u-chip svg{width:13px;height:13px;flex:none}\n.u-chip-err{border-color:var(--u-danger);color:var(--u-danger)}\n.u-chip-errtxt{font-size:10px}\n.u-chip-thumb{width:22px;height:22px;object-fit:cover;border-radius:5px}\n.u-chip-name{max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.u-chip-x{display:inline-flex;align-items:center;border:0;background:none;color:inherit;padding:2px;min-height:0}\n.u-chip-x svg{width:12px;height:12px}\n.u-spin{animation:u-spin 1s linear infinite}\n.u-rec{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:9px;background:var(--u-bg);font-size:12px;color:var(--u-muted)}\n.u-rec-dot{width:8px;height:8px;border-radius:50%;background:#ff3b30;animation:u-rec-pulse 1.2s ease-in-out infinite}\n@keyframes u-rec-pulse{0%,100%{opacity:1}50%{opacity:.35}}\n.u-rec-btn{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--u-border);background:var(--u-bg);color:var(--u-text);border-radius:999px;width:28px;height:28px;min-height:0;padding:0}\n.u-rec-btn svg{width:14px;height:14px}\n.u-rec-done{background:var(--u-accent);color:var(--u-accent-ink);border-color:var(--u-accent)}\n.u-sms-note{font-size:12px;color:var(--u-warn)}\n/* editor row: + button, pill with the editor and the inline send/\u2728 */\n.u-c-row{display:flex;align-items:flex-end;gap:8px;width:100%}\n.u-attach-wrap{position:relative;flex:none}\n.u-attach-btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;min-height:0;padding:0;margin-bottom:3px;border:1px solid var(--u-border);border-radius:999px;background:var(--u-bg);color:var(--u-muted);transition:color .15s,background .15s}\n.u-attach-btn svg{width:18px;height:18px}\n.u-attach-btn:hover:not(:disabled){color:var(--u-highlight);background:var(--u-highlight-soft)}\n.u-attach-btn:disabled{opacity:.45}\n.u-pill{position:relative;flex:1;min-width:0;display:flex;align-items:flex-end;gap:6px;background:var(--u-bg);border:1px solid var(--u-border);border-radius:14px;padding:4px 4px 4px 8px}\n.u-pill-grow{flex:1;min-width:0}\n.u-pill .u-editor{border:0;background:transparent;border-radius:0;padding:6px 4px;min-height:38px;max-height:220px;resize:none}\n.u-pill .u-editor:focus{outline:none}\n.u-pill:focus-within{border-color:var(--u-highlight)}\n/* Locked pill (stock intro, nothing to edit): gold shimmer ring like the draft cells. Reduced motion leaves a still ring. */\n.u-pill-locked{border-color:transparent}\n.u-pill-locked::before{content:\"\";position:absolute;inset:-1px;border-radius:15px;padding:1.5px;pointer-events:none;background:linear-gradient(110deg,var(--u-gold) 0%,var(--u-gold-hi) 25%,var(--u-gold) 50%,var(--u-gold-hi) 75%,var(--u-gold) 100%);background-size:250% 100%;animation:u-shimmer 3.2s linear infinite;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude}\n.u-pill-locked:focus-within{border-color:transparent}\n.u-editor-locked{cursor:default;caret-color:transparent}\n.u-send-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;min-height:0;padding:0;flex:none;border-radius:999px;border:0;background:var(--u-accent);color:var(--u-accent-ink);transition:transform .15s,opacity .15s}\n.u-send-btn svg{width:15px;height:15px;stroke:var(--u-accent-ink)}\n.u-send-btn:hover:not(:disabled){transform:translateY(-1px)}\n.u-send-btn:disabled{opacity:.4;cursor:not-allowed}\n.u-gen-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;min-height:0;padding:0;flex:none;border:0;border-radius:999px;background:transparent;color:var(--u-highlight);transition:background .15s}\n.u-gen-btn svg{width:16px;height:16px}\n.u-gen-btn:hover:not(:disabled){background:var(--u-highlight-soft)}\n.u-gen-btn:disabled{opacity:.4}\n.u-menu-backdrop{position:fixed;inset:0;z-index:40}\n.u-menu{position:absolute;bottom:calc(100% + 6px);z-index:41;display:flex;flex-direction:column;min-width:150px;padding:4px;border-radius:12px;background:var(--u-bg);border:1px solid var(--u-border);box-shadow:0 10px 30px rgba(0,0,0,.18)}\n.u-menu-left{left:0}.u-menu-right{right:0}\n.u-menu-title{padding:6px 12px 4px;font-size:11.5px;font-weight:600;color:var(--u-muted)}\n.u-menu-titlerow{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 6px 2px 0}\n.u-menu-titlerow .u-menu-title{padding:2px 12px 2px}\n.u-menu-cfg{display:inline-flex;align-items:center;justify-content:center;padding:4px;min-width:24px;min-height:24px;border:0;background:none;color:var(--u-muted);border-radius:6px}\n.u-menu-cfg svg{width:13px;height:13px}\n.u-menu-cfg:hover{color:var(--u-text);background:var(--u-surface-3)}\n/* proactive options editor */\n.u-po-help{font-size:13.5px;color:var(--u-muted);margin:0 0 10px}\n.u-po-list{display:flex;flex-direction:column;gap:10px}\n.u-po-row{border:1px solid var(--u-border);border-radius:12px;padding:10px;display:flex;flex-direction:column;gap:8px;background:var(--u-surface-2)}\n.u-po-top{display:flex;align-items:center;gap:6px}\n.u-po-label{flex:1;min-width:0;border:1px solid var(--u-border);border-radius:8px;padding:7px 10px;font:inherit;font-size:14px;background:var(--u-bg);color:var(--u-text)}\n.u-po-text{width:100%;border:1px solid var(--u-border);border-radius:8px;padding:7px 10px;font:inherit;font-size:13.5px;background:var(--u-bg);color:var(--u-text);resize:vertical}\n.u-po-iconwrap{position:relative;flex:none}\n.u-po-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;min-height:0;padding:0;border:1px solid var(--u-border);border-radius:8px;background:var(--u-bg);color:var(--u-text)}\n.u-po-iconbtn svg{width:15px;height:15px}\n.u-po-iconbtn:disabled{opacity:.4}\n.u-po-iconbtn-on{border-color:var(--u-highlight);box-shadow:0 0 0 1px var(--u-highlight);color:var(--u-highlight)}\n.u-po-remove:hover{color:var(--u-danger);border-color:var(--u-danger)}\n.u-po-iconpick{position:absolute;top:calc(100% + 4px);left:0;z-index:5;display:grid;grid-template-columns:repeat(6,32px);gap:4px;padding:6px;background:var(--u-bg);border:1px solid var(--u-border);border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,.18)}\n.u-po-add{margin-top:10px;border:1px dashed var(--u-border);background:transparent;border-radius:9px;padding:8px 12px;font-weight:600;color:var(--u-link);min-height:38px;width:100%}\n.u-po-actions{display:flex;gap:8px;align-items:center;margin-top:12px;flex-wrap:wrap}\n.u-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:0;border-radius:8px;background:none;text-align:left;font-size:14px;color:var(--u-text);min-height:36px}\n.u-menu-item:hover{background:var(--u-surface-3)}\n.u-menu-purpose svg{width:14px;height:14px;color:var(--u-highlight);flex:none}\n/* inbox rows (native ClientRow) */\n.u-row-open{position:relative}\n.u-r-ind{position:absolute;left:3px;top:50%;transform:translateY(-50%);width:20px;display:grid;place-items:center}\n.u-rows .u-row-open{padding-left:26px}\n.u-r-dot{width:8px;height:8px;border-radius:50%;background:var(--u-highlight)}\n.u-r-badge{min-width:18px;height:18px;padding:0 5px;border-radius:999px;background:var(--u-highlight);color:#fff;font-size:11px;font-weight:700;display:grid;place-items:center}\n/* The open conversation is the only row with a colour: a clear shade and an accent bar on the left\n edge, like WhatsApp's selected chat. Unread shows by the dot and bold name, never a tint. Built\n from the text colour so it reads on any host theme, light or dark. */\n.u-rows li:has(.u-row-open[aria-current=\"true\"]){background:color-mix(in srgb,var(--u-text) 8%,var(--u-bg));box-shadow:inset 3px 0 0 var(--u-accent)}\n.u-rows li:has(.u-row-open[aria-current=\"true\"]) .u-row-open{background:transparent}\n.u-r-name-unread{font-weight:700}\n.u-r-follow,.u-r-fail{display:inline-flex;align-items:center;flex:none}\n.u-r-follow svg,.u-r-fail svg{width:13px;height:13px}\n.u-r-follow{color:var(--u-warn)}\n.u-r-fail{color:var(--u-danger)}\n.u-r-prev{display:inline-flex;align-items:center;gap:5px;max-width:100%}\n.u-r-pico{display:inline-flex;flex:none}.u-r-pico svg{width:11px;height:11px}\n.u-r-prev-in .u-r-ptxt{color:var(--u-text)}\n.u-r-prev-in .u-r-pico{color:var(--u-highlight)}\n.u-r-prev-out .u-r-ptxt,.u-r-prev-out .u-r-pico{color:var(--u-muted)}\n.u-r-prev-ev .u-r-ptxt,.u-r-prev-ev .u-r-pico{color:var(--u-muted);font-style:italic}\n.u-r-ptxt{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}\n.u-r-hosttags{flex:1 0 100%;display:flex;flex-wrap:wrap;gap:4px;padding:0 12px 10px 72px;margin-top:-6px}\n.u-tag-connect{cursor:pointer;font:inherit;font-size:12px;font-weight:600;line-height:inherit}\n.u-tag-connect:hover{border-color:var(--u-highlight);color:var(--u-highlight);background:var(--u-highlight-soft)}\n.u-r-quick{flex:1 0 100%;display:flex;justify-content:flex-end;align-items:center;min-width:0;padding:0 12px 10px 72px}\n.u-qsend{display:inline-flex;align-items:center;gap:6px;max-width:100%;border:1px solid var(--u-highlight);background:var(--u-highlight);color:#fff;border-radius:999px;padding:4px 11px;font-size:12px;font-weight:600;min-height:26px}\n.u-qsend:hover:not(:disabled){filter:brightness(1.08)}\n/* Bulk generate states in the quick-send slot (native: Generating\u2026 / Generation failed) */\n.u-qsend.u-qsend-bulk{background:var(--u-surface-2);border-color:var(--u-border);color:var(--u-muted);cursor:default}\n.u-qsend-busy svg{width:12px;height:12px}\n/* Bulk generate sheet (native BulkGenerateModal) */\n.u-bulk-head{display:flex;align-items:flex-start;gap:10px;margin-bottom:6px}\n.u-bulk-spark{color:var(--u-highlight);display:grid;place-items:center;padding-top:9px}\n.u-bulk-spark svg{width:18px;height:18px}\n.u-bulk-titles{flex:1;min-width:0}\n.u-bulk-titles h3{margin:4px 0 2px;font-size:18px}\n.u-bulk-sub{margin:0;font-size:13.5px;color:var(--u-muted)}\n.u-bulk-sub .u-linkbtn{font-size:13px}\n.u-bulk-sec{margin-top:14px}\n.u-bulk-sechead{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}\n.u-bulk-sechead .u-linkbtn{font-size:13px}\n.u-bulk-label{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--u-muted)}\n.u-bulk-chips{display:flex;flex-wrap:wrap;gap:6px;max-height:180px;overflow:auto;padding:2px}\n.u-bulk-empty{font-size:13px;color:var(--u-muted)}\n.u-bulk-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--u-border);background:var(--u-bg);border-radius:999px;padding:3px 10px 3px 3px;font-size:13px;color:var(--u-muted);min-height:30px;max-width:100%}\n.u-bulk-chip-on{border-color:var(--u-highlight);background:var(--u-highlight-soft);color:var(--u-text)}\n.u-bulk-av{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:10px;font-weight:700;flex:none}\n.u-bulk-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.u-bulk-meta{font-size:11px;color:var(--u-muted)}\n.u-bulk-prompt{width:100%;box-sizing:border-box;border:1px solid var(--u-border);border-radius:10px;padding:10px 12px;font:inherit;font-size:14px;color:var(--u-text);background:var(--u-bg);resize:vertical}\n.u-bulk-prompt:focus{outline:none;border-color:var(--u-accent)}\n.u-bulk-hist{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:8px}\n.u-bulk-histlabel{font-size:12px;color:var(--u-muted)}\n.u-bulk-histbtn{border:1px solid var(--u-border);background:var(--u-surface-2);border-radius:999px;padding:3px 10px;font-size:12px;color:var(--u-text);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.u-bulk-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}\n.u-bulk-go{display:inline-flex;align-items:center;gap:6px}\n.u-bulk-go svg{width:14px;height:14px}\n/* Gold shimmer ring on a ready quick reply, same as the draft cells. Countdown, sending, sent and error states drop it. */\n.u-qsend{position:relative}\n.u-qsend:not(.u-qsend-count):not(.u-qsend-sending):not(.u-qsend-sent):not(.u-qsend-err):not(:disabled)::before{content:\"\";position:absolute;inset:-2px;border-radius:999px;padding:2px;pointer-events:none;background:linear-gradient(110deg,var(--u-gold) 0%,var(--u-gold-hi) 25%,var(--u-gold) 50%,var(--u-gold-hi) 75%,var(--u-gold) 100%);background-size:250% 100%;animation:u-shimmer 3.2s linear infinite;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude}\n.u-qsend svg{width:12px;height:12px;flex:none}\n.u-qsend-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.u-qsend-count{border-color:var(--u-warn);background:color-mix(in srgb,var(--u-warn) 12%,transparent);color:var(--u-warn)}\n.u-qsend-sent{border-color:var(--u-accent);background:var(--u-accent);color:var(--u-accent-ink)}\n.u-qsend-err{border-color:var(--u-danger);color:var(--u-danger);background:transparent}\n.u-qsend:disabled{opacity:.9}\n/* delivery receipts */\n.u-rcpt{display:inline-flex;align-items:center;margin-left:4px;color:var(--u-muted)}\n.u-rcpt svg{width:13px;height:13px}\n.u-rcpt-ok{color:var(--u-highlight)}\n.u-rcpt-bad{color:var(--u-danger)}\n/* inline reply drafts under the latest client message */\n.u-inl{align-self:flex-start;max-width:78%;display:flex;flex-direction:column;gap:6px;margin-top:2px}\n.u-inl-h{display:flex;align-items:center;gap:4px}\n.u-inl-toggle{display:inline-flex;align-items:center;gap:6px;border:0;background:transparent;color:var(--u-muted);font-size:12px;font-weight:600;padding:2px 6px;border-radius:6px;min-height:24px}\n.u-inl-toggle:hover{background:var(--u-surface-3);color:var(--u-text)}\n.u-inl-notnow{border:0;background:transparent;color:var(--u-muted);font-size:12px;padding:2px 6px;min-height:24px;border-radius:6px}\n.u-inl-notnow:hover{color:var(--u-text);background:var(--u-surface-3)}\n.u-inl-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;width:100%}\n.u-inl-cell{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:0;border:1px solid var(--u-border);background:var(--u-bg);border-radius:12px;padding:7px 10px;text-align:left;color:var(--u-text)}\n/* Gold shimmer ring, same as the composer's draft cells. Reduced motion leaves a still ring. */\n.u-inl-cell::before{content:\"\";position:absolute;inset:-1px;border-radius:13px;padding:1.5px;pointer-events:none;background:linear-gradient(110deg,var(--u-gold) 0%,var(--u-gold-hi) 25%,var(--u-gold) 50%,var(--u-gold-hi) 75%,var(--u-gold) 100%);background-size:250% 100%;animation:u-shimmer 3.2s linear infinite;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude}\n.u-inl-cell:hover{border-color:var(--u-highlight)}\n.u-inl-txt{font-size:13px;line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n/* Item action row (native InlineDrafts): under client messages, and inside activity cards. */\n.u-ia{align-self:flex-start;width:78%;display:flex;flex-direction:column;gap:6px;margin-top:2px}\n.u-ev .u-ia{width:100%;margin-top:6px}\n.u-ev>div{flex:1}\n.u-ev>div{min-width:0}\n.u-ev .u-ia svg{width:13px;height:13px;margin-top:0}\n.u-ia-h{display:flex;flex-wrap:wrap;align-items:center;gap:2px;margin-left:-6px}\n.u-ia-h .u-inl-toggle svg{width:13px;height:13px}\n.u-ia-ai{display:flex;flex-direction:column;gap:6px;border:1px solid var(--u-border);background:var(--u-bg);border-radius:12px;padding:10px;min-width:min(420px,100%)}\n.u-ia-ai-label{font-size:12.5px;font-weight:700}\n.u-ia-ai-hint{font-size:12px;color:var(--u-muted)}\n.u-ia-ai-note{font-size:12px;color:var(--u-warn);background:color-mix(in srgb,var(--u-warn) 10%,transparent);border-radius:8px;padding:6px 8px}\n.u-ia-ai textarea{font:inherit;font-size:13.5px;color:var(--u-text);background:var(--u-surface-2);border:1px solid var(--u-border);border-radius:8px;padding:8px 10px;resize:vertical;min-height:64px}\n.u-ia-ai-row{display:flex;align-items:center;gap:10px;font-size:12px}\n.u-ia-ai-count{color:var(--u-muted);font-variant-numeric:tabular-nums}\n.u-ia-ai-err{color:var(--u-danger)}\n.u-cx-h4{display:flex;align-items:center;gap:6px}\n.u-cx-info{display:inline-grid;place-items:center;width:22px;height:22px;border:0;border-radius:999px;background:transparent;color:var(--u-muted);padding:0;cursor:pointer}\n.u-cx-info:hover{color:var(--u-highlight);background:var(--u-highlight-soft)}\n.u-cx-info svg{width:15px;height:15px}\n.u-cx-head{display:flex;align-items:center;gap:10px}\n.u-cx-mark{display:inline-grid;place-items:center;width:30px;height:30px;border-radius:999px;color:#fff;flex:none}\n.u-cx-rule{margin:10px 0}\n.u-cx-rule h4{margin:0 0 3px;font-size:14px}\n.u-cx-rule p{margin:0;font-size:13.5px;line-height:1.5;color:var(--u-muted)}\n.u-cx-sec{display:block;margin-top:14px;font-size:13px;font-weight:600}\n.u-cx-mocks{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:8px 0 10px}\n.u-cx-col{display:flex;flex-direction:column;gap:4px;min-width:0}\n.u-cx-label{font-size:11.5px;font-weight:500;color:var(--u-muted)}\n.u-cx-phone{border:1px solid var(--u-border);border-radius:12px;padding:10px;display:flex;flex-direction:column;gap:8px;min-height:120px}\n.u-cx-coach{background:var(--u-surface-2)}\n.u-cx-coach-bub{align-self:flex-end;max-width:95%;background:var(--u-highlight);color:#fff;border-radius:12px;border-bottom-right-radius:4px;padding:8px 10px;font-size:12px;line-height:1.45}\n.u-cx-tpl{display:inline-block;margin-top:6px;padding:2px 8px;border-radius:999px;background:rgba(255,255,255,.22);font-size:10px;font-weight:500}\n.u-cx-client{background:#e5ddd5;border-color:#d5cdc4}\n.u-cx-client-bub{align-self:flex-start;max-width:95%;background:#fff;color:#1c1c1e;border-radius:12px;border-top-left-radius:4px;padding:8px 10px;font-size:12px;line-height:1.45;box-shadow:0 1px 1px rgba(0,0,0,.08)}\n.u-cx-link{display:block;margin-top:6px;color:#027eb5;font-weight:500}\n.u-cx-meta{font-size:10px;color:var(--u-muted);text-align:center;margin-top:auto}\n.u-cx-client .u-cx-meta{color:#7a7269}\n.u-cx-foot{font-size:12px;line-height:1.5;color:var(--u-muted)}\n.u-offer-who{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--u-muted);margin:2px 0 8px}\n.u-offer-avs{display:inline-flex}\n.u-offer-avs .u-av{border:2px solid var(--u-bg);margin-left:-6px}\n.u-offer-avs .u-av:first-child{margin-left:0}\n.u-offer-list{list-style:none;margin:10px 0;padding:0;display:flex;flex-direction:column;gap:7px;font-size:13.5px}\n.u-offer-list li{display:flex;gap:8px;align-items:flex-start}\n.u-offer-tick{display:inline-flex;color:var(--u-accent);flex:none;margin-top:2px}\n.u-offer-tick svg{width:15px;height:15px}\n.u-ai-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}\n.u-ai-plan{display:flex;align-items:center;gap:10px;flex-wrap:wrap;border:1px solid var(--u-border);border-radius:10px;padding:8px 11px;font-size:13px;margin:0 0 10px}\n.u-ai-plan .u-linkbtn{font-size:13px}\n.u-ai-err{color:var(--u-danger,#b42318);font-size:12.5px;width:100%}\n.u-ai-disclaimer{display:flex;gap:8px;align-items:flex-start;background:var(--u-highlight-soft);border-radius:10px;padding:9px 11px;font-size:12.5px;line-height:1.45;margin:6px 0 10px}\n.u-ai-disclaimer svg{width:15px;height:15px;flex:none;margin-top:2px;color:var(--u-highlight)}\n.u-ai-tabs{display:flex;flex-wrap:wrap;gap:4px;border-bottom:1px solid var(--u-border);margin-bottom:10px}\n.u-ai-tab{border:0;background:transparent;padding:7px 10px;font-size:13px;font-weight:600;color:var(--u-muted);border-bottom:2px solid transparent;margin-bottom:-1px;border-radius:0}\n.u-ai-tab-on{color:var(--u-text);border-bottom-color:var(--u-highlight)}\n.u-ai-body{display:flex;flex-direction:column;gap:14px}\n.u-ai-sec{display:flex;flex-direction:column;gap:6px}\n.u-ai-sec h4{margin:0;font-size:14px}\n.u-ai-area,.u-ai-input{font:inherit;font-size:13.5px;color:var(--u-text);background:var(--u-surface-2);border:1px solid var(--u-border);border-radius:8px;padding:8px 10px;width:100%;box-sizing:border-box}\n.u-ai-area{resize:vertical}\n.u-ai-hr{border:0;border-top:1px solid var(--u-border);margin:8px 0}\n.u-ai-form{display:flex;flex-direction:column;gap:6px;border:1px solid var(--u-border);border-radius:10px;padding:10px}\n.u-ai-form label{font-size:12.5px;font-weight:700}\n.u-ai-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}\n.u-ai-list li{border:1px solid var(--u-border);border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:3px}\n.u-ai-item-head{display:flex;align-items:center;gap:6px;font-size:13px}\n.u-ai-check{color:var(--u-accent);display:inline-flex}\n.u-ai-check svg{width:14px;height:14px}\n.u-ai-tags{display:flex;flex-wrap:wrap;gap:4px}\n.u-ai-k{font-size:11.5px;font-weight:700;color:var(--u-muted);text-transform:uppercase;letter-spacing:.04em}\n.u-ai-v{font-size:13.5px;white-space:pre-wrap}\n.u-ai-voice{display:flex;flex-direction:column;gap:6px}\n.u-ai-locked{border:1px dashed var(--u-border);border-radius:10px;padding:12px;font-size:13px;color:var(--u-muted)}\n.u-ai-locked strong{color:var(--u-text)}\n.u-ai-field{display:flex;flex-direction:column;gap:3px;margin-top:10px}\n.u-ai-field textarea{font:inherit;font-size:13.5px;color:var(--u-text);background:var(--u-surface-2);border:1px solid var(--u-border);border-radius:8px;padding:8px 10px;resize:vertical}\n.u-ai-labelrow{display:flex;justify-content:space-between;gap:8px;font-size:13px;font-weight:700}\n.u-ai-sub{margin-top:16px!important;font-size:12.5px;font-weight:700;color:var(--u-muted)}\n.u-ai-ok{color:var(--u-accent);font-size:13px;font-weight:600}\n.u-ai-more{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--u-border);font-size:13px;color:var(--u-muted)}\n.u-ia-save{border:1px solid var(--u-accent);background:var(--u-accent);color:var(--u-accent-ink);border-radius:8px;padding:5px 12px;font-weight:600;font-size:13px;min-height:30px}\n.u-ia-save:disabled{opacity:.5}\n/* WhatsApp closed window */\n.u-wa{display:flex;gap:8px;align-items:flex-start;padding:8px 12px;border-radius:9px;background:color-mix(in srgb,var(--u-warn) 10%,var(--u-bg));border:1px solid color-mix(in srgb,var(--u-warn) 35%,transparent);font-size:13px;line-height:1.4}\n.u-wa-ico{display:inline-flex;color:var(--u-warn);flex:none;margin-top:2px}.u-wa-ico svg{width:14px;height:14px}\n.u-wa-body{min-width:0}\n.u-wa-more{display:inline-flex;align-items:center;gap:2px;border:0;background:transparent;color:var(--u-link);font-weight:600;font-size:12.5px;padding:0 4px;min-height:0;margin-left:4px}\n.u-wa-more svg{width:12px;height:12px}\n.u-wa-why{margin:6px 0 0;color:var(--u-muted);font-size:12.5px}\n.u-ghost{display:flex;flex-direction:column;align-items:flex-end;gap:2px;opacity:.7}\n.u-ghost-bub{border:1px dashed color-mix(in srgb,var(--u-out-ink) 50%,transparent);background:color-mix(in srgb,var(--u-out) 60%,transparent)}\n.u-ghost-cut{font-weight:700}\n/* beginning of history */\n.u-hist-start{align-self:center;font-size:12px;color:var(--u-muted);padding:4px 0}\n/* header badges */\n.u-chan-badge{display:inline-flex;align-items:center;justify-content:center;position:absolute;right:-2px;bottom:-2px;width:16px;height:16px;border-radius:50%;color:#fff;border:2px solid var(--u-bg);box-sizing:content-box}\n.u-chan-wa{background:#25d366}\n.u-chan-sms{background:var(--u-highlight)}\n.u-r-av{grid-row:span 3;align-self:start}\n.u-r-av .u-av{grid-row:auto}\n.u-av-wrap{position:relative;display:inline-flex;flex:none}\n.u-head-status{margin-left:4px}\n/* attachments on thread messages */\n.u-att{display:flex;flex-wrap:wrap;gap:6px;max-width:78%}\n.u-att-out{align-self:flex-end;justify-content:flex-end}.u-att-in{align-self:flex-start}\n.u-att-img{border:0;background:none;padding:0;min-height:0;cursor:zoom-in}\n.u-att-img img{display:block;max-width:220px;max-height:220px;border-radius:12px;border:1px solid var(--u-border)}\n.u-att-desc{display:block;font-size:12px;color:var(--u-muted);max-width:220px}\n.u-att-video{display:block;max-width:280px;max-height:320px;border-radius:12px;background:#000;object-fit:contain}\n.u-att-audio{display:flex;flex-direction:column;gap:4px;max-width:300px}\n.u-att-player{width:100%;max-width:300px}\n.u-att-trans{font-size:13px;color:var(--u-muted);font-style:italic}\n.u-lightbox{position:fixed;inset:0;z-index:60;background:rgba(0,0,0,.85);display:grid;place-items:center;padding:24px}\n.u-lightbox img{max-width:100%;max-height:100%;border-radius:8px}\n.u-lightbox-x{position:absolute;top:16px;right:16px;width:40px;height:40px;border-radius:999px;border:0;background:rgba(255,255,255,.15);color:#fff;display:grid;place-items:center}\n.u-lightbox-x svg{width:18px;height:18px}\n.u-att-file{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;background:var(--u-bg);border:1px solid var(--u-border);font-size:13px;color:var(--u-link);text-decoration:none}\n.u-att-file svg{width:14px;height:14px}\n.u-editor{width:100%;border:1px solid var(--u-border);border-radius:var(--u-radius);padding:10px 12px;min-height:64px;font:inherit;font-size:14.5px;background:var(--u-bg);color:var(--u-text);resize:vertical}\n.u-editor::placeholder{color:var(--u-muted)}\n.u-editor-rich{min-height:64px;max-height:220px;overflow-y:auto;white-space:normal;word-break:break-word;line-height:1.5}\n.u-editor-rich:empty::before{content:attr(data-placeholder);color:var(--u-muted);pointer-events:none}\n.u-editor-rich[aria-disabled=\"true\"]{opacity:.6}\n/* Draft pills, ported from native: one per clause, hue hashed from the text, \u00D7 drops it. */\n.u-seg{display:inline;padding:1px 2px;margin:0 2px;border-radius:3px;background:hsl(var(--u-seg-h) 55% var(--u-seg-l));color:var(--u-text);font-weight:500;user-select:none;transition:opacity .15s ease}\n.u-seg:hover{opacity:.85}\n/* Stock intro: no pill highlight, the text itself shimmers gold (gradient clipped to the glyphs). Reduced motion leaves a still gold gradient. */\n.u-seg-lock{cursor:default;user-select:text;padding:0;margin:0;border-radius:0;font-weight:600;background:linear-gradient(110deg,var(--u-gold-ink) 0%,var(--u-gold-ink-hi) 30%,var(--u-gold-ink) 50%,var(--u-gold-ink-hi) 70%,var(--u-gold-ink) 100%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;animation:u-shimmer 4s linear infinite}\n.u-seg-lock:hover{opacity:1}\n.u-seg-x{display:inline-flex;align-items:center;justify-content:center;margin-left:4px;padding:0 8px;min-width:24px;min-height:22px;cursor:pointer;font-size:15px;font-weight:700;color:#111;background:rgba(255,200,0,.8);border-radius:999px;line-height:1;vertical-align:middle;touch-action:manipulation;-webkit-tap-highlight-color:transparent}\n.u-seg-x:hover,.u-seg-x:active,.u-seg-x:focus-visible{color:#fff;background:#c00;outline:none}\n.u-editor:disabled{opacity:.6}\n.u-send{border:0;background:var(--u-accent);color:var(--u-accent-ink);font-weight:700;border-radius:9px;padding:8px 16px;min-height:40px}\n.u-send:disabled{opacity:.45}\n.u-gen{border:1px solid var(--u-border);background:var(--u-bg);border-radius:9px;padding:8px 14px;font-weight:600;min-height:40px}\n.u-gen:disabled{opacity:.5}\n.u-note{margin-top:8px;border-radius:9px;padding:9px 12px;font-size:13.5px;display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center}\n.u-note-err{background:color-mix(in srgb,var(--u-danger) 9%,var(--u-bg));border:1px solid color-mix(in srgb,var(--u-danger) 35%,transparent)}\n.u-note-warn{background:color-mix(in srgb,var(--u-warn) 10%,var(--u-bg));border:1px solid color-mix(in srgb,var(--u-warn) 35%,transparent)}\n.u-note-ok{background:var(--u-highlight-soft)}\n.u-banner{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;padding:10px 16px;font-size:14px;border-bottom:1px solid var(--u-border);background:var(--u-accent-soft)}\n.u-headbtn{border:1px solid var(--u-border);background:var(--u-bg);border-radius:8px;padding:6px 11px;font-size:14px;font-weight:600;min-height:34px}\n.u-headbtn:disabled{opacity:.5}\n.u-connect{margin-left:4px;display:inline-flex;align-items:center;gap:7px;flex:none}\n/* AI settings + full screen: the right end of the conversation header (no panel header row). */\n.u-head-acts{margin-left:auto;display:inline-flex;align-items:center;gap:6px;flex:none}\n.u-chan ~ .u-head-acts{margin-left:6px}\n.u-pane-head-empty{justify-content:flex-end;min-height:62px;box-sizing:border-box}\n/* On wide panels the toolbar leaves them to the conversation header. */\n.u-toolbar-acts{display:none}\n.u-toolbar .u-addbtn{flex:none}\n.u-connect svg{flex:none}\n.u-example{width:100%;border:1px dashed var(--u-border);border-radius:12px;padding:12px;background:var(--u-surface-2);display:flex;flex-direction:column}\n.u-ex-lab{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--u-muted);margin-bottom:6px}\n.u-sheet-wrap{position:absolute;inset:0;background:rgba(10,10,10,.45);display:grid;place-items:center;padding:16px;z-index:5}\n.u-sheet{width:min(560px,100%);max-height:100%;overflow:auto;background:var(--u-bg);color:var(--u-text);border:1px solid var(--u-border);border-radius:16px;box-shadow:0 18px 50px rgba(0,0,0,.25);padding:20px;outline:none}\n.u-eyebrow{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--u-muted)}\n.u-sheet h3{font-size:21px;margin:6px 0 8px}\n.u-lede{font-size:14.5px;color:var(--u-muted)}\n.u-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px;align-items:center}\n.u-secondary{border:1px solid var(--u-border);background:var(--u-bg);border-radius:9px;padding:8px 14px;font-weight:600;min-height:40px}\n.u-steps{display:flex;gap:6px;margin-bottom:12px}\n.u-steps span{flex:1;height:4px;border-radius:999px;background:var(--u-surface-3)}\n.u-steps span.u-on{background:var(--u-highlight)}\n.u-plan{margin-top:14px;border:1px solid var(--u-highlight);border-radius:12px;padding:14px;background:var(--u-highlight-soft)}\n.u-plan-name{font-weight:700;font-size:15px}\n.u-plan-price{font-size:30px;font-weight:700;margin-top:2px}\n.u-plan-price small{font-size:15px;font-weight:500;color:var(--u-muted)}\n.u-plan-vs{font-size:13.5px;color:var(--u-muted)}\n.u-feats{margin:12px 0 0;padding-left:18px;font-size:14px}\n.u-feats li{margin:3px 0}\n.u-chanbox{margin-top:12px;border:1px solid var(--u-border);border-radius:12px;padding:11px 13px}\n.u-chanbox h4{font-size:15px}\n.u-chanbox p{font-size:14px;margin-top:4px;color:var(--u-text)}\n.u-tick{display:flex;gap:10px;align-items:flex-start;margin-top:12px;font-size:14.5px}\n.u-tick input{width:20px;height:20px;margin-top:1px;accent-color:var(--u-highlight)}\n.u-field{margin-top:12px;display:flex;flex-direction:column;gap:5px}\n.u-field>label,.u-field>span:first-child{font-size:13.5px;font-weight:600}\n.u-field select{border:1px solid var(--u-border);background:var(--u-bg);color:var(--u-text);border-radius:9px;padding:9px 11px;font:inherit;min-height:42px}\n.u-field input{border:1px solid var(--u-border);background:var(--u-bg);color:var(--u-text);border-radius:9px;padding:9px 11px;font:inherit;min-height:42px}\n.u-field input[aria-invalid=\"true\"]{border-color:var(--u-danger)}\n.u-hint{font-size:13px;color:var(--u-muted)}\n.u-err{font-size:13px;color:var(--u-danger)}\n.u-chanpick{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.u-chanpick button{border:1px solid var(--u-border);background:var(--u-bg);border-radius:10px;padding:9px;text-align:left;min-height:56px}\n.u-chanpick button[aria-checked=\"true\"]{border-color:var(--u-highlight);box-shadow:0 0 0 1px var(--u-highlight)}\n.u-chanpick b{display:block;font-size:14.5px}\n.u-chanpick small{font-size:12.5px;color:var(--u-muted)}\n@media (prefers-reduced-motion:reduce){.uplift *{transition:none!important;animation:none!important}}\n@container panel (max-width:759px){\n .u-cx-mocks{grid-template-columns:1fr}\n .u-inl-grid{grid-template-columns:1fr}\n .u-ia{width:100%}\n .u-split{grid-template-columns:1fr;height:min(80vh,720px)}\n .u-split.u-show-thread .u-list{display:none}\n .u-split:not(.u-show-thread) .u-pane{display:none}\n .u-back{display:inline-flex}\n .u-toolbar-acts{display:inline-flex;flex:none;margin-left:auto}\n .u-toolbar-acts .u-head-acts{margin-left:0}\n /* Phone widths: the toolbar wraps its buttons rather than cutting them off; the conversation header\n keeps name, Connect and the buttons on one line by dropping the phone number and Connect's label. */\n .u-toolbar{flex-wrap:wrap;row-gap:6px}\n .u-sortgroup button{padding:4px 7px}\n .u-pane-head{gap:8px;padding:10px 12px}\n .u-pane-head .u-chan{display:none}\n .u-who{flex:0 1 auto}\n .u-who strong,.u-who small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n .u-connect{padding:6px 9px}\n .u-connect span{display:none}\n .u-ag-grid{grid-template-columns:1fr}\n .u-c-actions .u-meta{flex-basis:100%}\n .u-sheet-wrap{padding:0}\n .u-sheet{width:100%;height:100%;border-radius:0}\n}\n";
13
+ /** Add the panel stylesheet to `doc` once. Safe to call on every render. */
14
+ export declare function injectStyles(doc?: Document | undefined): void;
15
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD,eAAO,MAAM,YAAY,458CA2gBxB,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,GAAE,QAAQ,GAAG,SAAkE,GAAG,IAAI,CAMrH"}