@inkandswitch/patchwork-pkg-base 0.0.111 → 0.0.113

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 (84) hide show
  1. package/module-settings-url +1 -1
  2. package/package.json +1 -1
  3. package/packages/account/dist/{AccountPicker-DCX77HQI.js → AccountPicker-L3IHAMPQ.js} +25 -18
  4. package/packages/account/dist/AccountPicker-L3IHAMPQ.js.map +7 -0
  5. package/packages/account/dist/index.js +1 -1
  6. package/packages/account/package.json +1 -1
  7. package/packages/account-history/dist/assets/{HistoryRecorder-TRWDhOKO.js → HistoryRecorder-mRdg9-Sa.js} +2 -2
  8. package/packages/account-history/dist/assets/{HistoryRecorder-TRWDhOKO.js.map → HistoryRecorder-mRdg9-Sa.js.map} +1 -1
  9. package/packages/account-history/dist/assets/{HistoryViewer-BmG0rAfK.js → HistoryViewer-yhYv3jqn.js} +2 -2
  10. package/packages/account-history/dist/assets/{HistoryViewer-BmG0rAfK.js.map → HistoryViewer-yhYv3jqn.js.map} +1 -1
  11. package/packages/account-history/dist/assets/{NotebookViewer-DZ_ZQU5x.js → NotebookViewer-CLhIU0hN.js} +2 -2
  12. package/packages/account-history/dist/assets/{NotebookViewer-DZ_ZQU5x.js.map → NotebookViewer-CLhIU0hN.js.map} +1 -1
  13. package/packages/account-history/dist/assets/{context-wyGzlZK-.js → context-CgDNOWHV.js} +1 -4
  14. package/packages/account-history/dist/assets/{context-wyGzlZK-.js.map → context-CgDNOWHV.js.map} +1 -1
  15. package/packages/account-history/dist/assets/{index-DBnlnSMc.js → index-Bx2CKRPA.js} +5 -5
  16. package/packages/account-history/dist/assets/{index-DBnlnSMc.js.map → index-Bx2CKRPA.js.map} +1 -1
  17. package/packages/account-history/dist/index.js +1 -1
  18. package/packages/account-history/package.json +1 -1
  19. package/packages/chat/dist/{ChatRoot-1d-658Rr.js → ChatRoot-Ly8PORLd.js} +704 -696
  20. package/packages/chat/dist/{context-tool-iP64Oz6H.js → context-tool-DHIbdY80.js} +2 -2
  21. package/packages/chat/dist/{index-Dm_2jZcu.js → index-fGaJgJ-s.js} +3 -3
  22. package/packages/chat/dist/index.js +1 -1
  23. package/packages/chat/dist/{tool-BmNd5mrj.js → tool-CpslbjKC.js} +1 -1
  24. package/packages/chat/package.json +1 -1
  25. package/packages/codemirror-base/dist/tool.js +1 -1
  26. package/packages/codemirror-base/dist/tool.js.map +1 -1
  27. package/packages/codemirror-base/package.json +1 -1
  28. package/packages/comments-view/dist/assets/{main-wSSvAVfi.js → main-IR1Yfgas.js} +14 -7
  29. package/packages/comments-view/dist/assets/main-IR1Yfgas.js.map +1 -0
  30. package/packages/comments-view/dist/index.js +3 -3
  31. package/packages/comments-view/package.json +1 -1
  32. package/packages/drafts/dist/assets/main-CG9HOCai.js.map +1 -1
  33. package/packages/drafts/package.json +1 -1
  34. package/packages/file/dist/index.js +1 -1
  35. package/packages/file/dist/{tool-Bt8I8T2-.js → tool-DMegb4Cw.js} +814 -806
  36. package/packages/file/dist/tool-DMegb4Cw.js.map +1 -0
  37. package/packages/file/dist/{typescript-language-server-Db4173Y5.js → typescript-language-server-Cx5RlH3z.js} +2 -2
  38. package/packages/file/dist/{typescript-language-server-Db4173Y5.js.map → typescript-language-server-Cx5RlH3z.js.map} +1 -1
  39. package/packages/file/package.json +1 -1
  40. package/packages/history-view/dist/assets/{HistoryTimeline-Bo-BTf2A.js → HistoryTimeline-DOndzpUR.js} +15 -8
  41. package/packages/history-view/dist/assets/HistoryTimeline-DOndzpUR.js.map +1 -0
  42. package/packages/history-view/dist/assets/{index-B5Afrk9Y.js → index-D7nqWI0b.js} +2 -2
  43. package/packages/history-view/dist/assets/{index-B5Afrk9Y.js.map → index-D7nqWI0b.js.map} +1 -1
  44. package/packages/history-view/dist/index.js +1 -1
  45. package/packages/history-view/package.json +1 -1
  46. package/packages/settings/dist/assets/{FrameConfigurator-DVRBzIR-.js → FrameConfigurator-C0ZRifTs.js} +2 -2
  47. package/packages/settings/dist/assets/FrameConfigurator-C0ZRifTs.js.map +1 -0
  48. package/packages/settings/dist/index.js +1 -1
  49. package/packages/settings/package.json +1 -1
  50. package/packages/sideboard/dist/account-bar-67PDNT3H.js +2 -0
  51. package/packages/sideboard/dist/{chunk-25X3B3RC.js → chunk-6KORX3GC.js} +2 -2
  52. package/packages/sideboard/dist/chunk-FFQGRRLJ.js +2 -0
  53. package/packages/sideboard/dist/chunk-FFQGRRLJ.js.map +7 -0
  54. package/packages/sideboard/dist/{chunk-H6GFMJFM.js → chunk-XIUFUJKM.js} +2 -2
  55. package/packages/sideboard/dist/{chunk-H6GFMJFM.js.map → chunk-XIUFUJKM.js.map} +1 -1
  56. package/packages/sideboard/dist/document-list-panel-SPPMZDMX.js +2 -0
  57. package/packages/sideboard/dist/index.js +1 -1
  58. package/packages/sideboard/dist/sideboard/sideboard.js +1 -1
  59. package/packages/sideboard/package.json +1 -1
  60. package/packages/sync-indicator/dist/assets/SyncIndicator-oVMcVRXg.js.map +1 -1
  61. package/packages/sync-indicator/package.json +1 -1
  62. package/packages/threepane/dist/IsolatedDocumentArea-E3VEPUEG.js +2 -0
  63. package/packages/threepane/dist/{PatchworkFrame-22UEOQ6E.js → PatchworkFrame-HCSYM5W5.js} +2 -2
  64. package/packages/threepane/dist/{chunk-U4IJVHXK.js → chunk-HXEHZ5WC.js} +7 -7
  65. package/packages/threepane/dist/chunk-HXEHZ5WC.js.map +7 -0
  66. package/packages/threepane/dist/index.js +1 -1
  67. package/packages/threepane/package.json +1 -1
  68. package/plugin-registry-url +1 -1
  69. package/packages/account/dist/AccountPicker-DCX77HQI.js.map +0 -7
  70. package/packages/comments-view/dist/assets/main-wSSvAVfi.js.map +0 -1
  71. package/packages/file/dist/tool-Bt8I8T2-.js.map +0 -1
  72. package/packages/history-view/dist/assets/HistoryTimeline-Bo-BTf2A.js.map +0 -1
  73. package/packages/settings/dist/assets/FrameConfigurator-DVRBzIR-.js.map +0 -1
  74. package/packages/sideboard/dist/account-bar-JHI3FZZT.js +0 -2
  75. package/packages/sideboard/dist/chunk-FEMULUBJ.js +0 -2
  76. package/packages/sideboard/dist/chunk-FEMULUBJ.js.map +0 -7
  77. package/packages/sideboard/dist/document-list-panel-SEKNECHI.js +0 -2
  78. package/packages/threepane/dist/IsolatedDocumentArea-5WRK3TWL.js +0 -2
  79. package/packages/threepane/dist/chunk-U4IJVHXK.js.map +0 -7
  80. /package/packages/sideboard/dist/{account-bar-JHI3FZZT.js.map → account-bar-67PDNT3H.js.map} +0 -0
  81. /package/packages/sideboard/dist/{chunk-25X3B3RC.js.map → chunk-6KORX3GC.js.map} +0 -0
  82. /package/packages/sideboard/dist/{document-list-panel-SEKNECHI.js.map → document-list-panel-SPPMZDMX.js.map} +0 -0
  83. /package/packages/threepane/dist/{IsolatedDocumentArea-5WRK3TWL.js.map → IsolatedDocumentArea-E3VEPUEG.js.map} +0 -0
  84. /package/packages/threepane/dist/{PatchworkFrame-22UEOQ6E.js.map → PatchworkFrame-HCSYM5W5.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { render as k, createComponent as y, insert as H, template as U } from "solid-js/web";
2
2
  import { createSignal as C, createEffect as m, onCleanup as S, Show as x } from "solid-js";
3
- import { C as T, s as _ } from "./ChatRoot-1d-658Rr.js";
4
- import { s as v, t as D } from "./index-Dm_2jZcu.js";
3
+ import { C as T, s as _ } from "./ChatRoot-Ly8PORLd.js";
4
+ import { s as v, t as D } from "./index-fGaJgJ-s.js";
5
5
  var L = /* @__PURE__ */ U("<div class=chat-context-empty>");
6
6
  const g = ["computer", "model"], A = ["computer"];
7
7
  function w(e) {
@@ -306,7 +306,7 @@ const J = [
306
306
  icon: "MessageSquare",
307
307
  supportedDatatypes: ["chitterchatter", "chat", "chitter"],
308
308
  async load() {
309
- return (await import("./tool-BmNd5mrj.js")).ChatTool;
309
+ return (await import("./tool-CpslbjKC.js")).ChatTool;
310
310
  }
311
311
  },
312
312
  {
@@ -317,7 +317,7 @@ const J = [
317
317
  name: "Chat",
318
318
  icon: "MessageSquare",
319
319
  async load() {
320
- return (await import("./tool-BmNd5mrj.js")).ChatComponent;
320
+ return (await import("./tool-CpslbjKC.js")).ChatComponent;
321
321
  }
322
322
  },
323
323
  {
@@ -330,7 +330,7 @@ const J = [
330
330
  icon: "MessageCircle",
331
331
  tags: ["context-tool"],
332
332
  async load() {
333
- const { ChatContextComponent: e } = await import("./context-tool-iP64Oz6H.js");
333
+ const { ChatContextComponent: e } = await import("./context-tool-DHIbdY80.js");
334
334
  return e;
335
335
  }
336
336
  },
@@ -1,5 +1,5 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var r=document.createElement("style");r.appendChild(document.createTextNode('.chat-root{--bg-dark: var(--editor-fill, var(--studio-fill, oklch(.15 .03 270)));--bg-darkest: var(--editor-fill-offset-20, var(--studio-fill-offset-20, oklch(.12 .02 270)));--bg-mid: var(--editor-fill-offset-10, var(--studio-fill-offset-10, oklch(.19 .03 270)));--bg-input: var(--editor-fill, var(--studio-fill, oklch(.17 .03 270)));--bg-hover: var(--editor-fill-offset-20, var(--studio-fill-offset-20, oklch(.22 .04 270)));--border: var(--editor-fill-offset-20, var(--studio-fill-offset-20, oklch(.28 .05 270)));--accent: var(--studio-primary-fill, var(--studio-primary, oklch(.55 .18 270)));--accent-line: var(--studio-primary-line, var(--editor-fill, var(--studio-fill, oklch(1 0 0))));--accent-text: var(--studio-primary-text, var(--accent));--accent-hover: color-mix(in oklch, var(--accent), var(--studio-line, black) 18%);--accent-soft: color-mix(in oklch, var(--accent), transparent 85%);--accent-fg: var(--accent-line);--theme: var(--accent);--text-primary: var(--studio-line, oklch(1 0 0));--text-secondary: var(--studio-line-offset-30, oklch(1 0 0 / .6));--text-muted: var(--studio-line-offset-50, oklch(1 0 0 / .4));--link: var(--studio-link-text, var(--studio-link, oklch(.75 .15 250)))}.chat-root{display:flex;flex-direction:row;position:absolute;inset:0;font-family:var(--studio-family-sans, system-ui,-apple-system,sans-serif);background:var(--bg-dark);color:var(--text-primary);box-sizing:border-box;font-size:var(--studio-font-size, 15px);overflow:hidden;user-select:text;-webkit-user-select:text;height:100%}.chat-context-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;text-align:center;padding:24px;color:var(--text-secondary, #888);font-family:var(--studio-family-sans, system-ui,-apple-system,sans-serif);font-size:var(--studio-font-size, 15px)}.chat-root *,.chat-root *:before,.chat-root *:after{box-sizing:border-box}.chat-root a{color:var(--link);text-decoration:underline}.chat-root a:hover{text-decoration:none}.chat-theme-btn{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:16px;padding:2px 6px;border-radius:4px;position:relative}.chat-theme-btn:hover,.chat-notify-btn:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-notify-btn{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);padding:2px 4px;border-radius:4px;display:flex;align-items:center;position:relative}.chat-notify-menu{display:none;position:absolute;top:100%;right:0;margin-top:4px;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;padding:8px;min-width:180px;z-index:var(--studio-layer-dropdown, 200)}.chat-notify-menu.show{display:block;transform-origin:top right;transition:opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) var(--studio-ease-out, cubic-bezier(.23, 1, .32, 1)),transform max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) var(--studio-ease-out, cubic-bezier(.23, 1, .32, 1))}@starting-style{.chat-notify-menu.show{opacity:0;transform:scale(.97)}}.chat-notify-menu-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 4px;font-size:13px;color:var(--text-secondary);cursor:var(--studio-cursor-pointer, pointer);border-radius:4px}.chat-notify-menu-row:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-notify-toggle{width:32px;height:18px;border-radius:9px;border:none;cursor:var(--studio-cursor-pointer, pointer);background:var(--bg-hover);position:relative;transition:background max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));flex-shrink:0}.chat-notify-toggle.on{background:var(--accent)}.chat-notify-toggle:after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-notify-toggle.on:after{transform:translate(14px)}.chat-presence-bar{padding:4px 16px;background:var(--bg-darkest);border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);display:flex;gap:8px;align-items:center;flex-shrink:0;min-height:24px;position:relative;z-index:50;overflow:visible}.chat-presence-user{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--text-secondary);transition:opacity max(1ms,calc(.2s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-presence-user.away{opacity:.9}.chat-presence-avatar{width:18px;height:18px;border-radius:50%;overflow:hidden;flex-shrink:0;background:var(--bg-hover);display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--text-muted)}.chat-presence-avatar img{width:100%;height:100%;object-fit:cover}.chat-messages{flex:1;overflow-y:auto;padding:8px 0;display:flex;flex-direction:column;min-height:0;height:100%;overflow:scroll}.chat-msg-group{padding:2px 16px;display:flex;gap:12px;position:relative}.chat-msg-group:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-avatar-col{width:40px;flex-shrink:0;padding-top:2px}.chat-avatar{width:40px;height:40px;border-radius:50%;background:var(--accent);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:700;color:var(--accent-fg);overflow:hidden;cursor:var(--studio-cursor-pointer, pointer);position:relative;user-select:none}.chat-avatar img{width:100%;height:100%;object-fit:cover}.chat-avatar-view{display:block;width:100%;height:100%}.chat-avatar-view img{width:100%;height:100%;object-fit:cover}.chat-avatar.gif-selfie,.chat-avatar.gif-selfie img{border-radius:4px}.chat-avatar.cat-ears:before{content:"";position:absolute;top:-6px;left:2px;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:12px solid var(--accent);z-index:2}.chat-avatar.cat-ears:after{content:"";position:absolute;top:-6px;right:2px;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:12px solid var(--accent);z-index:2}.chat-msg-body{flex:1;min-width:0}.chat-msg-header{display:flex;align-items:baseline;gap:8px}.chat-msg-name{font-weight:600;font-size:15px;color:var(--text-primary);cursor:var(--studio-cursor-pointer, pointer)}.chat-msg-name:hover{text-decoration:underline}.chat-msg-time{font-size:11px;color:var(--text-muted)}.chat-msg-text{color:var(--text-primary);line-height:1.45;margin-top:2px;white-space:pre-wrap;word-wrap:break-word}.chat-msg-text.emoji-only{font-size:2em;line-height:1.2}.chat-quick-replies{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.chat-quick-reply{font:inherit;font-size:.9em;cursor:var(--studio-cursor-pointer, pointer);padding:4px 10px;border-radius:var(--studio-radius-round, 999px);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--accent-line, currentColor);background:transparent;color:var(--accent-text, var(--text-primary))}.chat-quick-reply:hover:not(:disabled){background:var(--accent);color:var(--accent-fg)}.chat-quick-reply:disabled{opacity:var(--studio-disabled-opacity, .5);cursor:var(--studio-cursor-default, default)}.chat-msg-text.emoji-only .chat-emoticon-inline{height:2em}.chat-msg-text code:not(.shiki code):not(.chat-code-block code){background:var(--bg-hover);padding:1px 4px;border-radius:3px;font-family:ui-monospace,monospace;font-size:.9em}.chat-msg-text a{color:var(--link);text-decoration:underline}.chat-msg-text a:hover{text-decoration:none}.chat-msg-text.streaming:after{content:"";display:inline-block;width:6px;height:1em;background:var(--accent);margin-left:2px;vertical-align:text-bottom;border-radius:1px;animation:blink-cursor .8s step-end infinite}.chat-msg-text.streaming:empty:after{content:"";width:auto;height:auto;background:none;animation:none}.chat-msg-text.streaming:empty:before{content:"• • •";letter-spacing:2px;color:var(--text-muted);font-size:18px;animation:thinking-dots 1.4s ease-in-out infinite}@keyframes thinking-dots{0%,to{opacity:.3}50%{opacity:1}}@keyframes blink-cursor{0%,to{opacity:1}50%{opacity:0}}.chat-streaming-cancel{margin-top:4px;padding:2px 10px;border-radius:4px;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);background:var(--bg-hover);color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:11px}.chat-streaming-cancel:hover{color:var(--text-primary);background:var(--bg-mid)}.chat-spoiler{background:var(--text-primary);color:transparent;border-radius:3px;padding:0 3px;cursor:var(--studio-cursor-pointer, pointer);transition:all max(1ms,calc(.2s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-spoiler.revealed{background:var(--bg-hover);color:var(--text-primary)}.chat-inverted{background:var(--text-primary);color:var(--bg-dark);padding:0 3px;border-radius:3px}.chat-underline-em{text-decoration:underline;font-style:italic}.chat-msg-action{padding:4px 16px;font-style:italic;color:var(--text-secondary);font-size:14px;position:relative}.chat-msg-action:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-msg-action .chat-msg-action-name{font-weight:600;color:var(--text-primary)}.chat-time-gap{margin-top:16px}.chat-input-wrap{position:relative;flex:1;min-width:0}.chat-input-wrap .cm-editor{background:transparent}.chat-input-wrap .cm-editor .cm-content,.chat-input-wrap .cm-editor .cm-scroller{max-height:120px}.chat-msg-continuation{padding:0 16px 0 68px;position:relative}.chat-msg-continuation.has-gif{padding-left:16px;display:flex;gap:12px;align-items:flex-start}.chat-msg-continuation:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-msg-inline-time{font-size:10px;color:var(--text-muted);position:absolute;top:100%;right:0;white-space:nowrap;margin-top:2px;pointer-events:none}.chat-msg-gif-inline{width:40px;height:40px;border-radius:4px;object-fit:cover;border:none;display:block;margin-right:6px;flex-shrink:0}.chat-msg-reply-ref{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-muted);margin-bottom:2px;padding-left:36px;cursor:var(--studio-cursor-pointer, pointer);position:relative}.chat-msg-reply-ref:before{content:"";position:absolute;left:20px;top:50%;width:12px;height:12px;border-left:2px solid var(--border);border-top:2px solid var(--border);border-radius:6px 0 0;transform:translateY(-20%)}.chat-msg-reply-ref:hover{color:var(--text-primary)}.chat-msg-reply-ref-avatar{width:16px;height:16px;border-radius:50%;overflow:hidden;flex-shrink:0}.chat-msg-reply-ref-avatar img{width:100%;height:100%;object-fit:cover}.chat-msg-reply-ref-name{font-weight:600;color:var(--text-primary)}.chat-msg-reply-ref-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:300px}.chat-msg-image-wrap{position:relative;display:inline-block;margin-top:4px;max-width:100%}.chat-msg-image{display:block;border-radius:8px;cursor:var(--studio-cursor-pointer, pointer);width:100%;height:100%;object-fit:cover}.chat-msg-embed{margin-top:6px;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;width:100%;height:300px;position:relative;background:var(--bg-surface);display:flex;flex-direction:column}.chat-msg-embed patchwork-view{width:100%;flex:1;min-height:0;display:block;overflow:hidden}.chat-msg-embed-title{padding:0 8px 0 0;font-weight:500;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:1;min-width:0}.chat-embed-infobar{display:flex;align-items:center;gap:4px;padding:3px 6px;background:var(--bg-darkest);border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);font-size:11px;overflow:hidden;flex-wrap:wrap}.chat-embed-pill{display:inline-flex;align-items:center;gap:3px;background:var(--bg-hover);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:10px;padding:1px 8px;font-size:10px;color:var(--text-secondary);white-space:nowrap;cursor:var(--studio-cursor-default, default);max-width:200px;overflow:hidden;text-overflow:ellipsis;flex-shrink:0}.chat-embed-pill.clickable{cursor:var(--studio-cursor-pointer, pointer)}.chat-embed-pill.clickable:hover{color:var(--text-primary);border-color:var(--accent-line);background:var(--bg-input)}.chat-embed-pill-label{opacity:.6;font-size:9px;text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .3px)}.chat-embed-tool-input{background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--accent-line);border-radius:10px;color:var(--text-primary);font-size:10px;padding:1px 8px;outline:none;width:120px}.chat-embed-tool-menu{position:absolute;top:100%;left:0;z-index:20;background:var(--bg-surface);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:6px;padding:2px;box-shadow:0 2px 8px #0000004d;white-space:nowrap;min-width:140px;max-height:200px;overflow-y:auto}.chat-embed-tool-menu button{display:block;width:100%;text-align:left;background:none;border:none;color:var(--text-secondary);font-size:11px;padding:4px 8px;cursor:var(--studio-cursor-pointer, pointer);border-radius:4px}.chat-embed-tool-menu button:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-embed-tool-menu button.active{color:var(--accent-text);font-weight:600}.chat-embed-tool-menu .tool-menu-input-row{display:flex;gap:4px;padding:4px;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);margin-top:2px}.chat-embed-tool-menu .tool-menu-input-row input{flex:1;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:10px;padding:2px 6px;outline:none;min-width:0}.chat-embed-tool-menu .tool-menu-input-row input:focus{border-color:var(--accent-line)}.chat-embed-url-menu{position:absolute;top:100%;left:0;z-index:20;background:var(--bg-surface);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:6px;padding:2px;box-shadow:0 2px 8px #0000004d;white-space:nowrap}.chat-embed-url-menu button{display:block;width:100%;text-align:left;background:none;border:none;color:var(--text-secondary);font-size:11px;padding:4px 10px;cursor:var(--studio-cursor-pointer, pointer);border-radius:4px}.chat-embed-url-menu button:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-resize-handle{position:absolute;bottom:0;right:0;width:16px;height:16px;cursor:nwse-resize;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));z-index:5}.chat-msg-image-wrap:hover .chat-resize-handle,.chat-msg-embed:hover .chat-resize-handle{opacity:.6}.chat-resize-handle:hover{opacity:1!important}.chat-resize-handle svg{width:10px;height:10px;color:var(--text-muted)}.chat-rich-blocks{display:flex;flex-direction:column;gap:4px;margin-top:6px}.chat-rich-block{border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:6px;overflow:hidden;background:var(--bg-darkest);font-size:13px}.chat-rich-block-header{display:flex;align-items:center;gap:6px;padding:5px 10px;cursor:var(--studio-cursor-pointer, pointer);border:none;background:transparent;color:var(--text-secondary);width:100%;text-align:left;font-size:12px;font-family:monospace}.chat-rich-block-header:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-rich-block-chevron{transition:transform max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));flex-shrink:0}.chat-rich-block.open .chat-rich-block-chevron{transform:rotate(90deg)}.chat-rich-block-label{opacity:.8}.chat-rich-block-body{border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);max-height:400px;overflow:auto}.chat-rich-block-code{margin:0;font-size:12px;line-height:1.5}.chat-rich-block-code pre{margin:0;padding:10px;overflow-x:auto}.chat-rich-block-code code{font-family:monospace;white-space:pre}.chat-rich-block-result-label{font-size:11px;color:var(--text-muted);padding:6px 10px 2px;text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .5px);border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border)}.shiki{margin:0!important;padding:10px 12px!important;font-size:13px!important;line-height:1.5!important;overflow-x:auto;border-radius:6px}.shiki code{font-family:ui-monospace,SF Mono,Cascadia Code,Menlo,Consolas,monospace!important}.chat-code-block{background:var(--bg-darkest);border:none;border-radius:6px;padding:0;margin:6px 0;overflow-x:auto;font-size:13px;line-height:1.5}.chat-code-block code{font-family:ui-monospace,SF Mono,Cascadia Code,Menlo,Consolas,monospace;white-space:pre;display:block;padding:10px 12px}.chat-msg-text .shiki{border-radius:6px;border:none;margin:6px 0}.chat-msg-text .shiki code{white-space:pre;display:block}.chat-rich-block-code .shiki{margin:0;border-radius:0}.chat-think-block{background:var(--bg-darkest);border-radius:6px;margin:6px 0;font-size:13px;overflow:hidden}.chat-think-block summary{cursor:var(--studio-cursor-pointer, pointer);padding:5px 10px;color:var(--text-secondary);font-family:ui-monospace,monospace;font-size:12px;user-select:none;list-style:none}.chat-think-block summary:before{content:"▶ ";display:inline;font-size:10px}.chat-think-block[open] summary:before{content:"▼ "}.chat-think-block summary:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-think-content{padding:8px 12px;white-space:pre-wrap;color:var(--text-secondary);font-family:ui-monospace,monospace;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--bg-hover);max-height:300px;overflow-y:auto}.chat-voice-note{display:flex;align-items:center;gap:8px;margin-top:4px;padding:8px 12px;background:var(--bg-darkest);border-radius:8px;max-width:300px;flex-wrap:wrap}.chat-voice-transcription{width:100%;font-size:13px;color:var(--text-secondary);font-style:italic;padding-left:2px;margin-top:2px}.chat-voice-transcribing{opacity:.5;animation:chat-pulse 1.5s ease-in-out infinite}@keyframes chat-pulse{0%,to{opacity:.5}50%{opacity:.3}}.chat-voice-transcribe-btn{background:none;border:none;color:var(--text-muted);font-size:11px;cursor:var(--studio-cursor-pointer, pointer);padding:2px 4px;opacity:.6;font-style:italic}.chat-voice-transcribe-btn:hover{opacity:1;text-decoration:underline}.chat-voice-play-btn{width:32px;height:32px;border-radius:50%;background:var(--accent);color:var(--accent-fg);border:none;font-size:14px;cursor:var(--studio-cursor-pointer, pointer);display:flex;align-items:center;justify-content:center;flex-shrink:0}.chat-voice-play-btn:hover{background:var(--accent-hover)}.chat-voice-waveform{flex:1;height:24px;display:flex;align-items:center;gap:2px}.chat-voice-bar{width:3px;background:var(--accent);border-radius:2px;min-height:3px}.chat-voice-duration{font-size:12px;color:var(--text-muted);flex-shrink:0}.chat-reactions{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.chat-reaction{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:8px;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);background:var(--bg-dark);font-size:15px;cursor:var(--studio-cursor-pointer, pointer);user-select:none;transition:all max(1ms,calc(.1s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-reaction:hover{border-color:var(--accent-line);background:var(--studio-hover-fill, var(--bg-hover))}.chat-reaction.mine{border-color:var(--accent-line);background:var(--accent-soft)}.chat-reaction-count{font-size:12px;color:var(--text-secondary);font-weight:500}.chat-reaction-add{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;border:1px dashed var(--border);background:transparent;font-size:16px;cursor:var(--studio-cursor-pointer, pointer);color:var(--text-muted);transition:all max(1ms,calc(.1s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-reaction-add:hover{border-color:var(--accent-line);color:var(--text-primary);background:var(--studio-hover-fill, var(--bg-hover))}.chat-emoticon-tooltip{position:absolute;z-index:200;pointer-events:none;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;padding:8px 12px;box-shadow:0 4px 16px #0000004d;display:none;flex-direction:column;align-items:center;gap:4px;max-width:200px}.chat-emoticon-tooltip.show{display:flex;pointer-events:auto}.chat-emoticon-tooltip-preview{font-size:48px;line-height:1}.chat-emoticon-tooltip-preview img{width:48px;height:48px;object-fit:contain}.chat-emoticon-tooltip-name{font-size:12px;color:var(--text-muted)}.chat-emoticon-tooltip-names{font-size:11px;color:var(--text-secondary);text-align:center}.chat-emoticon-tooltip-adopt{background:var(--accent);color:var(--accent-fg);border:none;cursor:var(--studio-cursor-pointer, pointer);font-size:11px;padding:2px 10px;border-radius:4px;font-weight:600}.chat-emoticon-tooltip-adopt:hover{opacity:.85}.chat-msg-actions{position:absolute;top:-14px;right:16px;display:none;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;z-index:10}.chat-msg-group:hover .chat-msg-actions,.chat-msg-continuation:hover .chat-msg-actions,.chat-msg-action:hover .chat-msg-actions{display:flex}.chat-msg-action-btn{background:none;border:none;color:var(--text-secondary);padding:6px 8px;cursor:var(--studio-cursor-pointer, pointer);font-size:16px}.chat-msg-action-btn:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-emoji-picker-overlay{position:fixed;inset:0;z-index:100;display:none}.chat-emoji-picker-overlay.show{display:block}.chat-emoji-picker{position:absolute;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;padding:8px;box-shadow:0 4px 20px #0000004d;z-index:101;max-width:280px;width:280px;display:flex;flex-direction:column;max-height:320px}.chat-emoji-picker-scroll{overflow-y:auto;overscroll-behavior:contain;min-height:0;flex:1}.chat-emoji-grid{display:flex;flex-wrap:wrap;gap:2px}.chat-emoji-grid button{background:none;border:none;font-size:22px;cursor:var(--studio-cursor-pointer, pointer);padding:4px;border-radius:4px;width:36px;height:36px;display:flex;align-items:center;justify-content:center}.chat-emoji-grid button:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-emoji-active{background:var(--accent)!important;outline:2px solid var(--accent-line);outline-offset:-2px;opacity:.8}.chat-emoji-picker-search{width:100%;padding:6px 10px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:14px;margin-bottom:6px;outline:none;flex-shrink:0}.chat-emoji-picker-search:focus{border-color:var(--accent-line)}.chat-emoticon-section{border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);padding-bottom:6px;margin-bottom:6px}.chat-emoticon-section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .5px)}.chat-emoticon-section-label{font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .5px);margin:6px 0 4px;padding:0 2px}.chat-emoticon-btn{position:relative;width:36px;height:36px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:4px;cursor:var(--studio-cursor-pointer, pointer);padding:2px}.chat-emoticon-btn:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-emoticon-img{width:28px;height:28px;object-fit:contain}.chat-emoticon-add-btn{background:none;border:1px dashed var(--border);color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:11px;padding:2px 8px;border-radius:4px}.chat-emoticon-add-btn:hover{border-color:var(--accent-line);color:var(--text-primary)}.chat-emoticon-grid{display:flex;flex-wrap:wrap;gap:2px}.chat-emoticon-grid button{background:none;border:none;cursor:var(--studio-cursor-pointer, pointer);padding:2px;border-radius:4px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;position:relative}.chat-emoticon-grid button:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-emoticon-grid button img{width:28px;height:28px;object-fit:contain}.chat-emoticon-adopt{position:absolute;top:-2px;right:-2px;width:14px;height:14px;border-radius:50%;background:var(--accent);color:var(--accent-fg);border:none;cursor:var(--studio-cursor-pointer, pointer);font-size:10px;display:none;align-items:center;justify-content:center;line-height:1}.chat-emoticon-grid button:hover .chat-emoticon-adopt{display:flex}.chat-emoticon-remove{position:absolute;top:-4px;right:-4px;width:16px;height:16px;border-radius:50%;background:var(--bg-hover);color:var(--text-muted);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);cursor:var(--studio-cursor-pointer, pointer);font-size:10px;display:none;align-items:center;justify-content:center;line-height:1}.chat-emoticon-grid button:hover .chat-emoticon-remove{display:flex}.chat-emoticon-remove:hover{background:#ed4245!important;color:#fff!important;border-color:#ed4245!important}.chat-emoticon-remove.confirm{background:#ed4245;color:#fff;border-color:#ed4245;display:flex}.chat-emoticon-inline{height:1.5em;vertical-align:middle;display:inline}.chat-emoticon-dialog{padding:8px;display:flex;flex-direction:column;gap:8px}.chat-emoticon-dialog input[type=text]{width:100%;padding:6px 10px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:14px;outline:none}.chat-emoticon-dialog input[type=text]:focus{border-color:var(--accent-line)}.chat-emoticon-dialog-preview{width:80px;height:80px;border-radius:4px;background:var(--bg-hover);display:flex;align-items:center;justify-content:center;overflow:hidden;align-self:center;color:var(--text-muted);font-size:24px}.chat-emoticon-dialog-preview:hover{background:var(--bg-input);border:1px dashed var(--border)}.chat-emoticon-dialog-preview img{width:100%;height:100%;object-fit:contain}.chat-emoticon-dialog-counter{font-size:11px;color:var(--text-muted);text-align:center}.chat-emoticon-dialog-btns{display:flex;gap:6px;justify-content:flex-end}.chat-emoticon-dialog-btns button{padding:4px 12px;border-radius:4px;font-size:13px;cursor:var(--studio-cursor-pointer, pointer);border:none}.chat-emoticon-dialog .cancel-btn{background:var(--bg-hover);color:var(--text-primary)}.chat-emoticon-dialog .save-btn{background:var(--accent);color:var(--accent-fg);font-weight:600}.chat-emoticon-dialog .save-btn:disabled{opacity:var(--studio-disabled-opacity, .5);cursor:var(--studio-cursor-default, default)}.chat-font-dialog{padding:8px;display:flex;flex-direction:column;gap:8px}.chat-font-dialog input[type=text]{width:100%;padding:6px 10px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:14px;outline:none}.chat-font-dialog input[type=text]:focus{border-color:var(--accent-line)}.chat-font-dialog-preview{padding:10px;border-radius:4px;background:var(--bg-hover);text-align:center;font-size:18px;color:var(--text-primary);min-height:48px;display:flex;align-items:center;justify-content:center}.chat-font-dialog-filebtn{background:none;border:1px dashed var(--border);color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:13px;padding:6px 12px;border-radius:4px;text-align:center}.chat-font-dialog-filebtn:hover{border-color:var(--accent-line);color:var(--text-primary)}.chat-font-dialog-btns{display:flex;gap:6px;justify-content:flex-end}.chat-font-dialog-btns button{padding:4px 12px;border-radius:4px;font-size:13px;cursor:var(--studio-cursor-pointer, pointer);border:none}.chat-font-dialog .cancel-btn{background:var(--bg-hover);color:var(--text-primary)}.chat-font-dialog .save-btn{background:var(--accent);color:var(--accent-fg);font-weight:600}.chat-font-dialog .save-btn:disabled{opacity:var(--studio-disabled-opacity, .5);cursor:var(--studio-cursor-default, default)}.chat-font-list{display:flex;flex-direction:column;gap:2px;max-height:120px;overflow-y:auto;overscroll-behavior:contain}.chat-font-list-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;font-size:13px;color:var(--text-primary)}.chat-font-list-item:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-font-list-item .font-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-font-list-remove{width:18px;height:18px;border-radius:50%;background:var(--bg-hover);color:var(--text-muted);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);cursor:var(--studio-cursor-pointer, pointer);font-size:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chat-font-list-remove:hover,.chat-font-list-remove.confirm{background:#ed4245;color:#fff;border-color:#ed4245}.chat-msg-menu-wrap{position:relative}.chat-msg-menu{display:none;position:absolute;top:100%;right:0;margin-top:2px;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:6px;padding:4px 0;min-width:120px;z-index:20;box-shadow:0 4px 12px #0000004d}.chat-msg-menu.show{display:block}.chat-msg-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px;background:none;border:none;color:var(--text-primary);font-size:13px;cursor:var(--studio-cursor-pointer, pointer);text-align:left}.chat-msg-menu-item:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-msg-menu-item.danger{color:#ed4245}.chat-msg-menu-item.danger:hover{background:#ed42451a}.chat-typing-bar{padding:0 16px;min-height:22px;font-size:12px;color:var(--text-muted);font-style:italic;flex-shrink:0}.chat-llm-status{padding:0 16px;min-height:22px;font-size:12px;color:var(--text-muted);font-style:italic;flex-shrink:0;font-family:monospace}.chat-stop-btn{display:inline-flex;align-items:center;gap:4px;padding:2px 10px;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;background:var(--bg-mid);color:var(--text-secondary);font-size:12px;font-family:inherit;cursor:var(--studio-cursor-pointer, pointer);font-style:normal}.chat-stop-btn:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-input-wrapper{flex-shrink:0;padding:0 16px 16px;position:relative}.chat-autocomplete{display:none;position:absolute;bottom:100%;left:0;right:0;background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;max-height:200px;overflow-y:auto;overscroll-behavior:contain;box-shadow:0 -4px 16px #0000004d;z-index:50;margin-bottom:4px}.chat-autocomplete.show{display:block}.chat-autocomplete-item{display:flex;align-items:center;gap:8px;padding:6px 12px;cursor:var(--studio-cursor-pointer, pointer);font-size:14px;color:var(--text-primary)}.chat-autocomplete-item:hover,.chat-autocomplete-item.active{background:var(--bg-hover)}.chat-autocomplete-item-emoji{font-size:20px;width:28px;text-align:center;flex-shrink:0}.chat-autocomplete-item-emoji img{width:24px;height:24px;object-fit:contain}.chat-autocomplete-item-name{color:var(--text-secondary);font-size:12px}.chat-autocomplete-item-desc{color:var(--text-muted);font-size:11px;margin-left:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%}.chat-autocomplete-item-cmd{font-weight:600;font-size:14px;color:var(--text-primary);min-width:0}.chat-autocomplete-pop{position:fixed;z-index:50;min-width:200px;max-width:340px;max-height:200px;overflow-y:auto;overscroll-behavior:contain;background:var(--editor-fill, Canvas);color:var(--editor-line, currentColor);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;box-shadow:0 4px 16px #0000004d}.chat-autocomplete-item-icon{width:20px;height:20px;flex-shrink:0;color:var(--text-muted)}.chat-reply-bar{display:none;padding:8px 12px;background:var(--bg-mid);border-radius:8px 8px 0 0;border-left:3px solid var(--accent-line);align-items:center;gap:8px;font-size:13px;color:var(--text-secondary)}.chat-reply-bar.show{display:flex}.chat-reply-bar-text{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.chat-reply-bar-close{background:none;border:none;font-size:16px;cursor:var(--studio-cursor-pointer, pointer);color:var(--text-secondary)}.chat-reply-bar-close:hover{color:var(--text-primary)}.chat-paste-preview{display:none;padding:8px 12px;background:var(--bg-mid);align-items:center;gap:8px;flex-wrap:wrap}.chat-paste-preview.show{display:flex}.chat-paste-preview img{max-height:50px;border-radius:4px}.chat-paste-preview video{max-height:50px;border-radius:4px}.chat-paste-preview-close{background:none;border:none;font-size:16px;cursor:var(--studio-cursor-pointer, pointer);color:var(--text-secondary);margin-left:auto}.chat-paste-file{display:flex;align-items:center;gap:6px;background:var(--bg-hover);border-radius:6px;padding:4px 8px;font-size:12px;color:var(--text-secondary);max-width:200px}.chat-paste-file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-paste-file-remove{background:none;border:none;cursor:var(--studio-cursor-pointer, pointer);color:var(--text-secondary);padding:0;display:flex;align-items:center}.chat-paste-file-remove:hover{color:var(--text-primary)}.chat-paste-embed{display:flex;align-items:center;gap:6px;background:var(--bg-hover);border-radius:6px;padding:4px 8px;font-size:12px;color:var(--text-secondary);max-width:200px}.chat-paste-embed-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-selection-chip{display:inline-flex;align-items:center;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--bg-hover);color:var(--text-secondary);border-radius:6px;padding:2px 8px;margin:0 4px;font-size:12px}.chat-paste-embed-remove{background:none;border:none;cursor:var(--studio-cursor-pointer, pointer);color:var(--text-secondary);padding:0;display:flex;align-items:center}.chat-paste-embed-remove:hover{color:var(--text-primary)}.chat-sidebar-pinned-wrap{position:relative}.chat-sidebar-pinned-wrap[data-drop-position=above]:before{content:"";position:absolute;top:-2px;left:4px;right:4px;height:2px;background:var(--accent);border-radius:1px;z-index:10}.chat-sidebar-pinned-wrap[data-drop-position=below]:after{content:"";position:absolute;bottom:-2px;left:4px;right:4px;height:2px;background:var(--accent);border-radius:1px;z-index:10}.chat-sidebar-pinned-wrap.dragging{opacity:.4}.chat-drop-overlay{display:none;position:absolute;inset:0;z-index:100;background:color-mix(in oklch,var(--theme) 20%,black 60%);align-items:center;justify-content:center;font-size:18px;color:var(--text-primary);font-weight:600;border:3px dashed var(--accent-line);border-radius:12px;pointer-events:none}.chat-drop-overlay.show{display:flex}.chat-msg-video-wrap{max-width:350px;border-radius:8px;overflow:hidden;margin-top:4px;position:relative}.chat-msg-video{width:100%;display:block;border-radius:8px;cursor:var(--studio-cursor-pointer, pointer)}.chat-lightbox{display:none;position:absolute;inset:0;z-index:200;background:#000000d9;align-items:center;justify-content:center;cursor:zoom-out}.chat-lightbox.show{display:flex}.chat-lightbox img,.chat-lightbox video{max-width:95%;max-height:95%;object-fit:contain;border-radius:4px;cursor:var(--studio-cursor-default, default)}.chat-lightbox video{background:#000}.chat-msg-file{display:inline-flex;align-items:center;gap:6px;background:var(--bg-hover);border-radius:6px;padding:6px 10px;margin-top:4px;font-size:13px;color:var(--text-secondary);cursor:var(--studio-cursor-pointer, pointer);text-decoration:none}.chat-msg-file:hover{background:var(--bg-input);color:var(--text-primary)}.chat-msg-file-icon{flex-shrink:0}.chat-input-row{display:flex;gap:0;background:var(--bg-mid);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;padding:3px;align-items:flex-end}.chat-input{width:100%;padding:8px 12px;border:none;font-size:15px;outline:none;background:transparent;color:var(--text-primary);font-family:inherit;resize:none;max-height:120px;min-height:24px;line-height:1.4;position:relative;z-index:1}.chat-input::placeholder{color:var(--text-muted)}.chat-input-btn{width:36px;height:36px;background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:20px;border-radius:4px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chat-input-btn:hover{color:var(--text-primary)}.chat-input-btn.recording{color:#ed4245;animation:pulse 1s infinite}@keyframes pulse{0%,to{transform:scale(1)}50%{transform:scale(1.15)}}.chat-recording-bar{display:flex;align-items:center;gap:10px;background:var(--bg-input);border-radius:8px;padding:8px 12px;animation:fadeIn max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) ease}.chat-recording-overlay{position:absolute;inset:0;z-index:3}@keyframes fadeIn{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}.chat-recording-dot{width:10px;height:10px;border-radius:50%;background:#ed4245;flex-shrink:0;animation:recPulse 1s ease-in-out infinite}@keyframes recPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.8)}}.chat-recording-time{font-size:14px;color:var(--text-primary);font-variant-numeric:tabular-nums;min-width:40px}.chat-recording-viz{flex:1;height:24px;display:flex;align-items:center;gap:2px;overflow:hidden}.chat-recording-viz-bar{width:3px;border-radius:2px;background:var(--accent);min-height:3px;transition:height var(--studio-transition-fast, .1s ease)}.chat-recording-cancel{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:13px;padding:4px 10px;border-radius:4px}.chat-recording-cancel:hover{color:var(--text-primary);background:var(--studio-hover-fill, var(--bg-hover))}.chat-recording-send{background:var(--accent);color:var(--accent-fg);border:none;cursor:var(--studio-cursor-pointer, pointer);padding:6px 14px;border-radius:6px;font-size:13px;font-weight:600}.chat-recording-send:hover{background:var(--accent-hover)}.chat-gif-toggle{width:36px;height:36px;border:none;cursor:var(--studio-cursor-pointer, pointer);border-radius:4px;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:none;color:var(--text-muted);font-size:20px;position:relative;overflow:hidden}.chat-gif-toggle:hover{color:var(--text-primary)}.chat-gif-toggle.active{color:var(--accent-text)}.chat-gif-toggle video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:4px;display:none}.chat-gif-toggle.active video{display:block}.chat-gif-toggle.active .chat-gif-icon{display:none}.chat-gif-toggle.recording{pointer-events:none;position:relative;overflow:visible}.chat-gif-progress{position:absolute;top:-10px;left:-10px;width:calc(100% + 20px);height:calc(100% + 20px);z-index:20;pointer-events:none}.chat-gif-progress circle.chat-gif-progress-bg{fill:none;stroke:#00000026;stroke-width:2}.chat-gif-progress circle.chat-gif-progress-fg{fill:none;stroke:var(--accent-line);stroke-width:2;stroke-linecap:round;transform:rotate(-90deg);transform-origin:center;transition:stroke-dashoffset max(1ms,calc(.1s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) linear}.chat-input-row.processing .chat-input,.chat-input-row.processing .chat-input-wrap,.chat-input-row.processing .chat-input-btn{opacity:.5;pointer-events:none}.chat-empty{flex:1;display:flex;align-items:center;justify-content:center;color:var(--text-muted);font-size:16px}@keyframes chat-skeleton-pulse{0%,to{opacity:.3}50%{opacity:.6}}.chat-msg-loading{opacity:.5}.chat-skeleton{background:var(--bg-hover);animation:chat-skeleton-pulse 1.5s ease-in-out infinite}.chat-skeleton-line{height:14px;background:var(--bg-hover);border-radius:4px;margin:4px 0;animation:chat-skeleton-pulse 1.5s ease-in-out infinite;width:60%}.chat-skeleton-line.short{width:30%}.chat-main{display:flex;flex-direction:column;flex:1;min-width:0;position:relative;height:100%}.chat-sidebar{display:none;flex-direction:column;width:40%;min-width:15%;border-left:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);background:var(--bg-darkest);overflow:hidden;position:relative}.chat-sidebar.visible{display:flex}.chat-sidebar.drop-target{display:flex;min-width:60px;width:60px;align-items:center;justify-content:center;border:2px dashed var(--accent-line);background:color-mix(in oklch,var(--accent) 10%,var(--bg-darkest))}.chat-sidebar.drop-target:after{content:"Pin";font-size:11px;color:var(--accent-text);font-weight:600;pointer-events:none}.chat-sidebar.visible.drop-target{width:40%;min-width:15%}.chat-sidebar.visible.drop-target:after{display:none}.chat-sidebar.collapsed{width:0!important;min-width:0!important;border-left:none;overflow:hidden}.chat-root.sidebar-left{flex-direction:row-reverse}.chat-root.sidebar-left .chat-sidebar{border-left:none;border-right:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border)}.chat-root.sidebar-left .chat-sidebar-resize{left:auto;right:-3px}.chat-sidebar-resize{position:absolute;left:-3px;top:0;bottom:0;width:6px;cursor:var(--studio-cursor-resize-col, col-resize);z-index:10}.chat-sidebar-resize:hover,.chat-sidebar-resize.dragging{background:var(--accent);opacity:.3}.chat-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:4px 6px;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);flex-shrink:0}.chat-sidebar-header-title{font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .5px)}.chat-sidebar-collapse-btn{background:none;border:none;cursor:var(--studio-cursor-pointer, pointer);padding:2px 4px;color:var(--text-muted);display:flex;align-items:center}.chat-sidebar-collapse-btn:hover{color:var(--text-primary)}.chat-sidebar-pinned{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:0;padding:4px}.chat-sidebar-pinned:empty{display:none}.chat-sidebar-pinned-wrap{position:relative;display:flex;flex-direction:column;flex:1;min-height:200px;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:6px;overflow:hidden;margin-bottom:4px;background:var(--bg-mid)}.chat-sidebar-pinned-toolbar{position:absolute;top:4px;right:4px;z-index:10;display:flex;gap:2px;opacity:0;transition:opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));pointer-events:auto}.chat-sidebar-pinned-wrap:hover .chat-sidebar-pinned-toolbar{opacity:1}.chat-sidebar-pinned-toolbar button{background:var(--bg-darkest);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);padding:2px 4px;font-size:10px;display:flex;align-items:center;gap:2px;line-height:1}.chat-sidebar-pinned-toolbar button:hover{color:var(--text-primary);background:var(--bg-mid)}.chat-sidebar-pinned-toolbar button svg{width:12px;height:12px}.chat-sidebar-pinned iframe{width:100%;flex:1;border:none;border-radius:4px;min-height:200px;background:var(--bg-mid)}.chat-sidebar-pinned-info{background:var(--bg-darkest);border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);font-size:11px;color:var(--text-secondary)}.chat-sidebar-pinned-info-main{display:flex;align-items:center;gap:4px;padding:3px 8px;cursor:var(--studio-cursor-pointer, pointer)}.chat-sidebar-pinned-info-main:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-sidebar-pinned-info-title{flex:1;font-weight:600;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.chat-sidebar-pinned-info-chevron{font-size:10px;transition:transform max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));flex-shrink:0}.chat-sidebar-pinned-info-chevron.open{transform:rotate(90deg)}.chat-sidebar-pinned-info-details{padding:2px 8px 4px}.chat-sidebar-pinned-info-row{display:flex;align-items:center;gap:4px;padding:1px 0}.chat-sidebar-pinned-info-label{color:var(--text-muted);font-size:10px;min-width:24px;flex-shrink:0}.chat-sidebar-pinned-info-value{font-family:monospace;font-size:10px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-sidebar-pinned-info-url{cursor:var(--studio-cursor-pointer, pointer)}.chat-sidebar-pinned-info-url:hover{color:var(--text-primary);text-decoration:underline}.chat-sidebar-pinned-info-editable{cursor:var(--studio-cursor-pointer, pointer);border-bottom:1px dashed var(--text-muted)}.chat-sidebar-pinned-info-editable:hover{color:var(--text-primary)}.chat-sidebar-pinned-info-input{font-family:monospace;font-size:10px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:3px;color:var(--text-primary);padding:1px 4px;flex:1;min-width:0}.chat-sidebar-pinned-resize-handle{height:6px;cursor:var(--studio-cursor-resize-row, row-resize);flex-shrink:0;background:transparent;position:relative}.chat-sidebar-pinned-resize-handle:after{content:"";position:absolute;left:20%;right:20%;top:2px;height:2px;border-radius:1px;background:var(--border);opacity:0;transition:opacity max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))}.chat-sidebar-pinned-resize-handle:hover:after,.chat-sidebar-pinned-resize-handle.active:after{opacity:1}.chat-sidebar-pinned-resize-handle.active:after{background:var(--accent)}.chat-sidebar-status{padding:4px 8px;font-size:11px;color:var(--text-muted);text-align:center}.chat-sidebar-toggle-btn{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);padding:2px 4px;border-radius:4px;display:flex;align-items:center}.chat-sidebar-toggle-btn:hover{background:var(--studio-hover-fill, var(--bg-hover));color:var(--text-primary)}.chat-embed-pin{cursor:var(--studio-cursor-pointer, pointer)}.chat-embed-pin.pinned{color:var(--accent-text)}.chat-msg-name-computer{color:var(--accent-text);font-style:italic}.chat-avatar.computer{background:var(--accent-soft);overflow:hidden}.chat-avatar.computer img{width:100%;height:100%;object-fit:cover;display:block}.computer-presence img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}.chat-dialog-overlay{position:fixed;inset:0;z-index:var(--studio-layer-overlay, 100);background:#00000080;display:flex;align-items:center;justify-content:center;animation:fadeIn max(1ms,calc(.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1))) ease}.chat-emoticon-dialog,.chat-font-dialog{background:var(--bg-dark);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 8px 32px #0006}.chat-plugin-panel{background:var(--bg-dark);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;min-width:300px;max-width:420px;max-height:70vh;display:flex;flex-direction:column;box-shadow:0 8px 32px #0006}.chat-plugin-panel-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);font-size:14px;font-weight:600}.chat-plugin-panel-close{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:18px;line-height:1}.chat-plugin-panel-close:hover{color:var(--text-primary)}.chat-plugin-panel-body{padding:6px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}.chat-plugin-section{font-size:11px;text-transform:uppercase;letter-spacing:var(--studio-chrome-letter-spacing, .04em);color:var(--text-muted);padding:10px 6px 4px}.chat-plugin-item{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:4px;cursor:var(--studio-cursor-pointer, pointer);font-size:13px;color:var(--text-primary)}.chat-plugin-item:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-plugin-item input{cursor:var(--studio-cursor-pointer, pointer)}.chat-plugin-item-locked,.chat-plugin-item-locked input{cursor:var(--studio-cursor-default, default)}.chat-plugin-item-locked{opacity:.55}.chat-plugin-item-locked:hover{background:none}.chat-plugin-id{margin-left:auto;font-family:ui-monospace,monospace;font-size:11px;color:var(--text-muted)}.chat-emoticon-dialog-header,.chat-font-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);font-size:14px;font-weight:600}.chat-emoticon-dialog-close,.chat-font-dialog-close{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:18px;line-height:1}.chat-emoticon-dialog-close:hover,.chat-font-dialog-close:hover{color:var(--text-primary)}.chat-emoticon-dialog-body,.chat-font-dialog-body{padding:12px;display:flex;flex-direction:column;gap:8px}.chat-emoticon-dialog-footer,.chat-font-dialog-footer{display:flex;gap:6px;justify-content:flex-end;padding:8px 12px;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border)}.chat-emoticon-dialog-footer button,.chat-font-dialog-footer button{padding:6px 14px;border-radius:6px;font-size:13px;cursor:var(--studio-cursor-pointer, pointer);border:none}.chat-emoticon-dialog-save,.chat-font-dialog-save{background:var(--accent);color:var(--accent-fg);font-weight:600}.chat-emoticon-dialog-save:disabled,.chat-font-dialog-save:disabled{opacity:var(--studio-disabled-opacity, .5);cursor:var(--studio-cursor-default, default)}.chat-emoticon-dialog-save:not(:disabled):hover,.chat-font-dialog-save:not(:disabled):hover{background:var(--accent-hover)}.chat-emoticon-dialog-nav{display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;color:var(--text-muted)}.chat-emoticon-dialog-nav button{background:none;border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);color:var(--text-secondary);cursor:var(--studio-cursor-pointer, pointer);padding:2px 8px;border-radius:4px;font-size:12px}.chat-emoticon-dialog-nav button:disabled{opacity:.4;cursor:var(--studio-cursor-default, default)}.chat-emoticon-dialog-nav button:not(:disabled):hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-emoticon-dialog-name,.chat-font-dialog-name{width:100%;padding:6px 10px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:14px;outline:none}.chat-emoticon-dialog-name:focus,.chat-font-dialog-name:focus{border-color:var(--accent-line)}.chat-font-dialog-list{display:flex;flex-direction:column;gap:2px;max-height:120px;overflow-y:auto}.chat-font-dialog-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;font-size:13px}.chat-font-dialog-item:hover{background:var(--studio-hover-fill, var(--bg-hover))}.chat-font-dialog-remove{width:20px;height:20px;border-radius:50%;background:var(--bg-hover);color:var(--text-muted);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);cursor:var(--studio-cursor-pointer, pointer);font-size:12px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chat-font-dialog-remove:hover{background:#ed4245;color:#fff;border-color:#ed4245}.chat-font-dialog-choose{background:none;border:1px dashed var(--border);color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:13px;padding:8px 12px;border-radius:4px;text-align:center;width:100%}.chat-font-dialog-choose:hover{border-color:var(--accent-line);color:var(--text-primary)}.chat-font-dialog-preview{padding:10px;border-radius:4px;background:var(--bg-hover);text-align:center;font-size:16px;color:var(--text-primary)}.chat-gif-toggle .chat-gif-progress{position:absolute;inset:-4px;width:calc(100% + 8px);height:calc(100% + 8px);z-index:20;pointer-events:none}.chat-time-gap{text-align:center;color:var(--text-muted);font-size:11px;padding:8px 0 4px;position:relative}.chat-time-gap:before{content:"";position:absolute;left:20%;right:20%;top:50%;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);z-index:0}.chat-time-gap span{position:relative;z-index:1;background:var(--bg-dark);padding:0 8px}.chat-model-dialog{background:var(--bg-mid);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:8px;width:420px;max-width:90vw;padding:0;overflow:hidden}.chat-model-dialog-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);font-weight:600;font-size:14px}.chat-model-dialog-close{background:none;border:none;color:var(--text-muted);cursor:var(--studio-cursor-pointer, pointer);font-size:20px;padding:0 4px}.chat-model-dialog-close:hover{color:var(--text-primary)}.chat-model-dialog-tabs{display:flex;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border)}.chat-model-dialog-tabs button{flex:1;background:none;border:none;color:var(--text-secondary);padding:8px 12px;cursor:var(--studio-cursor-pointer, pointer);font-size:13px;border-bottom:2px solid transparent}.chat-model-dialog-tabs button:hover{color:var(--text-primary)}.chat-model-dialog-tabs button.active{color:var(--accent-text);border-bottom-color:var(--accent-line)}.chat-model-dialog-body{padding:12px 16px;min-height:120px}.chat-model-dialog-label{display:block;font-size:12px;color:var(--text-secondary);margin-bottom:10px}.chat-model-dialog-input{display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg-input);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);font-size:13px;outline:none}.chat-model-dialog-input:focus{border-color:var(--accent-line)}select.chat-model-dialog-input{flex:1}.chat-model-dialog-btn{background:var(--bg-hover);border:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);border-radius:4px;color:var(--text-primary);padding:6px 12px;cursor:var(--studio-cursor-pointer, pointer);font-size:13px}.chat-model-dialog-btn:hover{background:var(--accent-soft)}.chat-model-dialog-btn.primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent-line)}.chat-model-dialog-btn.primary:hover{opacity:.9}.chat-model-dialog-footer{display:flex;gap:8px;justify-content:flex-end;padding:12px 16px;border-top:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border)}@media (max-width: 600px){.chat-root,.chat-root.sidebar-left{flex-direction:column-reverse!important}.chat-sidebar{width:100%!important;min-width:0!important;border-left:none!important;border-right:none!important;border-bottom:var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--border);max-height:50%}.chat-sidebar.visible{max-height:50%}.chat-sidebar.drop-target{width:100%!important;min-width:0!important;height:60px}.chat-sidebar.visible.drop-target{width:100%!important}.chat-sidebar-resize{display:none}.chat-msg-group{padding:2px 10px;gap:8px}.chat-msg-continuation{padding:0 10px 0 48px}.chat-msg-continuation.has-gif{padding-left:10px}.chat-msg-action{padding:4px 10px}.chat-avatar-col{width:30px}.chat-avatar{width:30px;height:30px;font-size:14px}.chat-msg-gif-inline{width:30px;height:30px}.chat-presence-bar{padding:4px 10px;gap:6px;flex-wrap:wrap}.chat-input-wrapper{padding:0 8px 8px}.chat-input{padding:6px 8px;font-size:14px}.chat-input-btn,.chat-gif-toggle{width:32px;height:32px;font-size:18px}.chat-reply-bar{padding:6px 8px;font-size:12px}.chat-msg-reply-ref{padding-left:24px;font-size:12px}.chat-msg-reply-ref:before{left:12px}.chat-msg-reply-ref-text{max-width:180px}.chat-voice-note{max-width:100%}.chat-msg-embed{height:200px}.chat-msg-video-wrap,.chat-msg-image-wrap{max-width:100%}.chat-code-block code{font-size:12px}.shiki{font-size:12px!important}.chat-emoji-picker{max-width:260px;width:260px}.chat-emoticon-dialog,.chat-font-dialog{min-width:0;max-width:calc(100vw - 24px);width:calc(100vw - 24px)}.chat-model-dialog{width:calc(100vw - 24px)}.chat-autocomplete-item{padding:6px 8px;font-size:13px}.chat-typing-bar,.chat-llm-status{padding:0 10px}.chat-recording-bar{padding:6px 8px}.chat-sidebar-pinned-wrap{min-height:120px}.chat-sidebar-toggle-btn svg,.chat-sidebar-collapse-btn svg{transform:rotate(90deg)}.chat-time-gap:before{left:10%;right:10%}}')),document.head.appendChild(r)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
- import { p as r } from "./index-Dm_2jZcu.js";
2
+ import { p as r } from "./index-fGaJgJ-s.js";
3
3
  export {
4
4
  r as plugins
5
5
  };
@@ -1,5 +1,5 @@
1
1
  import { render as p, createComponent as c } from "solid-js/web";
2
- import { s as e, C as u } from "./ChatRoot-1d-658Rr.js";
2
+ import { s as e, C as u } from "./ChatRoot-Ly8PORLd.js";
3
3
  function C(t, o) {
4
4
  e(o.repo), getComputedStyle(o).position === "static" && (o.style.position = "relative");
5
5
  const s = p(() => c(u, {
@@ -30,7 +30,7 @@
30
30
  "@inkandswitch/patchwork-elements": "^6.0.2",
31
31
  "@inkandswitch/patchwork-filesystem": "^0.2.9",
32
32
  "cute.txt": "^0.0.6",
33
- "solid-automerge": "^2.0.2",
33
+ "solid-automerge": "^2.1.0",
34
34
  "solid-js": "^1.9.11"
35
35
  },
36
36
  "devDependencies": {
@@ -318,7 +318,7 @@ var commentUI = (options) => {
318
318
  import { cursor as cursor2 } from "@automerge/automerge-repo/slim";
319
319
  import { getRegistry } from "@inkandswitch/patchwork-plugins";
320
320
 
321
- // node_modules/.pnpm/@inkandswitch+patchwork-providers-solid@0.2.8_@automerge+automerge-repo@2.6.0-subductio_6905546828d892b9e331a5daae96ed66/node_modules/@inkandswitch/patchwork-providers-solid/dist/index.js
321
+ // node_modules/.pnpm/@inkandswitch+patchwork-providers-solid@0.2.8_@automerge+automerge-repo@2.6.0-subductio_338b96d72659ff6d7779dae6acebdc97/node_modules/@inkandswitch/patchwork-providers-solid/dist/index.js
322
322
  import { createEffect, createSignal, onCleanup, onMount } from "solid-js";
323
323
  import { createStore, reconcile } from "solid-js/store";
324
324
  import * as Providers from "@inkandswitch/patchwork-providers";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/tool.tsx", "../src/lib/extensions/commentUI.ts", "../src/lib/extensions/comments.ts", "../node_modules/.pnpm/@inkandswitch+patchwork-providers-solid@0.2.8_@automerge+automerge-repo@2.6.0-subductio_6905546828d892b9e331a5daae96ed66/node_modules/@inkandswitch/patchwork-providers-solid/dist/index.js"],
3
+ "sources": ["../src/tool.tsx", "../src/lib/extensions/commentUI.ts", "../src/lib/extensions/comments.ts", "../node_modules/.pnpm/@inkandswitch+patchwork-providers-solid@0.2.8_@automerge+automerge-repo@2.6.0-subductio_338b96d72659ff6d7779dae6acebdc97/node_modules/@inkandswitch/patchwork-providers-solid/dist/index.js"],
4
4
  "sourcesContent": ["import { template as _$template } from \"solid-js/web\";\nimport { insert as _$insert } from \"solid-js/web\";\nimport { createComponent as _$createComponent } from \"solid-js/web\";\nvar _tmpl$ = /*#__PURE__*/_$template(`<div style=\"width:100%;height:100%;overflow:hidden;position:relative;background:var(--studio-fill, white)\"><div style=display:flex;height:100%><div style=position:relative;flex:1;height:100%>`);\nimport { CodeMirror } from \"./lib/codemirror.tsx\";\nimport { render } from \"solid-js/web\";\nimport { RangeSet } from \"@codemirror/state\";\nimport { Decoration } from \"@codemirror/view\";\nimport { commentUI } from \"./lib/extensions/commentUI.ts\";\nimport { cursor } from \"@automerge/automerge-repo/slim\";\nimport { getRegistry } from \"@inkandswitch/patchwork-plugins\";\nimport { subscribeDoc, subscribe } from \"@inkandswitch/patchwork-providers-solid\";\nimport { createMemo, createResource, Show } from \"solid-js\";\nimport { createCommentForRange } from \"./lib/extensions/comments.ts\";\nconst PATH = [\"content\"];\nexport function CodeMirrorEditor(props) {\n const baseline = subscribe(props.element, {\n type: \"draft:baseline\",\n url: props.handle.url\n }, {\n heads: null\n });\n const commentEntries = subscribe(props.element, {\n type: \"patchwork:comments\"\n }, []);\n const [focusDoc, focusHandle] = subscribeDoc(props.element, {\n type: \"patchwork:focus\"\n });\n const contactUrl = subscribe(props.element, {\n type: \"patchwork:contact\"\n });\n const [commentTargets] = createResource(commentEntries, entries => getDedupedCommentTargets(entries, props.handle.url, props.repo), {\n initialValue: []\n });\n const focusRefUrls = createMemo(() => {\n const doc = focusDoc();\n return [...Object.keys(doc?.selection ?? {}), ...Object.keys(doc?.highlight ?? {})];\n });\n const [emphasisTargets] = createResource(focusRefUrls, async urls => resolveSubDocUrlsOfDoc(urls, props.handle.url, props.repo), {\n initialValue: []\n });\n const scrollTarget = createMemo(() => {\n let from = Infinity;\n let to = -Infinity;\n for (const ref of emphasisTargets()) {\n const positions = ref.rangePositions();\n if (!positions) continue;\n const [start, end] = positions;\n from = Math.min(from, start);\n to = Math.max(to, end);\n }\n return from <= to ? [from, to] : null;\n });\n let lastEmittedUrl;\n const onChangeSelection = (from, to) => {\n const handle = focusHandle();\n if (!handle) return;\n const nextUrl = props.handle.sub(...PATH, cursor(from, to)).url;\n if (nextUrl === lastEmittedUrl) return;\n handle.change(doc => {\n doc.selection = {\n [nextUrl]: true\n };\n });\n lastEmittedUrl = nextUrl;\n };\n const decorations = () => {\n const targetRefs = commentTargets();\n const emphasisRefs = emphasisTargets();\n return RangeSet.of(buildCommentDecorations(targetRefs, emphasisRefs), true\n // sort ranges\n );\n };\n const createThreadForRange = (from, to) => {\n const url = contactUrl();\n if (!url) {\n console.warn(\"Cannot create comment: no contactUrl available\");\n return null;\n }\n return createCommentForRange(props.handle, PATH, from, to, url);\n };\n const threadAtPos = pos => {\n const threadByTarget = /* @__PURE__ */new Map();\n for (const entry of commentEntries()) {\n threadByTarget.set(entry.targetUrl, entry.threadUrl);\n }\n for (const handle of commentTargets()) {\n const positions = handle.rangePositions();\n if (!positions) continue;\n const [start, end] = positions;\n if (start === end || pos < start || pos > end) continue;\n const threadUrl = threadByTarget.get(handle.url);\n if (threadUrl) return {\n threadUrl,\n from: start\n };\n }\n return null;\n };\n const findThreadByUrl = threadUrl => {\n const threads = props.handle.doc()?.[\"@comments\"]?.threads ?? [];\n return threads.find(thread => props.handle.sub(\"@comments\", \"threads\", {\n id: thread.id\n }).url === threadUrl);\n };\n const watchThreadForClose = (threadUrl, close) => {\n const contact = contactUrl();\n const hasOwnDraft = thread => thread.comments.some(c => c.contactUrl === contact && (c.draftContent !== void 0 || c.content === void 0));\n const seed = findThreadByUrl(threadUrl);\n let sawDraft = seed ? hasOwnDraft(seed) : false;\n const onChange = () => {\n const thread = findThreadByUrl(threadUrl);\n if (!thread) return close();\n if (hasOwnDraft(thread)) sawDraft = true;else if (sawDraft) close();\n };\n props.handle.on(\"change\", onChange);\n return () => props.handle.off(\"change\", onChange);\n };\n const onClosePopover = threadUrl => {\n const contact = contactUrl();\n const isEmptyOwnDraft = c => c.contactUrl === contact && c.content === void 0 && (c.draftContent === void 0 || c.draftContent.trim() === \"\");\n const thread = findThreadByUrl(threadUrl);\n if (!thread || !thread.comments.some(isEmptyOwnDraft)) return;\n const threadId = thread.id;\n queueMicrotask(() => {\n props.handle.change(doc => {\n const list = doc[\"@comments\"]?.threads;\n if (!list) return;\n const index = list.findIndex(t => t.id === threadId);\n if (index === -1) return;\n const target = list[index];\n for (let i = target.comments.length - 1; i >= 0; i--) {\n if (isEmptyOwnDraft(target.comments[i])) target.comments.splice(i, 1);\n }\n if (target.comments.length === 0) list.splice(index, 1);\n });\n });\n };\n const [datatypeExtensions] = createResource(() => loadCodeMirrorExtensionsForDoc(props.handle));\n const extensions = () => [commentUI({\n createThreadForRange,\n threadAtPos,\n watchThreadForClose,\n onClose: onClosePopover\n }), ...(datatypeExtensions() ?? [])];\n return (() => {\n var _el$ = _tmpl$(),\n _el$2 = _el$.firstChild,\n _el$3 = _el$2.firstChild;\n _$insert(_el$3, _$createComponent(Show, {\n get when() {\n return datatypeExtensions.state === \"ready\";\n },\n get children() {\n return _$createComponent(CodeMirror, {\n get handle() {\n return props.handle;\n },\n get repo() {\n return props.repo;\n },\n path: PATH,\n decorations: decorations,\n baseline: () => baseline()?.heads ?? null,\n get extensions() {\n return extensions();\n },\n onChangeSelection: onChangeSelection,\n scrollTarget: scrollTarget,\n contactUrl: () => contactUrl() ?? null\n });\n }\n }));\n return _el$;\n })();\n}\nexport const mount = (handle, element) => render(() => _$createComponent(CodeMirrorEditor, {\n handle: handle,\n get repo() {\n return element.repo;\n },\n element: element\n}), element);\nasync function getDedupedCommentTargets(comments, docUrl, repo) {\n if (!comments) return [];\n const overlappingRefs = /* @__PURE__ */new Set();\n for (const comment of comments) {\n if (comment.targetUrl.startsWith(docUrl)) {\n const target = await repo.find(comment.targetUrl);\n overlappingRefs.add(target);\n }\n }\n return Array.from(overlappingRefs);\n}\nasync function resolveSubDocUrlsOfDoc(urls, docUrl, repo) {\n const refs = /* @__PURE__ */new Set();\n for (const url of urls) {\n if (url.startsWith(docUrl)) {\n refs.add(await repo.find(url));\n }\n }\n return Array.from(refs);\n}\nfunction buildCommentDecorations(targetRefs, emphasisRefs) {\n const out = [];\n for (const ref of targetRefs) {\n const positions = ref.rangePositions();\n if (!positions) continue;\n const [start, end] = positions;\n if (start === end) continue;\n const isEmphasised = emphasisRefs.some(s => s.overlaps(ref));\n out.push(Decoration.mark({\n attributes: {\n style: commentTargetStyle(isEmphasised)\n }\n }).range(start, end));\n }\n return out;\n}\nfunction commentTargetStyle(isEmphasised) {\n const paper = isEmphasised ? \"56%\" : \"82%\";\n return `\n border-bottom: 2px solid var(--text-editor-secondary-text);\n background-color: color-mix(in oklch, var(--studio-secondary), var(--text-editor-fill) ${paper});\n `;\n}\nasync function loadCodeMirrorExtensionsForDoc(handle) {\n const docType = handle.doc()?.[\"@patchwork\"]?.type;\n const registry = getRegistry(\"codemirror:extension\");\n const loaded = await registry.loadAll(registry.filter(ext => {\n return ext.supportedDatatypes === \"*\" || Array.isArray(ext.supportedDatatypes) && ext.supportedDatatypes.includes(docType);\n }));\n return loaded.flatMap(ext => {\n const impl = ext.module;\n return Array.isArray(impl) ? impl : [impl];\n });\n}", "import {\n Extension,\n StateEffect,\n StateField,\n type EditorState,\n} from \"@codemirror/state\";\nimport {\n EditorView,\n showTooltip,\n type Tooltip,\n type TooltipView,\n} from \"@codemirror/view\";\nimport type { AutomergeUrl } from \"@automerge/automerge-repo/slim\";\nimport { COMMENT_THREAD_TYPE } from \"./comments.ts\";\n\n// The data hooks the editor UI needs from its host (the CodeMirror tool). The\n// extension owns all the DOM/positioning/lifecycle; the host owns everything\n// that needs the repo, the current contact, or the comment index.\nexport type CommentUIOptions = {\n // Create a thread targeting [from, to] and return its url, or null if it\n // couldn't be created (e.g. no current contact). Called when the floating\n // \"Comment\" button is clicked.\n createThreadForRange: (from: number, to: number) => AutomergeUrl | null;\n // Map a document position to the thread whose commented range covers it (and\n // that range's start), or null. Called when the user clicks commented text so\n // we can pop that thread open under the range's start.\n threadAtPos: (\n pos: number\n ) => { threadUrl: AutomergeUrl; from: number } | null;\n // Watch a thread and invoke `close` once its pending draft is submitted (or\n // cancelled, or the thread is removed). Returns an unsubscribe. Lets the\n // popover dismiss itself the moment the comment is saved.\n watchThreadForClose: (threadUrl: AutomergeUrl, close: () => void) => () => void;\n // Called whenever a popover closes, for any reason. Lets the host discard an\n // abandoned, never-filled-in draft so dismissing the popover doesn't litter\n // the document with empty comments.\n onClose: (threadUrl: AutomergeUrl) => void;\n};\n\n// Which thread the popover is showing, and the document position it hangs off.\ntype PopoverState = { threadUrl: AutomergeUrl; anchor: number };\n\nconst openPopover = StateEffect.define<PopoverState>();\nconst closePopover = StateEffect.define<null>();\n// Hide the floating \"Comment\" button until the next selection change (Escape).\nconst dismissButton = StateEffect.define<null>();\n\n// Mutable UI state shared across the extension's pieces (not editor state\n// because it isn't versioned/undoable): the thread we most recently dismissed,\n// so a click that stays inside it doesn't immediately pop it back open.\ntype CommentUIState = { suppressed: AutomergeUrl | null };\n\nconst POPOVER_CLASS = \"cm-comment-popover\";\n\n// A speech-bubble icon + \"Comment\" label, shown floating above the selection.\nconst buildCommentButton = (\n from: number,\n to: number,\n head: number,\n view: EditorView,\n options: CommentUIOptions\n): HTMLElement => {\n const button = document.createElement(\"button\");\n button.className = \"cm-comment-button\";\n button.setAttribute(\"aria-label\", \"Comment\");\n\n button.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\"\n fill=\"currentColor\" stroke=\"none\"/>\n </svg>\n <span>Comment</span>\n `;\n\n // Without this, the browser focuses the button on mousedown, the editor\n // blurs, the selection collapses, our tooltip source returns null, and\n // CodeMirror tears down the button before `click` fires \u2014 so the first\n // press silently does nothing and the user has to click twice. Swallowing\n // mousedown keeps the editor focused and the selection (and button) alive\n // long enough for the click to land.\n button.addEventListener(\"mousedown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n });\n\n button.addEventListener(\"click\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n const threadUrl = options.createThreadForRange(from, to);\n if (!threadUrl) return;\n // Open the popover right where the button was (the selection head).\n view.dispatch({ effects: openPopover.of({ threadUrl, anchor: head }) });\n });\n\n return button;\n};\n\n// The popover body: the shared comment-thread tool, rendered inline via the\n// `patchwork-view` custom element. It's mounted inside `view.dom`, so the\n// element's provider events (repo, contact, \u2026) still bubble up to the host.\nconst buildThreadPopover = (\n view: EditorView,\n state: PopoverState,\n options: CommentUIOptions,\n ui: CommentUIState\n): TooltipView => {\n const dom = document.createElement(\"div\");\n dom.className = POPOVER_CLASS;\n\n const threadView = document.createElement(\"patchwork-view\");\n threadView.setAttribute(\"doc-url\", state.threadUrl);\n threadView.setAttribute(\"tool-id\", COMMENT_THREAD_TYPE);\n dom.append(threadView);\n\n const close = () => view.dispatch({ effects: closePopover.of(null) });\n\n // Dismiss on a click anywhere outside the popover, or on Escape. Both are\n // armed on a deferred tick so the very interaction that opened the popover\n // (the button click / the click on commented text) doesn't also close it.\n const onOutsideMouseDown = (event: MouseEvent) => {\n if (!dom.contains(event.target as Node)) close();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") close();\n };\n const doc = view.win.document;\n const armTimer = view.win.setTimeout(() => {\n doc.addEventListener(\"mousedown\", onOutsideMouseDown, true);\n doc.addEventListener(\"keydown\", onKeyDown, true);\n }, 0);\n\n // Close as soon as the draft is submitted (or the thread goes away).\n const stopWatch = options.watchThreadForClose(state.threadUrl, close);\n\n return {\n dom,\n destroy() {\n view.win.clearTimeout(armTimer);\n doc.removeEventListener(\"mousedown\", onOutsideMouseDown, true);\n doc.removeEventListener(\"keydown\", onKeyDown, true);\n stopWatch();\n // Remember this thread as dismissed so clicking within its range again\n // doesn't immediately reopen it (cleared once a click lands elsewhere).\n ui.suppressed = state.threadUrl;\n options.onClose(state.threadUrl);\n },\n };\n};\n\nconst buttonTooltip = (\n state: EditorState,\n options: CommentUIOptions\n): Tooltip | null => {\n const sel = state.selection.main;\n // A read-only editor can't take the comment write, so don't offer the button.\n if (sel.empty || state.readOnly) return null;\n\n // Anchor the button at the drag tail (the selection head) rather than the\n // start, so dragging left-to-right lands it on the right and right-to-left\n // on the left.\n return {\n pos: sel.head,\n above: true,\n strictSide: false,\n arrow: false,\n create: (view) => ({\n dom: buildCommentButton(sel.from, sel.to, sel.head, view, options),\n }),\n };\n};\n\nconst popoverTooltip = (\n state: PopoverState,\n options: CommentUIOptions,\n ui: CommentUIState\n): Tooltip => ({\n pos: state.anchor,\n above: false, // comes out underneath the anchor\n strictSide: false,\n arrow: false,\n create: (view) => buildThreadPopover(view, state, options, ui),\n});\n\ntype FieldValue = {\n popover: PopoverState | null;\n // The floating button is hidden while this is true \u2014 after Escape, or after a\n // comment is added \u2014 until a fresh selection re-arms it.\n buttonDismissed: boolean;\n tooltip: Tooltip | null;\n};\n\n// A single field driving the one tooltip slot: the thread popover when one is\n// open, otherwise the selection's \"Comment\" button.\nconst commentUIField = (options: CommentUIOptions, ui: CommentUIState) =>\n StateField.define<FieldValue>({\n create: (state) => ({\n popover: null,\n buttonDismissed: false,\n tooltip: buttonTooltip(state, options),\n }),\n update(value, tr) {\n let popover = value.popover;\n let buttonDismissed = value.buttonDismissed;\n let popoverChanged = false;\n\n // Read-only can flip mid-session: entering it closes any open popover \u2014\n // its reply box writes to a doc that rejects writes \u2014 and the flip\n // itself must recompute the tooltip so the button hides/re-arms.\n const readOnlyChanged = tr.startState.readOnly !== tr.state.readOnly;\n if (readOnlyChanged && tr.state.readOnly && popover) {\n popover = null;\n popoverChanged = true;\n }\n\n // Keep the popover pinned to its text as the document shifts under it.\n if (popover && tr.docChanged) {\n popover = { ...popover, anchor: tr.changes.mapPos(popover.anchor) };\n popoverChanged = true;\n }\n for (const effect of tr.effects) {\n if (effect.is(openPopover)) {\n popover = effect.value;\n popoverChanged = true;\n } else if (effect.is(closePopover)) {\n popover = null;\n popoverChanged = true;\n // A comment was just added (or dismissed): don't flash the button\n // back up over the still-selected text.\n buttonDismissed = true;\n } else if (effect.is(dismissButton)) {\n buttonDismissed = true;\n }\n }\n // Any fresh selection re-arms the button.\n if (tr.selection) buttonDismissed = false;\n\n if (popover) {\n // Reuse the exact same tooltip object unless the popover state itself\n // changed. Otherwise an unrelated transaction (a stray selection\n // change, an extension reconfigure, \u2026) would hand CodeMirror a fresh\n // Tooltip and it would tear down and remount the thread view mid-edit.\n if (!popoverChanged) {\n return buttonDismissed === value.buttonDismissed\n ? value\n : { ...value, buttonDismissed };\n }\n return {\n popover,\n buttonDismissed,\n tooltip: popoverTooltip(popover, options, ui),\n };\n }\n\n // No popover: show the selection button, unless it's been dismissed.\n // Recompute only when something relevant changed.\n if (\n !popoverChanged &&\n !tr.docChanged &&\n !tr.selection &&\n !readOnlyChanged &&\n buttonDismissed === value.buttonDismissed\n ) {\n return value;\n }\n return {\n popover: null,\n buttonDismissed,\n tooltip: buttonDismissed ? null : buttonTooltip(tr.state, options),\n };\n },\n provide: (field) => showTooltip.from(field, (value) => value.tooltip),\n });\n\n// Editor-level interactions: click commented text to (re)open its thread, and\n// Escape to dismiss the floating button.\nconst commentInteractions = (\n options: CommentUIOptions,\n ui: CommentUIState,\n field: StateField<FieldValue>\n): Extension =>\n EditorView.domEventHandlers({\n mousedown(event, view) {\n if (\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.altKey ||\n event.shiftKey\n ) {\n return false;\n }\n // Clicks inside an open popover are the thread tool's own business.\n if ((event.target as HTMLElement | null)?.closest(\".\" + POPOVER_CLASS)) {\n return false;\n }\n // Read-only: don't open threads either \u2014 the popover's reply box would\n // write into a doc that rejects writes.\n if (view.state.readOnly) return false;\n const pos = view.posAtCoords({ x: event.clientX, y: event.clientY });\n if (pos == null) return false;\n const hit = options.threadAtPos(pos);\n if (!hit) {\n ui.suppressed = null; // clicked away from any comment; re-arm reopening\n return false;\n }\n // Don't reopen the thread we just dismissed while the click stays inside\n // it \u2014 the user has to click elsewhere (or another comment) first.\n if (hit.threadUrl === ui.suppressed) return false;\n ui.suppressed = null;\n view.dispatch({\n effects: openPopover.of({ threadUrl: hit.threadUrl, anchor: hit.from }),\n });\n return false; // let the click also move the cursor as usual\n },\n keydown(event, view) {\n if (event.key !== \"Escape\") return false;\n const state = view.state.field(field, false);\n // While a popover is open its own Escape handler wins (it also works when\n // the popover's textarea holds focus); here we only hide the button.\n if (!state || state.popover || !state.tooltip) return false;\n view.dispatch({ effects: dismissButton.of(null) });\n return true;\n },\n });\n\n// Global colours are lifted into local --cm-comment-* tokens in a\n// :root/:host/[theme] block so they re-evaluate when the theme swaps. This\n// derivation can't live in the baseTheme below \u2014 CodeMirror prefixes every\n// non-\"&\" selector with the editor's scope class, so a `:root` key would\n// become `.cm... :root` and never match. It's injected as a plain stylesheet\n// instead, and the button reads only the derived tokens. The button is editor\n// UI, so it derives from --editor-* (not --studio-*, which is studio chrome).\nconst COMMENT_BUTTON_VARS_ID = \"cm-comment-button-vars\";\nconst ensureCommentButtonVars = (): void => {\n if (\n typeof document === \"undefined\" ||\n document.getElementById(COMMENT_BUTTON_VARS_ID)\n ) {\n return;\n }\n const style = document.createElement(\"style\");\n style.id = COMMENT_BUTTON_VARS_ID;\n style.textContent = `\n :root, :host, [theme] {\n /* the button sits on the editor surface: bg is the plain editor fill,\n text is the editor ink, and hover lifts a gentle one step up the fill\n ramp. see --text-editor-* in the theme. */\n --cm-comment-button-fg: var(--text-editor-line, #0a2b23);\n --cm-comment-button-bg: var(--text-editor-fill, #35f7ca);\n --cm-comment-button-bg-hover: var(--text-editor-fill-offset-10, #2ce0b6);\n }\n `;\n document.head.append(style);\n};\n\nconst commentUITheme = EditorView.baseTheme({\n \".cm-tooltip:has(.cm-comment-button)\": {\n border: \"none\",\n background: \"transparent\",\n boxShadow: \"none\",\n },\n \".cm-comment-button\": {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"5px\",\n padding: \"4px 9px\",\n font: \"inherit\",\n fontSize: \"12px\",\n fontWeight: \"500\",\n lineHeight: \"1\",\n color: \"var(--cm-comment-button-fg)\",\n background: \"var(--cm-comment-button-bg)\",\n border: \"none\",\n borderRadius: \"6px\",\n boxShadow: \"0 2px 8px rgba(0, 0, 0, 0.25)\",\n cursor: \"var(--studio-cursor-pointer, pointer)\",\n userSelect: \"none\",\n whiteSpace: \"nowrap\",\n transition: \"background-color max(1ms, calc(0.15s * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)))\",\n },\n \".cm-comment-button:hover\": {\n background: \"var(--cm-comment-button-bg-hover)\",\n },\n \".cm-comment-button svg\": {\n display: \"block\",\n },\n // The thread tool carries its own card (background, border, padding), so the\n // tooltip wrapper is just a transparent, softly-lifted host for it.\n \".cm-tooltip:has(.cm-comment-popover)\": {\n border: \"none\",\n background: \"transparent\",\n boxShadow: \"none\",\n },\n \".cm-comment-popover\": {\n width: \"min(360px, 92vw)\",\n marginTop: \"6px\",\n fontFamily: \"var(--editor-family)\",\n filter: \"drop-shadow(0 4px 14px rgba(0, 0, 0, 0.25))\",\n },\n // The popover supplies its own frame (the tooltip wrapper's shadow), so the\n // thread card inside drops its own border and shadow to avoid doubling up.\n \".cm-comment-popover .comments-thread-card\": {\n border: \"0\",\n boxShadow: \"none\",\n },\n // The draft textarea is width:100% with its own padding + border; without\n // border-box it spills out of the card's right edge (the card's own reset is\n // scoped to the sidebar panel, which the popover isn't inside).\n \".cm-comment-popover .comment-draft-editor\": {\n boxSizing: \"border-box\",\n maxWidth: \"100%\",\n minWidth: \"0\",\n width: \"100%\",\n },\n \".cm-comment-popover .comment-draft-editor .cm-content\": {\n minHeight: \"0\",\n minWidth: \"0\",\n margin: \"0\",\n padding: \"8px\",\n },\n \".cm-comment-popover .comment-draft-editor .cm-line\": {\n margin: \"0\",\n padding: \"0\",\n },\n \".cm-comment-popover .comment-draft-editor .cm-scroller\": {\n minWidth: \"0\",\n },\n});\n\n// The comment UI: the floating \"Comment\" button on a selection, and the thread\n// popover it (and clicking commented text) opens.\nexport const commentUI = (options: CommentUIOptions): Extension => {\n ensureCommentButtonVars();\n const ui: CommentUIState = { suppressed: null };\n const field = commentUIField(options, ui);\n return [field, commentInteractions(options, ui, field), commentUITheme];\n};\n", "import {\n cursor,\n type AutomergeUrl,\n type DocHandle,\n} from \"@automerge/automerge-repo/slim\";\n\nexport type DocWithComments = {\n \"@comments\"?: {\n threads: CommentThread[];\n };\n};\n\n/**\n * The `@patchwork.type` stamped on a comment thread so a datatype (and thus a\n * relevant tool) can be resolved when the thread's subdocument is opened on its\n * own. Mirrors `COMMENT_THREAD_TYPE` in the comments-view module.\n */\nexport const COMMENT_THREAD_TYPE = \"comment-thread\";\n\nexport type CommentThread = {\n id: string;\n refs: AutomergeUrl[];\n isResolved: boolean;\n comments: Comment[];\n \"@patchwork\"?: { type: string; title?: string };\n};\n\nexport type Comment = {\n id: string;\n content?: string;\n draftContent?: string;\n contactUrl: AutomergeUrl;\n timestamp: number;\n};\n\n// Creates a thread (with one empty, unfilled comment) targeting [from, to] and\n// returns the thread's url so the caller can open it \u2014 e.g. in a popover \u2014 for\n// the author to fill in. An abandoned, never-filled comment should be cleaned\n// up by the caller (see the comment UI's `onClose`).\nexport function createCommentForRange(\n handle: DocHandle<unknown>,\n path: readonly string[],\n from: number,\n to: number,\n contactUrl: AutomergeUrl\n): AutomergeUrl {\n const targetUrl = handle.sub(...path, cursor(from, to)).url;\n const threadId = crypto.randomUUID();\n const commentId = crypto.randomUUID();\n\n handle.change((doc: DocWithComments) => {\n doc[\"@comments\"] ??= { threads: [] };\n doc[\"@comments\"].threads.push({\n id: threadId,\n refs: [targetUrl],\n isResolved: false,\n comments: [\n {\n id: commentId,\n contactUrl,\n timestamp: Date.now(),\n },\n ],\n \"@patchwork\": { type: COMMENT_THREAD_TYPE },\n });\n });\n\n return handle.sub(\"@comments\", \"threads\", { id: threadId }).url;\n}\n", "import { createEffect, createSignal, onCleanup, onMount, } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\nimport * as Providers from \"@inkandswitch/patchwork-providers\";\nfunction resolveElement(source) {\n return typeof source === \"function\" ? source() : source;\n}\n/**\n * Generic reactive request. Resolves the first value a provider emits for\n * `selector` (via the one-shot `request` helper) and returns an accessor that\n * reads `undefined` until then. `T` is the response type.\n */\nexport function request(element, selector) {\n const [value, setValue] = createSignal(undefined);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n Providers.request(target, selector).then((v) => {\n if (v == null)\n return;\n setValue(() => v);\n });\n });\n return value;\n}\nexport function subscribe(element, selector, initialValue) {\n const [value, setValue] = createSignal(initialValue);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n const unsubscribe = Providers.subscribe(target, selector, setValue);\n onCleanup(unsubscribe);\n });\n return value;\n}\n/**\n * Store-backed subscription. Use this when a consumer wants Solid's\n * fine-grained nested reactivity for incoming JSON object or array snapshots.\n * Requires an initial object/array so the store has a stable root.\n *\n * `reconcile` preserves stable object/array identity where possible, so this\n * helper is not a good fit when the top-level value is used as an identity key\n * for resources or memos.\n */\nexport function subscribeReconciled(element, selector, initialValue) {\n const [store, setStore] = createStore(initialValue);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n const unsubscribe = Providers.subscribe(target, selector, (v) => {\n setStore(reconcile(v));\n });\n onCleanup(unsubscribe);\n });\n return store;\n}\n/**\n * Handle-specialized subscription. Use when the answering provider emits an\n * `AutomergeUrl`. The handle is recovered locally from the global repo\n * (`window.repo`), so it stays fully live \u2014 reads project reactively and writes go\n * straight back to the same repo. Returns `[doc, handle]` matching the shape\n * of `solid-automerge`'s `useDocument`; both read `undefined` until the first\n * url arrives. `T` is the doc shape inside the handle.\n */\nexport function subscribeDoc(element, selector) {\n const [handle, setHandle] = createSignal(undefined);\n onMount(() => {\n const target = resolveElement(element);\n if (!target)\n return;\n let canceled = false;\n const unsubscribe = Providers.subscribe(target, selector, (url) => {\n if (!url)\n return;\n const repo = \"repo\" in window ? window.repo : undefined;\n if (!repo)\n return;\n void Promise.resolve(repo.find(url)).then((h) => {\n if (canceled)\n return;\n setHandle(() => h);\n });\n });\n onCleanup(() => {\n canceled = true;\n unsubscribe();\n });\n });\n // Mirror the doc into a store by `reconcile`-ing against the *materialized*\n // snapshot (`handle.doc()`) on every change, rather than replaying the\n // change's incremental patches (as `solid-automerge`'s `createDocumentProjection`\n // / `autoproduce` does).\n //\n // A whole-value write such as `doc.list = [...]` is lowered by Automerge to\n // `putObjectFromHydrate`, whose patch stream is a `put` that materializes the\n // new container *plus* per-element `insert` patches. Replaying that delta with\n // `applyPatches` double-applies the contents \u2014 the `put` seeds `[a, b]`, then\n // the inserts splice `a, b` in again, yielding `[a, b, a, b]` \u2014 even though the\n // document itself is correct. The materialized snapshot is always\n // authoritative, so reconciling against it is robust to any valid change,\n // whole-array reassignment included.\n const [store, setStore] = createStore({});\n const [ready, setReady] = createSignal(false);\n createEffect(() => {\n const h = handle();\n if (!h) {\n setReady(false);\n return;\n }\n const sync = () => {\n setStore(reconcile((h.doc() ?? {})));\n setReady(true);\n };\n sync();\n h.on(\"change\", sync);\n onCleanup(() => h.off(\"change\", sync));\n });\n const doc = () => (ready() ? store : undefined);\n return [doc, handle];\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["cursor", "subscribe", "subscribe", "cursor"]
@@ -35,7 +35,7 @@
35
35
  "@inkandswitch/patchwork-plugins": "^1.2.5",
36
36
  "@inkandswitch/patchwork-providers": "^0.5.2",
37
37
  "@inkandswitch/patchwork-providers-solid": "^0.2.8",
38
- "solid-automerge": "^2.0.2",
38
+ "solid-automerge": "^2.1.0",
39
39
  "solid-js": "^1.9.9",
40
40
  "vite-plugin-wasm": "^3.5.0"
41
41
  },
@@ -719,9 +719,6 @@ function makeDocumentProjection(handle) {
719
719
  }
720
720
  handle.on("change", patch);
721
721
  handle.on("delete", ondelete);
722
- handle.whenReady().then(() => {
723
- set(structuredClone(handle.doc()));
724
- });
725
722
  return doc;
726
723
  }
727
724
  const access = (v) => typeof v === "function" && !v.length ? v() : v;
@@ -744,12 +741,11 @@ function useDocHandle(url, options) {
744
741
  if (options?.["~skipInitialValue"]) return void 0;
745
742
  const unwrappedURL = access(url);
746
743
  if (!unwrappedURL) return void 0;
747
- const state = repo.findWithProgress(unwrappedURL).peek();
748
- return state.state === "ready" ? state.handle : void 0;
744
+ return peekReadyHandle(repo, unwrappedURL);
749
745
  }
750
746
  const [handle, { mutate }] = createResource(
751
747
  url,
752
- (url2) => repo.findWithProgress(url2).whenReady(),
748
+ (url2) => repo.find(url2),
753
749
  {
754
750
  initialValue: getExistingHandle()
755
751
  }
@@ -761,6 +757,17 @@ function useDocHandle(url, options) {
761
757
  });
762
758
  return handle;
763
759
  }
760
+ function isQueryable(repo) {
761
+ return typeof repo.query == "function";
762
+ }
763
+ function peekReadyHandle(repo, url) {
764
+ if (isQueryable(repo)) {
765
+ const state2 = repo.query(url).state();
766
+ return state2.status == "ready" ? state2.handle : void 0;
767
+ }
768
+ const state = repo.findWithProgress(url).peek();
769
+ return state.state == "ready" ? state.handle : void 0;
770
+ }
764
771
  function useDocument(url, options) {
765
772
  const handle = useDocHandle(url, options);
766
773
  return [createDocumentProjection(handle), handle];
@@ -2903,4 +2910,4 @@ export {
2903
2910
  renderCommentThread,
2904
2911
  renderCommentsView
2905
2912
  };
2906
- //# sourceMappingURL=main-wSSvAVfi.js.map
2913
+ //# sourceMappingURL=main-IR1Yfgas.js.map