@creaditor/newsletter-starterkit 1.0.56 → 1.0.57

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 (119) hide show
  1. package/dist/1142.creaditor.bundle.js +1 -1
  2. package/dist/1142.creaditor.bundle.js.gz +0 -0
  3. package/dist/1260.creaditor.bundle.js +112 -63
  4. package/dist/1260.creaditor.bundle.js.gz +0 -0
  5. package/dist/1271.creaditor.bundle.js +544 -1
  6. package/dist/1271.creaditor.bundle.js.gz +0 -0
  7. package/dist/1334.creaditor.bundle.js +3 -3
  8. package/dist/1334.creaditor.bundle.js.gz +0 -0
  9. package/dist/170.creaditor.bundle.js +149 -22
  10. package/dist/170.creaditor.bundle.js.gz +0 -0
  11. package/dist/211.creaditor.bundle.js +1 -1
  12. package/dist/211.creaditor.bundle.js.gz +0 -0
  13. package/dist/2234.creaditor.bundle.js +121 -1
  14. package/dist/2234.creaditor.bundle.js.gz +0 -0
  15. package/dist/2590.creaditor.bundle.js +1 -1
  16. package/dist/2590.creaditor.bundle.js.gz +0 -0
  17. package/dist/271.creaditor.bundle.js +6 -6
  18. package/dist/271.creaditor.bundle.js.gz +0 -0
  19. package/dist/2765.creaditor.bundle.js +1 -1
  20. package/dist/2765.creaditor.bundle.js.gz +0 -0
  21. package/dist/2956.creaditor.bundle.js +1 -1
  22. package/dist/2956.creaditor.bundle.js.gz +0 -0
  23. package/dist/3521.creaditor.bundle.js +2 -2
  24. package/dist/3521.creaditor.bundle.js.gz +0 -0
  25. package/dist/353.creaditor.bundle.js +3 -3
  26. package/dist/353.creaditor.bundle.js.gz +0 -0
  27. package/dist/3553.creaditor.bundle.js +1 -1
  28. package/dist/3553.creaditor.bundle.js.gz +0 -0
  29. package/dist/3606.creaditor.bundle.js +12 -4
  30. package/dist/3606.creaditor.bundle.js.gz +0 -0
  31. package/dist/3932.creaditor.bundle.js +4 -4
  32. package/dist/3932.creaditor.bundle.js.gz +0 -0
  33. package/dist/4061.creaditor.bundle.js +177 -0
  34. package/dist/4061.creaditor.bundle.js.LICENSE.txt +23 -0
  35. package/dist/4061.creaditor.bundle.js.LICENSE.txt.gz +0 -0
  36. package/dist/4061.creaditor.bundle.js.gz +0 -0
  37. package/dist/4186.creaditor.bundle.js +5 -1
  38. package/dist/4186.creaditor.bundle.js.gz +0 -0
  39. package/dist/4288.creaditor.bundle.js +10 -10
  40. package/dist/4288.creaditor.bundle.js.gz +0 -0
  41. package/dist/4475.creaditor.bundle.js +1 -1
  42. package/dist/4475.creaditor.bundle.js.gz +0 -0
  43. package/dist/453.creaditor.bundle.js +8 -7
  44. package/dist/453.creaditor.bundle.js.gz +0 -0
  45. package/dist/4639.creaditor.bundle.js +1 -1
  46. package/dist/4639.creaditor.bundle.js.gz +0 -0
  47. package/dist/4762.creaditor.bundle.js +4 -4
  48. package/dist/4762.creaditor.bundle.js.gz +0 -0
  49. package/dist/4770.creaditor.bundle.js +3 -3
  50. package/dist/4770.creaditor.bundle.js.gz +0 -0
  51. package/dist/5133.creaditor.bundle.js +3 -3
  52. package/dist/5133.creaditor.bundle.js.gz +0 -0
  53. package/dist/5379.creaditor.bundle.js +70 -0
  54. package/dist/5379.creaditor.bundle.js.gz +0 -0
  55. package/dist/5391.creaditor.bundle.js +1 -1
  56. package/dist/5391.creaditor.bundle.js.gz +0 -0
  57. package/dist/567.creaditor.bundle.js +469 -364
  58. package/dist/567.creaditor.bundle.js.gz +0 -0
  59. package/dist/5849.creaditor.bundle.js +2 -2
  60. package/dist/5849.creaditor.bundle.js.gz +0 -0
  61. package/dist/589.creaditor.bundle.js +25 -8
  62. package/dist/589.creaditor.bundle.js.gz +0 -0
  63. package/dist/5909.creaditor.bundle.js +651 -0
  64. package/dist/5909.creaditor.bundle.js.gz +0 -0
  65. package/dist/5926.creaditor.bundle.js +216 -34
  66. package/dist/5926.creaditor.bundle.js.gz +0 -0
  67. package/dist/638.creaditor.bundle.js +49 -20
  68. package/dist/638.creaditor.bundle.js.gz +0 -0
  69. package/dist/6814.creaditor.bundle.js +1 -1
  70. package/dist/6814.creaditor.bundle.js.gz +0 -0
  71. package/dist/7209.creaditor.bundle.js +98 -56
  72. package/dist/7209.creaditor.bundle.js.gz +0 -0
  73. package/dist/752.creaditor.bundle.js +6 -4
  74. package/dist/752.creaditor.bundle.js.gz +0 -0
  75. package/dist/7564.creaditor.bundle.js +1 -1
  76. package/dist/7564.creaditor.bundle.js.gz +0 -0
  77. package/dist/763.creaditor.bundle.js +9 -9
  78. package/dist/763.creaditor.bundle.js.gz +0 -0
  79. package/dist/7654.creaditor.bundle.js +221 -0
  80. package/dist/7654.creaditor.bundle.js.gz +0 -0
  81. package/dist/7918.creaditor.bundle.js +1 -0
  82. package/dist/7918.creaditor.bundle.js.gz +0 -0
  83. package/dist/7937.creaditor.bundle.js +21 -48
  84. package/dist/7937.creaditor.bundle.js.gz +0 -0
  85. package/dist/7997.creaditor.bundle.js +1 -1
  86. package/dist/7997.creaditor.bundle.js.gz +0 -0
  87. package/dist/8141.creaditor.bundle.js +2 -3
  88. package/dist/8141.creaditor.bundle.js.gz +0 -0
  89. package/dist/8250.creaditor.bundle.js +1 -1
  90. package/dist/8250.creaditor.bundle.js.gz +0 -0
  91. package/dist/8443.creaditor.bundle.js +1 -1
  92. package/dist/8443.creaditor.bundle.js.gz +0 -0
  93. package/dist/8547.creaditor.bundle.js +1270 -0
  94. package/dist/8547.creaditor.bundle.js.gz +0 -0
  95. package/dist/8570.creaditor.bundle.js +3 -3
  96. package/dist/8570.creaditor.bundle.js.gz +0 -0
  97. package/dist/8646.creaditor.bundle.js +20 -24
  98. package/dist/8646.creaditor.bundle.js.gz +0 -0
  99. package/dist/8654.creaditor.bundle.js +7 -7
  100. package/dist/8654.creaditor.bundle.js.gz +0 -0
  101. package/dist/8854.creaditor.bundle.js +4 -4
  102. package/dist/8854.creaditor.bundle.js.gz +0 -0
  103. package/dist/8916.creaditor.bundle.js +3 -1
  104. package/dist/8916.creaditor.bundle.js.gz +0 -0
  105. package/dist/9041.creaditor.bundle.js +14 -16
  106. package/dist/9041.creaditor.bundle.js.gz +0 -0
  107. package/dist/9250.creaditor.bundle.js +1 -1
  108. package/dist/9250.creaditor.bundle.js.gz +0 -0
  109. package/dist/9431.creaditor.bundle.js +1 -1
  110. package/dist/9431.creaditor.bundle.js.gz +0 -0
  111. package/dist/9694.creaditor.bundle.js +1 -1
  112. package/dist/9694.creaditor.bundle.js.gz +0 -0
  113. package/dist/creaditor.bundle.js +2848 -1978
  114. package/dist/creaditor.bundle.js.LICENSE.txt +6 -0
  115. package/dist/creaditor.bundle.js.LICENSE.txt.gz +0 -0
  116. package/dist/creaditor.bundle.js.gz +0 -0
  117. package/dist/service-worker.js +1 -1
  118. package/dist/service-worker.js.gz +0 -0
  119. package/package.json +1 -1
@@ -1,439 +1,544 @@
1
- "use strict";(("undefined"!=typeof self?self:this).webpackChunkCreaditor=("undefined"!=typeof self?self:this).webpackChunkCreaditor||[]).push([[567],{70567(t,e,n){n.r(e),n.d(e,{TextPromptEditor:()=>s});var r,a,o=n(86959),i=n(59929);let s=(0,n(49410).EM)("cdtr-text-prompt-editor")(((a=class extends i.WF{constructor(){super(),this.prompt=localStorage.getItem("textPromptEditor_prompt")||"",this.generatedText="",this.isLoading=!1,this.context="",this.businessType=localStorage.getItem("textPromptEditor_businessType")||"",this.businessName=localStorage.getItem("textPromptEditor_businessName")||"",this.includeContext="true"===localStorage.getItem("textPromptEditor_includeContext")||!1,this.url=localStorage.getItem("textPromptEditor_url")||"",this.detectCurrentElementType()}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.detectCurrentElementType()},100)}detectCurrentElementType(){try{const t=window.getSelection();if(t&&t.rangeCount>0){const e=t.getRangeAt(0).commonAncestorContainer;let n=e.nodeType===Node.TEXT_NODE?e.parentElement:e;for(;n&&n!==document.body;){if(n.tagName&&/^h[1-6]$/i.test(n.tagName)){const t=n.parentElement,e=Array.from(t?.children||[]),r=e.some(t=>t!==n&&/^h[1-6]$/i.test(t.tagName)),a=e.some(t=>t!==n&&/^p$|^div$/i.test(t.tagName));return!a||r&&!a?(this.contentType="title",void console.log("TextPromptEditor: Detected standalone heading from DOM")):(this.contentType="paragraph",void console.log("TextPromptEditor: Detected heading within paragraph structure"))}this.contentType="paragraph",n=n.parentElement}}this.contentType||(this.contentType="paragraph",console.log("TextPromptEditor: Defaulting to paragraph"))}catch(t){console.warn("Error detecting current element type:",t),this.contentType||(this.contentType="paragraph")}}handleIncludeContextChange(t){this.includeContext=!t.target.checked,localStorage.setItem("textPromptEditor_includeContext",this.includeContext)}handleContentTypeChange(t){this.contentType=t,this.dispatchEvent(new CustomEvent("content-type-changed",{detail:{contentType:this.contentType},bubbles:!0,composed:!0}))}handlePromptChange(t){this.prompt=t.target.value,localStorage.setItem("textPromptEditor_prompt",this.prompt);["כתוב כותרת","כתוב תמונה","כתבי כותרת","write heading"].some(t=>this.prompt.startsWith(t))&&this.handleContentTypeChange("title")}handleBusinessTypeChange(t){this.businessType=t.target.value,localStorage.setItem("textPromptEditor_businessType",this.businessType)}handleBusinessNameChange(t){this.businessName=t.target.value,localStorage.setItem("textPromptEditor_businessName",this.businessName)}handleUrlChange(t){this.url=t.target.value,localStorage.setItem("textPromptEditor_url",this.url)}async handleGenerate(){this.isLoading=!0,this.generatedText="";try{if("title"===this.contentType){Array.from(document.querySelectorAll(".text-component")).map(t=>t.textContent).join("\n")}this.context.length>1500&&(this.context=this.context.slice(0,1500));const t=o.XW.agent_url,e=await fetch(t+"prompt/text",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({prompt:this.prompt,context:this.includeContext?this.context:"",businessType:this.businessType,businessName:this.businessName,contentType:this.contentType,url:this.url,options:{maxTokens:1e3,temperature:0,model:"gpt-3.5-turbo"}})});if(!e.ok)throw new Error("Failed to generate text");const n=e.body.getReader(),r=new TextDecoder;let a="";for(;;){const{done:t,value:e}=await n.read();if(t){this.dispatchEvent(new CustomEvent("text-generation-complete",{detail:{text:this.generatedText},bubbles:!0,composed:!0}));break}a+=r.decode(e,{stream:!0});const o=a.split("\n\n");for(let t=0;t<o.length-1;t++){const e=o[t];if(e.startsWith("data: "))try{const t=e.slice(6),n=JSON.parse(t);if("start"===n.metadata?.type){this.generatedText="",this.dispatchEvent(new CustomEvent("text-generation-start",{detail:{model:n.metadata.model},bubbles:!0,composed:!0}));continue}n.text&&(this.generatedText+=n.text,this.dispatchEvent(new CustomEvent("text-generation-chunk",{detail:{chunk:n.text,fullText:this.generatedText},bubbles:!0,composed:!0}))),"complete"===n.status&&(this.generatedText=this.generatedText.replace(/^"|"$/g,""),this.dispatchEvent(new CustomEvent("text-generation-complete",{detail:{text:this.generatedText},bubbles:!0,composed:!0})))}catch(t){console.error("Error parsing JSON:",t)}}a=o[o.length-1]}}catch(t){console.error("Error generating text:",t),this.dispatchEvent(new CustomEvent("text-generation-error",{detail:{error:t.message},bubbles:!0,composed:!0}))}finally{this.isLoading=!1}}render(){const t=this.contentType;return i.qy`
1
+ "use strict";(("undefined"!=typeof self?self:this).webpackChunkCreaditor=("undefined"!=typeof self?self:this).webpackChunkCreaditor||[]).push([[567],{70567(e,t,s){s.r(t),s.d(t,{TextPromptEditor:()=>b});var n,i,o=s(86959),a=s(86319),r=s(59929),l=s(49410);const c="/api/text-color",p=()=>{try{const e=a.M.get("app","_id");return"string"==typeof e&&e.length>0?e:null}catch(e){return null}},d="#111827",h="#ffffff",g=e=>{const t=/^#?([0-9a-f]{6})$/i.exec((e||"").trim());if(!t)return null;const s=parseInt(t[1],16);return{r:s>>16&255,g:s>>8&255,b:255&s}},m=e=>{const t=e/255;return t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)},u=e=>{let{r:t,g:s,b:n}=e;return.2126*m(t)+.7152*m(s)+.0722*m(n)},f=(e,t)=>{const s=g(e),n=g(t);if(!s||!n)return 1;const i=u(s),o=u(n);return(Math.max(i,o)+.05)/(Math.min(i,o)+.05)},_=(e,t,s)=>e&&f(e,t)>=s?e:f(d,t)>=f(h,t)?d:h,x={en:{title:"Edit with AI",placeholder:"Tell me how to change this text…",send:"Send",thinking:"Working…",keepLength:"Keep length",editingSelection:"Selection",editingElement:"Whole text",error:"Something went wrong. Please try again.",empty:"Ask me to improve, shorten, or rewrite this text.",roleHeading:"Headings",roleBody:"Body",colorize:"Colorize",colorizing:"Picking colors…",colorizeDone:"Applied on-brand colors.",actions:{improve:"Improve",shorten:"Shorten",lengthen:"Lengthen",grammar:"Fix grammar",tone:"Warmer tone"},prompts:{improve:"Improve this text — make it clearer and more compelling. Keep the meaning.",shorten:"Make this shorter and more concise, without losing the key point.",lengthen:"Expand this with a little more detail and flow.",grammar:"Fix any spelling and grammar mistakes. Keep the wording and meaning.",tone:"Make the tone warmer and friendlier."}},he:{title:"עריכה עם AI",placeholder:"כתבו לי איך לשנות את הטקסט…",send:"שליחה",thinking:"עובד…",keepLength:"שמור על האורך",editingSelection:"קטע מסומן",editingElement:"כל הטקסט",error:"משהו השתבש. נסו שוב.",empty:"בקשו ממני לשפר, לקצר או לנסח מחדש את הטקסט.",roleHeading:"כותרות",roleBody:"טקסט",colorize:"צביעה חכמה",colorizing:"בוחר צבעים…",colorizeDone:"הוחלו צבעים בהתאמה למותג.",actions:{improve:"שיפור",shorten:"קיצור",lengthen:"הרחבה",grammar:"תיקון שגיאות",tone:"טון חם יותר"},prompts:{improve:"שפר את הטקסט הזה — שיהיה ברור ומשכנע יותר, בלי לשנות את המשמעות.",shorten:"קצר את הטקסט הזה ותהפוך אותו לתמציתי יותר, בלי לאבד את העיקר.",lengthen:"הרחב את הטקסט הזה עם עוד קצת פירוט וזרימה.",grammar:"תקן שגיאות כתיב ודקדוק. שמור על הניסוח והמשמעות.",tone:"הפוך את הטון לחם וידידותי יותר."}}};let b=(0,l.EM)("cdtr-text-prompt-editor")(((i=class extends r.WF{constructor(){super(),this.commands=null,this.elementId=null,this._messages=[],this._input="",this._busy=!1,this._colorizing=!1,this._scope="element",this._error="",this._keepLength=!1,this._lang="he",this._selPreview="",this._streamingIdx=null}connectedCallback(){super.connectedCallback();const e=a.M.get("config","language"),t=this.commands&&this.commands.getText&&this.commands.getText()||"";this._lang="he"===e||"en"===e?e:t?/[\u0590-\u05FF]/.test(t||"")?"he":"en":"rtl"===document?.documentElement?.dir?"he":"en",this._scope=this._currentScope(),this._selPreview=this._readSelPreview(),this._onSelChange=()=>{const e=this._currentScope();e!==this._scope&&(this._scope=e);const t=this._readSelPreview();t!==this._selPreview&&(this._selPreview=t)},this.commands?.onSelectionChange&&(this._unsubSel=this.commands.onSelectionChange(this._onSelChange)),document.addEventListener("selectionchange",this._onSelChange),setTimeout(()=>{const e=this.renderRoot?.querySelector(".composer-input");e&&e.focus()},50),this._hydrate()}async _hydrate(){const e=p();if(!e||!this.elementId)return;const t=await this._resolveToken(!1);if(!t)return;const s=`${o.XW.studio_url}/api/datastore/sessions/by-doc?doc_id=${encodeURIComponent(e)}&surface=text-element&element_id=${encodeURIComponent(this.elementId)}`;try{const e=await fetch(s,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t}`}});if(!e.ok)return;const n=await e.json(),i=Array.isArray(n?.messages)?n.messages:[];if(0===i.length)return;if(this._messages.length>0||this._busy)return;this._messages=i.filter(e=>e&&("user"===e.role||"assistant"===e.role)).map(e=>({role:e.role,content:e.content})).filter(e=>"string"==typeof e.content&&e.content.length>0)}catch(e){}}disconnectedCallback(){super.disconnectedCallback(),this._unsubSel&&(this._unsubSel(),this._unsubSel=null),this._onSelChange&&(document.removeEventListener("selectionchange",this._onSelChange),this._onSelChange=null)}get t(){const e=x[this._lang]||x.en,t=e=>{const t=a.M.get("lang",e);return"string"==typeof t&&t?t:void 0};return{title:t("text_ai_title")??e.title,placeholder:t("text_ai_placeholder")??e.placeholder,send:t("text_ai_send")??e.send,thinking:t("text_ai_thinking")??e.thinking,keepLength:t("text_ai_keep_length")??e.keepLength,editingSelection:t("text_ai_scope_selection")??e.editingSelection,editingElement:t("text_ai_scope_element")??e.editingElement,error:t("text_ai_error")??e.error,empty:t("text_ai_empty")??e.empty,roleHeading:t("text_ai_role_heading")??e.roleHeading,roleBody:t("text_ai_role_body")??e.roleBody,colorize:t("text_ai_action_colorize")??e.colorize,colorizing:t("text_ai_colorizing")??e.colorizing,colorizeDone:t("text_ai_colorize_done")??e.colorizeDone,actions:{improve:t("text_ai_action_improve")??e.actions.improve,shorten:t("text_ai_action_shorten")??e.actions.shorten,lengthen:t("text_ai_action_lengthen")??e.actions.lengthen,grammar:t("text_ai_action_grammar")??e.actions.grammar,tone:t("text_ai_action_tone")??e.actions.tone},prompts:{improve:t("text_ai_prompt_improve")??e.prompts.improve,shorten:t("text_ai_prompt_shorten")??e.prompts.shorten,lengthen:t("text_ai_prompt_lengthen")??e.prompts.lengthen,grammar:t("text_ai_prompt_grammar")??e.prompts.grammar,tone:t("text_ai_prompt_tone")??e.prompts.tone}}}_currentScope(){const e=this.commands;return e&&e.hasSelection&&e.hasSelection()?"selection":"element"}_readSelPreview(){const e=this.commands;if(!e||!e.hasSelection||!e.hasSelection())return"";const t=e.getSelectionText&&e.getSelectionText()||"";return this._truncateMiddle(t.replace(/\s+/g," ").trim(),96)}_truncateMiddle(e,t){if(e.length<=t)return e;const s=Math.ceil(.6*(t-1)),n=t-1-s;return`${e.slice(0,s)}…${e.slice(e.length-n)}`}_dismissSelection(){const e=this.commands,t=e&&e.getSelectionRange&&e.getSelectionRange();t&&e.setSelectionRange&&e.setSelectionRange(t.to,t.to),this._scope="element",this._selPreview=""}_onInput(e){this._input=e.target.value}_onKeydown(e){"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this._send(this._input))}_quickAction(e){this._send(this.t.prompts[e])}_toggleKeepLength(e){this._keepLength=!!e.target.checked}async _send(e){const t=(e||"").trim();if(!t||this._busy||!this.commands)return;const s=this._currentScope();this._scope=s;const n="selection"===s?this.commands.getSelectionHTML?.()??this.commands.getSelectionText():this.commands.getHTML?.()??this.commands.getText(),i="heading"===(this.commands.getBlockType?.()||{}).type?"title":"paragraph";this._messages=[...this._messages,{role:"user",content:t}],this._input="",this._error="",this._busy=!0;const o=this._messages.filter(e=>"user"===e.role||"assistant"===e.role).map(e=>({role:e.role,content:(e.content||"").slice(0,8e3)})).filter(e=>e.content.length>0),a=p(),r={messages:o,text:(n||"").slice(0,4e4),scope:s,format:"html",contentType:i,keepLength:this._keepLength,language:this._lang,...a?{doc_id:a}:{},...a&&this.elementId?{element_id:this.elementId}:{}};try{await this._runStream(r,s)}catch(e){console.error("[text-chat] turn failed:",e),this._error=this.t.error,this._messages=[...this._messages,{role:"error",content:this.t.error}]}finally{this._busy=!1,this._streamingIdx=null,this._scope=this._currentScope(),this._selPreview=this._readSelPreview()}}async _resolveToken(e){const t=a.M.get("resolveStudioToken");if("function"!=typeof t)return console.warn("[text-chat] no resolveStudioToken on store; request will likely 401."),null;try{return await t({forceRefresh:!!e})}catch(e){return console.warn("[text-chat] token resolution failed:",e),null}}async _postTo(e,t,s,n){const i=await this._resolveToken(s),a={"Content-Type":"application/json",Accept:n||"application/json"};return i&&(a.Authorization=`Bearer ${i}`),fetch(o.XW.studio_url+e,{method:"POST",headers:a,body:JSON.stringify(t)})}async _post(e,t){return this._postTo("/api/text-chat",e,t,"text/event-stream, application/json")}_gatherPalette(){const e=new Set,t=(s,n)=>{if(!(n>5||null==s))return"string"==typeof s?(t=>{const s=/^#?([0-9a-f]{6})$/i.exec((t||"").trim());s&&e.add(`#${s[1].toLowerCase()}`)})(s):Array.isArray(s)?s.forEach(e=>t(e,n+1)):"object"==typeof s?Object.values(s).forEach(e=>t(e,n+1)):void 0};try{t(a.M.get("colorPalletes"),0)}catch(e){}return Array.from(e).slice(0,48)}async _postColor(e){let t=await this._postTo(c,e,!1);401===t.status&&(t=await this._postTo(c,e,!0));let s=null;try{s=await t.json()}catch(e){}if(!t.ok||!s||!1===s.ok)throw new Error(s&&s.reason||`HTTP ${t.status}`);return s}async _colorize(){if(this._busy||this._colorizing||!this.commands)return;const e=this.commands,t=e.getBlocks&&e.getBlocks()||[];if(!t.length)return;const s=e=>"heading"===e.type?"heading":"body",n=Array.from(new Set(t.map(s))),i=e.getBackgroundColor&&e.getBackgroundColor()||h,o=this._gatherPalette(),a=t.filter(e=>"heading"===s(e)).map(e=>e.text).join(" ").slice(0,500),r=t.filter(e=>"body"===s(e)).map(e=>e.text).join(" ").slice(0,500);this._messages=[...this._messages,{role:"user",content:`🎨 ${this.t.colorize}`}],this._error="",this._colorizing=!0,this._busy=!0;try{const l=await this._postColor({roles:n,background:i,palette:o,...a?{headingText:a}:{},...r?{bodyText:r}:{},language:this._lang}),c=l.heading?_(l.heading,i,3):null,p=l.body?_(l.body,i,4.5):null;t.forEach(t=>{const n="heading"===s(t)?c:p;n&&e.setColorRange&&e.setColorRange(t.from,t.to,n)});const d=[];c&&d.push({label:this.t.roleHeading,color:c}),p&&d.push({label:this.t.roleBody,color:p}),this._messages=[...this._messages,{role:"assistant",content:l.rationale||this.t.colorizeDone,swatches:d}]}catch(e){console.error("[text-color] colorize failed:",e),this._error=this.t.error,this._messages=[...this._messages,{role:"error",content:this.t.error}]}finally{this._colorizing=!1,this._busy=!1}}async _runStream(e,t){let s=await this._post(e,!1);if(401===s.status&&(s=await this._post(e,!0)),!s.ok){let e=`HTTP ${s.status}`;try{const t=await s.json();t&&t.reason&&(e=t.reason)}catch{}throw new Error(e)}const n=this._messages.length;this._messages=[...this._messages,{role:"assistant",content:""}],this._streamingIdx=n;let i="";await this._consumeSse(s.body,(e,t)=>{if("text"===e&&t&&"string"==typeof t.delta)i+=t.delta,this._updateAssistant(n,(e=>{const t=document.createElement("div");return t.innerHTML=e||"",(t.textContent||"").replace(/^[#>\-\s]+/gm,"").replace(/\*\*?|__?|`|~~/g,"").replace(/\|/g," ").replace(/\n{2,}/g,"\n").trim()})(i));else if("error"===e)throw new Error(t&&t.reason||"stream error")}),i.trim()&&("element"===t?(this.commands.selectAll(),this.commands.insertContentHtml(i)):this.commands.insertInlineMarkdown?this.commands.insertInlineMarkdown(i):this.commands.insertContent(i))}_updateAssistant(e,t){const s=this._messages.slice();s[e]&&(s[e]={role:"assistant",content:t}),this._messages=s}async _consumeSse(e,t){const s=e.getReader(),n=new TextDecoder;let i="";try{for(;;){const{done:e,value:o}=await s.read();if(e)break;let a;for(i+=n.decode(o,{stream:!0});-1!==(a=i.indexOf("\n\n"));){const e=i.slice(0,a);i=i.slice(a+2);let s,n="message",o="";for(const t of e.split("\n"))t.startsWith("event:")?n=t.slice(6).trim():t.startsWith("data:")&&(o+=(o?"\n":"")+t.slice(5).replace(/^ /,""));if(o){try{s=JSON.parse(o)}catch{continue}t(n,s)}}}}finally{try{s.releaseLock()}catch{}}}render(){const e=this.t,t="he"===this._lang,s=this._messages.length>0||this._busy,n=!this._busy&&this._input.trim().length>0;return r.qy`
2
2
  <cdtr-editor-container>
3
- <div class="editor-container">
4
- <div class="prompt-section">
5
- <div class="prompt-header">
6
- <div class="prompt-icon">✍️</div>
7
- <label class="prompt-label" for="prompt-input">
8
- <lang-text text="prompt_editor_title"></lang-text>
9
- </label>
10
- </div>
11
-
12
- <cdtr-input
13
- id="business-name-input"
14
- label="Business Name"
15
- .value=${this.businessName}
16
- @input=${this.handleBusinessNameChange}
17
- placeholder="Enter_your_business_name"
18
- ></cdtr-input>
19
-
20
- <cdtr-input
21
- id="business-type-input"
22
- label="Business Type"
23
- .value=${this.businessType}
24
- @input=${this.handleBusinessTypeChange}
25
- placeholder="Enter_your_business_type"
26
- ></cdtr-input>
27
-
28
- <cdtr-input
29
- id="url-input"
30
- label="URL"
31
- .value=${this.url}
32
- @input=${this.handleUrlChange}
33
- placeholder="Enter_the_URL_of_the_page"
34
- ></cdtr-input>
35
-
36
- <cdtr-textarea
37
- autofocus=${!0}
38
- id="prompt-input"
39
- class="prompt-input"
40
- placeholder=""
41
- .value=${this.prompt}
42
- @input=${this.handlePromptChange}
43
- ></cdtr-textarea>
44
-
45
- <cdtr-dropdown .value=${t}>
46
- <cdtr-dropdown-button slot="trigger">
47
- <lang-text text="${t||"paragraph"}"></lang-text>
48
- </cdtr-dropdown-button>
49
- <div slot="content">
50
- <cdtr-dropdown-item
51
- @click=${()=>this.handleContentTypeChange("title")}
52
- >
53
- <lang-text text="title"></lang-text>
54
- </cdtr-dropdown-item>
55
- <cdtr-dropdown-item
56
- @click=${()=>this.handleContentTypeChange("paragraph")}
3
+ <div class="ai" dir=${t?"rtl":"ltr"}>
4
+ <header class="ai-head">
5
+ <span class="brand">
6
+ <span class="spark">✨</span>
7
+ <span class="brand-title">${e.title}</span>
8
+ </span>
9
+ <span class="scope" data-scope=${this._scope}>
10
+ ${"selection"===this._scope?e.editingSelection:e.editingElement}
11
+ </span>
12
+ </header>
13
+
14
+ <div class="quick">
15
+ ${["improve","shorten","lengthen","grammar","tone"].map(t=>r.qy`
16
+ <button
17
+ class="chip"
18
+ ?disabled=${this._busy}
19
+ @click=${()=>this._quickAction(t)}
57
20
  >
58
- <lang-text text="paragraph"></lang-text>
59
- </cdtr-dropdown-item>
60
- </div>
61
- </cdtr-dropdown>
62
- <cdtr-row justify="space-between">
63
- <cdtr-col>
64
- <span class="prompt-context">
65
- <lang-text text="prompt_editor_context"></lang-text>
66
- </span>
67
- </cdtr-col>
68
- <cdtr-col sm="2">
69
- <cdtr-checkbox
70
- .checked=${this.includeContext}
71
- @change=${this.handleIncludeContextChange}
72
- ></cdtr-checkbox>
73
- </cdtr-col>
74
- </cdtr-row>
75
- <paper-button
76
- fullWidth
77
- class="generate-button"
78
- ?disabled=${this.isLoading||!this.prompt}
79
- @click=${this.handleGenerate}
21
+ ${e.actions[t]}
22
+ </button>
23
+ `)}
24
+ <button
25
+ class="chip chip--color"
26
+ ?disabled=${this._busy}
27
+ @click=${()=>this._colorize()}
28
+ title=${e.colorize}
80
29
  >
81
- ${this.isLoading?i.qy`
82
- <div class="loading-spinner"></div>
83
- <lang-text text="creating_magic"></lang-text>
84
- `:i.qy` <lang-text text="generate_content"></lang-text> `}
85
- </paper-button>
30
+ <span class="chip-swatch"></span>
31
+ ${this._colorizing?e.colorizing:e.colorize}
32
+ </button>
86
33
  </div>
87
34
 
88
- ${this.generatedText?i.qy`
89
- <div class="result-section">
90
- <div class="result-content">${this.generatedText}</div>
91
- </div>
92
- `:""}
35
+ <label class="keeplen">
36
+ <input
37
+ type="checkbox"
38
+ .checked=${this._keepLength}
39
+ ?disabled=${this._busy}
40
+ @change=${this._toggleKeepLength}
41
+ />
42
+ <span>${e.keepLength}</span>
43
+ </label>
44
+
45
+ ${s?r.qy`<div class="log">
46
+ ${this._messages.map((e,t)=>{const s="assistant"===e.role&&t===this._streamingIdx,n=s&&!e.content;return r.qy`
47
+ <div class="msg ${e.role}">
48
+ <div
49
+ class="bubble ${s?"streaming":""} ${n?"thinking":""}"
50
+ >
51
+ ${n?r.qy`<span class="dot"></span><span class="dot"></span
52
+ ><span class="dot"></span>`:r.qy`${e.content}${e.swatches&&e.swatches.length?r.qy`<span class="swatches">
53
+ ${e.swatches.map(e=>r.qy`<span
54
+ class="swatch"
55
+ title=${e.label}
56
+ >
57
+ <span
58
+ class="swatch-dot"
59
+ style="background:${e.color}"
60
+ ></span>
61
+ <span class="swatch-label"
62
+ >${e.label}</span
63
+ >
64
+ </span>`)}
65
+ </span>`:""}`}
66
+ </div>
67
+ </div>
68
+ `})}
69
+ ${this._busy&&null===this._streamingIdx?r.qy`<div class="msg assistant">
70
+ <div class="bubble thinking">
71
+ <span class="dot"></span><span class="dot"></span
72
+ ><span class="dot"></span>
73
+ </div>
74
+ </div>`:""}
75
+ </div>`:r.qy`<p class="hint">${e.empty}</p>`}
76
+
77
+ ${"selection"===this._scope&&this._selPreview?r.qy`<div class="selpill" title=${this._selPreview}>
78
+ <span class="selpill-label">${e.editingSelection}</span>
79
+ <span class="selpill-text">"${this._selPreview}"</span>
80
+ <button
81
+ class="selpill-x"
82
+ title=${e.editingElement}
83
+ aria-label=${e.editingElement}
84
+ ?disabled=${this._busy}
85
+ @click=${this._dismissSelection}
86
+ >
87
+ ✕
88
+ </button>
89
+ </div>`:""}
90
+
91
+ <div class="composer">
92
+ <textarea
93
+ class="composer-input"
94
+ rows="1"
95
+ .value=${this._input}
96
+ placeholder=${e.placeholder}
97
+ ?disabled=${this._busy}
98
+ @input=${this._onInput}
99
+ @keydown=${this._onKeydown}
100
+ ></textarea>
101
+ <button
102
+ class="send"
103
+ title=${e.send}
104
+ aria-label=${e.send}
105
+ ?disabled=${!n}
106
+ @click=${()=>this._send(this._input)}
107
+ >
108
+ <svg
109
+ class=${t?"flip":""}
110
+ viewBox="0 0 24 24"
111
+ width="18"
112
+ height="18"
113
+ fill="none"
114
+ stroke="currentColor"
115
+ stroke-width="2"
116
+ stroke-linecap="round"
117
+ stroke-linejoin="round"
118
+ >
119
+ <path d="M22 2 11 13" />
120
+ <path d="M22 2 15 22 11 13 2 9z" />
121
+ </svg>
122
+ </button>
123
+ </div>
93
124
  </div>
94
125
  </cdtr-editor-container>
95
- `}}).properties={prompt:{type:String},generatedText:{type:String},isLoading:{type:Boolean},context:{type:String},includeContext:{type:Boolean},businessType:{type:String},businessName:{type:String},contentType:{type:String},url:{type:String}},a.styles=i.AH`
96
- :host {
97
- --primary: #7c3aed;
98
- --primary-light: #a78bfa;
99
- --primary-dark: #5b21b6;
100
- --accent: #f472b6;
101
- --accent-light: #f9a8d4;
102
- --accent-dark: #db2777;
103
- --surface: #f8fafc;
104
- --surface-dark: #f1f5f9;
105
- --text-primary: #0f172a;
106
- --text-secondary: #334155;
107
- --gradient-primary: linear-gradient(
108
- 135deg,
109
- var(--primary) 0%,
110
- var(--accent) 100%
111
- );
112
- --gradient-accent: linear-gradient(
113
- 135deg,
114
- var(--accent) 0%,
115
- var(--primary) 100%
116
- );
117
- --gradient-surface: linear-gradient(
118
- 135deg,
119
- var(--surface) 0%,
120
- var(--surface-dark) 100%
121
- );
122
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
123
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
124
- 0 2px 4px -1px rgba(0, 0, 0, 0.06);
125
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
126
- 0 4px 6px -2px rgba(0, 0, 0, 0.05);
127
- --shadow-glow: 0 0 20px rgba(124, 58, 237, 0.3),
128
- 0 0 40px rgba(244, 114, 182, 0.2);
129
- }
130
-
131
- * {
126
+ `}}).properties={commands:{attribute:!1},elementId:{attribute:!1},_messages:{state:!0},_input:{state:!0},_busy:{state:!0},_colorizing:{state:!0},_scope:{state:!0},_error:{state:!0},_keepLength:{state:!0},_selPreview:{state:!0},_streamingIdx:{state:!0},_lang:{state:!0}},i.styles=r.AH`
127
+ *,
128
+ *::before,
129
+ *::after {
132
130
  box-sizing: border-box;
133
- margin: 0;
134
- padding: 0;
135
131
  }
136
-
137
132
  :host {
138
133
  display: block;
134
+ font-family: inherit;
135
+ --accent: #7c3aed;
136
+ --accent-2: #a855f7;
137
+ --ink: #1f2937;
138
+ --muted: #6b7280;
139
+ --line: #ececf1;
140
+ --surface: #f6f6f9;
141
+ }
142
+ .ai {
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 12px;
139
146
  width: 100%;
140
- margin: 0;
141
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
142
- Ubuntu, Cantarell, sans-serif;
143
- background: var(--gradient-surface);
144
- min-height: 100vh;
145
- position: relative;
146
- overflow: hidden;
147
+ min-width: 0;
148
+ padding: 2px;
149
+ color: var(--ink);
147
150
  }
148
151
 
149
- :host::before {
150
- content: "";
151
- position: absolute;
152
- top: 0;
153
- left: 0;
154
- right: 0;
155
- bottom: 0;
156
- background: radial-gradient(
157
- circle at 0% 0%,
158
- rgba(124, 58, 237, 0.1) 0%,
159
- transparent 50%
160
- ),
161
- radial-gradient(
162
- circle at 100% 100%,
163
- rgba(244, 114, 182, 0.1) 0%,
164
- transparent 50%
165
- );
166
- pointer-events: none;
167
- animation: gradientShift 15s ease infinite;
152
+ /* Header */
153
+ .ai-head {
154
+ display: flex;
155
+ align-items: center;
156
+ justify-content: space-between;
157
+ gap: 8px;
158
+ min-width: 0;
168
159
  }
169
-
170
- @keyframes gradientShift {
171
- 0% {
172
- background-position: 0% 0%;
173
- }
174
- 50% {
175
- background-position: 100% 100%;
176
- }
177
- 100% {
178
- background-position: 0% 0%;
179
- }
160
+ .brand {
161
+ display: inline-flex;
162
+ align-items: center;
163
+ gap: 7px;
164
+ min-width: 0;
180
165
  }
181
-
182
- .editor-container {
183
- display: flex;
184
- flex-direction: column;
185
- gap: 1.5rem;
186
- padding: 1.5rem;
187
- position: relative;
166
+ .spark {
167
+ font-size: 15px;
168
+ line-height: 1;
169
+ }
170
+ .brand-title {
171
+ font-weight: 700;
172
+ font-size: 14px;
173
+ letter-spacing: -0.01em;
174
+ white-space: nowrap;
188
175
  overflow: hidden;
176
+ text-overflow: ellipsis;
177
+ }
178
+ .scope {
179
+ flex: none;
180
+ font-size: 11px;
181
+ font-weight: 600;
182
+ color: var(--accent);
183
+ background: #f3ecff;
184
+ border-radius: 999px;
185
+ padding: 3px 9px;
186
+ white-space: nowrap;
187
+ }
188
+ .scope[data-scope="selection"] {
189
+ color: #b45309;
190
+ background: #fdf1dc;
189
191
  }
190
192
 
191
- .prompt-section {
193
+ /* Quick actions */
194
+ .quick {
192
195
  display: flex;
193
- flex-direction: column;
194
- gap: 1rem;
195
- position: relative;
196
+ flex-wrap: wrap;
197
+ gap: 6px;
198
+ }
199
+ .chip {
200
+ border: 1px solid var(--line);
201
+ background: #fff;
202
+ color: #374151;
203
+ border-radius: 8px;
204
+ padding: 6px 11px;
205
+ font: inherit;
206
+ font-size: 12px;
207
+ font-weight: 500;
208
+ cursor: pointer;
209
+ transition: border-color 0.12s ease, color 0.12s ease,
210
+ background 0.12s ease;
211
+ }
212
+ .chip:hover:not(:disabled) {
213
+ border-color: var(--accent-2);
214
+ color: var(--accent);
215
+ background: #faf6ff;
216
+ }
217
+ .chip:active:not(:disabled) {
218
+ transform: translateY(0.5px);
219
+ }
220
+ .chip:disabled {
221
+ opacity: 0.45;
222
+ cursor: default;
196
223
  }
197
224
 
198
- .prompt-header {
199
- display: flex;
225
+ /* Colorize chip — accented so it reads as a distinct "smart color" action */
226
+ .chip--color {
227
+ display: inline-flex;
200
228
  align-items: center;
201
- justify-content: space-between;
202
- gap: 0.75rem;
203
- margin-bottom: 0.5rem;
229
+ gap: 6px;
230
+ border-color: transparent;
231
+ color: #fff;
232
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
233
+ }
234
+ .chip--color:hover:not(:disabled) {
235
+ color: #fff;
236
+ background: linear-gradient(135deg, var(--accent-2), var(--accent));
237
+ filter: brightness(1.03);
238
+ }
239
+ .chip-swatch {
240
+ width: 11px;
241
+ height: 11px;
242
+ border-radius: 3px;
243
+ background: conic-gradient(
244
+ from 0deg,
245
+ #f87171,
246
+ #fbbf24,
247
+ #34d399,
248
+ #60a5fa,
249
+ #a855f7,
250
+ #f87171
251
+ );
252
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
204
253
  }
205
254
 
206
- .prompt-icon {
207
- width: 40px;
208
- height: 40px;
209
- background: var(--gradient-primary);
210
- border-radius: 12px;
255
+ /* Applied-color swatches shown under a colorize result bubble */
256
+ .swatches {
211
257
  display: flex;
258
+ flex-wrap: wrap;
259
+ gap: 6px 12px;
260
+ margin-top: 7px;
261
+ }
262
+ .swatch {
263
+ display: inline-flex;
212
264
  align-items: center;
213
- justify-content: center;
214
- color: white;
215
- font-weight: bold;
216
- position: relative;
217
- transform-origin: center;
218
- animation: iconFloat 3s ease-in-out infinite;
265
+ gap: 5px;
266
+ font-size: 11px;
267
+ color: var(--muted);
219
268
  }
220
-
221
- @keyframes iconFloat {
222
- 0%,
223
- 100% {
224
- transform: translateY(0) rotate(0deg);
225
- }
226
- 50% {
227
- transform: translateY(-5px) rotate(5deg);
228
- }
269
+ .swatch-dot {
270
+ width: 13px;
271
+ height: 13px;
272
+ border-radius: 4px;
273
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
229
274
  }
230
275
 
231
- .prompt-icon::after {
232
- content: "";
233
- position: absolute;
234
- inset: -2px;
235
- background: var(--gradient-primary);
236
- border-radius: 14px;
237
- z-index: -1;
238
- opacity: 0.5;
239
- filter: blur(8px);
240
- animation: iconGlow 3s ease-in-out infinite;
276
+ /* Keep-length toggle */
277
+ .keeplen {
278
+ display: inline-flex;
279
+ align-items: center;
280
+ gap: 7px;
281
+ font-size: 12px;
282
+ color: var(--muted);
283
+ cursor: pointer;
284
+ user-select: none;
285
+ align-self: flex-start;
286
+ }
287
+ .keeplen input {
288
+ width: 15px;
289
+ height: 15px;
290
+ accent-color: var(--accent);
291
+ cursor: pointer;
292
+ margin: 0;
241
293
  }
242
294
 
243
- @keyframes iconGlow {
244
- 0%,
245
- 100% {
246
- opacity: 0.5;
247
- filter: blur(8px);
248
- }
249
- 50% {
250
- opacity: 0.8;
251
- filter: blur(12px);
252
- }
295
+ /* Hint (empty state) */
296
+ .hint {
297
+ margin: 0;
298
+ font-size: 12.5px;
299
+ line-height: 1.5;
300
+ color: #9aa1ad;
253
301
  }
254
302
 
255
- .prompt-label {
256
- font-size: 1.25rem;
257
- font-weight: 600;
258
- color: var(--text-primary);
259
- letter-spacing: -0.02em;
303
+ /* Message log */
304
+ .log {
305
+ display: flex;
306
+ flex-direction: column;
307
+ gap: 8px;
308
+ max-height: 240px;
309
+ overflow-y: auto;
310
+ padding: 2px 1px;
311
+ scrollbar-width: thin;
312
+ }
313
+ .msg {
260
314
  display: flex;
315
+ }
316
+ .msg.user {
317
+ justify-content: flex-end;
318
+ }
319
+ .msg.assistant,
320
+ .msg.error {
321
+ justify-content: flex-start;
322
+ }
323
+ .bubble {
324
+ max-width: 88%;
325
+ padding: 8px 11px;
326
+ border-radius: 13px;
327
+ font-size: 13px;
328
+ line-height: 1.45;
329
+ white-space: pre-wrap;
330
+ overflow-wrap: anywhere;
331
+ }
332
+ .msg.user .bubble {
333
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
334
+ color: #fff;
335
+ border-end-end-radius: 4px;
336
+ }
337
+ .msg.assistant .bubble {
338
+ background: var(--surface);
339
+ color: var(--ink);
340
+ border-end-start-radius: 4px;
341
+ }
342
+ .msg.error .bubble {
343
+ background: #fef2f2;
344
+ color: #b91c1c;
345
+ border: 1px solid #fecaca;
346
+ }
347
+ .bubble.thinking {
348
+ display: inline-flex;
261
349
  align-items: center;
262
- gap: 0.75rem;
350
+ gap: 4px;
351
+ padding: 11px;
263
352
  }
264
-
265
- .prompt-label::after {
266
- content: "AI";
267
- font-size: 0.875rem;
268
- background: var(--gradient-primary);
269
- color: white;
270
- padding: 0.25rem 0.75rem;
271
- border-radius: 6px;
272
- font-weight: 500;
273
- animation: badgeFloat 3s ease-in-out infinite;
353
+ .dot {
354
+ width: 6px;
355
+ height: 6px;
356
+ border-radius: 50%;
357
+ background: var(--accent-2);
358
+ display: inline-block;
359
+ animation: blink 1.2s infinite both;
274
360
  }
275
-
276
- @keyframes badgeFloat {
361
+ .dot:nth-child(2) {
362
+ animation-delay: 0.15s;
363
+ }
364
+ .dot:nth-child(3) {
365
+ animation-delay: 0.3s;
366
+ }
367
+ @keyframes blink {
277
368
  0%,
369
+ 80%,
278
370
  100% {
371
+ opacity: 0.25;
279
372
  transform: translateY(0);
280
373
  }
281
- 50% {
282
- transform: translateY(-2px);
374
+ 40% {
375
+ opacity: 1;
376
+ transform: translateY(-1px);
283
377
  }
284
378
  }
285
379
 
286
- .generate-button {
287
- width: 100%;
288
- align-self: flex-end;
289
- padding: 0.875rem 1.75rem;
290
- background: var(--gradient-primary);
291
- color: white;
292
- border: none;
293
- border-radius: 10px;
294
- font-size: 1rem;
295
- font-weight: 600;
296
- cursor: pointer;
297
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
298
- display: flex;
299
- align-items: center;
300
- gap: 0.75rem;
380
+ /* Streaming shimmer FX — a soft light sweeps across the bubble while the
381
+ model types, plus a gentle purple glow. Text stays fully readable. */
382
+ .msg.assistant .bubble.streaming {
301
383
  position: relative;
302
384
  overflow: hidden;
303
- box-shadow: var(--shadow-md);
385
+ box-shadow: 0 0 0 1px #ece0ff, 0 4px 16px -6px rgba(124, 58, 237, 0.4);
386
+ animation: bubbleGlow 1.8s ease-in-out infinite;
304
387
  }
305
-
306
- .generate-button::before {
388
+ .msg.assistant .bubble.streaming::after {
307
389
  content: "";
308
390
  position: absolute;
309
- top: 0;
310
- left: 0;
311
- right: 0;
312
- bottom: 0;
391
+ inset: 0;
313
392
  background: linear-gradient(
314
- 135deg,
315
- rgba(255, 255, 255, 0.2) 0%,
316
- rgba(255, 255, 255, 0) 100%
393
+ 105deg,
394
+ transparent 20%,
395
+ rgba(168, 85, 247, 0.22) 50%,
396
+ transparent 80%
317
397
  );
318
- opacity: 0;
319
- transition: opacity 0.3s ease;
398
+ transform: translateX(-120%);
399
+ animation: sweep 1.5s ease-in-out infinite;
400
+ pointer-events: none;
320
401
  }
321
-
322
- .generate-button:hover::before {
323
- opacity: 1;
402
+ @keyframes sweep {
403
+ to {
404
+ transform: translateX(120%);
405
+ }
324
406
  }
325
-
326
- .generate-button:hover {
327
- transform: translateY(-2px);
328
- box-shadow: var(--shadow-glow);
329
- background: var(--gradient-accent);
407
+ @keyframes bubbleGlow {
408
+ 0%,
409
+ 100% {
410
+ box-shadow: 0 0 0 1px #ece0ff, 0 3px 12px -6px rgba(124, 58, 237, 0.3);
411
+ }
412
+ 50% {
413
+ box-shadow: 0 0 0 1px #e3d0ff, 0 6px 20px -6px rgba(168, 85, 247, 0.55);
414
+ }
330
415
  }
331
416
 
332
- .generate-button:active {
333
- transform: translateY(0);
417
+ /* Selection context pill (what a "Selection" edit will target) */
418
+ .selpill {
419
+ display: flex;
420
+ align-items: center;
421
+ gap: 7px;
422
+ min-width: 0;
423
+ padding: 6px 8px 6px 11px;
424
+ border: 1px solid #f0e4d3;
425
+ background: linear-gradient(90deg, #fdf6ea, #fef1dc);
426
+ border-radius: 10px;
427
+ font-size: 12px;
428
+ animation: pillIn 0.18s ease;
334
429
  }
335
-
336
- .generate-button:disabled {
337
- background: var(--gradient-surface);
338
- cursor: not-allowed;
339
- transform: none;
340
- box-shadow: none;
430
+ .selpill-label {
431
+ flex: none;
432
+ font-weight: 700;
433
+ color: #b45309;
434
+ white-space: nowrap;
341
435
  }
342
-
343
- .result-section {
344
- margin-top: 0.5rem;
345
- padding: 1.5rem;
346
- background: rgba(255, 255, 255, 0.8);
347
- border-radius: 12px;
348
- min-height: 160px;
349
- opacity: 0;
350
- transform: translateY(10px);
351
- animation: fadeIn 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
352
- position: relative;
436
+ .selpill-text {
437
+ flex: 1 1 auto;
438
+ min-width: 0;
439
+ color: #7c5a2a;
440
+ white-space: nowrap;
353
441
  overflow: hidden;
354
- backdrop-filter: blur(8px);
355
- box-shadow: var(--shadow-md);
356
- }
357
-
358
- .result-section::before {
359
- content: "";
360
- position: absolute;
361
- top: 0;
362
- left: 0;
363
- right: 0;
364
- height: 3px;
365
- background: var(--gradient-primary);
366
- opacity: 0.8;
442
+ text-overflow: ellipsis;
443
+ font-style: italic;
367
444
  }
368
-
369
- .result-content {
370
- white-space: pre-wrap;
371
- line-height: 1.7;
372
- color: var(--text-primary);
373
- font-size: 1rem;
374
- }
375
-
376
- .loading-spinner {
445
+ .selpill-x {
446
+ flex: none;
377
447
  width: 20px;
378
448
  height: 20px;
379
- border: 2px solid rgba(255, 255, 255, 0.3);
380
- border-top: 2px solid white;
381
- border-radius: 50%;
382
- animation: spin 1s linear infinite;
449
+ display: inline-flex;
450
+ align-items: center;
451
+ justify-content: center;
452
+ border: none;
453
+ border-radius: 6px;
454
+ background: transparent;
455
+ color: #b08a55;
456
+ font-size: 12px;
457
+ line-height: 1;
458
+ cursor: pointer;
459
+ transition: background 0.12s ease, color 0.12s ease;
383
460
  }
384
-
385
- @keyframes spin {
386
- 0% {
387
- transform: rotate(0deg);
388
- }
389
- 100% {
390
- transform: rotate(360deg);
391
- }
461
+ .selpill-x:hover:not(:disabled) {
462
+ background: #f6e6cd;
463
+ color: #92400e;
392
464
  }
393
-
394
- @keyframes fadeIn {
465
+ .selpill-x:disabled {
466
+ opacity: 0.4;
467
+ cursor: default;
468
+ }
469
+ @keyframes pillIn {
395
470
  from {
396
471
  opacity: 0;
397
- transform: translateY(10px);
398
- }
399
- to {
400
- opacity: 1;
401
- transform: translateY(0);
472
+ transform: translateY(3px);
402
473
  }
403
474
  }
404
475
 
405
- /* Decorative elements */
406
- .editor-container::after {
407
- content: "";
408
- position: absolute;
409
- top: 50%;
410
- left: 50%;
411
- width: 200%;
412
- height: 200%;
413
- background: radial-gradient(
414
- circle at center,
415
- rgba(124, 58, 237, 0.1) 0%,
416
- transparent 50%
417
- );
418
- transform: translate(-50%, -50%);
419
- pointer-events: none;
420
- animation: pulse 4s ease-in-out infinite;
476
+ /* Composer */
477
+ .composer {
478
+ display: flex;
479
+ align-items: flex-end;
480
+ gap: 8px;
481
+ border: 1px solid var(--line);
482
+ border-radius: 14px;
483
+ padding: 6px 6px 6px 10px;
484
+ background: #fff;
485
+ transition: border-color 0.12s ease, box-shadow 0.12s ease;
421
486
  }
422
-
423
- .prompt-context {
487
+ .composer:focus-within {
488
+ border-color: var(--accent-2);
489
+ box-shadow: 0 0 0 3px #f1e9ff;
490
+ }
491
+ .composer-input {
492
+ flex: 1 1 auto;
493
+ min-width: 0;
494
+ resize: none;
495
+ border: none;
496
+ outline: none;
497
+ background: transparent;
498
+ padding: 6px 2px;
499
+ font: inherit;
424
500
  font-size: 13px;
425
- color: var(--text-secondary);
501
+ line-height: 1.4;
502
+ color: var(--ink);
503
+ max-height: 96px;
504
+ }
505
+ .composer-input::placeholder {
506
+ color: #aab0bb;
507
+ }
508
+ .send {
509
+ flex: none;
510
+ width: 34px;
511
+ height: 34px;
512
+ display: inline-flex;
513
+ align-items: center;
514
+ justify-content: center;
515
+ border: none;
516
+ border-radius: 10px;
517
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
518
+ color: #fff;
519
+ cursor: pointer;
520
+ transition: opacity 0.12s ease, transform 0.12s ease;
521
+ }
522
+ .send:hover:not(:disabled) {
523
+ transform: translateY(-1px);
524
+ }
525
+ .send:disabled {
526
+ opacity: 0.4;
527
+ cursor: default;
528
+ }
529
+ .send svg.flip {
530
+ transform: scaleX(-1);
426
531
  }
427
532
 
428
- @keyframes pulse {
429
- 0%,
430
- 100% {
431
- transform: translate(-50%, -50%) scale(1);
432
- opacity: 0.5;
433
- }
434
- 50% {
435
- transform: translate(-50%, -50%) scale(1.1);
436
- opacity: 0.3;
533
+ @media (prefers-reduced-motion: reduce) {
534
+ .dot,
535
+ .send,
536
+ .chip,
537
+ .selpill,
538
+ .msg.assistant .bubble.streaming,
539
+ .msg.assistant .bubble.streaming::after {
540
+ animation: none;
541
+ transition: none;
437
542
  }
438
543
  }
439
- `,r=a))||r}}]);
544
+ `,n=i))||n}}]);