refinekit 0.1.0 → 0.2.0

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.
package/README.md CHANGED
@@ -1,61 +1,43 @@
1
- # reFiner
1
+ # refinekit
2
2
 
3
- Leave visual feedback directly on any web page. Click an element, type what should change, and reFiner saves your notes as structured annotations that AI coding tools can read and act on.
3
+ Leave visual feedback directly on any web page. Click an element, type what should change, and refinekit saves your notes as structured annotations that AI coding tools can read and act on.
4
4
 
5
- ## What it does
5
+ ## Install
6
6
 
7
- 1. You add a single line to your HTML file
8
- 2. A small toolbar appears on your page
9
- 3. Click any element to leave a note about what should change
10
- 4. Copy all your notes and paste them into an AI coding tool like [Claude Code](https://claude.com/claude-code) — it knows exactly which elements to fix
7
+ ### With Claude Code (recommended)
11
8
 
12
- reFiner stays out of the way. It doesn't change your page's appearance or break any styles.
9
+ If you're using [Claude Code](https://claude.com/claude-code), tell it:
13
10
 
14
- ## Getting started
11
+ > Add refinekit to my HTML files
15
12
 
16
- ### Step 1: Add reFiner to your page
13
+ Claude Code will add the script tag to your HTML files for you. You can also use the built-in skill:
17
14
 
18
- Open your HTML file and paste this line just before the closing `</body>` tag:
19
-
20
- ```html
21
- <script src="https://unpkg.com/refinekit/dist/refiner.js"></script>
15
+ ```
16
+ /refinekit
22
17
  ```
23
18
 
24
- Your file should look something like this:
19
+ ### Manually
20
+
21
+ Add this line to your HTML file, just before the closing `</body>` tag:
25
22
 
26
23
  ```html
27
- <!DOCTYPE html>
28
- <html>
29
- <head>
30
- <title>My Page</title>
31
- </head>
32
- <body>
33
- <!-- your page content here -->
34
-
35
- <script src="https://unpkg.com/refinekit/dist/refiner.js"></script>
36
- </body>
37
- </html>
24
+ <script src="https://unpkg.com/refinekit/dist/refiner.js"></script>
38
25
  ```
39
26
 
40
- ### Step 2: Open your page in a browser
27
+ Open the file in your browser and the refinekit toolbar will appear in the bottom-right corner.
41
28
 
42
- Open the HTML file in Chrome, Safari, Firefox, or any modern browser. You'll see a small pen icon in the bottom-right corner — that's the reFiner toolbar.
29
+ ## How to use it
43
30
 
44
- ### Step 3: Start annotating
45
-
46
- 1. Click the **pen icon** to expand the toolbar
31
+ 1. Click the **pen icon** in the bottom-right corner to expand the toolbar
47
32
  2. Click any element on the page — a heading, a button, an image, anything
48
- 3. A dialog appears. Type what should change (e.g. "Make this font bigger" or "Change this color to blue")
33
+ 3. Type what should change (e.g. "Make this font bigger" or "Change this color to blue")
49
34
  4. Click **Add** (or press `Cmd+Enter` on Mac / `Ctrl+Enter` on Windows)
50
- 5. A numbered marker appears on the element
51
-
52
- Repeat for as many elements as you'd like to annotate.
35
+ 5. A numbered marker appears on the element — repeat for as many elements as you'd like
36
+ 6. Click the **copy icon** in the toolbar to copy all your annotations
53
37
 
54
- ### Step 4: Copy your annotations
38
+ Paste the copied annotations into [Claude Code](https://claude.com/claude-code) or any AI coding tool. It will know exactly which elements to change and what to do.
55
39
 
56
- Click the **copy icon** in the toolbar. All your annotations are copied to your clipboard as a formatted list, ready to paste into Claude Code or any AI coding assistant.
57
-
58
- What gets copied looks like this:
40
+ ### What gets copied
59
41
 
60
42
  ```
61
43
  # Design Annotations — My Page Title
@@ -69,8 +51,6 @@ Element: #hero > .cta-button
69
51
  Issue: Change this color to blue and add more padding
70
52
  ```
71
53
 
72
- The AI agent uses the element selectors to find and fix exactly the right elements in your code.
73
-
74
54
  ## Toolbar guide
75
55
 
76
56
  | Button | What it does |
@@ -87,19 +67,9 @@ The AI agent uses the element selectors to find and fix exactly the right elemen
87
67
  - **Clear on copy** — automatically remove annotations after copying them
88
68
  - **Block page interactions** — prevents you from accidentally clicking links or buttons while annotating (on by default)
89
69
 
90
- ## Using reFiner with Claude Code
91
-
92
- [Claude Code](https://claude.com/claude-code) is an AI coding tool that can read your reFiner annotations and make the changes for you.
93
-
94
- ### Quick setup
95
-
96
- If you already have Claude Code installed, just type:
97
-
98
- ```
99
- /refiner
100
- ```
70
+ ## Using refinekit with Claude Code
101
71
 
102
- Claude Code will detect your project and add reFiner for you automatically.
72
+ [Claude Code](https://claude.com/claude-code) is an AI coding tool that can read your refinekit annotations and make the changes for you.
103
73
 
104
74
  ### Autonomous design critique
105
75
 
@@ -113,13 +83,13 @@ Claude opens your page in a browser and drives through it like a design reviewer
113
83
 
114
84
  ### Real-time sync with MCP
115
85
 
116
- By default, you copy annotations and paste them into Claude Code. But you can skip the copy-paste entirely by running the reFiner MCP server:
86
+ By default, you copy annotations and paste them into Claude Code. But you can skip the copy-paste entirely by running the refinekit MCP server:
117
87
 
118
88
  ```bash
119
89
  npx refinekit-mcp server
120
90
  ```
121
91
 
122
- Once running, annotations flow directly to Claude Code as you add them. The settings panel in reFiner will show "MCP Connected" to confirm the link is active.
92
+ Once running, annotations flow directly to Claude Code as you add them. The settings panel will show "MCP Connected" to confirm the link is active.
123
93
 
124
94
  To make this permanent in Claude Code:
125
95
 
@@ -140,7 +110,7 @@ You watch Session 1 critique the design while Session 2 implements the fixes —
140
110
 
141
111
  ## Advanced
142
112
 
143
- Everything below is for developers who want more control over reFiner.
113
+ Everything below is for developers who want more control over refinekit.
144
114
 
145
115
  ### npm install
146
116
 
@@ -163,8 +133,8 @@ const refiner = new Refiner();
163
133
  src="https://unpkg.com/refinekit/dist/refiner.js"
164
134
  data-refiner-enabled="true"
165
135
  data-refiner-position="right"
166
- data-refinekit-mcp-enabled="true"
167
- data-refinekit-mcp-port="4848"
136
+ data-refiner-mcp-enabled="true"
137
+ data-refiner-mcp-port="4848"
168
138
  ></script>
169
139
  ```
170
140
 
@@ -172,8 +142,8 @@ const refiner = new Refiner();
172
142
  |-----------|--------|---------|-------------|
173
143
  | `data-refiner-enabled` | `true` / `false` | `true` | Whether to activate on load |
174
144
  | `data-refiner-position` | `left` / `right` | `right` | Which side of the viewport |
175
- | `data-refinekit-mcp-enabled` | `true` / `false` | `true` | Auto-discover MCP server |
176
- | `data-refinekit-mcp-port` | number | `4848` | MCP server HTTP port |
145
+ | `data-refiner-mcp-enabled` | `true` / `false` | `true` | Auto-discover MCP server |
146
+ | `data-refiner-mcp-port` | number | `4848` | MCP server HTTP port |
177
147
 
178
148
  #### Constructor options
179
149
 
@@ -246,7 +216,7 @@ npx refinekit-mcp doctor
246
216
 
247
217
  ```bash
248
218
  # From the refiner project directory
249
- ln -sf "$(pwd)/skills/refiner" ~/.claude/skills/refiner
219
+ ln -sf "$(pwd)/skills/refinekit" ~/.claude/skills/refinekit
250
220
  ln -sf "$(pwd)/skills/refiner-self-driving" ~/.claude/skills/refiner-self-driving
251
221
  ```
252
222
 
package/dist/overlay.d.ts CHANGED
@@ -11,6 +11,7 @@ export declare class Overlay {
11
11
  private isOverOwnUI;
12
12
  private handleMouseMove;
13
13
  private handleClick;
14
+ private handleKeyBlock;
14
15
  private getElementAt;
15
16
  private showHighlight;
16
17
  private hideHighlight;
package/dist/refiner.js CHANGED
@@ -1,2 +1,2 @@
1
- var Refiner=function(t){"use strict";class e{constructor(){this.annotations=new Map,this.listeners=new Map}add(t,e,n){const i={id:crypto.randomUUID(),targetSelector:t,targetRect:{x:e.x,y:e.y,width:e.width,height:e.height},text:n,timestamp:Date.now(),resolved:!1};return this.annotations.set(i.id,i),this.emit("add",i),i}resolve(t){const e=this.annotations.get(t);e&&(e.resolved=!0,this.emit("resolve",e))}remove(t){const e=this.annotations.get(t);e&&(this.annotations.delete(t),this.emit("remove",e))}get(t){return this.annotations.get(t)}getAll(){return Array.from(this.annotations.values())}getPending(){return this.getAll().filter(t=>!t.resolved)}getCount(){return this.annotations.size}exportJSON(){return JSON.stringify(this.getAll(),null,2)}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){this.listeners.get(t)?.delete(e)}emit(t,e){this.listeners.get(t)?.forEach(t=>t(e))}}class n{constructor(t){this.root=t,this.collapsed=!0,this.settingsOpen=!1,this.el=document.createElement("div"),this.el.className="refiner-toolbar",this.el.setAttribute("data-refiner-toolbar",""),this.el.setAttribute("data-collapsed","true"),this.render(),t.appendChild(this.el),requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.collapsed=!1,this.el.setAttribute("data-collapsed","false"),this.updateBadgeVisibility()})})}render(){const t=document.createElement("div");t.className="toolbar-pill",this.innerEl=document.createElement("div"),this.innerEl.className="toolbar-inner",this.countBadge=document.createElement("span"),this.countBadge.className="toolbar-count",this.countBadge.textContent="0",this.innerEl.appendChild(this.createBtn(this.countBadge,"Annotations",null));const e='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';this.copyBtn=this.createBtn(e,"Copy annotations",()=>{this.copyBtn.classList.contains("disabled")||(this.onCopy?.(),this.copyBtn.querySelector(".toolbar-icon").innerHTML='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{this.copyBtn.querySelector(".toolbar-icon").innerHTML=e},1500))}),this.copyBtn.classList.add("disabled"),this.innerEl.appendChild(this.copyBtn),this.clearBtn=this.createBtn('<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',"Clear all",()=>{this.clearBtn.classList.contains("disabled")||this.onClear?.()}),this.clearBtn.classList.add("disabled"),this.innerEl.appendChild(this.clearBtn),this.innerEl.appendChild(this.createBtn('<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',"Settings",()=>this.onSettings?.()));const n=document.createElement("div");n.className="toolbar-divider",this.innerEl.appendChild(n),t.appendChild(this.innerEl);const i='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>';this.toggleBtn=this.createBtn(i,"",()=>this.toggleCollapse()),this.toggleBtn.classList.add("toolbar-toggle-btn"),t.appendChild(this.toggleBtn),this.expandBadge=document.createElement("span"),this.expandBadge.className="toolbar-expand-badge hidden",this.expandBadge.textContent="0",t.appendChild(this.expandBadge),this.el.appendChild(t),this.el.addEventListener("transitionend",()=>{this.toggleBtn.querySelector(".toolbar-icon").innerHTML=this.collapsed?i:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>'})}createBtn(t,e,n){const i=document.createElement("button");i.className="toolbar-btn";const s=document.createElement("span");if(s.className="toolbar-icon","string"==typeof t?s.innerHTML=t:s.appendChild(t),i.appendChild(s),e){const t=document.createElement("span");t.className="toolbar-tooltip",t.textContent=e,i.appendChild(t)}return n&&i.addEventListener("click",n),i}toggleCollapse(){this.collapsed=!this.collapsed,this.el.setAttribute("data-collapsed",String(this.collapsed)),this.updateBadgeVisibility(),this.collapsed&&this.onCollapse?.()}setSettingsOpen(t){this.settingsOpen=t,this.el.classList.toggle("tooltips-hidden",t)}updateCount(t){this.countBadge.textContent=String(t),this.expandBadge.textContent=String(t),this.updateBadgeVisibility(t);const e=0===t;this.copyBtn.classList.toggle("disabled",e),this.clearBtn.classList.toggle("disabled",e)}updateBadgeVisibility(t){const e=t??parseInt(this.expandBadge.textContent||"0",10);this.expandBadge.classList.toggle("hidden",0===e||!this.collapsed)}}class i{constructor(t){this.root=t,this.enabled=!0,this.blocking=!0,this.currentTarget=null,this.highlightColor="#7C3AED",this.handleMouseMove=t=>{if(!this.enabled)return;if(this.isOverOwnUI(t.clientX,t.clientY))return void this.hideHighlight();const e=this.getElementAt(t.clientX,t.clientY);e&&e!==this.currentTarget&&(this.currentTarget=e,this.showHighlight(e))},this.handleClick=t=>{if(!this.enabled)return;if(this.isOverOwnUI(t.clientX,t.clientY))return;t.preventDefault(),t.stopPropagation();const e=this.getElementAt(t.clientX,t.clientY);if(e){const t=e.getBoundingClientRect();this.onClick?.(e,t)}},this.el=document.createElement("div"),this.el.className="refiner-overlay",this.el.setAttribute("data-blocking","true"),this.highlight=document.createElement("div"),this.highlight.className="refiner-highlight",this.highlight.style.display="none",t.appendChild(this.highlight),t.appendChild(this.el),this.el.addEventListener("mousemove",this.handleMouseMove),this.el.addEventListener("click",this.handleClick),this.el.addEventListener("mouseleave",()=>this.hideHighlight())}isOverOwnUI(t,e){const n=this.root.elementFromPoint(t,e);return!!n&&(n!==this.el&&n!==this.highlight)}getElementAt(t,e){this.el.style.pointerEvents="none",this.highlight.style.pointerEvents="none";const n=document.elementFromPoint(t,e);return this.el.style.pointerEvents="",this.highlight.style.pointerEvents="",n&&n===this.root.host?null:n}showHighlight(t){const e=t.getBoundingClientRect();this.highlight.style.display="block",this.highlight.style.top=e.top-2+"px",this.highlight.style.left=e.left-2+"px",this.highlight.style.width=`${e.width+4}px`,this.highlight.style.height=`${e.height+4}px`,this.highlight.style.borderColor=this.highlightColor}hideHighlight(){this.highlight.style.display="none",this.currentTarget=null}setHighlightColor(t){this.highlightColor=t}setBlocking(t){this.blocking=t,this.el.setAttribute("data-blocking",String(t)),t||this.hideHighlight()}setEnabled(t){this.enabled=t,this.el.classList.toggle("hidden",!t),t||this.hideHighlight()}}class s{constructor(t){this.root=t,this.el=document.createElement("div"),this.el.className="refiner-dialog hidden",this.render(),t.appendChild(this.el)}render(){const t=document.createElement("div");t.className="dialog-header";const e=document.createElement("span");e.textContent="What should change?",t.appendChild(e),this.el.appendChild(t),this.textarea=document.createElement("textarea"),this.textarea.className="dialog-textarea",this.textarea.placeholder="Describe the issue or improvement...",this.textarea.addEventListener("input",()=>{this.addBtn.disabled=0===this.textarea.value.trim().length}),this.textarea.addEventListener("keydown",t=>{"Enter"===t.key&&(t.metaKey||t.ctrlKey)&&this.textarea.value.trim()&&this.submit(),"Escape"===t.key&&(this.hide(),this.onCancel?.())}),this.el.appendChild(this.textarea);const n=document.createElement("div");n.className="dialog-actions";const i=document.createElement("button");i.className="dialog-btn dialog-btn-cancel",i.textContent="Cancel",i.addEventListener("click",()=>{this.hide(),this.onCancel?.()}),this.addBtn=document.createElement("button"),this.addBtn.className="dialog-btn dialog-btn-add",this.addBtn.textContent="Add",this.addBtn.disabled=!0,this.addBtn.addEventListener("click",()=>this.submit()),n.appendChild(i),n.appendChild(this.addBtn),this.el.appendChild(n)}submit(){const t=this.textarea.value.trim();t&&(this.onSubmit?.(t),this.hide())}show(t,e){let n=t+12,i=e+12;n+320>window.innerWidth-16&&(n=t-320-12),i+200>window.innerHeight-16&&(i=e-200-12),this.el.style.left=`${Math.max(16,n)}px`,this.el.style.top=`${Math.max(16,i)}px`,this.el.classList.remove("hidden"),this.textarea.value="",this.addBtn.disabled=!0,requestAnimationFrame(()=>this.textarea.focus())}hide(){this.el.classList.add("hidden"),this.textarea.value=""}isVisible(){return!this.el.classList.contains("hidden")}}class o{constructor(t,e){this.root=t,this.store=e,this.markers=new Map,this.rafId=null,this.color="#7C3AED",this.container=document.createElement("div"),this.container.className="refiner-markers",t.appendChild(this.container),e.on("add",t=>this.addMarker(t)),e.on("resolve",t=>this.updateMarker(t)),e.on("remove",t=>this.removeMarker(t.id));const n=()=>this.repositionAll();window.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",n,{passive:!0})}addMarker(t){const e=document.createElement("div");e.className="refiner-marker",e.setAttribute("data-annotation-marker",t.id),e.setAttribute("data-resolved",String(t.resolved)),e.style.background=this.color;const n=this.markers.size+1;e.textContent=String(n);const i=document.createElement("div");i.className="marker-tooltip";const s=document.createElement("div");s.textContent=t.text,i.appendChild(s);const o=document.createElement("div");o.className="marker-tooltip-actions";const r=document.createElement("button");r.className="marker-tooltip-btn resolve",r.textContent="Resolve",r.addEventListener("click",e=>{e.stopPropagation(),this.store.resolve(t.id)});const a=document.createElement("button");a.className="marker-tooltip-btn delete",a.textContent="Delete",a.addEventListener("click",e=>{e.stopPropagation(),this.store.remove(t.id)}),o.appendChild(r),o.appendChild(a),i.appendChild(o),e.appendChild(i),this.positionMarker(e,t),this.container.appendChild(e),this.markers.set(t.id,{el:e,annotation:t})}updateMarker(t){const e=this.markers.get(t.id);e&&(e.annotation=t,e.el.setAttribute("data-resolved",String(t.resolved)))}removeMarker(t){const e=this.markers.get(t);e&&(e.el.remove(),this.markers.delete(t),this.renumber())}renumber(){let t=1;for(const[,e]of this.markers){const n=e.el.childNodes[0];n&&n.nodeType===Node.TEXT_NODE&&(n.textContent=String(t)),t++}}positionMarker(t,e){const n=this.queryTarget(e.targetSelector);if(n){const e=n.getBoundingClientRect();t.style.top=e.top-8+"px",t.style.left=e.right-8+"px"}else t.style.top=e.targetRect.y-8+"px",t.style.left=e.targetRect.x+e.targetRect.width-8+"px"}queryTarget(t){try{return document.querySelector(t)}catch{return null}}setColor(t){this.color=t;for(const[,e]of this.markers)e.el.style.background=t}clearAll(){for(const[t]of this.markers)this.removeMarker(t)}repositionAll(){null===this.rafId&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null;for(const[,t]of this.markers)this.positionMarker(t.el,t.annotation)}))}}const r=[{id:"purple",color:"#7C3AED"},{id:"blue",color:"#2563EB"},{id:"green",color:"#059669"},{id:"yellow",color:"#D97706"},{id:"orange",color:"#EA580C"},{id:"red",color:"#DC2626"},{id:"pink",color:"#DB2777"}];class a{constructor(t){this.root=t,this.visible=!1,this.settings={clearOnCopy:!1,blockInteractions:!0,markerColor:"#7C3AED"},this.el=document.createElement("div"),this.el.className="settings-panel hidden",this.render(),t.appendChild(this.el)}render(){const t=document.createElement("div");t.className="settings-header";const e=document.createElement("span");e.className="settings-title",e.textContent="reFiner";const n=document.createElement("span");n.className="settings-version",n.textContent="v0.1.0",t.appendChild(e),t.appendChild(n),this.el.appendChild(t),this.el.appendChild(this.createDivider());const i=document.createElement("div");i.className="settings-section";const s=document.createElement("span");s.className="settings-label",s.textContent="Marker Colour",i.appendChild(s);const o=document.createElement("div");o.className="settings-color-row";for(const t of r){const e=document.createElement("button");e.className="settings-swatch",e.style.background=t.color,e.setAttribute("data-color",t.color),t.color===this.settings.markerColor&&e.classList.add("selected"),e.addEventListener("click",()=>{o.querySelectorAll(".settings-swatch").forEach(t=>t.classList.remove("selected")),e.classList.add("selected"),this.settings.markerColor=t.color,this.emitChange()}),o.appendChild(e)}i.appendChild(o),this.el.appendChild(i),this.el.appendChild(this.createDivider()),this.el.appendChild(this.createCheckbox("Clear on copy",this.settings.clearOnCopy,t=>{this.settings.clearOnCopy=t,this.emitChange()})),this.el.appendChild(this.createCheckbox("Block page interactions",this.settings.blockInteractions,t=>{this.settings.blockInteractions=t,this.emitChange()})),this.el.appendChild(this.createDivider());const a=document.createElement("div");a.className="settings-mcp-row",this.mcpDot=document.createElement("span"),this.mcpDot.className="settings-mcp-dot disconnected",this.mcpLabel=document.createElement("span"),this.mcpLabel.className="settings-check-label",this.mcpLabel.textContent="MCP Disconnected",a.appendChild(this.mcpDot),a.appendChild(this.mcpLabel),this.el.appendChild(a)}createCheckbox(t,e,n){const i=document.createElement("label");i.className="settings-check-row";const s=document.createElement("input");s.type="checkbox",s.className="settings-checkbox",s.checked=e,s.addEventListener("change",()=>n(s.checked));const o=document.createElement("span");return o.className="settings-check-label",o.textContent=t,i.appendChild(s),i.appendChild(o),i}createDivider(){const t=document.createElement("div");return t.className="settings-divider",t}emitChange(){this.onChange?.({...this.settings})}toggle(){this.visible=!this.visible,this.el.classList.toggle("hidden",!this.visible)}hide(){this.visible=!1,this.el.classList.add("hidden")}isVisible(){return this.visible}setMcpStatus(t){this.mcpDot.className="settings-mcp-dot "+(t?"connected":"disconnected"),this.mcpLabel.textContent=t?"MCP Connected":"MCP Disconnected"}getSettings(){return{...this.settings}}}class l{constructor(t,e=4848){this.store=t,this.sessionId=null,this.connected=!1,this.retryTimer=null,this.baseUrl=`http://localhost:${e}`,this.discover(),this.store.on("add",t=>this.postAnnotation(t)),this.store.on("resolve",t=>this.patchAnnotation(t))}async discover(){try{const t=await fetch(`${this.baseUrl}/health`),e=await t.json();e&&"object"==typeof e&&"status"in e&&"ok"===e.status&&(this.connected=!0,this.onChange?.(!0),await this.createSession(),this.stopRetry())}catch{this.connected=!1,this.onChange?.(!1),this.startRetry()}}startRetry(){this.retryTimer||(this.retryTimer=setInterval(()=>this.discover(),5e3))}stopRetry(){this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=null)}async createSession(){try{const t=await fetch(`${this.baseUrl}/sessions`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:window.location.href,title:document.title||window.location.pathname})}),e=await t.json();this.sessionId=e.id}catch{}}async postAnnotation(t){if(this.connected&&this.sessionId)try{await fetch(`${this.baseUrl}/sessions/${this.sessionId}/annotations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({targetSelector:t.targetSelector,targetRect:t.targetRect,text:t.text})})}catch{}}async patchAnnotation(t){if(this.connected)try{await fetch(`${this.baseUrl}/annotations/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({resolved:!0,summary:"Resolved from browser"})})}catch{}}isConnected(){return this.connected}destroy(){this.stopRetry()}}class d{constructor(t={}){this.mcpBridge=null,this.currentTarget=null,this.currentRect=null,this.clearOnCopy=!1,this.host=document.createElement("div"),this.host.id="refiner-host",this.shadow=this.host.attachShadow({mode:"open"});const r=document.createElement("style");r.textContent='\n :host {\n all: initial;\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', system-ui, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n color: #1a1a2e;\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Toolbar ── */\n\n .refiner-toolbar {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10;\n user-select: none;\n }\n\n .toolbar-pill {\n display: flex;\n align-items: center;\n position: relative;\n background: #1a1a2e;\n border-radius: 100px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15);\n padding: 6px;\n transform: scale(1);\n transform-origin: right center;\n transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .refiner-toolbar[data-collapsed="true"] .toolbar-pill {\n transform: scale(0.92);\n }\n\n .toolbar-inner {\n display: flex;\n align-items: center;\n gap: 2px;\n overflow: hidden;\n clip-path: inset(0);\n max-width: 300px;\n opacity: 1;\n padding-right: 2px;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s ease 0.1s,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .refiner-toolbar[data-collapsed="true"] .toolbar-inner {\n max-width: 0;\n opacity: 0;\n padding-right: 0;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.15s ease,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .toolbar-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #a0a0b8;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n\n .toolbar-btn:hover {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolbar-btn.active {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n }\n\n .toolbar-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .toolbar-count {\n font-size: 14px;\n font-weight: 700;\n min-width: 18px;\n text-align: center;\n }\n\n .toolbar-divider {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.15);\n margin: 0 4px;\n flex-shrink: 0;\n }\n\n /* Tooltip */\n .toolbar-tooltip {\n position: absolute;\n bottom: calc(100% + 10px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px 10px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n }\n\n .toolbar-tooltip::after {\n content: \'\';\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 5px solid transparent;\n border-top-color: #1a1a2e;\n }\n\n .toolbar-btn:hover .toolbar-tooltip {\n opacity: 1;\n }\n\n .tooltips-hidden .toolbar-tooltip {\n display: none;\n }\n\n .toolbar-btn.disabled {\n opacity: 0.3;\n cursor: default;\n }\n\n .toolbar-btn.disabled:hover {\n color: #a0a0b8;\n background: transparent;\n }\n\n /* Toggle button (always visible) */\n .toolbar-toggle-btn {\n flex-shrink: 0;\n }\n\n /* Badge for collapsed state */\n .toolbar-expand-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 20px;\n height: 20px;\n padding: 0 5px;\n border-radius: 10px;\n background: #DC2626;\n color: #ffffff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n }\n\n .toolbar-expand-badge.hidden {\n display: none;\n }\n\n /* ── Settings Panel ── */\n\n .settings-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 300px;\n z-index: 12;\n background: #1a1a2e;\n border-radius: 16px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 20px;\n color: #e8e8f0;\n transform-origin: bottom right;\n transition: transform 0.25s ease, opacity 0.1s ease;\n transform: scale(1);\n opacity: 1;\n }\n\n .settings-panel.hidden {\n transform: scale(0.4);\n opacity: 0;\n pointer-events: none;\n }\n\n .settings-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .settings-title {\n font-size: 16px;\n font-weight: 700;\n font-style: normal;\n color: #ffffff;\n }\n\n .settings-version {\n font-size: 12px;\n color: #6b6b80;\n font-weight: 500;\n }\n\n .settings-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.08);\n margin: 16px 0;\n }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .settings-label {\n font-size: 14px;\n font-weight: 500;\n color: #c0c0d0;\n }\n\n .settings-color-row {\n display: flex;\n gap: 8px;\n }\n\n .settings-swatch {\n width: 24px;\n height: 24px;\n border-radius: 4px;\n border: 2px solid transparent;\n cursor: pointer;\n transition: transform 0.15s, border-color 0.15s;\n outline: none;\n }\n\n .settings-swatch:hover {\n transform: scale(1.1);\n }\n\n .settings-swatch.selected {\n border-color: #ffffff;\n transform: scale(1.1);\n }\n\n .settings-check-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n padding: 2px 0;\n }\n\n .settings-checkbox {\n appearance: none;\n -webkit-appearance: none;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 2px solid #4a4a60;\n background: transparent;\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n transition: background 0.15s, border-color 0.15s;\n }\n\n .settings-checkbox:checked {\n background: #2563EB;\n border-color: #2563EB;\n }\n\n .settings-checkbox:checked::after {\n content: \'\';\n position: absolute;\n top: 2px;\n left: 5px;\n width: 5px;\n height: 9px;\n border: solid #ffffff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .settings-check-label {\n font-size: 14px;\n font-weight: 500;\n color: #e8e8f0;\n }\n\n /* ── Overlay ── */\n\n .refiner-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n cursor: crosshair;\n z-index: 1;\n }\n\n .refiner-overlay[data-blocking="true"] {\n pointer-events: all;\n }\n\n .refiner-overlay[data-blocking="false"] {\n pointer-events: none;\n }\n\n .refiner-overlay.hidden {\n display: none;\n }\n\n /* ── Highlight ── */\n\n .refiner-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px dashed;\n border-radius: 3px;\n z-index: 2;\n transition: all 0.1s ease;\n }\n\n /* ── Dialog ── */\n\n .refiner-dialog {\n position: fixed;\n width: 320px;\n background: #1a1a2e;\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 14px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 11;\n color: #e8e8f0;\n animation: dialog-in 0.2s ease;\n }\n\n @keyframes dialog-in {\n from { opacity: 0; transform: translateY(4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .refiner-dialog.hidden {\n display: none;\n }\n\n .dialog-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .dialog-header span {\n font-size: 12px;\n font-weight: 600;\n color: #c0c0d0;\n }\n\n .dialog-textarea {\n width: 100%;\n min-height: 72px;\n padding: 10px 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 10px;\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: #e8e8f0;\n background: rgba(255, 255, 255, 0.06);\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .dialog-textarea:focus {\n border-color: rgba(255, 255, 255, 0.25);\n }\n\n .dialog-textarea::placeholder {\n color: #6b6b80;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n }\n\n .dialog-btn {\n height: 32px;\n padding: 0 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .dialog-btn-cancel {\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.12);\n color: #a0a0b8;\n }\n\n .dialog-btn-cancel:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #e8e8f0;\n }\n\n .dialog-btn-add {\n background: #2563EB;\n border: none;\n color: #ffffff;\n }\n\n .dialog-btn-add:hover {\n background: #3B82F6;\n }\n\n .dialog-btn-add:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n /* ── Markers ── */\n\n .refiner-marker {\n position: fixed;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n color: #ffffff;\n cursor: pointer;\n z-index: 10;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n transition: transform 0.15s;\n pointer-events: all;\n }\n\n .refiner-marker:hover {\n transform: scale(1.2);\n }\n\n .refiner-marker[data-resolved="true"] {\n opacity: 0.4;\n }\n\n .marker-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n width: 220px;\n padding: 10px 12px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n line-height: 1.4;\n border-radius: 10px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .refiner-marker:hover .marker-tooltip {\n opacity: 1;\n }\n\n .marker-tooltip-actions {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n border-top: 1px solid rgba(255,255,255,0.1);\n padding-top: 8px;\n }\n\n .marker-tooltip-btn {\n height: 22px;\n padding: 0 8px;\n border-radius: 5px;\n border: none;\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .marker-tooltip-btn.resolve {\n background: #34D399;\n color: #0a2e1f;\n }\n\n .marker-tooltip-btn.resolve:hover {\n background: #4ade80;\n }\n\n .marker-tooltip-btn.delete {\n background: rgba(255,255,255,0.1);\n color: #e8e8f0;\n }\n\n .marker-tooltip-btn.delete:hover {\n background: #FF6B6B;\n color: #fff;\n }\n\n /* MCP status */\n .settings-mcp-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n }\n\n .settings-mcp-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .settings-mcp-dot.connected {\n background: #34D399;\n box-shadow: 0 0 6px #34D39980;\n }\n\n .settings-mcp-dot.disconnected {\n background: #6B7280;\n }\n',this.shadow.appendChild(r),this.store=new e,this.toolbar=new n(this.shadow),this.settings=new a(this.shadow),this.overlay=new i(this.shadow),this.dialog=new s(this.shadow),this.markers=new o(this.shadow,this.store),this.toolbar.onCopy=()=>this.copyAnnotations(),this.toolbar.onClear=()=>this.clearAnnotations(),this.toolbar.onSettings=()=>{this.settings.toggle(),this.toolbar.setSettingsOpen(this.settings.isVisible())},this.toolbar.onCollapse=()=>{this.settings.hide(),this.toolbar.setSettingsOpen(!1)},this.settings.onChange=t=>{this.clearOnCopy=t.clearOnCopy,this.overlay.setBlocking(t.blockInteractions),this.markers.setColor(t.markerColor),this.overlay.setHighlightColor(t.markerColor)},this.overlay.onClick=(t,e)=>{if(this.settings.isVisible())return void this.settings.hide();if(this.dialog.isVisible())return void this.dialog.hide();this.currentTarget=t,this.currentRect=e;const n=e.left+e.width/2,i=e.top+e.height/2;this.dialog.show(n,i)},this.dialog.onSubmit=t=>{if(this.currentTarget&&this.currentRect){const e=function(t){if(t.id)return`#${CSS.escape(t.id)}`;if(t.classList.length>0){const e=`${t.tagName.toLowerCase()}.${Array.from(t.classList).map(CSS.escape).join(".")}`;if(1===document.querySelectorAll(e).length)return e}const e=[];let n=t;for(;n&&n!==document.documentElement;){const t=n.tagName.toLowerCase(),i=n.parentElement;if(n.id){e.unshift(`#${CSS.escape(n.id)}`);break}if(i){const s=Array.from(i.children).filter(t=>t.tagName===n.tagName);if(1===s.length)e.unshift(t);else{const i=s.indexOf(n)+1;e.unshift(`${t}:nth-child(${i})`)}}else e.unshift(t);n=i}return e.join(" > ")}(this.currentTarget);this.store.add(e,this.currentRect,t),this.toolbar.updateCount(this.store.getCount())}this.currentTarget=null,this.currentRect=null},this.dialog.onCancel=()=>{this.currentTarget=null,this.currentRect=null},this.store.on("resolve",()=>this.toolbar.updateCount(this.store.getCount())),this.store.on("remove",()=>this.toolbar.updateCount(this.store.getCount())),!1!==t.mcpEnabled&&(this.mcpBridge=new l(this.store,t.mcpPort),this.mcpBridge.onChange=t=>{this.settings.setMcpStatus(t)}),document.body.appendChild(this.host),!1===t.enabled&&this.disable()}enable(){this.host.style.display="",this.overlay.setEnabled(!0)}disable(){this.host.style.display="none",this.overlay.setEnabled(!1)}destroy(){this.mcpBridge?.destroy(),this.host.remove()}getAnnotations(){return this.store.getAll()}getAnnotationCount(){return this.store.getCount()}formatForAgent(){const t=this.store.getAll();if(0===t.length)return"No annotations.";const e=[`# Design Annotations — ${document.title||window.location.pathname}`,""];for(let n=0;n<t.length;n++){const i=t[n],s=i.resolved?" (resolved)":"";e.push(`## ${n+1}.${s}`),e.push(`**Element:** \`${i.targetSelector}\``),e.push(`**Issue:** ${i.text}`),e.push("")}return e.join("\n")}clearAnnotations(){const t=this.store.getAll();for(const e of t)this.store.remove(e.id);this.toolbar.updateCount(0)}copyAnnotations(){const t=this.formatForAgent();navigator.clipboard.writeText(t),this.clearOnCopy&&this.clearAnnotations()}}if("undefined"!=typeof window&&"undefined"!=typeof document){const t=()=>{if(window.__refiner)return;const t=document.currentScript,e=t?.dataset.refinerPosition??"right",n="false"!==t?.dataset.refinerEnabled,i=t?.dataset.refinerMcpPort?parseInt(t.dataset.refinerMcpPort,10):void 0,s="false"!==t?.dataset.refinerMcpEnabled,o=new d({position:e,enabled:n,mcpPort:i,mcpEnabled:s});window.__refiner=o};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}return t.Refiner=d,t}({});
1
+ var Refiner=function(t){"use strict";class e{constructor(){this.annotations=new Map,this.listeners=new Map}add(t,e,n){const i={id:crypto.randomUUID(),targetSelector:t,targetRect:{x:e.x,y:e.y,width:e.width,height:e.height},text:n,timestamp:Date.now(),resolved:!1};return this.annotations.set(i.id,i),this.emit("add",i),i}resolve(t){const e=this.annotations.get(t);e&&(e.resolved=!0,this.emit("resolve",e))}remove(t){const e=this.annotations.get(t);e&&(this.annotations.delete(t),this.emit("remove",e))}get(t){return this.annotations.get(t)}getAll(){return Array.from(this.annotations.values())}getPending(){return this.getAll().filter(t=>!t.resolved)}getCount(){return this.annotations.size}exportJSON(){return JSON.stringify(this.getAll(),null,2)}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){this.listeners.get(t)?.delete(e)}emit(t,e){this.listeners.get(t)?.forEach(t=>t(e))}}class n{constructor(t){this.root=t,this.collapsed=!0,this.settingsOpen=!1,this.el=document.createElement("div"),this.el.className="refiner-toolbar",this.el.setAttribute("data-refiner-toolbar",""),this.el.setAttribute("data-collapsed","true"),this.render(),t.appendChild(this.el),requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.collapsed=!1,this.el.setAttribute("data-collapsed","false"),this.updateBadgeVisibility()})})}render(){const t=document.createElement("div");t.className="toolbar-pill",this.innerEl=document.createElement("div"),this.innerEl.className="toolbar-inner",this.countBadge=document.createElement("span"),this.countBadge.className="toolbar-count",this.countBadge.textContent="0",this.innerEl.appendChild(this.createBtn(this.countBadge,"Annotations",null));const e='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';this.copyBtn=this.createBtn(e,"Copy annotations",()=>{this.copyBtn.classList.contains("disabled")||(this.onCopy?.(),this.copyBtn.querySelector(".toolbar-icon").innerHTML='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>',setTimeout(()=>{this.copyBtn.querySelector(".toolbar-icon").innerHTML=e},1500))}),this.copyBtn.classList.add("disabled"),this.innerEl.appendChild(this.copyBtn),this.clearBtn=this.createBtn('<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',"Clear all",()=>{this.clearBtn.classList.contains("disabled")||this.onClear?.()}),this.clearBtn.classList.add("disabled"),this.innerEl.appendChild(this.clearBtn),this.innerEl.appendChild(this.createBtn('<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',"Settings",()=>this.onSettings?.()));const n=document.createElement("div");n.className="toolbar-divider",this.innerEl.appendChild(n),t.appendChild(this.innerEl);const i='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>';this.toggleBtn=this.createBtn(i,"",()=>this.toggleCollapse()),this.toggleBtn.classList.add("toolbar-toggle-btn"),t.appendChild(this.toggleBtn),this.expandBadge=document.createElement("span"),this.expandBadge.className="toolbar-expand-badge hidden",this.expandBadge.textContent="0",t.appendChild(this.expandBadge),this.el.appendChild(t),this.el.addEventListener("transitionend",()=>{this.toggleBtn.querySelector(".toolbar-icon").innerHTML=this.collapsed?i:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>'})}createBtn(t,e,n){const i=document.createElement("button");i.className="toolbar-btn";const s=document.createElement("span");if(s.className="toolbar-icon","string"==typeof t?s.innerHTML=t:s.appendChild(t),i.appendChild(s),e){const t=document.createElement("span");t.className="toolbar-tooltip",t.textContent=e,i.appendChild(t)}return n&&i.addEventListener("click",n),i}toggleCollapse(){this.collapsed=!this.collapsed,this.el.setAttribute("data-collapsed",String(this.collapsed)),this.updateBadgeVisibility(),this.collapsed?this.onCollapse?.():this.onExpand?.()}setSettingsOpen(t){this.settingsOpen=t,this.el.classList.toggle("tooltips-hidden",t)}updateCount(t){this.countBadge.textContent=String(t),this.expandBadge.textContent=String(t),this.updateBadgeVisibility(t);const e=0===t;this.copyBtn.classList.toggle("disabled",e),this.clearBtn.classList.toggle("disabled",e)}updateBadgeVisibility(t){const e=t??parseInt(this.expandBadge.textContent||"0",10);this.expandBadge.classList.toggle("hidden",0===e||!this.collapsed)}}class i{constructor(t){this.root=t,this.enabled=!0,this.blocking=!0,this.currentTarget=null,this.highlightColor="#7C3AED",this.handleMouseMove=t=>{if(!this.enabled)return;if(this.isOverOwnUI(t.clientX,t.clientY))return void this.hideHighlight();const e=this.getElementAt(t.clientX,t.clientY);e&&e!==this.currentTarget&&(this.currentTarget=e,this.showHighlight(e))},this.handleClick=t=>{if(!this.enabled)return;if(this.isOverOwnUI(t.clientX,t.clientY))return;t.preventDefault(),t.stopPropagation();const e=this.getElementAt(t.clientX,t.clientY);if(e){const t=e.getBoundingClientRect();this.onClick?.(e,t)}},this.handleKeyBlock=t=>{if(!this.enabled||!this.blocking)return;const e=t.target;e&&(e===this.root.host||this.root.host.contains(e))||(t.preventDefault(),t.stopPropagation())},this.el=document.createElement("div"),this.el.className="refiner-overlay",this.el.setAttribute("data-blocking","true"),this.highlight=document.createElement("div"),this.highlight.className="refiner-highlight",this.highlight.style.display="none",t.appendChild(this.highlight),t.appendChild(this.el),this.el.addEventListener("mousemove",this.handleMouseMove),this.el.addEventListener("click",this.handleClick),this.el.addEventListener("mouseleave",()=>this.hideHighlight()),document.addEventListener("keydown",this.handleKeyBlock,!0)}isOverOwnUI(t,e){const n=this.root.elementFromPoint(t,e);return!!n&&(n!==this.el&&n!==this.highlight)}getElementAt(t,e){this.el.style.pointerEvents="none",this.highlight.style.pointerEvents="none";const n=document.elementFromPoint(t,e);return this.el.style.pointerEvents="",this.highlight.style.pointerEvents="",n&&n===this.root.host?null:n}showHighlight(t){const e=t.getBoundingClientRect();this.highlight.style.display="block",this.highlight.style.top=e.top-2+"px",this.highlight.style.left=e.left-2+"px",this.highlight.style.width=`${e.width+4}px`,this.highlight.style.height=`${e.height+4}px`,this.highlight.style.borderColor=this.highlightColor}hideHighlight(){this.highlight.style.display="none",this.currentTarget=null}setHighlightColor(t){this.highlightColor=t}setBlocking(t){this.blocking=t,this.el.setAttribute("data-blocking",String(t)),t||this.hideHighlight()}setEnabled(t){this.enabled=t,this.el.classList.toggle("hidden",!t),t||this.hideHighlight()}}class s{constructor(t){this.root=t,this.el=document.createElement("div"),this.el.className="refiner-dialog hidden",this.render(),t.appendChild(this.el)}render(){const t=document.createElement("div");t.className="dialog-header";const e=document.createElement("span");e.textContent="What should change?",t.appendChild(e),this.el.appendChild(t),this.textarea=document.createElement("textarea"),this.textarea.className="dialog-textarea",this.textarea.placeholder="Describe the issue or improvement...",this.textarea.addEventListener("input",()=>{this.addBtn.disabled=0===this.textarea.value.trim().length}),this.textarea.addEventListener("keydown",t=>{"Enter"===t.key&&(t.metaKey||t.ctrlKey)&&this.textarea.value.trim()&&this.submit(),"Escape"===t.key&&(this.hide(),this.onCancel?.())}),this.el.appendChild(this.textarea);const n=document.createElement("div");n.className="dialog-actions";const i=document.createElement("button");i.className="dialog-btn dialog-btn-cancel",i.textContent="Cancel",i.addEventListener("click",()=>{this.hide(),this.onCancel?.()}),this.addBtn=document.createElement("button"),this.addBtn.className="dialog-btn dialog-btn-add",this.addBtn.textContent="Add",this.addBtn.disabled=!0,this.addBtn.addEventListener("click",()=>this.submit()),n.appendChild(i),n.appendChild(this.addBtn),this.el.appendChild(n)}submit(){const t=this.textarea.value.trim();t&&(this.onSubmit?.(t),this.hide())}show(t,e){let n=t+12,i=e+12;n+320>window.innerWidth-16&&(n=t-320-12),i+200>window.innerHeight-16&&(i=e-200-12),this.el.style.left=`${Math.max(16,n)}px`,this.el.style.top=`${Math.max(16,i)}px`,this.el.classList.remove("hidden"),this.textarea.value="",this.addBtn.disabled=!0,requestAnimationFrame(()=>this.textarea.focus())}hide(){this.el.classList.add("hidden"),this.textarea.value=""}isVisible(){return!this.el.classList.contains("hidden")}}class o{constructor(t,e){this.root=t,this.store=e,this.markers=new Map,this.rafId=null,this.color="#7C3AED",this.container=document.createElement("div"),this.container.className="refiner-markers",t.appendChild(this.container),e.on("add",t=>this.addMarker(t)),e.on("resolve",t=>this.updateMarker(t)),e.on("remove",t=>this.removeMarker(t.id));const n=()=>this.repositionAll();window.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",n,{passive:!0})}addMarker(t){const e=document.createElement("div");e.className="refiner-marker",e.setAttribute("data-annotation-marker",t.id),e.setAttribute("data-resolved",String(t.resolved)),e.style.background=this.color;const n=this.markers.size+1;e.textContent=String(n);const i=document.createElement("div");i.className="marker-tooltip";const s=document.createElement("div");s.textContent=t.text,i.appendChild(s);const o=document.createElement("div");o.className="marker-tooltip-actions";const r=document.createElement("button");r.className="marker-tooltip-btn resolve",r.textContent="Resolve",r.addEventListener("click",e=>{e.stopPropagation(),this.store.resolve(t.id)});const a=document.createElement("button");a.className="marker-tooltip-btn delete",a.textContent="Delete",a.addEventListener("click",e=>{e.stopPropagation(),this.store.remove(t.id)}),o.appendChild(r),o.appendChild(a),i.appendChild(o),e.appendChild(i),this.positionMarker(e,t),this.container.appendChild(e),this.markers.set(t.id,{el:e,annotation:t})}updateMarker(t){const e=this.markers.get(t.id);e&&(e.annotation=t,e.el.setAttribute("data-resolved",String(t.resolved)))}removeMarker(t){const e=this.markers.get(t);e&&(e.el.remove(),this.markers.delete(t),this.renumber())}renumber(){let t=1;for(const[,e]of this.markers){const n=e.el.childNodes[0];n&&n.nodeType===Node.TEXT_NODE&&(n.textContent=String(t)),t++}}positionMarker(t,e){const n=this.queryTarget(e.targetSelector);if(n){const e=n.getBoundingClientRect();t.style.top=e.top-8+"px",t.style.left=e.right-8+"px"}else t.style.top=e.targetRect.y-8+"px",t.style.left=e.targetRect.x+e.targetRect.width-8+"px"}queryTarget(t){try{return document.querySelector(t)}catch{return null}}setColor(t){this.color=t;for(const[,e]of this.markers)e.el.style.background=t}clearAll(){for(const[t]of this.markers)this.removeMarker(t)}repositionAll(){null===this.rafId&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null;for(const[,t]of this.markers)this.positionMarker(t.el,t.annotation)}))}}const r=[{id:"purple",color:"#7C3AED"},{id:"blue",color:"#2563EB"},{id:"green",color:"#059669"},{id:"yellow",color:"#D97706"},{id:"orange",color:"#EA580C"},{id:"red",color:"#DC2626"},{id:"pink",color:"#DB2777"}];class a{constructor(t){this.root=t,this.visible=!1,this.settings={clearOnCopy:!1,blockInteractions:!0,markerColor:"#7C3AED"},this.el=document.createElement("div"),this.el.className="settings-panel hidden",this.render(),t.appendChild(this.el)}render(){const t=document.createElement("div");t.className="settings-header";const e=document.createElement("span");e.className="settings-title",e.textContent="reFiner";const n=document.createElement("span");n.className="settings-version",n.textContent="v0.1.0",t.appendChild(e),t.appendChild(n),this.el.appendChild(t),this.el.appendChild(this.createDivider());const i=document.createElement("div");i.className="settings-section";const s=document.createElement("span");s.className="settings-label",s.textContent="Marker Colour",i.appendChild(s);const o=document.createElement("div");o.className="settings-color-row";for(const t of r){const e=document.createElement("button");e.className="settings-swatch",e.style.background=t.color,e.setAttribute("data-color",t.color),t.color===this.settings.markerColor&&e.classList.add("selected"),e.addEventListener("click",()=>{o.querySelectorAll(".settings-swatch").forEach(t=>t.classList.remove("selected")),e.classList.add("selected"),this.settings.markerColor=t.color,this.emitChange()}),o.appendChild(e)}i.appendChild(o),this.el.appendChild(i),this.el.appendChild(this.createDivider()),this.el.appendChild(this.createCheckbox("Clear on copy",this.settings.clearOnCopy,t=>{this.settings.clearOnCopy=t,this.emitChange()})),this.el.appendChild(this.createCheckbox("Block page interactions",this.settings.blockInteractions,t=>{this.settings.blockInteractions=t,this.emitChange()})),this.el.appendChild(this.createDivider());const a=document.createElement("div");a.className="settings-mcp-row",this.mcpDot=document.createElement("span"),this.mcpDot.className="settings-mcp-dot disconnected",this.mcpLabel=document.createElement("span"),this.mcpLabel.className="settings-check-label",this.mcpLabel.textContent="MCP Disconnected",a.appendChild(this.mcpDot),a.appendChild(this.mcpLabel),this.el.appendChild(a)}createCheckbox(t,e,n){const i=document.createElement("label");i.className="settings-check-row";const s=document.createElement("input");s.type="checkbox",s.className="settings-checkbox",s.checked=e,s.addEventListener("change",()=>n(s.checked));const o=document.createElement("span");return o.className="settings-check-label",o.textContent=t,i.appendChild(s),i.appendChild(o),i}createDivider(){const t=document.createElement("div");return t.className="settings-divider",t}emitChange(){this.onChange?.({...this.settings})}toggle(){this.visible=!this.visible,this.el.classList.toggle("hidden",!this.visible)}hide(){this.visible=!1,this.el.classList.add("hidden")}isVisible(){return this.visible}setMcpStatus(t){this.mcpDot.className="settings-mcp-dot "+(t?"connected":"disconnected"),this.mcpLabel.textContent=t?"MCP Connected":"MCP Disconnected"}getSettings(){return{...this.settings}}}class l{constructor(t,e=4848){this.store=t,this.sessionId=null,this.connected=!1,this.retryTimer=null,this.baseUrl=`http://localhost:${e}`,this.discover(),this.store.on("add",t=>this.postAnnotation(t)),this.store.on("resolve",t=>this.patchAnnotation(t))}async discover(){try{const t=await fetch(`${this.baseUrl}/health`),e=await t.json();e&&"object"==typeof e&&"status"in e&&"ok"===e.status&&(this.connected=!0,this.onChange?.(!0),await this.createSession(),this.stopRetry())}catch{this.connected=!1,this.onChange?.(!1),this.startRetry()}}startRetry(){this.retryTimer||(this.retryTimer=setInterval(()=>this.discover(),5e3))}stopRetry(){this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=null)}async createSession(){try{const t=await fetch(`${this.baseUrl}/sessions`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:window.location.href,title:document.title||window.location.pathname})}),e=await t.json();this.sessionId=e.id}catch{}}async postAnnotation(t){if(this.connected&&this.sessionId)try{await fetch(`${this.baseUrl}/sessions/${this.sessionId}/annotations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({targetSelector:t.targetSelector,targetRect:t.targetRect,text:t.text})})}catch{}}async patchAnnotation(t){if(this.connected)try{await fetch(`${this.baseUrl}/annotations/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({resolved:!0,summary:"Resolved from browser"})})}catch{}}isConnected(){return this.connected}destroy(){this.stopRetry()}}class d{constructor(t={}){this.mcpBridge=null,this.currentTarget=null,this.currentRect=null,this.clearOnCopy=!1,this.host=document.createElement("div"),this.host.id="refiner-host",this.shadow=this.host.attachShadow({mode:"open"});const r=document.createElement("style");r.textContent='\n :host {\n all: initial;\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', system-ui, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n color: #1a1a2e;\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Toolbar ── */\n\n .refiner-toolbar {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10;\n user-select: none;\n }\n\n .toolbar-pill {\n display: flex;\n align-items: center;\n position: relative;\n background: #1a1a2e;\n border-radius: 100px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15);\n padding: 6px;\n transform: scale(1);\n transform-origin: right center;\n transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .refiner-toolbar[data-collapsed="true"] .toolbar-pill {\n transform: scale(0.92);\n }\n\n .toolbar-inner {\n display: flex;\n align-items: center;\n gap: 2px;\n overflow: hidden;\n clip-path: inset(0);\n max-width: 300px;\n opacity: 1;\n padding-right: 2px;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s ease 0.1s,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .refiner-toolbar[data-collapsed="true"] .toolbar-inner {\n max-width: 0;\n opacity: 0;\n padding-right: 0;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.15s ease,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .toolbar-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #a0a0b8;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n\n .toolbar-btn:hover {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolbar-btn.active {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n }\n\n .toolbar-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .toolbar-count {\n font-size: 14px;\n font-weight: 700;\n min-width: 18px;\n text-align: center;\n }\n\n .toolbar-divider {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.15);\n margin: 0 4px;\n flex-shrink: 0;\n }\n\n /* Tooltip */\n .toolbar-tooltip {\n position: absolute;\n bottom: calc(100% + 10px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px 10px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n }\n\n .toolbar-tooltip::after {\n content: \'\';\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 5px solid transparent;\n border-top-color: #1a1a2e;\n }\n\n .toolbar-btn:hover .toolbar-tooltip {\n opacity: 1;\n }\n\n .tooltips-hidden .toolbar-tooltip {\n display: none;\n }\n\n .toolbar-btn.disabled {\n opacity: 0.3;\n cursor: default;\n }\n\n .toolbar-btn.disabled:hover {\n color: #a0a0b8;\n background: transparent;\n }\n\n /* Toggle button (always visible) */\n .toolbar-toggle-btn {\n flex-shrink: 0;\n }\n\n /* Badge for collapsed state */\n .toolbar-expand-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 20px;\n height: 20px;\n padding: 0 5px;\n border-radius: 10px;\n background: #DC2626;\n color: #ffffff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n }\n\n .toolbar-expand-badge.hidden {\n display: none;\n }\n\n /* ── Settings Panel ── */\n\n .settings-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 300px;\n z-index: 12;\n background: #1a1a2e;\n border-radius: 16px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 20px;\n color: #e8e8f0;\n transform-origin: bottom right;\n transition: transform 0.25s ease, opacity 0.1s ease;\n transform: scale(1);\n opacity: 1;\n }\n\n .settings-panel.hidden {\n transform: scale(0.4);\n opacity: 0;\n pointer-events: none;\n }\n\n .settings-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .settings-title {\n font-size: 16px;\n font-weight: 700;\n font-style: normal;\n color: #ffffff;\n }\n\n .settings-version {\n font-size: 12px;\n color: #6b6b80;\n font-weight: 500;\n }\n\n .settings-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.08);\n margin: 16px 0;\n }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .settings-label {\n font-size: 14px;\n font-weight: 500;\n color: #c0c0d0;\n }\n\n .settings-color-row {\n display: flex;\n gap: 8px;\n }\n\n .settings-swatch {\n width: 24px;\n height: 24px;\n border-radius: 4px;\n border: 2px solid transparent;\n cursor: pointer;\n transition: transform 0.15s, border-color 0.15s;\n outline: none;\n }\n\n .settings-swatch:hover {\n transform: scale(1.1);\n }\n\n .settings-swatch.selected {\n border-color: #ffffff;\n transform: scale(1.1);\n }\n\n .settings-check-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n padding: 2px 0;\n }\n\n .settings-checkbox {\n appearance: none;\n -webkit-appearance: none;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 2px solid #4a4a60;\n background: transparent;\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n transition: background 0.15s, border-color 0.15s;\n }\n\n .settings-checkbox:checked {\n background: #2563EB;\n border-color: #2563EB;\n }\n\n .settings-checkbox:checked::after {\n content: \'\';\n position: absolute;\n top: 2px;\n left: 5px;\n width: 5px;\n height: 9px;\n border: solid #ffffff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .settings-check-label {\n font-size: 14px;\n font-weight: 500;\n color: #e8e8f0;\n }\n\n /* ── Overlay ── */\n\n .refiner-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n cursor: crosshair;\n z-index: 1;\n }\n\n .refiner-overlay[data-blocking="true"] {\n pointer-events: all;\n }\n\n .refiner-overlay[data-blocking="false"] {\n pointer-events: none;\n }\n\n .refiner-overlay.hidden {\n display: none;\n }\n\n /* ── Highlight ── */\n\n .refiner-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px dashed;\n border-radius: 3px;\n z-index: 2;\n transition: all 0.1s ease;\n }\n\n /* ── Dialog ── */\n\n .refiner-dialog {\n position: fixed;\n width: 320px;\n background: #1a1a2e;\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 14px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 11;\n color: #e8e8f0;\n animation: dialog-in 0.2s ease;\n }\n\n @keyframes dialog-in {\n from { opacity: 0; transform: translateY(4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .refiner-dialog.hidden {\n display: none;\n }\n\n .dialog-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .dialog-header span {\n font-size: 12px;\n font-weight: 600;\n color: #c0c0d0;\n }\n\n .dialog-textarea {\n width: 100%;\n min-height: 72px;\n padding: 10px 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 10px;\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: #e8e8f0;\n background: rgba(255, 255, 255, 0.06);\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .dialog-textarea:focus {\n border-color: rgba(255, 255, 255, 0.25);\n }\n\n .dialog-textarea::placeholder {\n color: #6b6b80;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n }\n\n .dialog-btn {\n height: 32px;\n padding: 0 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .dialog-btn-cancel {\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.12);\n color: #a0a0b8;\n }\n\n .dialog-btn-cancel:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #e8e8f0;\n }\n\n .dialog-btn-add {\n background: #2563EB;\n border: none;\n color: #ffffff;\n }\n\n .dialog-btn-add:hover {\n background: #3B82F6;\n }\n\n .dialog-btn-add:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n /* ── Markers ── */\n\n .refiner-marker {\n position: fixed;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n color: #ffffff;\n cursor: pointer;\n z-index: 10;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n transition: transform 0.15s;\n pointer-events: all;\n }\n\n .refiner-marker:hover {\n transform: scale(1.2);\n }\n\n .refiner-marker[data-resolved="true"] {\n opacity: 0.4;\n }\n\n .marker-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n width: 220px;\n padding: 10px 12px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n line-height: 1.4;\n border-radius: 10px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .refiner-marker:hover .marker-tooltip {\n opacity: 1;\n }\n\n .marker-tooltip-actions {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n border-top: 1px solid rgba(255,255,255,0.1);\n padding-top: 8px;\n }\n\n .marker-tooltip-btn {\n height: 22px;\n padding: 0 8px;\n border-radius: 5px;\n border: none;\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .marker-tooltip-btn.resolve {\n background: #34D399;\n color: #0a2e1f;\n }\n\n .marker-tooltip-btn.resolve:hover {\n background: #4ade80;\n }\n\n .marker-tooltip-btn.delete {\n background: rgba(255,255,255,0.1);\n color: #e8e8f0;\n }\n\n .marker-tooltip-btn.delete:hover {\n background: #FF6B6B;\n color: #fff;\n }\n\n /* MCP status */\n .settings-mcp-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n }\n\n .settings-mcp-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .settings-mcp-dot.connected {\n background: #34D399;\n box-shadow: 0 0 6px #34D39980;\n }\n\n .settings-mcp-dot.disconnected {\n background: #6B7280;\n }\n',this.shadow.appendChild(r),this.store=new e,this.toolbar=new n(this.shadow),this.settings=new a(this.shadow),this.overlay=new i(this.shadow),this.dialog=new s(this.shadow),this.markers=new o(this.shadow,this.store),this.toolbar.onCopy=()=>this.copyAnnotations(),this.toolbar.onClear=()=>this.clearAnnotations(),this.toolbar.onSettings=()=>{this.settings.toggle(),this.toolbar.setSettingsOpen(this.settings.isVisible())},this.toolbar.onCollapse=()=>{this.settings.hide(),this.toolbar.setSettingsOpen(!1),this.overlay.setEnabled(!1),this.host.style.pointerEvents="none"},this.toolbar.onExpand=()=>{this.overlay.setEnabled(!0),this.host.style.pointerEvents=""},this.settings.onChange=t=>{this.clearOnCopy=t.clearOnCopy,this.overlay.setBlocking(t.blockInteractions),this.markers.setColor(t.markerColor),this.overlay.setHighlightColor(t.markerColor)},this.overlay.onClick=(t,e)=>{if(this.settings.isVisible())return void this.settings.hide();if(this.dialog.isVisible())return void this.dialog.hide();this.currentTarget=t,this.currentRect=e;const n=e.left+e.width/2,i=e.top+e.height/2;this.dialog.show(n,i)},this.dialog.onSubmit=t=>{if(this.currentTarget&&this.currentRect){const e=function(t){if(t.id)return`#${CSS.escape(t.id)}`;if(t.classList.length>0){const e=`${t.tagName.toLowerCase()}.${Array.from(t.classList).map(CSS.escape).join(".")}`;if(1===document.querySelectorAll(e).length)return e}const e=[];let n=t;for(;n&&n!==document.documentElement;){const t=n.tagName.toLowerCase(),i=n.parentElement;if(n.id){e.unshift(`#${CSS.escape(n.id)}`);break}if(i){const s=Array.from(i.children).filter(t=>t.tagName===n.tagName);if(1===s.length)e.unshift(t);else{const i=s.indexOf(n)+1;e.unshift(`${t}:nth-child(${i})`)}}else e.unshift(t);n=i}return e.join(" > ")}(this.currentTarget);this.store.add(e,this.currentRect,t),this.toolbar.updateCount(this.store.getCount())}this.currentTarget=null,this.currentRect=null},this.dialog.onCancel=()=>{this.currentTarget=null,this.currentRect=null},this.store.on("resolve",()=>this.toolbar.updateCount(this.store.getCount())),this.store.on("remove",()=>this.toolbar.updateCount(this.store.getCount())),!1!==t.mcpEnabled&&(this.mcpBridge=new l(this.store,t.mcpPort),this.mcpBridge.onChange=t=>{this.settings.setMcpStatus(t)}),document.body.appendChild(this.host),!1===t.enabled&&this.disable()}enable(){this.host.style.display="",this.overlay.setEnabled(!0)}disable(){this.host.style.display="none",this.overlay.setEnabled(!1)}destroy(){this.mcpBridge?.destroy(),this.host.remove()}getAnnotations(){return this.store.getAll()}getAnnotationCount(){return this.store.getCount()}formatForAgent(){const t=this.store.getAll();if(0===t.length)return"No annotations.";const e=document.title||window.location.pathname,n=window.location.pathname,i=[`# Design Annotations — ${e}`,`**File:** \`${n.substring(n.lastIndexOf("/")+1)||"index.html"}\``,""];for(let e=0;e<t.length;e++){const n=t[e],s=n.resolved?" (resolved)":"";i.push(`## ${e+1}.${s}`),i.push(`**Element:** \`${n.targetSelector}\``),i.push(`**Issue:** ${n.text}`),i.push("")}return i.join("\n")}clearAnnotations(){const t=this.store.getAll();for(const e of t)this.store.remove(e.id);this.toolbar.updateCount(0)}copyAnnotations(){const t=this.formatForAgent();navigator.clipboard.writeText(t),this.clearOnCopy&&this.clearAnnotations()}}if("undefined"!=typeof window&&"undefined"!=typeof document){const t=()=>{if(window.__refiner)return;const t=document.currentScript,e=t?.dataset.refinerPosition??"right",n="false"!==t?.dataset.refinerEnabled,i=t?.dataset.refinerMcpPort?parseInt(t.dataset.refinerMcpPort,10):void 0,s="false"!==t?.dataset.refinerMcpEnabled,o=new d({position:e,enabled:n,mcpPort:i,mcpEnabled:s});window.__refiner=o};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}return t.Refiner=d,t}({});
2
2
  //# sourceMappingURL=refiner.js.map