@agent-native/pinpoint 0.1.9 → 0.1.11

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.
@@ -985,7 +985,7 @@ var PinMarkerManager = class {
985
985
  }
986
986
  };
987
987
 
988
- // ../../node_modules/.pnpm/solid-js@1.9.12/node_modules/solid-js/dist/solid.js
988
+ // ../../node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/dist/solid.js
989
989
  var sharedConfig = {
990
990
  context: void 0,
991
991
  registry: void 0,
@@ -1159,20 +1159,23 @@ function readSignal() {
1159
1159
  }
1160
1160
  }
1161
1161
  if (Listener) {
1162
- const sSlot = this.observers ? this.observers.length : 0;
1163
- if (!Listener.sources) {
1164
- Listener.sources = [this];
1165
- Listener.sourceSlots = [sSlot];
1166
- } else {
1167
- Listener.sources.push(this);
1168
- Listener.sourceSlots.push(sSlot);
1169
- }
1170
- if (!this.observers) {
1171
- this.observers = [Listener];
1172
- this.observerSlots = [Listener.sources.length - 1];
1173
- } else {
1174
- this.observers.push(Listener);
1175
- this.observerSlots.push(Listener.sources.length - 1);
1162
+ const observers = this.observers;
1163
+ if (!observers || observers[observers.length - 1] !== Listener) {
1164
+ const sSlot = observers ? observers.length : 0;
1165
+ if (!Listener.sources) {
1166
+ Listener.sources = [this];
1167
+ Listener.sourceSlots = [sSlot];
1168
+ } else {
1169
+ Listener.sources.push(this);
1170
+ Listener.sourceSlots.push(sSlot);
1171
+ }
1172
+ if (!observers) {
1173
+ this.observers = [Listener];
1174
+ this.observerSlots = [Listener.sources.length - 1];
1175
+ } else {
1176
+ observers.push(Listener);
1177
+ this.observerSlots.push(Listener.sources.length - 1);
1178
+ }
1176
1179
  }
1177
1180
  }
1178
1181
  if (runningTransition && Transition.sources.has(this)) return this.tValue;
@@ -1674,7 +1677,7 @@ function Show(props) {
1674
1677
  }, void 0, void 0);
1675
1678
  }
1676
1679
 
1677
- // ../../node_modules/.pnpm/solid-js@1.9.12/node_modules/solid-js/web/dist/web.js
1680
+ // ../../node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/web/dist/web.js
1678
1681
  var booleans = [
1679
1682
  "allowfullscreen",
1680
1683
  "async",
@@ -2059,2038 +2062,1227 @@ function cleanChildren(parent, current, marker, replacement) {
2059
2062
  return [node];
2060
2063
  }
2061
2064
 
2062
- // src/ui/styles/theme.ts
2063
- var overlayStyles = `
2064
- :host {
2065
- all: initial;
2066
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
2067
- font-size: 13px;
2068
- line-height: 1.4;
2069
- color: var(--pp-text);
2070
- pointer-events: none;
2071
- }
2072
-
2073
- *,
2074
- *::before,
2075
- *::after {
2076
- box-sizing: border-box;
2077
- margin: 0;
2078
- padding: 0;
2079
- }
2080
-
2081
- /* Theme variables */
2082
- :host {
2083
- --pp-bg: rgba(24, 24, 27, 0.92);
2084
- --pp-bg-solid: #18181b;
2085
- --pp-text: #fafafa;
2086
- --pp-text-muted: #a1a1aa;
2087
- --pp-border: rgba(63, 63, 70, 0.6);
2088
- --pp-accent: #3b82f6;
2089
- --pp-accent-hover: #60a5fa;
2090
- --pp-success: #22c55e;
2091
- --pp-warning: #eab308;
2092
- --pp-danger: #ef4444;
2093
- --pp-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.06);
2094
- --pp-radius: 10px;
2095
- --pp-radius-sm: 6px;
2096
- }
2097
-
2098
- :host([data-theme="light"]) {
2099
- --pp-bg: rgba(255, 255, 255, 0.92);
2100
- --pp-bg-solid: #ffffff;
2101
- --pp-text: #18181b;
2102
- --pp-text-muted: #71717a;
2103
- --pp-border: rgba(228, 228, 231, 0.8);
2104
- --pp-accent: #2563eb;
2105
- --pp-accent-hover: #3b82f6;
2106
- --pp-shadow: 0 4px 24px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.06);
2107
- }
2108
-
2109
- :host([data-theme="light"]) .pp-popup__textarea {
2110
- background: rgba(0, 0, 0, 0.06);
2111
- }
2112
-
2113
- /* Toolbar */
2114
- .pp-toolbar {
2115
- position: fixed;
2116
- z-index: 2147483646;
2117
- pointer-events: auto;
2118
- backdrop-filter: blur(12px) saturate(180%);
2119
- -webkit-backdrop-filter: blur(12px) saturate(180%);
2120
- background: var(--pp-bg);
2121
- border: 1px solid var(--pp-border);
2122
- border-radius: var(--pp-radius);
2123
- box-shadow: var(--pp-shadow);
2124
- transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
2125
- user-select: none;
2126
- cursor: default;
2127
- }
2128
-
2129
- .pp-toolbar--collapsed {
2130
- padding: 10px;
2131
- display: flex;
2132
- align-items: center;
2133
- justify-content: center;
2134
- gap: 6px;
2135
- cursor: pointer;
2136
- }
2137
-
2138
- .pp-toolbar--expanded {
2139
- padding: 12px;
2140
- width: 320px;
2141
- max-height: 420px;
2142
- display: flex;
2143
- flex-direction: column;
2144
- gap: 8px;
2145
- }
2146
-
2147
- .pp-toolbar__badge {
2148
- display: inline-flex;
2149
- align-items: center;
2150
- justify-content: center;
2151
- min-width: 18px;
2152
- height: 18px;
2153
- padding: 0 5px;
2154
- border-radius: 9px;
2155
- background: var(--pp-accent);
2156
- color: #fff;
2157
- font-size: 11px;
2158
- font-weight: 600;
2159
- }
2160
-
2161
- /* Buttons */
2162
- .pp-btn {
2163
- display: inline-flex;
2164
- align-items: center;
2165
- justify-content: center;
2166
- gap: 4px;
2167
- padding: 5px 10px;
2168
- border: 1px solid var(--pp-border);
2169
- border-radius: var(--pp-radius-sm);
2170
- background: transparent;
2171
- color: var(--pp-text);
2172
- font-size: 12px;
2173
- font-weight: 500;
2174
- cursor: pointer;
2175
- transition: all 0.15s ease;
2176
- white-space: nowrap;
2177
- }
2178
-
2179
- .pp-btn:hover {
2180
- background: rgba(255, 255, 255, 0.06);
2181
- border-color: var(--pp-accent);
2182
- }
2183
-
2184
- .pp-btn--primary {
2185
- background: var(--pp-accent);
2186
- border-color: var(--pp-accent);
2187
- color: #fff;
2188
- }
2189
-
2190
- .pp-btn--primary:hover {
2191
- background: var(--pp-accent-hover);
2192
- }
2193
-
2194
- .pp-btn--sm {
2195
- padding: 3px 6px;
2196
- font-size: 11px;
2197
- }
2065
+ // src/ui/icons/index.ts
2066
+ var S = 'width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"';
2067
+ var icons = {
2068
+ pin: `<svg ${S}><path d="M15 4.5l-4 4l-4 1.5l-1.5 1.5l7 7l1.5 -1.5l1.5 -4l4 -4"/><path d="M9 15l-4.5 4.5"/><path d="M14.5 4l5.5 5.5"/></svg>`,
2069
+ mapPin: `<svg ${S}><path d="M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/><path d="M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0"/></svg>`,
2070
+ crosshair: `<svg ${S}><path d="M4 8v-2a2 2 0 0 1 2 -2h2"/><path d="M4 16v2a2 2 0 0 0 2 2h2"/><path d="M16 4h2a2 2 0 0 1 2 2v2"/><path d="M16 20h2a2 2 0 0 0 2 -2v-2"/><path d="M9 12l6 0"/><path d="M12 9l0 6"/></svg>`,
2071
+ send: `<svg ${S}><path d="M10 14l11 -11"/><path d="M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5"/></svg>`,
2072
+ copy: `<svg ${S}><path d="M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z"/><path d="M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1"/></svg>`,
2073
+ trash: `<svg ${S}><path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/></svg>`,
2074
+ settings: `<svg ${S}><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065"/><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/></svg>`,
2075
+ x: `<svg ${S}><path d="M18 6l-12 12"/><path d="M6 6l12 12"/></svg>`,
2076
+ chevronDown: `<svg ${S}><path d="M6 9l6 6l6 -6"/></svg>`,
2077
+ check: `<svg ${S}><path d="M5 12l5 5l10 -10"/></svg>`,
2078
+ messageSquare: `<svg ${S}><path d="M8 9h8"/><path d="M8 13h6"/><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"/></svg>`,
2079
+ eye: `<svg ${S}><path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"/><path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"/></svg>`,
2080
+ fileCode: `<svg ${S}><path d="M14 3v4a1 1 0 0 0 1 1h4"/><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2"/><path d="M10 13l-1 2l1 2"/><path d="M14 13l1 2l-1 2"/></svg>`,
2081
+ history: `<svg ${S}><path d="M12 8l0 4l2 2"/><path d="M3.05 11a9 9 0 1 1 .5 4m-.5 5v-5h5"/></svg>`,
2082
+ minus: `<svg ${S}><path d="M5 12l14 0"/></svg>`,
2083
+ // Draw mode icons
2084
+ pencil: `<svg ${S}><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4"/><path d="M13.5 6.5l4 4"/></svg>`,
2085
+ arrowUpRight: `<svg ${S}><path d="M17 7l-10 10"/><path d="M8 7l9 0l0 9"/></svg>`,
2086
+ circle: `<svg ${S}><circle cx="12" cy="12" r="9"/></svg>`,
2087
+ square: `<svg ${S}><rect x="4" y="4" width="16" height="16" rx="2"/></svg>`,
2088
+ typography: `<svg ${S}><path d="M4 20l3 0"/><path d="M14 20l7 0"/><path d="M6.9 15l6.9 0"/><path d="M10.2 6.3l5.8 13.7"/><path d="M5 20l6 -16l2 0l7 16"/></svg>`,
2089
+ undo: `<svg ${S}><path d="M9 14l-4 -4l4 -4"/><path d="M5 10h11a4 4 0 1 1 0 8h-1"/></svg>`,
2090
+ palette: `<svg ${S}><path d="M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25"/><circle cx="8.5" cy="10.5" r="1"/><circle cx="12.5" cy="7.5" r="1"/><circle cx="16.5" cy="10.5" r="1"/></svg>`,
2091
+ lineWeight: `<svg ${S}><path d="M4 6h16"/><path d="M4 12h16" stroke-width="3"/><path d="M4 18h16" stroke-width="5"/></svg>`,
2092
+ // Voice icon
2093
+ microphone: `<svg ${S}><path d="M9 2m0 3a3 3 0 0 1 3 -3h0a3 3 0 0 1 3 3v5a3 3 0 0 1 -3 3h0a3 3 0 0 1 -3 -3z"/><path d="M5 10a7 7 0 0 0 14 0"/><path d="M8 21l8 0"/><path d="M12 17l0 4"/></svg>`,
2094
+ microphoneOff: `<svg ${S}><path d="M3 3l18 18"/><path d="M9 5a3 3 0 0 1 6 0v5a3 3 0 0 1 -.13 .874m-2 2a3 3 0 0 1 -3.87 -2.872v-1"/><path d="M5 10a7 7 0 0 0 10.846 5.85m2 -2a6.967 6.967 0 0 0 1.152 -3.85"/><path d="M8 21l8 0"/><path d="M12 17l0 4"/></svg>`,
2095
+ // Queue & batch icons
2096
+ plus: `<svg ${S}><path d="M12 5l0 14"/><path d="M5 12l14 0"/></svg>`,
2097
+ stack: `<svg ${S}><path d="M12 2l-8 4l8 4l8 -4l-8 -4"/><path d="M4 10l8 4l8 -4"/><path d="M4 14l8 4l8 -4"/></svg>`,
2098
+ checkSquare: `<svg ${S}><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 12l2 2l4 -4"/></svg>`,
2099
+ squareEmpty: `<svg ${S}><rect x="3" y="3" width="18" height="18" rx="2"/></svg>`,
2100
+ bolt: `<svg ${S}><path d="M13 3l0 7l6 0l-8 11l0 -7l-6 0l8 -11"/></svg>`,
2101
+ checkCircle: `<svg ${S}><circle cx="12" cy="12" r="9"/><path d="M9 12l2 2l4 -4"/></svg>`
2102
+ };
2198
2103
 
2199
- .pp-btn--icon {
2200
- padding: 4px;
2201
- border: none;
2202
- background: transparent;
2203
- color: var(--pp-text-muted);
2204
- cursor: pointer;
2205
- border-radius: var(--pp-radius-sm);
2206
- }
2104
+ // src/ui/components/ContextMenu.tsx
2105
+ var _tmpl$ = /* @__PURE__ */ template(`<div class=pp-context-menu><div class=pp-context-menu__item><span></span>Add Annotation</div><div class=pp-context-menu__item><span></span>Quick Prompt</div><div class=pp-context-menu__separator></div><div class=pp-context-menu__item><span></span>Copy Element Context</div><div class=pp-context-menu__item><span></span>Copy HTML Snippet</div><div class=pp-context-menu__item><span></span>Copy Computed Styles`);
2106
+ var ContextMenu = (props) => {
2107
+ let menuRef;
2108
+ onMount(() => {
2109
+ const handleClick = (e) => {
2110
+ if (menuRef && !e.composedPath().includes(menuRef)) {
2111
+ props.onClose();
2112
+ }
2113
+ };
2114
+ const handleKeyDown = (e) => {
2115
+ if (e.key === "Escape") props.onClose();
2116
+ };
2117
+ setTimeout(() => {
2118
+ document.addEventListener("click", handleClick, true);
2119
+ document.addEventListener("keydown", handleKeyDown, true);
2120
+ }, 0);
2121
+ onCleanup(() => {
2122
+ document.removeEventListener("click", handleClick, true);
2123
+ document.removeEventListener("keydown", handleKeyDown, true);
2124
+ });
2125
+ });
2126
+ const x = Math.min(props.position.x, window.innerWidth - 200);
2127
+ const y = Math.min(props.position.y, window.innerHeight - 250);
2128
+ return (() => {
2129
+ var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$4.nextSibling, _el$7 = _el$6.nextSibling, _el$8 = _el$7.firstChild, _el$9 = _el$7.nextSibling, _el$0 = _el$9.firstChild, _el$1 = _el$9.nextSibling, _el$10 = _el$1.firstChild;
2130
+ var _ref$ = menuRef;
2131
+ typeof _ref$ === "function" ? use(_ref$, _el$) : menuRef = _el$;
2132
+ setStyleProperty(_el$, "left", `${x}px`);
2133
+ setStyleProperty(_el$, "top", `${y}px`);
2134
+ addEventListener(_el$2, "click", () => props.onAnnotate());
2135
+ addEventListener(_el$4, "click", () => props.onPrompt());
2136
+ addEventListener(_el$7, "click", () => props.onCopyContext());
2137
+ addEventListener(_el$9, "click", async () => {
2138
+ const html = props.element.outerHTML.replace(/\s+/g, " ").trim().slice(0, 500);
2139
+ await navigator.clipboard.writeText(html);
2140
+ props.onClose();
2141
+ });
2142
+ addEventListener(_el$1, "click", async () => {
2143
+ const styles = window.getComputedStyle(props.element);
2144
+ const relevant = ["color", "background-color", "font-size", "font-family", "padding", "margin", "border", "display", "position", "width", "height"];
2145
+ const result = relevant.map((key) => `${key}: ${styles.getPropertyValue(key)}`).join("\n");
2146
+ await navigator.clipboard.writeText(result);
2147
+ props.onClose();
2148
+ });
2149
+ createRenderEffect((_p$) => {
2150
+ var _v$ = icons.pin, _v$2 = icons.messageSquare, _v$3 = icons.copy, _v$4 = icons.fileCode, _v$5 = icons.eye;
2151
+ _v$ !== _p$.e && (_el$3.innerHTML = _p$.e = _v$);
2152
+ _v$2 !== _p$.t && (_el$5.innerHTML = _p$.t = _v$2);
2153
+ _v$3 !== _p$.a && (_el$8.innerHTML = _p$.a = _v$3);
2154
+ _v$4 !== _p$.o && (_el$0.innerHTML = _p$.o = _v$4);
2155
+ _v$5 !== _p$.i && (_el$10.innerHTML = _p$.i = _v$5);
2156
+ return _p$;
2157
+ }, {
2158
+ e: void 0,
2159
+ t: void 0,
2160
+ a: void 0,
2161
+ o: void 0,
2162
+ i: void 0
2163
+ });
2164
+ return _el$;
2165
+ })();
2166
+ };
2207
2167
 
2208
- .pp-btn--icon:hover {
2209
- background: rgba(255, 255, 255, 0.06);
2210
- color: var(--pp-text);
2168
+ // src/ui/components/OverlayCanvas.tsx
2169
+ var _tmpl$2 = /* @__PURE__ */ template(`<canvas style=position:fixed;top:0;left:0;z-index:2147483645>`);
2170
+ function lerp(start, end, t) {
2171
+ return start + (end - start) * t;
2211
2172
  }
2212
-
2213
- .pp-btn--icon-sm {
2214
- padding: 2px;
2215
- opacity: 0;
2216
- pointer-events: none;
2217
- transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease;
2218
- }
2219
-
2220
- .pp-pin-item:hover .pp-btn--icon-sm,
2221
- .pp-pin-item:focus-within .pp-btn--icon-sm {
2222
- opacity: 1;
2223
- pointer-events: auto;
2224
- }
2225
-
2226
- .pp-btn--icon-sm:hover {
2227
- background: rgba(239, 68, 68, 0.15);
2228
- color: var(--pp-danger);
2229
- }
2230
-
2231
- @media (hover: none) {
2232
- .pp-btn--icon-sm {
2233
- opacity: 0.6;
2234
- pointer-events: auto;
2173
+ var OverlayCanvas = (props) => {
2174
+ let canvasRef;
2175
+ let animFrameId = null;
2176
+ let currentRect = {
2177
+ x: 0,
2178
+ y: 0,
2179
+ width: 0,
2180
+ height: 0
2181
+ };
2182
+ let targetRect = null;
2183
+ const LERP_SPEED = 0.25;
2184
+ function resizeCanvas() {
2185
+ if (!canvasRef) return;
2186
+ const dpr = window.devicePixelRatio || 1;
2187
+ canvasRef.width = window.innerWidth * dpr;
2188
+ canvasRef.height = window.innerHeight * dpr;
2189
+ canvasRef.style.width = `${window.innerWidth}px`;
2190
+ canvasRef.style.height = `${window.innerHeight}px`;
2191
+ const ctx = canvasRef.getContext("2d");
2192
+ if (ctx) ctx.scale(dpr, dpr);
2235
2193
  }
2236
- }
2194
+ function drawStroke(ctx, stroke) {
2195
+ if (stroke.points.length < 1) return;
2196
+ ctx.strokeStyle = stroke.color;
2197
+ ctx.lineWidth = stroke.lineWidth;
2198
+ ctx.lineCap = "round";
2199
+ ctx.lineJoin = "round";
2200
+ ctx.setLineDash([]);
2201
+ if (stroke.type === "freehand") {
2202
+ ctx.beginPath();
2203
+ ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
2204
+ for (let i = 1; i < stroke.points.length; i++) {
2205
+ ctx.lineTo(stroke.points[i].x, stroke.points[i].y);
2206
+ }
2207
+ ctx.stroke();
2208
+ } else if (stroke.type === "arrow") {
2209
+ if (stroke.points.length < 2) return;
2210
+ const start = stroke.points[0];
2211
+ const end = stroke.points[stroke.points.length - 1];
2212
+ ctx.beginPath();
2213
+ ctx.moveTo(start.x, start.y);
2214
+ ctx.lineTo(end.x, end.y);
2215
+ ctx.stroke();
2216
+ const angle = Math.atan2(end.y - start.y, end.x - start.x);
2217
+ const headLen = 12 + stroke.lineWidth * 2;
2218
+ ctx.beginPath();
2219
+ ctx.moveTo(end.x, end.y);
2220
+ ctx.lineTo(end.x - headLen * Math.cos(angle - Math.PI / 6), end.y - headLen * Math.sin(angle - Math.PI / 6));
2221
+ ctx.moveTo(end.x, end.y);
2222
+ ctx.lineTo(end.x - headLen * Math.cos(angle + Math.PI / 6), end.y - headLen * Math.sin(angle + Math.PI / 6));
2223
+ ctx.stroke();
2224
+ } else if (stroke.type === "circle") {
2225
+ if (stroke.points.length < 2) return;
2226
+ const start = stroke.points[0];
2227
+ const end = stroke.points[stroke.points.length - 1];
2228
+ const rx = Math.abs(end.x - start.x) / 2;
2229
+ const ry = Math.abs(end.y - start.y) / 2;
2230
+ const cx = (start.x + end.x) / 2;
2231
+ const cy = (start.y + end.y) / 2;
2232
+ ctx.beginPath();
2233
+ ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
2234
+ ctx.stroke();
2235
+ } else if (stroke.type === "rect") {
2236
+ if (stroke.points.length < 2) return;
2237
+ const start = stroke.points[0];
2238
+ const end = stroke.points[stroke.points.length - 1];
2239
+ ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
2240
+ }
2241
+ }
2242
+ function drawTextNote(ctx, note) {
2243
+ const fontSize = 13;
2244
+ const padding = 6;
2245
+ ctx.font = `500 ${fontSize}px -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`;
2246
+ const metrics = ctx.measureText(note.text);
2247
+ const textWidth = metrics.width;
2248
+ const textHeight = fontSize + 2;
2249
+ ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
2250
+ const bgX = note.x - 2;
2251
+ const bgY = note.y - textHeight - padding / 2;
2252
+ const bgW = textWidth + padding * 2;
2253
+ const bgH = textHeight + padding;
2254
+ const r = 4;
2255
+ ctx.beginPath();
2256
+ ctx.moveTo(bgX + r, bgY);
2257
+ ctx.lineTo(bgX + bgW - r, bgY);
2258
+ ctx.quadraticCurveTo(bgX + bgW, bgY, bgX + bgW, bgY + r);
2259
+ ctx.lineTo(bgX + bgW, bgY + bgH - r);
2260
+ ctx.quadraticCurveTo(bgX + bgW, bgY + bgH, bgX + bgW - r, bgY + bgH);
2261
+ ctx.lineTo(bgX + r, bgY + bgH);
2262
+ ctx.quadraticCurveTo(bgX, bgY + bgH, bgX, bgY + bgH - r);
2263
+ ctx.lineTo(bgX, bgY + r);
2264
+ ctx.quadraticCurveTo(bgX, bgY, bgX + r, bgY);
2265
+ ctx.closePath();
2266
+ ctx.fill();
2267
+ ctx.fillStyle = note.color;
2268
+ ctx.beginPath();
2269
+ ctx.arc(bgX + padding, bgY + bgH / 2, 3, 0, Math.PI * 2);
2270
+ ctx.fill();
2271
+ ctx.fillStyle = "#ffffff";
2272
+ ctx.fillText(note.text, bgX + padding + 10, note.y - 2);
2273
+ }
2274
+ function draw() {
2275
+ if (!canvasRef) return;
2276
+ const ctx = canvasRef.getContext("2d");
2277
+ if (!ctx) return;
2278
+ const dpr = window.devicePixelRatio || 1;
2279
+ ctx.clearRect(0, 0, canvasRef.width / dpr, canvasRef.height / dpr);
2280
+ if (props.active && !props.drawMode && props.hoveredRect) {
2281
+ targetRect = {
2282
+ x: props.hoveredRect.x,
2283
+ y: props.hoveredRect.y,
2284
+ width: props.hoveredRect.width,
2285
+ height: props.hoveredRect.height
2286
+ };
2287
+ } else if (props.active && !props.drawMode) {
2288
+ targetRect = null;
2289
+ }
2290
+ if (props.active && !props.drawMode && targetRect) {
2291
+ currentRect.x = lerp(currentRect.x, targetRect.x, LERP_SPEED);
2292
+ currentRect.y = lerp(currentRect.y, targetRect.y, LERP_SPEED);
2293
+ currentRect.width = lerp(currentRect.width, targetRect.width, LERP_SPEED);
2294
+ currentRect.height = lerp(currentRect.height, targetRect.height, LERP_SPEED);
2295
+ ctx.strokeStyle = "rgba(59, 130, 246, 0.8)";
2296
+ ctx.lineWidth = 2;
2297
+ ctx.setLineDash([]);
2298
+ ctx.strokeRect(currentRect.x, currentRect.y, currentRect.width, currentRect.height);
2299
+ ctx.fillStyle = "rgba(59, 130, 246, 0.06)";
2300
+ ctx.fillRect(currentRect.x, currentRect.y, currentRect.width, currentRect.height);
2301
+ }
2302
+ if (props.active && !props.drawMode && props.dragRect) {
2303
+ ctx.strokeStyle = "rgba(59, 130, 246, 0.6)";
2304
+ ctx.lineWidth = 1;
2305
+ ctx.setLineDash([4, 4]);
2306
+ ctx.strokeRect(props.dragRect.x, props.dragRect.y, props.dragRect.width, props.dragRect.height);
2307
+ ctx.fillStyle = "rgba(59, 130, 246, 0.08)";
2308
+ ctx.fillRect(props.dragRect.x, props.dragRect.y, props.dragRect.width, props.dragRect.height);
2309
+ }
2310
+ for (const stroke of props.drawStrokes) {
2311
+ drawStroke(ctx, stroke);
2312
+ }
2313
+ if (props.currentStroke) {
2314
+ drawStroke(ctx, props.currentStroke);
2315
+ }
2316
+ for (const note of props.textNotes) {
2317
+ drawTextNote(ctx, note);
2318
+ }
2319
+ animFrameId = requestAnimationFrame(draw);
2320
+ }
2321
+ function handleMouseDown(e) {
2322
+ if (!props.drawMode) return;
2323
+ if (props.drawTool === "text") {
2324
+ props.onTextPlace(e.clientX, e.clientY);
2325
+ } else {
2326
+ props.onDrawStart(e.clientX, e.clientY);
2327
+ }
2328
+ }
2329
+ function handleMouseMove(e) {
2330
+ if (!props.drawMode) return;
2331
+ props.onDrawMove(e.clientX, e.clientY);
2332
+ }
2333
+ function handleMouseUp(_e) {
2334
+ if (!props.drawMode) return;
2335
+ props.onDrawEnd();
2336
+ }
2337
+ function handleTouchStart(e) {
2338
+ if (!props.drawMode) return;
2339
+ e.preventDefault();
2340
+ const touch = e.touches[0];
2341
+ if (props.drawTool === "text") {
2342
+ props.onTextPlace(touch.clientX, touch.clientY);
2343
+ } else {
2344
+ props.onDrawStart(touch.clientX, touch.clientY);
2345
+ }
2346
+ }
2347
+ function handleTouchMove(e) {
2348
+ if (!props.drawMode) return;
2349
+ e.preventDefault();
2350
+ const touch = e.touches[0];
2351
+ props.onDrawMove(touch.clientX, touch.clientY);
2352
+ }
2353
+ function handleTouchEnd(e) {
2354
+ if (!props.drawMode) return;
2355
+ e.preventDefault();
2356
+ props.onDrawEnd();
2357
+ }
2358
+ onMount(() => {
2359
+ resizeCanvas();
2360
+ window.addEventListener("resize", resizeCanvas);
2361
+ animFrameId = requestAnimationFrame(draw);
2362
+ });
2363
+ onCleanup(() => {
2364
+ window.removeEventListener("resize", resizeCanvas);
2365
+ if (animFrameId !== null) {
2366
+ cancelAnimationFrame(animFrameId);
2367
+ }
2368
+ });
2369
+ return (() => {
2370
+ var _el$ = _tmpl$2();
2371
+ _el$.$$touchend = handleTouchEnd;
2372
+ _el$.$$touchmove = handleTouchMove;
2373
+ _el$.$$touchstart = handleTouchStart;
2374
+ _el$.$$mouseup = handleMouseUp;
2375
+ _el$.$$mousemove = handleMouseMove;
2376
+ _el$.$$mousedown = handleMouseDown;
2377
+ var _ref$ = canvasRef;
2378
+ typeof _ref$ === "function" ? use(_ref$, _el$) : canvasRef = _el$;
2379
+ createRenderEffect((_p$) => {
2380
+ var _v$ = props.drawMode ? "auto" : "none", _v$2 = props.drawMode ? props.drawTool === "text" ? "text" : "crosshair" : "default";
2381
+ _v$ !== _p$.e && setStyleProperty(_el$, "pointer-events", _p$.e = _v$);
2382
+ _v$2 !== _p$.t && setStyleProperty(_el$, "cursor", _p$.t = _v$2);
2383
+ return _p$;
2384
+ }, {
2385
+ e: void 0,
2386
+ t: void 0
2387
+ });
2388
+ return _el$;
2389
+ })();
2390
+ };
2391
+ delegateEvents(["mousedown", "mousemove", "mouseup", "touchstart", "touchmove", "touchend"]);
2237
2392
 
2238
- @media (prefers-reduced-motion: reduce) {
2239
- .pp-btn--icon-sm { transition: none; }
2393
+ // src/ui/components/PinPopup.tsx
2394
+ var _tmpl$3 = /* @__PURE__ */ template(`<div class=pp-popup><div class=pp-popup__input-row><textarea class=pp-popup__textarea placeholder="Add your feedback..."></textarea></div><div class=pp-popup__actions><button class="pp-btn pp-btn--ghost"title="Send 'Fix this' to agent"><span style=display:inline-flex></span>Fix</button><div style=flex:1></div><button class=pp-btn>Cancel</button><button class="pp-btn pp-btn--primary">`);
2395
+ var _tmpl$22 = /* @__PURE__ */ template(`<div class=pp-popup__header><span class=pp-popup__name></span><span>`);
2396
+ var _tmpl$32 = /* @__PURE__ */ template(`<div><div class=pp-popup__details-inner><div class=pp-popup__element-info>`);
2397
+ var _tmpl$4 = /* @__PURE__ */ template(`<div class=pp-popup__source><span style=display:inline-flex;vertical-align:middle></span> `);
2398
+ var _tmpl$5 = /* @__PURE__ */ template(`<div class=pp-popup__component>`);
2399
+ var _tmpl$6 = /* @__PURE__ */ template(`<div class=pp-popup__element-info>`);
2400
+ var _tmpl$7 = /* @__PURE__ */ template(`<button>`);
2401
+ var _tmpl$8 = /* @__PURE__ */ template(`<button class=pp-btn title="Add to queue"><span style=display:inline-flex></span>Queue`);
2402
+ function getSpeechRecognition() {
2403
+ const w = window;
2404
+ return w.SpeechRecognition || w.webkitSpeechRecognition || null;
2240
2405
  }
2241
-
2242
- /* Pin list */
2243
- .pp-pin-list {
2244
- display: flex;
2245
- flex-direction: column;
2246
- gap: 4px;
2247
- overflow-y: auto;
2248
- max-height: 240px;
2249
- scrollbar-width: thin;
2250
- scrollbar-color: var(--pp-border) transparent;
2251
- }
2252
-
2253
- .pp-pin-item {
2254
- display: flex;
2255
- align-items: center;
2256
- gap: 8px;
2257
- padding: 6px 8px;
2258
- border-radius: var(--pp-radius-sm);
2259
- cursor: pointer;
2260
- transition: background 0.1s;
2261
- }
2262
-
2263
- .pp-pin-item:hover {
2264
- background: rgba(255, 255, 255, 0.04);
2265
- }
2266
-
2267
- .pp-pin-item__number {
2268
- display: flex;
2269
- align-items: center;
2270
- justify-content: center;
2271
- width: 22px;
2272
- height: 22px;
2273
- min-width: 22px;
2274
- padding: 0 4px;
2275
- border-radius: 11px;
2276
- background: var(--pp-accent);
2277
- color: #fff;
2278
- font-size: 11px;
2279
- font-weight: 600;
2280
- font-variant-numeric: tabular-nums;
2281
- flex-shrink: 0;
2282
- }
2283
-
2284
- .pp-pin-item__content {
2285
- flex: 1;
2286
- min-width: 0;
2287
- }
2288
-
2289
- .pp-pin-item__comment {
2290
- font-size: 12px;
2291
- color: var(--pp-text);
2292
- display: -webkit-box;
2293
- -webkit-line-clamp: 2;
2294
- -webkit-box-orient: vertical;
2295
- overflow: hidden;
2296
- word-break: break-word;
2297
- }
2298
-
2299
- .pp-pin-item__status {
2300
- width: 6px;
2301
- height: 6px;
2302
- border-radius: 50%;
2303
- flex-shrink: 0;
2304
- }
2305
-
2306
- .pp-pin-item__status--open { background: var(--pp-danger); }
2307
- .pp-pin-item__status--acknowledged { background: var(--pp-warning); }
2308
- .pp-pin-item__status--resolved { background: var(--pp-success); }
2309
- .pp-pin-item__status--dismissed { background: var(--pp-text-muted); }
2310
-
2311
- /* Action bar \u2014 horizontal icon bar at bottom */
2312
- .pp-actions {
2313
- display: flex;
2314
- align-items: center;
2315
- justify-content: center;
2316
- gap: 6px;
2317
- padding-top: 8px;
2318
- border-top: 1px solid var(--pp-border);
2319
- }
2320
-
2321
- .pp-actions .pp-btn--icon {
2322
- width: 32px;
2323
- height: 32px;
2324
- border-radius: 50%;
2325
- display: flex;
2326
- align-items: center;
2327
- justify-content: center;
2328
- }
2329
-
2330
- .pp-actions .pp-btn--icon:focus-visible {
2331
- outline: 2px solid var(--pp-accent);
2332
- outline-offset: 2px;
2333
- }
2334
-
2335
- /* Popup */
2336
- .pp-popup {
2337
- position: fixed;
2338
- z-index: 2147483647;
2339
- pointer-events: auto;
2340
- backdrop-filter: blur(12px) saturate(180%);
2341
- -webkit-backdrop-filter: blur(12px) saturate(180%);
2342
- background: var(--pp-bg);
2343
- border: 1px solid var(--pp-border);
2344
- border-radius: var(--pp-radius);
2345
- box-shadow: var(--pp-shadow);
2346
- padding: 10px;
2347
- min-width: 280px;
2348
- max-width: 360px;
2349
- display: flex;
2350
- flex-direction: column;
2351
- gap: 6px;
2352
- }
2353
-
2354
- .pp-popup__element-info {
2355
- font-size: 11px;
2356
- font-family: 'SF Mono', 'Fira Code', monospace;
2357
- color: var(--pp-accent);
2358
- word-break: break-all;
2359
- }
2360
-
2361
- .pp-popup__component {
2362
- font-size: 12px;
2363
- color: var(--pp-text-muted);
2364
- }
2365
-
2366
- .pp-popup__source {
2367
- font-size: 11px;
2368
- color: var(--pp-text-muted);
2369
- cursor: pointer;
2370
- display: flex;
2371
- align-items: center;
2372
- gap: 4px;
2373
- }
2374
-
2375
- .pp-popup__source:hover {
2376
- color: var(--pp-accent);
2377
- text-decoration: underline;
2378
- }
2379
-
2380
- /* Popup header with chevron toggle */
2381
- .pp-popup__header {
2382
- display: flex;
2383
- align-items: center;
2384
- justify-content: space-between;
2385
- cursor: pointer;
2386
- padding: 2px 0;
2387
- }
2388
-
2389
- .pp-popup__name {
2390
- font-size: 12px;
2391
- font-weight: 500;
2392
- color: var(--pp-text);
2393
- overflow: hidden;
2394
- text-overflow: ellipsis;
2395
- white-space: nowrap;
2396
- max-width: 280px;
2397
- }
2398
-
2399
- .pp-popup__chevron {
2400
- color: var(--pp-text-muted);
2401
- transition: transform 0.15s ease;
2402
- display: flex;
2403
- align-items: center;
2404
- flex-shrink: 0;
2405
- transform: rotate(-90deg);
2406
- }
2407
-
2408
- .pp-popup__chevron--open {
2409
- transform: rotate(0deg);
2410
- }
2411
-
2412
- /* CSS-based collapsible \u2014 keeps DOM, animates height */
2413
- .pp-popup__details {
2414
- display: grid;
2415
- grid-template-rows: 0fr;
2416
- transition: grid-template-rows 0.2s ease-out;
2417
- }
2418
-
2419
- .pp-popup__details--open {
2420
- grid-template-rows: 1fr;
2421
- }
2422
-
2423
- .pp-popup__details-inner {
2424
- overflow: hidden;
2425
- display: flex;
2426
- flex-direction: column;
2427
- gap: 3px;
2428
- }
2429
-
2430
- @media (prefers-reduced-motion: reduce) {
2431
- .pp-popup__chevron,
2432
- .pp-popup__details {
2433
- transition: none;
2406
+ var PinPopup = (props) => {
2407
+ const [comment, setComment] = createSignal(props.initialComment || "");
2408
+ const [showDetails, setShowDetails] = createSignal(false);
2409
+ const [isRecording, setIsRecording] = createSignal(false);
2410
+ let textareaRef;
2411
+ let recognitionRef = null;
2412
+ const compact = () => props.compactPopup ?? true;
2413
+ const hasSpeechAPI = !!getSpeechRecognition();
2414
+ const displayName = () => {
2415
+ if (props.context.framework?.componentPath) {
2416
+ return props.context.framework.componentPath;
2417
+ }
2418
+ return `<${props.context.element.tagName.toLowerCase()}>`;
2419
+ };
2420
+ const popupPosition = () => {
2421
+ const rect = props.context.element.boundingRect;
2422
+ const estimatedHeight = compact() && showDetails() ? 260 : 220;
2423
+ const popupX = Math.min(rect.x, window.innerWidth - 380);
2424
+ const popupY = rect.y + rect.height + 8;
2425
+ const adjustedY = popupY + estimatedHeight > window.innerHeight ? rect.y - estimatedHeight - 8 : popupY;
2426
+ return {
2427
+ x: Math.max(8, popupX),
2428
+ y: Math.max(8, adjustedY)
2429
+ };
2430
+ };
2431
+ async function openFileHandler() {
2432
+ try {
2433
+ const file = props.context.framework?.sourceFile;
2434
+ if (!file) return;
2435
+ const {
2436
+ openFile
2437
+ } = await import("./open-file-RQVHOCXI.js");
2438
+ openFile(file);
2439
+ } catch {
2440
+ }
2434
2441
  }
2435
- }
2436
-
2437
- .pp-popup__textarea {
2438
- width: 100%;
2439
- min-height: 48px;
2440
- max-height: 120px;
2441
- padding: 8px;
2442
- border: 1px solid var(--pp-border);
2443
- border-radius: var(--pp-radius-sm);
2444
- background: rgba(0, 0, 0, 0.2);
2445
- color: var(--pp-text);
2446
- font-size: 13px;
2447
- font-family: inherit;
2448
- resize: none;
2449
- overflow-y: auto;
2450
- outline: none;
2451
- }
2452
-
2453
- .pp-popup__textarea:focus {
2454
- border-color: var(--pp-accent);
2455
- }
2456
-
2457
- .pp-popup__actions {
2458
- display: flex;
2459
- gap: 6px;
2460
- justify-content: flex-end;
2461
- }
2462
-
2463
- .pp-popup__actions .pp-btn {
2464
- height: 26px;
2465
- padding: 0 10px;
2466
- font-size: 12px;
2467
- }
2468
-
2469
- /* Selection label */
2470
- .pp-selection-label {
2471
- position: fixed;
2472
- z-index: 2147483646;
2473
- pointer-events: none;
2474
- padding: 3px 8px;
2475
- border-radius: 4px;
2476
- background: var(--pp-accent);
2477
- color: #fff;
2478
- font-size: 11px;
2479
- font-weight: 500;
2480
- white-space: nowrap;
2481
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
2482
- }
2442
+ function toggleRecording() {
2443
+ if (isRecording()) {
2444
+ stopRecording();
2445
+ } else {
2446
+ startRecording();
2447
+ }
2448
+ }
2449
+ function startRecording() {
2450
+ const SpeechRecognitionClass = getSpeechRecognition();
2451
+ if (!SpeechRecognitionClass) return;
2452
+ const recognition = new SpeechRecognitionClass();
2453
+ recognition.continuous = true;
2454
+ recognition.interimResults = true;
2455
+ recognition.lang = "en-US";
2456
+ let finalTranscript = "";
2457
+ recognition.onresult = (event) => {
2458
+ let interim = "";
2459
+ for (let i = event.resultIndex; i < event.results.length; i++) {
2460
+ const transcript = event.results[i][0].transcript;
2461
+ if (event.results[i].isFinal) {
2462
+ finalTranscript += transcript;
2463
+ } else {
2464
+ interim = transcript;
2465
+ }
2466
+ }
2467
+ const current = comment();
2468
+ const separator = current && !current.endsWith(" ") ? " " : "";
2469
+ setComment(current + separator + finalTranscript + interim);
2470
+ finalTranscript = "";
2471
+ if (textareaRef) {
2472
+ textareaRef.style.height = "auto";
2473
+ textareaRef.style.height = Math.min(textareaRef.scrollHeight, 120) + "px";
2474
+ }
2475
+ };
2476
+ recognition.onerror = () => {
2477
+ setIsRecording(false);
2478
+ };
2479
+ recognition.onend = () => {
2480
+ setIsRecording(false);
2481
+ };
2482
+ recognition.start();
2483
+ recognitionRef = recognition;
2484
+ setIsRecording(true);
2485
+ }
2486
+ function stopRecording() {
2487
+ recognitionRef?.stop();
2488
+ recognitionRef = null;
2489
+ setIsRecording(false);
2490
+ }
2491
+ onMount(() => {
2492
+ textareaRef?.focus();
2493
+ if (props.initialComment && textareaRef) {
2494
+ textareaRef.selectionStart = textareaRef.value.length;
2495
+ }
2496
+ const onEsc = (e) => {
2497
+ if (e.key === "Escape") {
2498
+ e.stopPropagation();
2499
+ stopRecording();
2500
+ props.onCancel();
2501
+ }
2502
+ };
2503
+ document.addEventListener("keydown", onEsc, true);
2504
+ onCleanup(() => {
2505
+ document.removeEventListener("keydown", onEsc, true);
2506
+ stopRecording();
2507
+ });
2508
+ });
2509
+ function handleSubmit() {
2510
+ const text = comment().trim();
2511
+ if (!text) return;
2512
+ stopRecording();
2513
+ props.onAdd(text);
2514
+ }
2515
+ function handleQueue() {
2516
+ const text = comment().trim();
2517
+ if (!text) return;
2518
+ stopRecording();
2519
+ props.onQueue?.(text);
2520
+ }
2521
+ function handleFixThis() {
2522
+ const text = comment().trim() || `Fix this ${displayName()}`;
2523
+ stopRecording();
2524
+ props.onFixThis?.(text);
2525
+ }
2526
+ function handleKeyDown(e) {
2527
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
2528
+ e.preventDefault();
2529
+ handleSubmit();
2530
+ }
2531
+ if (e.key === "Escape") {
2532
+ stopRecording();
2533
+ props.onCancel();
2534
+ }
2535
+ }
2536
+ function handleAutoGrow(e) {
2537
+ const el = e.currentTarget;
2538
+ setComment(el.value);
2539
+ el.style.height = "auto";
2540
+ el.style.height = Math.min(el.scrollHeight, 120) + "px";
2541
+ }
2542
+ return (() => {
2543
+ var _el$ = _tmpl$3(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$5.nextSibling, _el$8 = _el$7.nextSibling, _el$9 = _el$8.nextSibling;
2544
+ insert(_el$, (() => {
2545
+ var _c$ = memo(() => !!compact());
2546
+ return () => _c$() ? (
2547
+ /* Compact mode — friendly name + collapsible details */
2548
+ [(() => {
2549
+ var _el$0 = _tmpl$22(), _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling;
2550
+ addEventListener(_el$0, "click", () => setShowDetails(!showDetails()));
2551
+ insert(_el$1, displayName);
2552
+ createRenderEffect((_p$) => {
2553
+ var _v$5 = `pp-popup__chevron ${showDetails() ? "pp-popup__chevron--open" : ""}`, _v$6 = icons.chevronDown, _v$7 = showDetails();
2554
+ _v$5 !== _p$.e && className(_el$10, _p$.e = _v$5);
2555
+ _v$6 !== _p$.t && (_el$10.innerHTML = _p$.t = _v$6);
2556
+ _v$7 !== _p$.a && setAttribute(_el$10, "aria-expanded", _p$.a = _v$7);
2557
+ return _p$;
2558
+ }, {
2559
+ e: void 0,
2560
+ t: void 0,
2561
+ a: void 0
2562
+ });
2563
+ return _el$0;
2564
+ })(), (() => {
2565
+ var _el$11 = _tmpl$32(), _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild;
2566
+ insert(_el$13, () => props.context.cssSelector);
2567
+ insert(_el$12, createComponent(Show, {
2568
+ get when() {
2569
+ return props.context.framework?.sourceFile;
2570
+ },
2571
+ children: (file) => (() => {
2572
+ var _el$14 = _tmpl$4(), _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
2573
+ addEventListener(_el$14, "click", openFileHandler);
2574
+ insert(_el$14, () => file().split("/").pop(), null);
2575
+ createRenderEffect((_p$) => {
2576
+ var _v$8 = file(), _v$9 = icons.fileCode;
2577
+ _v$8 !== _p$.e && setAttribute(_el$14, "title", _p$.e = _v$8);
2578
+ _v$9 !== _p$.t && (_el$15.innerHTML = _p$.t = _v$9);
2579
+ return _p$;
2580
+ }, {
2581
+ e: void 0,
2582
+ t: void 0
2583
+ });
2584
+ return _el$14;
2585
+ })()
2586
+ }), null);
2587
+ createRenderEffect(() => className(_el$11, `pp-popup__details ${showDetails() ? "pp-popup__details--open" : ""}`));
2588
+ return _el$11;
2589
+ })()]
2590
+ ) : (
2591
+ /* Expanded mode — all info visible */
2592
+ [(() => {
2593
+ var _el$17 = _tmpl$5();
2594
+ insert(_el$17, displayName);
2595
+ return _el$17;
2596
+ })(), (() => {
2597
+ var _el$18 = _tmpl$6();
2598
+ insert(_el$18, () => props.context.cssSelector);
2599
+ return _el$18;
2600
+ })(), createComponent(Show, {
2601
+ get when() {
2602
+ return props.context.framework?.sourceFile;
2603
+ },
2604
+ children: (file) => (() => {
2605
+ var _el$19 = _tmpl$4(), _el$20 = _el$19.firstChild, _el$21 = _el$20.nextSibling;
2606
+ addEventListener(_el$19, "click", openFileHandler);
2607
+ insert(_el$19, () => file().split("/").pop(), null);
2608
+ createRenderEffect((_p$) => {
2609
+ var _v$0 = file(), _v$1 = icons.fileCode;
2610
+ _v$0 !== _p$.e && setAttribute(_el$19, "title", _p$.e = _v$0);
2611
+ _v$1 !== _p$.t && (_el$20.innerHTML = _p$.t = _v$1);
2612
+ return _p$;
2613
+ }, {
2614
+ e: void 0,
2615
+ t: void 0
2616
+ });
2617
+ return _el$19;
2618
+ })()
2619
+ })]
2620
+ );
2621
+ })(), _el$2);
2622
+ addEventListener(_el$3, "keydown", handleKeyDown);
2623
+ addEventListener(_el$3, "input", handleAutoGrow);
2624
+ var _ref$ = textareaRef;
2625
+ typeof _ref$ === "function" ? use(_ref$, _el$3) : textareaRef = _el$3;
2626
+ insert(_el$2, hasSpeechAPI && (() => {
2627
+ var _el$22 = _tmpl$7();
2628
+ addEventListener(_el$22, "click", toggleRecording);
2629
+ createRenderEffect((_p$) => {
2630
+ var _v$10 = `pp-btn--icon pp-popup__mic ${isRecording() ? "pp-popup__mic--recording" : ""}`, _v$11 = isRecording() ? "Stop recording" : "Voice input", _v$12 = isRecording() ? "Stop recording" : "Voice input", _v$13 = isRecording() ? icons.microphoneOff : icons.microphone;
2631
+ _v$10 !== _p$.e && className(_el$22, _p$.e = _v$10);
2632
+ _v$11 !== _p$.t && setAttribute(_el$22, "title", _p$.t = _v$11);
2633
+ _v$12 !== _p$.a && setAttribute(_el$22, "aria-label", _p$.a = _v$12);
2634
+ _v$13 !== _p$.o && (_el$22.innerHTML = _p$.o = _v$13);
2635
+ return _p$;
2636
+ }, {
2637
+ e: void 0,
2638
+ t: void 0,
2639
+ a: void 0,
2640
+ o: void 0
2641
+ });
2642
+ return _el$22;
2643
+ })(), null);
2644
+ addEventListener(_el$5, "click", handleFixThis);
2645
+ addEventListener(_el$8, "click", () => props.onCancel());
2646
+ insert(_el$4, (() => {
2647
+ var _c$2 = memo(() => !!(props.queueMode && props.onQueue));
2648
+ return () => _c$2() && (() => {
2649
+ var _el$23 = _tmpl$8(), _el$24 = _el$23.firstChild;
2650
+ addEventListener(_el$23, "click", handleQueue);
2651
+ createRenderEffect((_p$) => {
2652
+ var _v$14 = !comment().trim(), _v$15 = icons.plus;
2653
+ _v$14 !== _p$.e && (_el$23.disabled = _p$.e = _v$14);
2654
+ _v$15 !== _p$.t && (_el$24.innerHTML = _p$.t = _v$15);
2655
+ return _p$;
2656
+ }, {
2657
+ e: void 0,
2658
+ t: void 0
2659
+ });
2660
+ return _el$23;
2661
+ })();
2662
+ })(), _el$9);
2663
+ addEventListener(_el$9, "click", () => handleSubmit());
2664
+ insert(_el$9, () => props.isEditing ? "Save" : "Add Pin");
2665
+ createRenderEffect((_p$) => {
2666
+ var _v$ = `${popupPosition().x}px`, _v$2 = `${popupPosition().y}px`, _v$3 = icons.bolt, _v$4 = !comment().trim();
2667
+ _v$ !== _p$.e && setStyleProperty(_el$, "left", _p$.e = _v$);
2668
+ _v$2 !== _p$.t && setStyleProperty(_el$, "top", _p$.t = _v$2);
2669
+ _v$3 !== _p$.a && (_el$6.innerHTML = _p$.a = _v$3);
2670
+ _v$4 !== _p$.o && (_el$9.disabled = _p$.o = _v$4);
2671
+ return _p$;
2672
+ }, {
2673
+ e: void 0,
2674
+ t: void 0,
2675
+ a: void 0,
2676
+ o: void 0
2677
+ });
2678
+ createRenderEffect(() => _el$3.value = comment());
2679
+ return _el$;
2680
+ })();
2681
+ };
2483
2682
 
2484
- /* Context menu */
2485
- .pp-context-menu {
2486
- position: fixed;
2487
- z-index: 2147483647;
2488
- pointer-events: auto;
2489
- background: var(--pp-bg-solid);
2490
- border: 1px solid var(--pp-border);
2491
- border-radius: var(--pp-radius-sm);
2492
- box-shadow: var(--pp-shadow);
2493
- padding: 4px;
2494
- min-width: 180px;
2495
- }
2496
-
2497
- .pp-context-menu__item {
2498
- display: flex;
2499
- align-items: center;
2500
- gap: 8px;
2501
- padding: 6px 8px;
2502
- border-radius: 4px;
2503
- cursor: pointer;
2504
- font-size: 12px;
2505
- color: var(--pp-text);
2506
- transition: background 0.1s;
2507
- }
2508
-
2509
- .pp-context-menu__item:hover {
2510
- background: rgba(255, 255, 255, 0.06);
2511
- }
2512
-
2513
- .pp-context-menu__separator {
2514
- height: 1px;
2515
- background: var(--pp-border);
2516
- margin: 4px 0;
2517
- }
2518
-
2519
- /* Prompt mode */
2520
- .pp-prompt {
2521
- position: fixed;
2522
- z-index: 2147483647;
2523
- pointer-events: auto;
2524
- display: flex;
2525
- gap: 6px;
2526
- align-items: center;
2527
- }
2528
-
2529
- .pp-prompt__input {
2530
- padding: 6px 10px;
2531
- border: 1px solid var(--pp-accent);
2532
- border-radius: var(--pp-radius-sm);
2533
- background: var(--pp-bg);
2534
- color: var(--pp-text);
2535
- font-size: 13px;
2536
- font-family: inherit;
2537
- min-width: 240px;
2538
- outline: none;
2539
- backdrop-filter: blur(12px) saturate(180%);
2540
- }
2541
-
2542
- /* Settings panel */
2543
- .pp-settings {
2544
- display: flex;
2545
- flex-direction: column;
2546
- gap: 8px;
2547
- padding-top: 8px;
2548
- border-top: 1px solid var(--pp-border);
2549
- }
2550
-
2551
- .pp-settings__row {
2552
- display: flex;
2553
- align-items: center;
2554
- justify-content: space-between;
2555
- gap: 8px;
2556
- }
2557
-
2558
- .pp-settings__label {
2559
- font-size: 12px;
2560
- color: var(--pp-text);
2561
- }
2562
-
2563
- .pp-settings__value {
2564
- font-size: 11px;
2565
- color: var(--pp-text-muted);
2566
- }
2567
-
2568
- /* Toggle switch */
2569
- .pp-toggle {
2570
- position: relative;
2571
- width: 32px;
2572
- height: 18px;
2573
- border-radius: 9px;
2574
- background: var(--pp-border);
2575
- cursor: pointer;
2576
- transition: background 0.2s;
2577
- }
2683
+ // src/ui/components/PromptMode.tsx
2684
+ var _tmpl$9 = /* @__PURE__ */ template(`<div class=pp-prompt><input class=pp-prompt__input type=text placeholder="Tell the agent what to do..."><button class="pp-btn pp-btn--primary pp-btn--sm"><span>`);
2685
+ var PromptMode = (props) => {
2686
+ const [instruction, setInstruction] = createSignal("");
2687
+ let inputRef;
2688
+ onMount(() => inputRef?.focus());
2689
+ function handleSubmit() {
2690
+ const text = instruction().trim();
2691
+ if (!text) return;
2692
+ props.onSend(text);
2693
+ }
2694
+ const rect = props.element.getBoundingClientRect();
2695
+ const x = Math.max(8, Math.min(rect.left, window.innerWidth - 300));
2696
+ const y = rect.bottom + 8 > window.innerHeight - 40 ? rect.top - 40 : rect.bottom + 8;
2697
+ return (() => {
2698
+ var _el$ = _tmpl$9(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
2699
+ setStyleProperty(_el$, "left", `${x}px`);
2700
+ setStyleProperty(_el$, "top", `${y}px`);
2701
+ _el$2.$$keydown = (e) => {
2702
+ if (e.key === "Enter") handleSubmit();
2703
+ if (e.key === "Escape") props.onCancel();
2704
+ };
2705
+ _el$2.$$input = (e) => setInstruction(e.currentTarget.value);
2706
+ var _ref$ = inputRef;
2707
+ typeof _ref$ === "function" ? use(_ref$, _el$2) : inputRef = _el$2;
2708
+ _el$3.$$click = handleSubmit;
2709
+ createRenderEffect(() => _el$4.innerHTML = icons.send);
2710
+ createRenderEffect(() => _el$2.value = instruction());
2711
+ return _el$;
2712
+ })();
2713
+ };
2714
+ delegateEvents(["input", "keydown", "click"]);
2578
2715
 
2579
- .pp-toggle--active {
2580
- background: var(--pp-accent);
2581
- }
2716
+ // src/ui/components/SelectionLabel.tsx
2717
+ var _tmpl$10 = /* @__PURE__ */ template(`<div class=pp-selection-label>`);
2718
+ var SelectionLabel = (props) => {
2719
+ return createComponent(Show, {
2720
+ get when() {
2721
+ return props.info;
2722
+ },
2723
+ children: (info) => {
2724
+ const {
2725
+ text,
2726
+ rect
2727
+ } = info();
2728
+ const y = rect.top > 30 ? rect.top - 24 : rect.bottom + 4;
2729
+ const x = Math.max(4, Math.min(rect.left, window.innerWidth - 300));
2730
+ return (() => {
2731
+ var _el$ = _tmpl$10();
2732
+ setStyleProperty(_el$, "left", `${x}px`);
2733
+ setStyleProperty(_el$, "top", `${y}px`);
2734
+ insert(_el$, text);
2735
+ return _el$;
2736
+ })();
2737
+ }
2738
+ });
2739
+ };
2582
2740
 
2583
- .pp-toggle__thumb {
2584
- position: absolute;
2585
- top: 2px;
2586
- left: 2px;
2587
- width: 14px;
2588
- height: 14px;
2589
- border-radius: 50%;
2590
- background: #fff;
2591
- transition: transform 0.2s;
2592
- }
2741
+ // src/ui/components/TextInputPopup.tsx
2742
+ var _tmpl$11 = /* @__PURE__ */ template(`<div class=pp-text-input-popup><div class=pp-text-input-popup__indicator></div><input class=pp-text-input-popup__input type=text placeholder="Add text note...">`);
2743
+ var TextInputPopup = (props) => {
2744
+ const [text, setText] = createSignal("");
2745
+ let inputRef;
2746
+ onMount(() => inputRef?.focus());
2747
+ function handleSubmit() {
2748
+ const t = text().trim();
2749
+ if (t) props.onSubmit(t);
2750
+ else props.onCancel();
2751
+ }
2752
+ const x = Math.max(8, Math.min(props.x, window.innerWidth - 260));
2753
+ const y = Math.max(8, Math.min(props.y + 8, window.innerHeight - 50));
2754
+ return (() => {
2755
+ var _el$ = _tmpl$11(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
2756
+ setStyleProperty(_el$, "left", `${x}px`);
2757
+ setStyleProperty(_el$, "top", `${y}px`);
2758
+ _el$3.addEventListener("blur", handleSubmit);
2759
+ _el$3.$$keydown = (e) => {
2760
+ if (e.key === "Enter") handleSubmit();
2761
+ if (e.key === "Escape") props.onCancel();
2762
+ };
2763
+ _el$3.$$input = (e) => setText(e.currentTarget.value);
2764
+ var _ref$ = inputRef;
2765
+ typeof _ref$ === "function" ? use(_ref$, _el$3) : inputRef = _el$3;
2766
+ createRenderEffect((_$p) => setStyleProperty(_el$2, "background", props.color));
2767
+ createRenderEffect(() => _el$3.value = text());
2768
+ return _el$;
2769
+ })();
2770
+ };
2771
+ delegateEvents(["input", "keydown"]);
2593
2772
 
2594
- .pp-toggle--active .pp-toggle__thumb {
2595
- transform: translateX(14px);
2773
+ // src/ui/components/Toolbar.tsx
2774
+ var _tmpl$12 = /* @__PURE__ */ template(`<div>`);
2775
+ var _tmpl$23 = /* @__PURE__ */ template(`<div style=display:flex;align-items:center;justify-content:center;gap:6px><span style=display:flex;align-items:center>`);
2776
+ var _tmpl$33 = /* @__PURE__ */ template(`<span class=pp-toolbar__badge>`);
2777
+ var _tmpl$42 = /* @__PURE__ */ template(`<button class="pp-btn pp-btn--primary"style=width:100%><span style=display:inline-flex></span>Send <!> selected to Claude`);
2778
+ var _tmpl$52 = /* @__PURE__ */ template(`<div class=pp-draw-tools><button title=Freehand></button><button title=Arrow></button><button title=Circle></button><button title=Rectangle></button><button title="Text note"></button><div style=flex:1></div><button class=pp-draw-tool title="Undo (remove last stroke)"></button><button class=pp-draw-tool title="Clear drawing">`);
2779
+ var _tmpl$62 = /* @__PURE__ */ template(`<div class=pp-draw-options><div class=pp-draw-colors></div><div class=pp-draw-widths>`);
2780
+ var _tmpl$72 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-text-muted);text-align:center> stroke`);
2781
+ var _tmpl$82 = /* @__PURE__ */ template(`<div class=pp-settings><div class=pp-settings__row><span class=pp-settings__label>Output detail</span><select style="background:var(--pp-bg-solid);color:var(--pp-text);border:1px solid var(--pp-border);border-radius:var(--pp-radius-sm);padding:2px 6px;font-size:11px"><option value=compact>Compact</option><option value=standard>Standard</option><option value=detailed>Detailed</option></select></div><div class=pp-settings__row><span class=pp-settings__label>Auto-submit</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Clear on send</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Block page clicks</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Compact popup</span><div><div class=pp-toggle__thumb>`);
2782
+ var _tmpl$92 = /* @__PURE__ */ template(`<div style=display:contents><div style=display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:600;letter-spacing:0.02em;color:var(--pp-text-muted)><span></span></div><div class=pp-mode-tabs role=tablist><button role=tab><span></span>Select</button><button role=tab><span></span>Draw</button><button role=tab><span></span>Queue</button></div><div class=pp-actions role=toolbar aria-label="Pinpoint actions"><button class=pp-btn--icon title="Send to agent"aria-label="Send to agent"></button><button class=pp-btn--icon title="Copy to clipboard"aria-label="Copy to clipboard"></button><button class=pp-btn--icon title=Settings aria-label="Toggle settings"></button><button class=pp-btn--icon title=Close aria-label="Close toolbar">`);
2783
+ var _tmpl$0 = /* @__PURE__ */ template(`<span class=pp-toolbar__queue-badge>`);
2784
+ var _tmpl$1 = /* @__PURE__ */ template(`<span class=pp-mode-tab__count>`);
2785
+ var _tmpl$102 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-accent);display:flex;align-items:center;gap:4px><span></span>Click any element to annotate`);
2786
+ var _tmpl$112 = /* @__PURE__ */ template(`<div class=pp-pin-list>`);
2787
+ var _tmpl$122 = /* @__PURE__ */ template(`<div class=pp-pin-item><div></div><span class=pp-pin-item__number></span><div class=pp-pin-item__content><div class=pp-pin-item__comment></div></div><button class="pp-btn--icon pp-btn--icon-sm"style=opacity:1;pointer-events:auto></button><button class="pp-btn--icon pp-btn--icon-sm"title="Remove pin"aria-label="Remove pin">`);
2788
+ var _tmpl$13 = /* @__PURE__ */ template(`<span style=color:var(--pp-text-muted);font-style:italic>No comment`);
2789
+ var _tmpl$14 = /* @__PURE__ */ template(`<button>`);
2790
+ var _tmpl$15 = /* @__PURE__ */ template(`<button><div style=width:16px>`);
2791
+ var _tmpl$16 = /* @__PURE__ */ template(`<div style="font-size:11px;color:var(--pp-text-muted);text-align:center;padding:8px 0">Queue is empty. Add pins or drawings, then queue them here.`);
2792
+ var _tmpl$17 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-text-muted);text-align:center>`);
2793
+ var _tmpl$18 = /* @__PURE__ */ template(`<div style=display:flex;gap:6px><button class=pp-btn style=flex:1>Clear</button><button class="pp-btn pp-btn--primary"style=flex:1><span style=display:inline-flex></span>Send All`);
2794
+ var _tmpl$19 = /* @__PURE__ */ template(`<div class=pp-pin-item><span class=pp-pin-item__number></span><div class=pp-pin-item__content><div class=pp-pin-item__comment>`);
2795
+ var _tmpl$20 = /* @__PURE__ */ template(`<button class=pp-btn--icon title="Clear all"aria-label="Clear all pins">`);
2796
+ var DRAW_COLORS = [{
2797
+ color: "#EF4444",
2798
+ name: "Red"
2799
+ }, {
2800
+ color: "#3B82F6",
2801
+ name: "Blue"
2802
+ }, {
2803
+ color: "#22C55E",
2804
+ name: "Green"
2805
+ }, {
2806
+ color: "#EAB308",
2807
+ name: "Yellow"
2808
+ }];
2809
+ var LINE_WIDTHS = [{
2810
+ width: 2,
2811
+ name: "Thin"
2812
+ }, {
2813
+ width: 4,
2814
+ name: "Medium"
2815
+ }, {
2816
+ width: 8,
2817
+ name: "Thick"
2818
+ }];
2819
+ var EDGE_GAP = 16;
2820
+ var COLLAPSED_TOOLBAR_SIZE = 60;
2821
+ var EXPANDED_TOOLBAR_WIDTH = 320;
2822
+ var AGENT_SIDEBAR_SELECTOR = ".agent-sidebar-panel";
2823
+ function clampRightOffset(right, toolbarWidth) {
2824
+ if (typeof window === "undefined") return right;
2825
+ const maxRight = Math.max(0, window.innerWidth - toolbarWidth - EDGE_GAP);
2826
+ return Math.min(right, maxRight);
2596
2827
  }
2597
-
2598
- /* Kbd hints */
2599
- .pp-kbd {
2600
- display: inline-flex;
2601
- align-items: center;
2602
- justify-content: center;
2603
- padding: 1px 4px;
2604
- border: 1px solid var(--pp-border);
2605
- border-radius: 3px;
2606
- background: rgba(255, 255, 255, 0.04);
2607
- font-size: 10px;
2608
- font-family: inherit;
2609
- color: var(--pp-text-muted);
2610
- line-height: 1;
2828
+ function getVisibleRightSidebarInset() {
2829
+ if (typeof window === "undefined") return 0;
2830
+ let inset = 0;
2831
+ for (const panel of document.querySelectorAll(AGENT_SIDEBAR_SELECTOR)) {
2832
+ const style2 = window.getComputedStyle(panel);
2833
+ if (style2.display === "none" || style2.visibility === "hidden" || panel.getAttribute("aria-hidden") === "true") {
2834
+ continue;
2835
+ }
2836
+ const rect = panel.getBoundingClientRect();
2837
+ const isVisible = rect.width > 0 && rect.height > 0;
2838
+ const isAnchoredToRight = rect.right >= window.innerWidth - 1 && rect.left < window.innerWidth - 1;
2839
+ if (!isVisible || !isAnchoredToRight) continue;
2840
+ inset = Math.max(inset, Math.ceil(window.innerWidth - rect.left));
2841
+ }
2842
+ return inset;
2611
2843
  }
2612
-
2613
- /* Mode tabs */
2614
- .pp-mode-tabs {
2615
- display: flex;
2616
- gap: 2px;
2617
- padding: 2px;
2618
- background: rgba(255, 255, 255, 0.04);
2619
- border-radius: var(--pp-radius-sm);
2620
- }
2621
-
2622
- .pp-mode-tab {
2623
- flex: 1;
2624
- display: flex;
2625
- align-items: center;
2626
- justify-content: center;
2627
- gap: 4px;
2628
- padding: 5px 8px;
2629
- border: none;
2630
- border-radius: 4px;
2631
- background: transparent;
2632
- color: var(--pp-text-muted);
2633
- font-size: 11px;
2634
- font-weight: 500;
2635
- cursor: pointer;
2636
- white-space: nowrap;
2637
- }
2638
-
2639
- .pp-mode-tab:hover {
2640
- color: var(--pp-text);
2641
- background: rgba(255, 255, 255, 0.04);
2642
- }
2643
-
2644
- .pp-mode-tab--active {
2645
- background: rgba(255, 255, 255, 0.08);
2646
- color: var(--pp-text);
2647
- }
2648
-
2649
- .pp-mode-tab__count {
2650
- display: inline-flex;
2651
- align-items: center;
2652
- justify-content: center;
2653
- min-width: 16px;
2654
- height: 16px;
2655
- padding: 0 4px;
2656
- border-radius: 8px;
2657
- background: var(--pp-accent);
2658
- color: #fff;
2659
- font-size: 10px;
2660
- font-weight: 600;
2661
- }
2662
-
2663
- /* Draw tools bar */
2664
- .pp-draw-tools {
2665
- display: flex;
2666
- align-items: center;
2667
- gap: 2px;
2668
- }
2669
-
2670
- .pp-draw-tool {
2671
- display: flex;
2672
- align-items: center;
2673
- justify-content: center;
2674
- width: 32px;
2675
- height: 32px;
2676
- border: none;
2677
- border-radius: var(--pp-radius-sm);
2678
- background: transparent;
2679
- color: var(--pp-text-muted);
2680
- cursor: pointer;
2681
- }
2682
-
2683
- .pp-draw-tool:hover {
2684
- background: rgba(255, 255, 255, 0.06);
2685
- color: var(--pp-text);
2686
- }
2687
-
2688
- .pp-draw-tool--active {
2689
- background: rgba(59, 130, 246, 0.15);
2690
- color: var(--pp-accent);
2691
- }
2692
-
2693
- .pp-draw-tool:disabled {
2694
- opacity: 0.3;
2695
- cursor: default;
2696
- }
2697
-
2698
- /* Draw options row */
2699
- .pp-draw-options {
2700
- display: flex;
2701
- align-items: center;
2702
- justify-content: space-between;
2703
- gap: 8px;
2704
- }
2705
-
2706
- .pp-draw-colors {
2707
- display: flex;
2708
- gap: 4px;
2709
- }
2710
-
2711
- .pp-color-swatch {
2712
- width: 20px;
2713
- height: 20px;
2714
- border-radius: 50%;
2715
- border: 2px solid transparent;
2716
- cursor: pointer;
2717
- padding: 0;
2718
- }
2719
-
2720
- .pp-color-swatch:hover {
2721
- opacity: 0.85;
2722
- }
2723
-
2724
- .pp-color-swatch--active {
2725
- border-color: #fff;
2726
- box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
2727
- }
2728
-
2729
- .pp-draw-widths {
2730
- display: flex;
2731
- gap: 4px;
2732
- }
2733
-
2734
- .pp-width-btn {
2735
- display: flex;
2736
- align-items: center;
2737
- justify-content: center;
2738
- width: 28px;
2739
- height: 28px;
2740
- border: none;
2741
- border-radius: var(--pp-radius-sm);
2742
- background: transparent;
2743
- cursor: pointer;
2744
- padding: 0;
2745
- }
2746
-
2747
- .pp-width-btn:hover {
2748
- background: rgba(255, 255, 255, 0.06);
2749
- }
2750
-
2751
- .pp-width-btn--active {
2752
- background: rgba(255, 255, 255, 0.1);
2753
- outline: 1px solid var(--pp-border);
2754
- }
2755
-
2756
- /* Queue badge in toolbar header */
2757
- .pp-toolbar__queue-badge {
2758
- display: inline-flex;
2759
- align-items: center;
2760
- justify-content: center;
2761
- min-width: 18px;
2762
- height: 18px;
2763
- padding: 0 5px;
2764
- border-radius: 9px;
2765
- background: var(--pp-warning);
2766
- color: #000;
2767
- font-size: 10px;
2768
- font-weight: 700;
2769
- }
2770
-
2771
- /* Popup input row with mic */
2772
- .pp-popup__input-row {
2773
- position: relative;
2774
- display: flex;
2775
- align-items: flex-start;
2776
- gap: 4px;
2777
- }
2778
-
2779
- .pp-popup__input-row .pp-popup__textarea {
2780
- flex: 1;
2781
- }
2782
-
2783
- .pp-popup__mic {
2784
- flex-shrink: 0;
2785
- width: 32px;
2786
- height: 32px;
2787
- display: flex;
2788
- align-items: center;
2789
- justify-content: center;
2790
- border-radius: 50%;
2791
- margin-top: 4px;
2792
- }
2793
-
2794
- .pp-popup__mic--recording {
2795
- color: var(--pp-danger) !important;
2796
- background: rgba(239, 68, 68, 0.15) !important;
2797
- animation: pp-mic-pulse 1.2s ease-in-out infinite;
2798
- }
2799
-
2800
- @keyframes pp-mic-pulse {
2801
- 0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
2802
- 50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
2803
- }
2804
-
2805
- /* Ghost button (Fix this) */
2806
- .pp-btn--ghost {
2807
- display: inline-flex;
2808
- align-items: center;
2809
- gap: 4px;
2810
- padding: 3px 8px;
2811
- border: none;
2812
- border-radius: var(--pp-radius-sm);
2813
- background: transparent;
2814
- color: var(--pp-warning);
2815
- font-size: 11px;
2816
- font-weight: 500;
2817
- cursor: pointer;
2818
- }
2819
-
2820
- .pp-btn--ghost:hover {
2821
- background: rgba(234, 179, 8, 0.1);
2822
- }
2823
-
2824
- /* Text input popup for draw-mode text annotations */
2825
- .pp-text-input-popup {
2826
- position: fixed;
2827
- z-index: 2147483647;
2828
- pointer-events: auto;
2829
- display: flex;
2830
- align-items: center;
2831
- gap: 6px;
2832
- padding: 4px 8px;
2833
- background: var(--pp-bg);
2834
- border: 1px solid var(--pp-border);
2835
- border-radius: var(--pp-radius-sm);
2836
- box-shadow: var(--pp-shadow);
2837
- backdrop-filter: blur(12px) saturate(180%);
2838
- -webkit-backdrop-filter: blur(12px) saturate(180%);
2839
- }
2840
-
2841
- .pp-text-input-popup__indicator {
2842
- width: 8px;
2843
- height: 8px;
2844
- border-radius: 50%;
2845
- flex-shrink: 0;
2846
- }
2847
-
2848
- .pp-text-input-popup__input {
2849
- border: none;
2850
- background: transparent;
2851
- color: var(--pp-text);
2852
- font-size: 13px;
2853
- font-family: inherit;
2854
- outline: none;
2855
- min-width: 200px;
2856
- }
2857
-
2858
- /* Scrollbar */
2859
- ::-webkit-scrollbar {
2860
- width: 4px;
2861
- }
2862
-
2863
- ::-webkit-scrollbar-track {
2864
- background: transparent;
2865
- }
2866
-
2867
- ::-webkit-scrollbar-thumb {
2868
- background: var(--pp-border);
2869
- border-radius: 2px;
2870
- }
2871
- `;
2872
-
2873
- // src/ui/icons/index.ts
2874
- var S = 'width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"';
2875
- var icons = {
2876
- pin: `<svg ${S}><path d="M15 4.5l-4 4l-4 1.5l-1.5 1.5l7 7l1.5 -1.5l1.5 -4l4 -4"/><path d="M9 15l-4.5 4.5"/><path d="M14.5 4l5.5 5.5"/></svg>`,
2877
- mapPin: `<svg ${S}><path d="M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/><path d="M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0"/></svg>`,
2878
- crosshair: `<svg ${S}><path d="M4 8v-2a2 2 0 0 1 2 -2h2"/><path d="M4 16v2a2 2 0 0 0 2 2h2"/><path d="M16 4h2a2 2 0 0 1 2 2v2"/><path d="M16 20h2a2 2 0 0 0 2 -2v-2"/><path d="M9 12l6 0"/><path d="M12 9l0 6"/></svg>`,
2879
- send: `<svg ${S}><path d="M10 14l11 -11"/><path d="M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5"/></svg>`,
2880
- copy: `<svg ${S}><path d="M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z"/><path d="M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1"/></svg>`,
2881
- trash: `<svg ${S}><path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/></svg>`,
2882
- settings: `<svg ${S}><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065"/><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"/></svg>`,
2883
- x: `<svg ${S}><path d="M18 6l-12 12"/><path d="M6 6l12 12"/></svg>`,
2884
- chevronDown: `<svg ${S}><path d="M6 9l6 6l6 -6"/></svg>`,
2885
- check: `<svg ${S}><path d="M5 12l5 5l10 -10"/></svg>`,
2886
- messageSquare: `<svg ${S}><path d="M8 9h8"/><path d="M8 13h6"/><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"/></svg>`,
2887
- eye: `<svg ${S}><path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"/><path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"/></svg>`,
2888
- fileCode: `<svg ${S}><path d="M14 3v4a1 1 0 0 0 1 1h4"/><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2"/><path d="M10 13l-1 2l1 2"/><path d="M14 13l1 2l-1 2"/></svg>`,
2889
- history: `<svg ${S}><path d="M12 8l0 4l2 2"/><path d="M3.05 11a9 9 0 1 1 .5 4m-.5 5v-5h5"/></svg>`,
2890
- minus: `<svg ${S}><path d="M5 12l14 0"/></svg>`,
2891
- // Draw mode icons
2892
- pencil: `<svg ${S}><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4"/><path d="M13.5 6.5l4 4"/></svg>`,
2893
- arrowUpRight: `<svg ${S}><path d="M17 7l-10 10"/><path d="M8 7l9 0l0 9"/></svg>`,
2894
- circle: `<svg ${S}><circle cx="12" cy="12" r="9"/></svg>`,
2895
- square: `<svg ${S}><rect x="4" y="4" width="16" height="16" rx="2"/></svg>`,
2896
- typography: `<svg ${S}><path d="M4 20l3 0"/><path d="M14 20l7 0"/><path d="M6.9 15l6.9 0"/><path d="M10.2 6.3l5.8 13.7"/><path d="M5 20l6 -16l2 0l7 16"/></svg>`,
2897
- undo: `<svg ${S}><path d="M9 14l-4 -4l4 -4"/><path d="M5 10h11a4 4 0 1 1 0 8h-1"/></svg>`,
2898
- palette: `<svg ${S}><path d="M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25"/><circle cx="8.5" cy="10.5" r="1"/><circle cx="12.5" cy="7.5" r="1"/><circle cx="16.5" cy="10.5" r="1"/></svg>`,
2899
- lineWeight: `<svg ${S}><path d="M4 6h16"/><path d="M4 12h16" stroke-width="3"/><path d="M4 18h16" stroke-width="5"/></svg>`,
2900
- // Voice icon
2901
- microphone: `<svg ${S}><path d="M9 2m0 3a3 3 0 0 1 3 -3h0a3 3 0 0 1 3 3v5a3 3 0 0 1 -3 3h0a3 3 0 0 1 -3 -3z"/><path d="M5 10a7 7 0 0 0 14 0"/><path d="M8 21l8 0"/><path d="M12 17l0 4"/></svg>`,
2902
- microphoneOff: `<svg ${S}><path d="M3 3l18 18"/><path d="M9 5a3 3 0 0 1 6 0v5a3 3 0 0 1 -.13 .874m-2 2a3 3 0 0 1 -3.87 -2.872v-1"/><path d="M5 10a7 7 0 0 0 10.846 5.85m2 -2a6.967 6.967 0 0 0 1.152 -3.85"/><path d="M8 21l8 0"/><path d="M12 17l0 4"/></svg>`,
2903
- // Queue & batch icons
2904
- plus: `<svg ${S}><path d="M12 5l0 14"/><path d="M5 12l14 0"/></svg>`,
2905
- stack: `<svg ${S}><path d="M12 2l-8 4l8 4l8 -4l-8 -4"/><path d="M4 10l8 4l8 -4"/><path d="M4 14l8 4l8 -4"/></svg>`,
2906
- checkSquare: `<svg ${S}><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 12l2 2l4 -4"/></svg>`,
2907
- squareEmpty: `<svg ${S}><rect x="3" y="3" width="18" height="18" rx="2"/></svg>`,
2908
- bolt: `<svg ${S}><path d="M13 3l0 7l6 0l-8 11l0 -7l-6 0l8 -11"/></svg>`,
2909
- checkCircle: `<svg ${S}><circle cx="12" cy="12" r="9"/><path d="M9 12l2 2l4 -4"/></svg>`
2910
- };
2911
-
2912
- // src/ui/components/Toolbar.tsx
2913
- var _tmpl$ = /* @__PURE__ */ template(`<div>`);
2914
- var _tmpl$2 = /* @__PURE__ */ template(`<div style=display:flex;align-items:center;justify-content:center;gap:6px><span style=display:flex;align-items:center>`);
2915
- var _tmpl$3 = /* @__PURE__ */ template(`<span class=pp-toolbar__badge>`);
2916
- var _tmpl$4 = /* @__PURE__ */ template(`<button class="pp-btn pp-btn--primary"style=width:100%><span style=display:inline-flex></span>Send <!> selected to Claude`);
2917
- var _tmpl$5 = /* @__PURE__ */ template(`<div class=pp-draw-tools><button title=Freehand></button><button title=Arrow></button><button title=Circle></button><button title=Rectangle></button><button title="Text note"></button><div style=flex:1></div><button class=pp-draw-tool title="Undo (remove last stroke)"></button><button class=pp-draw-tool title="Clear drawing">`);
2918
- var _tmpl$6 = /* @__PURE__ */ template(`<div class=pp-draw-options><div class=pp-draw-colors></div><div class=pp-draw-widths>`);
2919
- var _tmpl$7 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-text-muted);text-align:center> stroke`);
2920
- var _tmpl$8 = /* @__PURE__ */ template(`<div class=pp-settings><div class=pp-settings__row><span class=pp-settings__label>Output detail</span><select style="background:var(--pp-bg-solid);color:var(--pp-text);border:1px solid var(--pp-border);border-radius:var(--pp-radius-sm);padding:2px 6px;font-size:11px"><option value=compact>Compact</option><option value=standard>Standard</option><option value=detailed>Detailed</option></select></div><div class=pp-settings__row><span class=pp-settings__label>Auto-submit</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Clear on send</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Block page clicks</span><div><div class=pp-toggle__thumb></div></div></div><div class=pp-settings__row><span class=pp-settings__label>Compact popup</span><div><div class=pp-toggle__thumb>`);
2921
- var _tmpl$9 = /* @__PURE__ */ template(`<div style=display:contents><div style=display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:600;letter-spacing:0.02em;color:var(--pp-text-muted)><span></span></div><div class=pp-mode-tabs role=tablist><button role=tab><span></span>Select</button><button role=tab><span></span>Draw</button><button role=tab><span></span>Queue</button></div><div class=pp-actions role=toolbar aria-label="Pinpoint actions"><button class=pp-btn--icon title="Send to agent"aria-label="Send to agent"></button><button class=pp-btn--icon title="Copy to clipboard"aria-label="Copy to clipboard"></button><button class=pp-btn--icon title=Settings aria-label="Toggle settings"></button><button class=pp-btn--icon title=Close aria-label="Close toolbar">`);
2922
- var _tmpl$0 = /* @__PURE__ */ template(`<span class=pp-toolbar__queue-badge>`);
2923
- var _tmpl$1 = /* @__PURE__ */ template(`<span class=pp-mode-tab__count>`);
2924
- var _tmpl$10 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-accent);display:flex;align-items:center;gap:4px><span></span>Click any element to annotate`);
2925
- var _tmpl$11 = /* @__PURE__ */ template(`<div class=pp-pin-list>`);
2926
- var _tmpl$12 = /* @__PURE__ */ template(`<div class=pp-pin-item><div></div><span class=pp-pin-item__number></span><div class=pp-pin-item__content><div class=pp-pin-item__comment></div></div><button class="pp-btn--icon pp-btn--icon-sm"style=opacity:1;pointer-events:auto></button><button class="pp-btn--icon pp-btn--icon-sm"title="Remove pin"aria-label="Remove pin">`);
2927
- var _tmpl$13 = /* @__PURE__ */ template(`<span style=color:var(--pp-text-muted);font-style:italic>No comment`);
2928
- var _tmpl$14 = /* @__PURE__ */ template(`<button>`);
2929
- var _tmpl$15 = /* @__PURE__ */ template(`<button><div style=width:16px>`);
2930
- var _tmpl$16 = /* @__PURE__ */ template(`<div style="font-size:11px;color:var(--pp-text-muted);text-align:center;padding:8px 0">Queue is empty. Add pins or drawings, then queue them here.`);
2931
- var _tmpl$17 = /* @__PURE__ */ template(`<div style=font-size:11px;color:var(--pp-text-muted);text-align:center>`);
2932
- var _tmpl$18 = /* @__PURE__ */ template(`<div style=display:flex;gap:6px><button class=pp-btn style=flex:1>Clear</button><button class="pp-btn pp-btn--primary"style=flex:1><span style=display:inline-flex></span>Send All`);
2933
- var _tmpl$19 = /* @__PURE__ */ template(`<div class=pp-pin-item><span class=pp-pin-item__number></span><div class=pp-pin-item__content><div class=pp-pin-item__comment>`);
2934
- var _tmpl$20 = /* @__PURE__ */ template(`<button class=pp-btn--icon title="Clear all"aria-label="Clear all pins">`);
2935
- var DRAW_COLORS = [{
2936
- color: "#EF4444",
2937
- name: "Red"
2938
- }, {
2939
- color: "#3B82F6",
2940
- name: "Blue"
2941
- }, {
2942
- color: "#22C55E",
2943
- name: "Green"
2944
- }, {
2945
- color: "#EAB308",
2946
- name: "Yellow"
2947
- }];
2948
- var LINE_WIDTHS = [{
2949
- width: 2,
2950
- name: "Thin"
2951
- }, {
2952
- width: 4,
2953
- name: "Medium"
2954
- }, {
2955
- width: 8,
2956
- name: "Thick"
2957
- }];
2958
- var EDGE_GAP = 16;
2959
- var COLLAPSED_TOOLBAR_SIZE = 60;
2960
- var EXPANDED_TOOLBAR_WIDTH = 320;
2961
- var AGENT_SIDEBAR_SELECTOR = ".agent-sidebar-panel";
2962
- function clampRightOffset(right, toolbarWidth) {
2963
- if (typeof window === "undefined") return right;
2964
- const maxRight = Math.max(0, window.innerWidth - toolbarWidth - EDGE_GAP);
2965
- return Math.min(right, maxRight);
2966
- }
2967
- function getVisibleRightSidebarInset() {
2968
- if (typeof window === "undefined") return 0;
2969
- let inset = 0;
2970
- for (const panel of document.querySelectorAll(AGENT_SIDEBAR_SELECTOR)) {
2971
- const style2 = window.getComputedStyle(panel);
2972
- if (style2.display === "none" || style2.visibility === "hidden" || panel.getAttribute("aria-hidden") === "true") {
2973
- continue;
2974
- }
2975
- const rect = panel.getBoundingClientRect();
2976
- const isVisible = rect.width > 0 && rect.height > 0;
2977
- const isAnchoredToRight = rect.right >= window.innerWidth - 1 && rect.left < window.innerWidth - 1;
2978
- if (!isVisible || !isAnchoredToRight) continue;
2979
- inset = Math.max(inset, Math.ceil(window.innerWidth - rect.left));
2980
- }
2981
- return inset;
2982
- }
2983
- var Toolbar = (props) => {
2984
- const [pos, setPos] = createSignal(props.position ? {
2985
- right: window.innerWidth - props.position.x,
2986
- bottom: window.innerHeight - props.position.y
2987
- } : {
2988
- right: EDGE_GAP,
2989
- bottom: EDGE_GAP
2990
- });
2991
- const [reservedRight, setReservedRight] = createSignal(0);
2992
- const [dragStart, setDragStart] = createSignal({
2993
- x: 0,
2994
- y: 0,
2995
- right: 0,
2996
- bottom: 0
2997
- });
2998
- const [didDrag, setDidDrag] = createSignal(false);
2999
- onMount(() => {
3000
- if (typeof window === "undefined") return;
3001
- let resizeObserver;
3002
- const updateReservedRight = () => {
3003
- setReservedRight(getVisibleRightSidebarInset());
3004
- resizeObserver?.disconnect();
3005
- if (typeof ResizeObserver === "undefined") return;
3006
- resizeObserver = new ResizeObserver(() => {
3007
- setReservedRight(getVisibleRightSidebarInset());
3008
- });
3009
- for (const panel of document.querySelectorAll(AGENT_SIDEBAR_SELECTOR)) {
3010
- resizeObserver.observe(panel);
3011
- }
3012
- };
3013
- updateReservedRight();
3014
- const mutationObserver = new MutationObserver(updateReservedRight);
3015
- mutationObserver.observe(document.body, {
3016
- attributes: true,
3017
- attributeFilter: ["class", "style", "aria-hidden"],
3018
- childList: true,
3019
- subtree: true
3020
- });
3021
- window.addEventListener("resize", updateReservedRight);
3022
- onCleanup(() => {
3023
- mutationObserver.disconnect();
3024
- resizeObserver?.disconnect();
3025
- window.removeEventListener("resize", updateReservedRight);
3026
- });
3027
- });
3028
- const toolbarRight = () => {
3029
- const toolbarWidth = props.expanded ? EXPANDED_TOOLBAR_WIDTH : COLLAPSED_TOOLBAR_SIZE;
3030
- return clampRightOffset((props.expanded ? EDGE_GAP : pos().right) + reservedRight(), toolbarWidth);
3031
- };
3032
- function handleMouseDown(e) {
3033
- if (props.expanded) return;
3034
- setDidDrag(false);
3035
- setDragStart({
3036
- x: e.clientX,
3037
- y: e.clientY,
3038
- right: pos().right,
3039
- bottom: pos().bottom
3040
- });
3041
- const handleMove = (e2) => {
3042
- setDidDrag(true);
3043
- const start = dragStart();
3044
- const dx = e2.clientX - start.x;
3045
- const dy = e2.clientY - start.y;
3046
- const maxRight = Math.max(0, window.innerWidth - reservedRight() - COLLAPSED_TOOLBAR_SIZE);
3047
- setPos({
3048
- right: Math.max(0, Math.min(maxRight, start.right - dx)),
3049
- bottom: Math.max(0, Math.min(window.innerHeight - COLLAPSED_TOOLBAR_SIZE, start.bottom - dy))
3050
- });
3051
- };
3052
- const handleUp = () => {
3053
- window.removeEventListener("mousemove", handleMove);
3054
- window.removeEventListener("mouseup", handleUp);
3055
- };
3056
- window.addEventListener("mousemove", handleMove);
3057
- window.addEventListener("mouseup", handleUp);
3058
- }
3059
- function handleClick() {
3060
- if (props.expanded) return;
3061
- if (didDrag()) return;
3062
- props.onToggleExpand();
3063
- }
3064
- const queueSummary = () => {
3065
- const q = props.queue;
3066
- let draws = 0;
3067
- let clicks = 0;
3068
- for (const item of q) {
3069
- if (item.drawings?.length || item.textNotes?.length) draws++;
3070
- if (item.pin) clicks++;
3071
- }
3072
- const parts = [];
3073
- if (draws > 0) parts.push(`Draw x${draws}`);
3074
- if (clicks > 0) parts.push(`Click x${clicks}`);
3075
- return parts.join(" / ") || "Empty";
3076
- };
3077
- const totalBadgeCount = () => props.pins.length + props.queue.length + props.drawStrokeCount;
3078
- return (() => {
3079
- var _el$ = _tmpl$();
3080
- addEventListener(_el$, "click", handleClick);
3081
- addEventListener(_el$, "mousedown", props.expanded ? void 0 : handleMouseDown, true);
3082
- insert(_el$, (() => {
3083
- var _c$ = memo(() => !!!props.expanded);
3084
- return () => _c$() ? (
3085
- /* Collapsed pill */
3086
- (() => {
3087
- var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild;
3088
- insert(_el$2, (() => {
3089
- var _c$2 = memo(() => totalBadgeCount() > 0);
3090
- return () => _c$2() && (() => {
3091
- var _el$4 = _tmpl$3();
3092
- insert(_el$4, totalBadgeCount);
3093
- return _el$4;
3094
- })();
3095
- })(), _el$3);
3096
- createRenderEffect(() => _el$3.innerHTML = icons.pin);
3097
- return _el$2;
3098
- })()
3099
- ) : (
3100
- /* Expanded toolbar */
3101
- (() => {
3102
- var _el$5 = _tmpl$9(), _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild, _el$8 = _el$6.nextSibling, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$9.nextSibling, _el$10 = _el$1.firstChild, _el$11 = _el$1.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling, _el$49 = _el$8.nextSibling, _el$50 = _el$49.firstChild, _el$51 = _el$50.nextSibling, _el$52 = _el$51.nextSibling, _el$53 = _el$52.nextSibling;
3103
- addEventListener(_el$5, "click", (e) => e.stopPropagation());
3104
- insert(_el$7, () => props.author || "Pinpoint");
3105
- insert(_el$6, (() => {
3106
- var _c$3 = memo(() => props.queue.length > 0);
3107
- return () => _c$3() && (() => {
3108
- var _el$54 = _tmpl$0();
3109
- insert(_el$54, () => props.queue.length);
3110
- return _el$54;
3111
- })();
3112
- })(), null);
3113
- addEventListener(_el$9, "click", () => props.onModeChange("select"));
3114
- addEventListener(_el$1, "click", () => props.onModeChange("draw"));
3115
- addEventListener(_el$11, "click", () => props.onModeChange("queue"));
3116
- insert(_el$11, (() => {
3117
- var _c$4 = memo(() => props.queue.length > 0);
3118
- return () => _c$4() && (() => {
3119
- var _el$55 = _tmpl$1();
3120
- insert(_el$55, () => props.queue.length);
3121
- return _el$55;
3122
- })();
3123
- })(), null);
3124
- insert(_el$5, createComponent(Show, {
3125
- get when() {
3126
- return props.mode === "select";
3127
- },
3128
- get children() {
3129
- return [memo(() => memo(() => props.pins.length === 0)() && (() => {
3130
- var _el$56 = _tmpl$10(), _el$57 = _el$56.firstChild;
3131
- createRenderEffect(() => _el$57.innerHTML = icons.crosshair);
3132
- return _el$56;
3133
- })()), memo(() => memo(() => props.pins.length > 0)() && (() => {
3134
- var _el$58 = _tmpl$11();
3135
- insert(_el$58, createComponent(For, {
3136
- get each() {
3137
- return props.pins;
3138
- },
3139
- children: (pin, index) => (() => {
3140
- var _el$59 = _tmpl$12(), _el$60 = _el$59.firstChild, _el$61 = _el$60.nextSibling, _el$62 = _el$61.nextSibling, _el$63 = _el$62.firstChild, _el$64 = _el$62.nextSibling, _el$65 = _el$64.nextSibling;
3141
- addEventListener(_el$59, "click", () => props.onEditPin(pin));
3142
- insert(_el$61, () => index() + 1);
3143
- insert(_el$63, () => pin.comment || _tmpl$13());
3144
- addEventListener(_el$64, "click", (e) => {
3145
- e.stopPropagation();
3146
- props.onTogglePinSelect(pin);
3147
- });
3148
- addEventListener(_el$65, "click", (e) => {
3149
- e.stopPropagation();
3150
- props.onRemovePin(pin.id);
3151
- });
3152
- createRenderEffect((_p$) => {
3153
- var _v$32 = `pp-pin-item__status pp-pin-item__status--${pin.status.state}`, _v$33 = props.selectedPinIds.has(pin.id) ? "Deselect" : "Select for send", _v$34 = props.selectedPinIds.has(pin.id) ? "Deselect" : "Select for send", _v$35 = props.selectedPinIds.has(pin.id) ? icons.checkSquare : icons.squareEmpty, _v$36 = props.selectedPinIds.has(pin.id) ? "var(--pp-accent)" : "var(--pp-text-muted)", _v$37 = icons.minus;
3154
- _v$32 !== _p$.e && className(_el$60, _p$.e = _v$32);
3155
- _v$33 !== _p$.t && setAttribute(_el$64, "title", _p$.t = _v$33);
3156
- _v$34 !== _p$.a && setAttribute(_el$64, "aria-label", _p$.a = _v$34);
3157
- _v$35 !== _p$.o && (_el$64.innerHTML = _p$.o = _v$35);
3158
- _v$36 !== _p$.i && setStyleProperty(_el$64, "color", _p$.i = _v$36);
3159
- _v$37 !== _p$.n && (_el$65.innerHTML = _p$.n = _v$37);
3160
- return _p$;
3161
- }, {
3162
- e: void 0,
3163
- t: void 0,
3164
- a: void 0,
3165
- o: void 0,
3166
- i: void 0,
3167
- n: void 0
3168
- });
3169
- return _el$59;
3170
- })()
3171
- }));
3172
- return _el$58;
3173
- })()), createComponent(Show, {
3174
- get when() {
3175
- return props.selectedPinIds.size > 0;
3176
- },
3177
- get children() {
3178
- var _el$14 = _tmpl$4(), _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling, _el$18 = _el$16.nextSibling, _el$17 = _el$18.nextSibling;
3179
- addEventListener(_el$14, "click", () => props.onSendSelected());
3180
- insert(_el$14, () => props.selectedPinIds.size, _el$18);
3181
- createRenderEffect(() => _el$15.innerHTML = icons.send);
3182
- return _el$14;
3183
- }
3184
- })];
3185
- }
3186
- }), _el$49);
3187
- insert(_el$5, createComponent(Show, {
3188
- get when() {
3189
- return props.mode === "draw";
3190
- },
3191
- get children() {
3192
- return [(() => {
3193
- var _el$19 = _tmpl$5(), _el$20 = _el$19.firstChild, _el$21 = _el$20.nextSibling, _el$22 = _el$21.nextSibling, _el$23 = _el$22.nextSibling, _el$24 = _el$23.nextSibling, _el$25 = _el$24.nextSibling, _el$26 = _el$25.nextSibling, _el$27 = _el$26.nextSibling;
3194
- addEventListener(_el$20, "click", () => props.onDrawToolChange("freehand"));
3195
- addEventListener(_el$21, "click", () => props.onDrawToolChange("arrow"));
3196
- addEventListener(_el$22, "click", () => props.onDrawToolChange("circle"));
3197
- addEventListener(_el$23, "click", () => props.onDrawToolChange("rect"));
3198
- addEventListener(_el$24, "click", () => props.onDrawToolChange("text"));
3199
- addEventListener(_el$26, "click", () => props.onDrawUndo());
3200
- addEventListener(_el$27, "click", () => props.onDrawClear());
3201
- createRenderEffect((_p$) => {
3202
- var _v$3 = `pp-draw-tool ${props.drawTool === "freehand" ? "pp-draw-tool--active" : ""}`, _v$4 = icons.pencil, _v$5 = `pp-draw-tool ${props.drawTool === "arrow" ? "pp-draw-tool--active" : ""}`, _v$6 = icons.arrowUpRight, _v$7 = `pp-draw-tool ${props.drawTool === "circle" ? "pp-draw-tool--active" : ""}`, _v$8 = icons.circle, _v$9 = `pp-draw-tool ${props.drawTool === "rect" ? "pp-draw-tool--active" : ""}`, _v$0 = icons.square, _v$1 = `pp-draw-tool ${props.drawTool === "text" ? "pp-draw-tool--active" : ""}`, _v$10 = icons.typography, _v$11 = icons.undo, _v$12 = props.drawStrokeCount === 0, _v$13 = icons.trash, _v$14 = props.drawStrokeCount === 0;
3203
- _v$3 !== _p$.e && className(_el$20, _p$.e = _v$3);
3204
- _v$4 !== _p$.t && (_el$20.innerHTML = _p$.t = _v$4);
3205
- _v$5 !== _p$.a && className(_el$21, _p$.a = _v$5);
3206
- _v$6 !== _p$.o && (_el$21.innerHTML = _p$.o = _v$6);
3207
- _v$7 !== _p$.i && className(_el$22, _p$.i = _v$7);
3208
- _v$8 !== _p$.n && (_el$22.innerHTML = _p$.n = _v$8);
3209
- _v$9 !== _p$.s && className(_el$23, _p$.s = _v$9);
3210
- _v$0 !== _p$.h && (_el$23.innerHTML = _p$.h = _v$0);
3211
- _v$1 !== _p$.r && className(_el$24, _p$.r = _v$1);
3212
- _v$10 !== _p$.d && (_el$24.innerHTML = _p$.d = _v$10);
3213
- _v$11 !== _p$.l && (_el$26.innerHTML = _p$.l = _v$11);
3214
- _v$12 !== _p$.u && (_el$26.disabled = _p$.u = _v$12);
3215
- _v$13 !== _p$.c && (_el$27.innerHTML = _p$.c = _v$13);
3216
- _v$14 !== _p$.w && (_el$27.disabled = _p$.w = _v$14);
3217
- return _p$;
3218
- }, {
3219
- e: void 0,
3220
- t: void 0,
3221
- a: void 0,
3222
- o: void 0,
3223
- i: void 0,
3224
- n: void 0,
3225
- s: void 0,
3226
- h: void 0,
3227
- r: void 0,
3228
- d: void 0,
3229
- l: void 0,
3230
- u: void 0,
3231
- c: void 0,
3232
- w: void 0
3233
- });
3234
- return _el$19;
3235
- })(), (() => {
3236
- var _el$28 = _tmpl$6(), _el$29 = _el$28.firstChild, _el$30 = _el$29.nextSibling;
3237
- insert(_el$29, createComponent(For, {
3238
- each: DRAW_COLORS,
3239
- children: (c) => (() => {
3240
- var _el$67 = _tmpl$14();
3241
- addEventListener(_el$67, "click", () => props.onDrawColorChange(c.color));
3242
- createRenderEffect((_p$) => {
3243
- var _v$38 = `pp-color-swatch ${props.drawColor === c.color ? "pp-color-swatch--active" : ""}`, _v$39 = c.color, _v$40 = c.name;
3244
- _v$38 !== _p$.e && className(_el$67, _p$.e = _v$38);
3245
- _v$39 !== _p$.t && setStyleProperty(_el$67, "background", _p$.t = _v$39);
3246
- _v$40 !== _p$.a && setAttribute(_el$67, "title", _p$.a = _v$40);
3247
- return _p$;
3248
- }, {
3249
- e: void 0,
3250
- t: void 0,
3251
- a: void 0
3252
- });
3253
- return _el$67;
3254
- })()
3255
- }));
3256
- insert(_el$30, createComponent(For, {
3257
- each: LINE_WIDTHS,
3258
- children: (w) => (() => {
3259
- var _el$68 = _tmpl$15(), _el$69 = _el$68.firstChild;
3260
- addEventListener(_el$68, "click", () => props.onDrawLineWidthChange(w.width));
3261
- createRenderEffect((_p$) => {
3262
- var _v$41 = `pp-width-btn ${props.drawLineWidth === w.width ? "pp-width-btn--active" : ""}`, _v$42 = w.name, _v$43 = `${w.width}px`, _v$44 = props.drawColor, _v$45 = `${w.width / 2}px`;
3263
- _v$41 !== _p$.e && className(_el$68, _p$.e = _v$41);
3264
- _v$42 !== _p$.t && setAttribute(_el$68, "title", _p$.t = _v$42);
3265
- _v$43 !== _p$.a && setStyleProperty(_el$69, "height", _p$.a = _v$43);
3266
- _v$44 !== _p$.o && setStyleProperty(_el$69, "background", _p$.o = _v$44);
3267
- _v$45 !== _p$.i && setStyleProperty(_el$69, "border-radius", _p$.i = _v$45);
3268
- return _p$;
3269
- }, {
3270
- e: void 0,
3271
- t: void 0,
3272
- a: void 0,
3273
- o: void 0,
3274
- i: void 0
3275
- });
3276
- return _el$68;
3277
- })()
3278
- }));
3279
- return _el$28;
3280
- })(), createComponent(Show, {
3281
- get when() {
3282
- return props.drawStrokeCount > 0;
3283
- },
3284
- get children() {
3285
- var _el$31 = _tmpl$7(), _el$32 = _el$31.firstChild;
3286
- insert(_el$31, () => props.drawStrokeCount, _el$32);
3287
- insert(_el$31, () => props.drawStrokeCount !== 1 ? "s" : "", null);
3288
- return _el$31;
3289
- }
3290
- })];
3291
- }
3292
- }), _el$49);
3293
- insert(_el$5, createComponent(Show, {
3294
- get when() {
3295
- return props.mode === "queue";
3296
- },
3297
- get children() {
3298
- return memo(() => props.queue.length === 0)() ? _tmpl$16() : [(() => {
3299
- var _el$71 = _tmpl$17();
3300
- insert(_el$71, queueSummary);
3301
- return _el$71;
3302
- })(), (() => {
3303
- var _el$72 = _tmpl$11();
3304
- insert(_el$72, createComponent(For, {
3305
- get each() {
3306
- return props.queue;
3307
- },
3308
- children: (item, index) => (() => {
3309
- var _el$77 = _tmpl$19(), _el$78 = _el$77.firstChild, _el$79 = _el$78.nextSibling, _el$80 = _el$79.firstChild;
3310
- insert(_el$78, () => index() + 1);
3311
- insert(_el$80, (() => {
3312
- var _c$6 = memo(() => !!item.pin);
3313
- return () => _c$6() ? item.pin.comment || "Pin annotation" : `Drawing (${(item.drawings?.length || 0) + (item.textNotes?.length || 0)} items)`;
3314
- })());
3315
- return _el$77;
3316
- })()
3317
- }));
3318
- return _el$72;
3319
- })(), (() => {
3320
- var _el$73 = _tmpl$18(), _el$74 = _el$73.firstChild, _el$75 = _el$74.nextSibling, _el$76 = _el$75.firstChild;
3321
- addEventListener(_el$74, "click", () => props.onQueueClear());
3322
- addEventListener(_el$75, "click", () => props.onQueueSend());
3323
- createRenderEffect(() => _el$76.innerHTML = icons.send);
3324
- return _el$73;
3325
- })()];
3326
- }
3327
- }), _el$49);
3328
- insert(_el$5, createComponent(Show, {
3329
- get when() {
3330
- return props.showSettings;
3331
- },
3332
- get children() {
3333
- var _el$33 = _tmpl$8(), _el$34 = _el$33.firstChild, _el$35 = _el$34.firstChild, _el$36 = _el$35.nextSibling, _el$37 = _el$34.nextSibling, _el$38 = _el$37.firstChild, _el$39 = _el$38.nextSibling, _el$40 = _el$37.nextSibling, _el$41 = _el$40.firstChild, _el$42 = _el$41.nextSibling, _el$43 = _el$40.nextSibling, _el$44 = _el$43.firstChild, _el$45 = _el$44.nextSibling, _el$46 = _el$43.nextSibling, _el$47 = _el$46.firstChild, _el$48 = _el$47.nextSibling;
3334
- _el$36.addEventListener("change", (e) => props.onOutputFormatChange(e.currentTarget.value));
3335
- addEventListener(_el$39, "click", () => props.onAutoSubmitChange(!props.autoSubmit));
3336
- addEventListener(_el$42, "click", () => props.onClearOnSendChange(!props.clearOnSend));
3337
- addEventListener(_el$45, "click", () => props.onBlockInteractionsChange(!props.blockInteractions));
3338
- addEventListener(_el$48, "click", () => props.onCompactPopupChange(!props.compactPopup));
3339
- createRenderEffect((_p$) => {
3340
- var _v$15 = `pp-toggle ${props.autoSubmit ? "pp-toggle--active" : ""}`, _v$16 = `pp-toggle ${props.clearOnSend ? "pp-toggle--active" : ""}`, _v$17 = `pp-toggle ${props.blockInteractions ? "pp-toggle--active" : ""}`, _v$18 = `pp-toggle ${props.compactPopup ? "pp-toggle--active" : ""}`;
3341
- _v$15 !== _p$.e && className(_el$39, _p$.e = _v$15);
3342
- _v$16 !== _p$.t && className(_el$42, _p$.t = _v$16);
3343
- _v$17 !== _p$.a && className(_el$45, _p$.a = _v$17);
3344
- _v$18 !== _p$.o && className(_el$48, _p$.o = _v$18);
3345
- return _p$;
3346
- }, {
3347
- e: void 0,
3348
- t: void 0,
3349
- a: void 0,
3350
- o: void 0
3351
- });
3352
- createRenderEffect(() => _el$36.value = props.outputFormat);
3353
- return _el$33;
3354
- }
3355
- }), _el$49);
3356
- addEventListener(_el$50, "click", () => props.onSend());
3357
- addEventListener(_el$51, "click", () => props.onCopy());
3358
- insert(_el$49, (() => {
3359
- var _c$5 = memo(() => props.pins.length > 0);
3360
- return () => _c$5() && (() => {
3361
- var _el$81 = _tmpl$20();
3362
- addEventListener(_el$81, "click", () => props.onClear());
3363
- createRenderEffect(() => _el$81.innerHTML = icons.trash);
3364
- return _el$81;
3365
- })();
3366
- })(), _el$52);
3367
- addEventListener(_el$52, "click", () => props.onToggleSettings());
3368
- addEventListener(_el$53, "click", () => props.onToggleExpand());
3369
- createRenderEffect((_p$) => {
3370
- var _v$19 = `pp-mode-tab ${props.mode === "select" ? "pp-mode-tab--active" : ""}`, _v$20 = props.mode === "select", _v$21 = icons.crosshair, _v$22 = `pp-mode-tab ${props.mode === "draw" ? "pp-mode-tab--active" : ""}`, _v$23 = props.mode === "draw", _v$24 = icons.pencil, _v$25 = `pp-mode-tab ${props.mode === "queue" ? "pp-mode-tab--active" : ""}`, _v$26 = props.mode === "queue", _v$27 = icons.stack, _v$28 = icons.send, _v$29 = icons.copy, _v$30 = icons.settings, _v$31 = icons.x;
3371
- _v$19 !== _p$.e && className(_el$9, _p$.e = _v$19);
3372
- _v$20 !== _p$.t && setAttribute(_el$9, "aria-selected", _p$.t = _v$20);
3373
- _v$21 !== _p$.a && (_el$0.innerHTML = _p$.a = _v$21);
3374
- _v$22 !== _p$.o && className(_el$1, _p$.o = _v$22);
3375
- _v$23 !== _p$.i && setAttribute(_el$1, "aria-selected", _p$.i = _v$23);
3376
- _v$24 !== _p$.n && (_el$10.innerHTML = _p$.n = _v$24);
3377
- _v$25 !== _p$.s && className(_el$11, _p$.s = _v$25);
3378
- _v$26 !== _p$.h && setAttribute(_el$11, "aria-selected", _p$.h = _v$26);
3379
- _v$27 !== _p$.r && (_el$12.innerHTML = _p$.r = _v$27);
3380
- _v$28 !== _p$.d && (_el$50.innerHTML = _p$.d = _v$28);
3381
- _v$29 !== _p$.l && (_el$51.innerHTML = _p$.l = _v$29);
3382
- _v$30 !== _p$.u && (_el$52.innerHTML = _p$.u = _v$30);
3383
- _v$31 !== _p$.c && (_el$53.innerHTML = _p$.c = _v$31);
3384
- return _p$;
3385
- }, {
3386
- e: void 0,
3387
- t: void 0,
3388
- a: void 0,
3389
- o: void 0,
3390
- i: void 0,
3391
- n: void 0,
3392
- s: void 0,
3393
- h: void 0,
3394
- r: void 0,
3395
- d: void 0,
3396
- l: void 0,
3397
- u: void 0,
3398
- c: void 0
3399
- });
3400
- return _el$5;
3401
- })()
3402
- );
3403
- })());
3404
- createRenderEffect((_p$) => {
3405
- var _v$ = `pp-toolbar ${props.expanded ? "pp-toolbar--expanded" : "pp-toolbar--collapsed"}`, _v$2 = {
3406
- ...props.expanded ? {
3407
- bottom: `${EDGE_GAP}px`,
3408
- right: `${toolbarRight()}px`
3409
- } : {
3410
- right: `${toolbarRight()}px`,
3411
- bottom: `${pos().bottom}px`
3412
- }
3413
- };
3414
- _v$ !== _p$.e && className(_el$, _p$.e = _v$);
3415
- _p$.t = style(_el$, _v$2, _p$.t);
3416
- return _p$;
3417
- }, {
3418
- e: void 0,
3419
- t: void 0
3420
- });
3421
- return _el$;
3422
- })();
3423
- };
3424
- delegateEvents(["mousedown"]);
3425
-
3426
- // src/ui/components/OverlayCanvas.tsx
3427
- var _tmpl$21 = /* @__PURE__ */ template(`<canvas style=position:fixed;top:0;left:0;z-index:2147483645>`);
3428
- function lerp(start, end, t) {
3429
- return start + (end - start) * t;
3430
- }
3431
- var OverlayCanvas = (props) => {
3432
- let canvasRef;
3433
- let animFrameId = null;
3434
- let currentRect = {
3435
- x: 0,
3436
- y: 0,
3437
- width: 0,
3438
- height: 0
3439
- };
3440
- let targetRect = null;
3441
- const LERP_SPEED = 0.25;
3442
- function resizeCanvas() {
3443
- if (!canvasRef) return;
3444
- const dpr = window.devicePixelRatio || 1;
3445
- canvasRef.width = window.innerWidth * dpr;
3446
- canvasRef.height = window.innerHeight * dpr;
3447
- canvasRef.style.width = `${window.innerWidth}px`;
3448
- canvasRef.style.height = `${window.innerHeight}px`;
3449
- const ctx = canvasRef.getContext("2d");
3450
- if (ctx) ctx.scale(dpr, dpr);
3451
- }
3452
- function drawStroke(ctx, stroke) {
3453
- if (stroke.points.length < 1) return;
3454
- ctx.strokeStyle = stroke.color;
3455
- ctx.lineWidth = stroke.lineWidth;
3456
- ctx.lineCap = "round";
3457
- ctx.lineJoin = "round";
3458
- ctx.setLineDash([]);
3459
- if (stroke.type === "freehand") {
3460
- ctx.beginPath();
3461
- ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
3462
- for (let i = 1; i < stroke.points.length; i++) {
3463
- ctx.lineTo(stroke.points[i].x, stroke.points[i].y);
3464
- }
3465
- ctx.stroke();
3466
- } else if (stroke.type === "arrow") {
3467
- if (stroke.points.length < 2) return;
3468
- const start = stroke.points[0];
3469
- const end = stroke.points[stroke.points.length - 1];
3470
- ctx.beginPath();
3471
- ctx.moveTo(start.x, start.y);
3472
- ctx.lineTo(end.x, end.y);
3473
- ctx.stroke();
3474
- const angle = Math.atan2(end.y - start.y, end.x - start.x);
3475
- const headLen = 12 + stroke.lineWidth * 2;
3476
- ctx.beginPath();
3477
- ctx.moveTo(end.x, end.y);
3478
- ctx.lineTo(end.x - headLen * Math.cos(angle - Math.PI / 6), end.y - headLen * Math.sin(angle - Math.PI / 6));
3479
- ctx.moveTo(end.x, end.y);
3480
- ctx.lineTo(end.x - headLen * Math.cos(angle + Math.PI / 6), end.y - headLen * Math.sin(angle + Math.PI / 6));
3481
- ctx.stroke();
3482
- } else if (stroke.type === "circle") {
3483
- if (stroke.points.length < 2) return;
3484
- const start = stroke.points[0];
3485
- const end = stroke.points[stroke.points.length - 1];
3486
- const rx = Math.abs(end.x - start.x) / 2;
3487
- const ry = Math.abs(end.y - start.y) / 2;
3488
- const cx = (start.x + end.x) / 2;
3489
- const cy = (start.y + end.y) / 2;
3490
- ctx.beginPath();
3491
- ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2);
3492
- ctx.stroke();
3493
- } else if (stroke.type === "rect") {
3494
- if (stroke.points.length < 2) return;
3495
- const start = stroke.points[0];
3496
- const end = stroke.points[stroke.points.length - 1];
3497
- ctx.strokeRect(start.x, start.y, end.x - start.x, end.y - start.y);
3498
- }
3499
- }
3500
- function drawTextNote(ctx, note) {
3501
- const fontSize = 13;
3502
- const padding = 6;
3503
- ctx.font = `500 ${fontSize}px -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`;
3504
- const metrics = ctx.measureText(note.text);
3505
- const textWidth = metrics.width;
3506
- const textHeight = fontSize + 2;
3507
- ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
3508
- const bgX = note.x - 2;
3509
- const bgY = note.y - textHeight - padding / 2;
3510
- const bgW = textWidth + padding * 2;
3511
- const bgH = textHeight + padding;
3512
- const r = 4;
3513
- ctx.beginPath();
3514
- ctx.moveTo(bgX + r, bgY);
3515
- ctx.lineTo(bgX + bgW - r, bgY);
3516
- ctx.quadraticCurveTo(bgX + bgW, bgY, bgX + bgW, bgY + r);
3517
- ctx.lineTo(bgX + bgW, bgY + bgH - r);
3518
- ctx.quadraticCurveTo(bgX + bgW, bgY + bgH, bgX + bgW - r, bgY + bgH);
3519
- ctx.lineTo(bgX + r, bgY + bgH);
3520
- ctx.quadraticCurveTo(bgX, bgY + bgH, bgX, bgY + bgH - r);
3521
- ctx.lineTo(bgX, bgY + r);
3522
- ctx.quadraticCurveTo(bgX, bgY, bgX + r, bgY);
3523
- ctx.closePath();
3524
- ctx.fill();
3525
- ctx.fillStyle = note.color;
3526
- ctx.beginPath();
3527
- ctx.arc(bgX + padding, bgY + bgH / 2, 3, 0, Math.PI * 2);
3528
- ctx.fill();
3529
- ctx.fillStyle = "#ffffff";
3530
- ctx.fillText(note.text, bgX + padding + 10, note.y - 2);
3531
- }
3532
- function draw() {
3533
- if (!canvasRef) return;
3534
- const ctx = canvasRef.getContext("2d");
3535
- if (!ctx) return;
3536
- const dpr = window.devicePixelRatio || 1;
3537
- ctx.clearRect(0, 0, canvasRef.width / dpr, canvasRef.height / dpr);
3538
- if (props.active && !props.drawMode && props.hoveredRect) {
3539
- targetRect = {
3540
- x: props.hoveredRect.x,
3541
- y: props.hoveredRect.y,
3542
- width: props.hoveredRect.width,
3543
- height: props.hoveredRect.height
3544
- };
3545
- } else if (props.active && !props.drawMode) {
3546
- targetRect = null;
3547
- }
3548
- if (props.active && !props.drawMode && targetRect) {
3549
- currentRect.x = lerp(currentRect.x, targetRect.x, LERP_SPEED);
3550
- currentRect.y = lerp(currentRect.y, targetRect.y, LERP_SPEED);
3551
- currentRect.width = lerp(currentRect.width, targetRect.width, LERP_SPEED);
3552
- currentRect.height = lerp(currentRect.height, targetRect.height, LERP_SPEED);
3553
- ctx.strokeStyle = "rgba(59, 130, 246, 0.8)";
3554
- ctx.lineWidth = 2;
3555
- ctx.setLineDash([]);
3556
- ctx.strokeRect(currentRect.x, currentRect.y, currentRect.width, currentRect.height);
3557
- ctx.fillStyle = "rgba(59, 130, 246, 0.06)";
3558
- ctx.fillRect(currentRect.x, currentRect.y, currentRect.width, currentRect.height);
3559
- }
3560
- if (props.active && !props.drawMode && props.dragRect) {
3561
- ctx.strokeStyle = "rgba(59, 130, 246, 0.6)";
3562
- ctx.lineWidth = 1;
3563
- ctx.setLineDash([4, 4]);
3564
- ctx.strokeRect(props.dragRect.x, props.dragRect.y, props.dragRect.width, props.dragRect.height);
3565
- ctx.fillStyle = "rgba(59, 130, 246, 0.08)";
3566
- ctx.fillRect(props.dragRect.x, props.dragRect.y, props.dragRect.width, props.dragRect.height);
3567
- }
3568
- for (const stroke of props.drawStrokes) {
3569
- drawStroke(ctx, stroke);
3570
- }
3571
- if (props.currentStroke) {
3572
- drawStroke(ctx, props.currentStroke);
3573
- }
3574
- for (const note of props.textNotes) {
3575
- drawTextNote(ctx, note);
3576
- }
3577
- animFrameId = requestAnimationFrame(draw);
3578
- }
3579
- function handleMouseDown(e) {
3580
- if (!props.drawMode) return;
3581
- if (props.drawTool === "text") {
3582
- props.onTextPlace(e.clientX, e.clientY);
3583
- } else {
3584
- props.onDrawStart(e.clientX, e.clientY);
3585
- }
3586
- }
3587
- function handleMouseMove(e) {
3588
- if (!props.drawMode) return;
3589
- props.onDrawMove(e.clientX, e.clientY);
3590
- }
3591
- function handleMouseUp(_e) {
3592
- if (!props.drawMode) return;
3593
- props.onDrawEnd();
3594
- }
3595
- function handleTouchStart(e) {
3596
- if (!props.drawMode) return;
3597
- e.preventDefault();
3598
- const touch = e.touches[0];
3599
- if (props.drawTool === "text") {
3600
- props.onTextPlace(touch.clientX, touch.clientY);
3601
- } else {
3602
- props.onDrawStart(touch.clientX, touch.clientY);
3603
- }
3604
- }
3605
- function handleTouchMove(e) {
3606
- if (!props.drawMode) return;
3607
- e.preventDefault();
3608
- const touch = e.touches[0];
3609
- props.onDrawMove(touch.clientX, touch.clientY);
3610
- }
3611
- function handleTouchEnd(e) {
3612
- if (!props.drawMode) return;
3613
- e.preventDefault();
3614
- props.onDrawEnd();
3615
- }
3616
- onMount(() => {
3617
- resizeCanvas();
3618
- window.addEventListener("resize", resizeCanvas);
3619
- animFrameId = requestAnimationFrame(draw);
3620
- });
3621
- onCleanup(() => {
3622
- window.removeEventListener("resize", resizeCanvas);
3623
- if (animFrameId !== null) {
3624
- cancelAnimationFrame(animFrameId);
3625
- }
3626
- });
3627
- return (() => {
3628
- var _el$ = _tmpl$21();
3629
- _el$.$$touchend = handleTouchEnd;
3630
- _el$.$$touchmove = handleTouchMove;
3631
- _el$.$$touchstart = handleTouchStart;
3632
- _el$.$$mouseup = handleMouseUp;
3633
- _el$.$$mousemove = handleMouseMove;
3634
- _el$.$$mousedown = handleMouseDown;
3635
- var _ref$ = canvasRef;
3636
- typeof _ref$ === "function" ? use(_ref$, _el$) : canvasRef = _el$;
3637
- createRenderEffect((_p$) => {
3638
- var _v$ = props.drawMode ? "auto" : "none", _v$2 = props.drawMode ? props.drawTool === "text" ? "text" : "crosshair" : "default";
3639
- _v$ !== _p$.e && setStyleProperty(_el$, "pointer-events", _p$.e = _v$);
3640
- _v$2 !== _p$.t && setStyleProperty(_el$, "cursor", _p$.t = _v$2);
3641
- return _p$;
3642
- }, {
3643
- e: void 0,
3644
- t: void 0
3645
- });
3646
- return _el$;
3647
- })();
3648
- };
3649
- delegateEvents(["mousedown", "mousemove", "mouseup", "touchstart", "touchmove", "touchend"]);
3650
-
3651
- // src/ui/components/PinPopup.tsx
3652
- var _tmpl$22 = /* @__PURE__ */ template(`<div class=pp-popup><div class=pp-popup__input-row><textarea class=pp-popup__textarea placeholder="Add your feedback..."></textarea></div><div class=pp-popup__actions><button class="pp-btn pp-btn--ghost"title="Send 'Fix this' to agent"><span style=display:inline-flex></span>Fix</button><div style=flex:1></div><button class=pp-btn>Cancel</button><button class="pp-btn pp-btn--primary">`);
3653
- var _tmpl$23 = /* @__PURE__ */ template(`<div class=pp-popup__header><span class=pp-popup__name></span><span>`);
3654
- var _tmpl$32 = /* @__PURE__ */ template(`<div><div class=pp-popup__details-inner><div class=pp-popup__element-info>`);
3655
- var _tmpl$42 = /* @__PURE__ */ template(`<div class=pp-popup__source><span style=display:inline-flex;vertical-align:middle></span> `);
3656
- var _tmpl$52 = /* @__PURE__ */ template(`<div class=pp-popup__component>`);
3657
- var _tmpl$62 = /* @__PURE__ */ template(`<div class=pp-popup__element-info>`);
3658
- var _tmpl$72 = /* @__PURE__ */ template(`<button>`);
3659
- var _tmpl$82 = /* @__PURE__ */ template(`<button class=pp-btn title="Add to queue"><span style=display:inline-flex></span>Queue`);
3660
- function getSpeechRecognition() {
3661
- const w = window;
3662
- return w.SpeechRecognition || w.webkitSpeechRecognition || null;
3663
- }
3664
- var PinPopup = (props) => {
3665
- const [comment, setComment] = createSignal(props.initialComment || "");
3666
- const [showDetails, setShowDetails] = createSignal(false);
3667
- const [isRecording, setIsRecording] = createSignal(false);
3668
- let textareaRef;
3669
- let recognitionRef = null;
3670
- const compact = () => props.compactPopup ?? true;
3671
- const hasSpeechAPI = !!getSpeechRecognition();
3672
- const displayName = () => {
3673
- if (props.context.framework?.componentPath) {
3674
- return props.context.framework.componentPath;
3675
- }
3676
- return `<${props.context.element.tagName.toLowerCase()}>`;
3677
- };
3678
- const popupPosition = () => {
3679
- const rect = props.context.element.boundingRect;
3680
- const estimatedHeight = compact() && showDetails() ? 260 : 220;
3681
- const popupX = Math.min(rect.x, window.innerWidth - 380);
3682
- const popupY = rect.y + rect.height + 8;
3683
- const adjustedY = popupY + estimatedHeight > window.innerHeight ? rect.y - estimatedHeight - 8 : popupY;
3684
- return {
3685
- x: Math.max(8, popupX),
3686
- y: Math.max(8, adjustedY)
3687
- };
3688
- };
3689
- async function openFileHandler() {
3690
- try {
3691
- const file = props.context.framework?.sourceFile;
3692
- if (!file) return;
3693
- const {
3694
- openFile
3695
- } = await import("./open-file-RQVHOCXI.js");
3696
- openFile(file);
3697
- } catch {
3698
- }
3699
- }
3700
- function toggleRecording() {
3701
- if (isRecording()) {
3702
- stopRecording();
3703
- } else {
3704
- startRecording();
3705
- }
3706
- }
3707
- function startRecording() {
3708
- const SpeechRecognitionClass = getSpeechRecognition();
3709
- if (!SpeechRecognitionClass) return;
3710
- const recognition = new SpeechRecognitionClass();
3711
- recognition.continuous = true;
3712
- recognition.interimResults = true;
3713
- recognition.lang = "en-US";
3714
- let finalTranscript = "";
3715
- recognition.onresult = (event) => {
3716
- let interim = "";
3717
- for (let i = event.resultIndex; i < event.results.length; i++) {
3718
- const transcript = event.results[i][0].transcript;
3719
- if (event.results[i].isFinal) {
3720
- finalTranscript += transcript;
3721
- } else {
3722
- interim = transcript;
3723
- }
3724
- }
3725
- const current = comment();
3726
- const separator = current && !current.endsWith(" ") ? " " : "";
3727
- setComment(current + separator + finalTranscript + interim);
3728
- finalTranscript = "";
3729
- if (textareaRef) {
3730
- textareaRef.style.height = "auto";
3731
- textareaRef.style.height = Math.min(textareaRef.scrollHeight, 120) + "px";
3732
- }
3733
- };
3734
- recognition.onerror = () => {
3735
- setIsRecording(false);
3736
- };
3737
- recognition.onend = () => {
3738
- setIsRecording(false);
3739
- };
3740
- recognition.start();
3741
- recognitionRef = recognition;
3742
- setIsRecording(true);
3743
- }
3744
- function stopRecording() {
3745
- recognitionRef?.stop();
3746
- recognitionRef = null;
3747
- setIsRecording(false);
3748
- }
2844
+ var Toolbar = (props) => {
2845
+ const [pos, setPos] = createSignal(props.position ? {
2846
+ right: window.innerWidth - props.position.x,
2847
+ bottom: window.innerHeight - props.position.y
2848
+ } : {
2849
+ right: EDGE_GAP,
2850
+ bottom: EDGE_GAP
2851
+ });
2852
+ const [reservedRight, setReservedRight] = createSignal(0);
2853
+ const [dragStart, setDragStart] = createSignal({
2854
+ x: 0,
2855
+ y: 0,
2856
+ right: 0,
2857
+ bottom: 0
2858
+ });
2859
+ const [didDrag, setDidDrag] = createSignal(false);
3749
2860
  onMount(() => {
3750
- textareaRef?.focus();
3751
- if (props.initialComment && textareaRef) {
3752
- textareaRef.selectionStart = textareaRef.value.length;
3753
- }
3754
- const onEsc = (e) => {
3755
- if (e.key === "Escape") {
3756
- e.stopPropagation();
3757
- stopRecording();
3758
- props.onCancel();
2861
+ if (typeof window === "undefined") return;
2862
+ let resizeObserver;
2863
+ const updateReservedRight = () => {
2864
+ setReservedRight(getVisibleRightSidebarInset());
2865
+ resizeObserver?.disconnect();
2866
+ if (typeof ResizeObserver === "undefined") return;
2867
+ resizeObserver = new ResizeObserver(() => {
2868
+ setReservedRight(getVisibleRightSidebarInset());
2869
+ });
2870
+ for (const panel of document.querySelectorAll(AGENT_SIDEBAR_SELECTOR)) {
2871
+ resizeObserver.observe(panel);
3759
2872
  }
3760
2873
  };
3761
- document.addEventListener("keydown", onEsc, true);
2874
+ updateReservedRight();
2875
+ const mutationObserver = new MutationObserver(updateReservedRight);
2876
+ mutationObserver.observe(document.body, {
2877
+ attributes: true,
2878
+ attributeFilter: ["class", "style", "aria-hidden"],
2879
+ childList: true,
2880
+ subtree: true
2881
+ });
2882
+ window.addEventListener("resize", updateReservedRight);
3762
2883
  onCleanup(() => {
3763
- document.removeEventListener("keydown", onEsc, true);
3764
- stopRecording();
2884
+ mutationObserver.disconnect();
2885
+ resizeObserver?.disconnect();
2886
+ window.removeEventListener("resize", updateReservedRight);
3765
2887
  });
3766
2888
  });
3767
- function handleSubmit() {
3768
- const text = comment().trim();
3769
- if (!text) return;
3770
- stopRecording();
3771
- props.onAdd(text);
3772
- }
3773
- function handleQueue() {
3774
- const text = comment().trim();
3775
- if (!text) return;
3776
- stopRecording();
3777
- props.onQueue?.(text);
2889
+ const toolbarRight = () => {
2890
+ const toolbarWidth = props.expanded ? EXPANDED_TOOLBAR_WIDTH : COLLAPSED_TOOLBAR_SIZE;
2891
+ return clampRightOffset((props.expanded ? EDGE_GAP : pos().right) + reservedRight(), toolbarWidth);
2892
+ };
2893
+ function handleMouseDown(e) {
2894
+ if (props.expanded) return;
2895
+ setDidDrag(false);
2896
+ setDragStart({
2897
+ x: e.clientX,
2898
+ y: e.clientY,
2899
+ right: pos().right,
2900
+ bottom: pos().bottom
2901
+ });
2902
+ const handleMove = (e2) => {
2903
+ setDidDrag(true);
2904
+ const start = dragStart();
2905
+ const dx = e2.clientX - start.x;
2906
+ const dy = e2.clientY - start.y;
2907
+ const maxRight = Math.max(0, window.innerWidth - reservedRight() - COLLAPSED_TOOLBAR_SIZE);
2908
+ setPos({
2909
+ right: Math.max(0, Math.min(maxRight, start.right - dx)),
2910
+ bottom: Math.max(0, Math.min(window.innerHeight - COLLAPSED_TOOLBAR_SIZE, start.bottom - dy))
2911
+ });
2912
+ };
2913
+ const handleUp = () => {
2914
+ window.removeEventListener("mousemove", handleMove);
2915
+ window.removeEventListener("mouseup", handleUp);
2916
+ };
2917
+ window.addEventListener("mousemove", handleMove);
2918
+ window.addEventListener("mouseup", handleUp);
3778
2919
  }
3779
- function handleFixThis() {
3780
- const text = comment().trim() || `Fix this ${displayName()}`;
3781
- stopRecording();
3782
- props.onFixThis?.(text);
2920
+ function handleClick() {
2921
+ if (props.expanded) return;
2922
+ if (didDrag()) return;
2923
+ props.onToggleExpand();
3783
2924
  }
3784
- function handleKeyDown(e) {
3785
- if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
3786
- e.preventDefault();
3787
- handleSubmit();
3788
- }
3789
- if (e.key === "Escape") {
3790
- stopRecording();
3791
- props.onCancel();
2925
+ const queueSummary = () => {
2926
+ const q = props.queue;
2927
+ let draws = 0;
2928
+ let clicks = 0;
2929
+ for (const item of q) {
2930
+ if (item.drawings?.length || item.textNotes?.length) draws++;
2931
+ if (item.pin) clicks++;
3792
2932
  }
3793
- }
3794
- function handleAutoGrow(e) {
3795
- const el = e.currentTarget;
3796
- setComment(el.value);
3797
- el.style.height = "auto";
3798
- el.style.height = Math.min(el.scrollHeight, 120) + "px";
3799
- }
2933
+ const parts = [];
2934
+ if (draws > 0) parts.push(`Draw x${draws}`);
2935
+ if (clicks > 0) parts.push(`Click x${clicks}`);
2936
+ return parts.join(" / ") || "Empty";
2937
+ };
2938
+ const totalBadgeCount = () => props.pins.length + props.queue.length + props.drawStrokeCount;
3800
2939
  return (() => {
3801
- var _el$ = _tmpl$22(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$7 = _el$5.nextSibling, _el$8 = _el$7.nextSibling, _el$9 = _el$8.nextSibling;
2940
+ var _el$ = _tmpl$12();
2941
+ addEventListener(_el$, "click", handleClick);
2942
+ addEventListener(_el$, "mousedown", props.expanded ? void 0 : handleMouseDown, true);
3802
2943
  insert(_el$, (() => {
3803
- var _c$ = memo(() => !!compact());
2944
+ var _c$ = memo(() => !!!props.expanded);
3804
2945
  return () => _c$() ? (
3805
- /* Compact mode — friendly name + collapsible details */
3806
- [(() => {
3807
- var _el$0 = _tmpl$23(), _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling;
3808
- addEventListener(_el$0, "click", () => setShowDetails(!showDetails()));
3809
- insert(_el$1, displayName);
3810
- createRenderEffect((_p$) => {
3811
- var _v$5 = `pp-popup__chevron ${showDetails() ? "pp-popup__chevron--open" : ""}`, _v$6 = icons.chevronDown, _v$7 = showDetails();
3812
- _v$5 !== _p$.e && className(_el$10, _p$.e = _v$5);
3813
- _v$6 !== _p$.t && (_el$10.innerHTML = _p$.t = _v$6);
3814
- _v$7 !== _p$.a && setAttribute(_el$10, "aria-expanded", _p$.a = _v$7);
3815
- return _p$;
3816
- }, {
3817
- e: void 0,
3818
- t: void 0,
3819
- a: void 0
3820
- });
3821
- return _el$0;
3822
- })(), (() => {
3823
- var _el$11 = _tmpl$32(), _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild;
3824
- insert(_el$13, () => props.context.cssSelector);
3825
- insert(_el$12, createComponent(Show, {
2946
+ /* Collapsed pill */
2947
+ (() => {
2948
+ var _el$2 = _tmpl$23(), _el$3 = _el$2.firstChild;
2949
+ insert(_el$2, (() => {
2950
+ var _c$2 = memo(() => totalBadgeCount() > 0);
2951
+ return () => _c$2() && (() => {
2952
+ var _el$4 = _tmpl$33();
2953
+ insert(_el$4, totalBadgeCount);
2954
+ return _el$4;
2955
+ })();
2956
+ })(), _el$3);
2957
+ createRenderEffect(() => _el$3.innerHTML = icons.pin);
2958
+ return _el$2;
2959
+ })()
2960
+ ) : (
2961
+ /* Expanded toolbar */
2962
+ (() => {
2963
+ var _el$5 = _tmpl$92(), _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild, _el$8 = _el$6.nextSibling, _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$9.nextSibling, _el$10 = _el$1.firstChild, _el$11 = _el$1.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$12.nextSibling, _el$49 = _el$8.nextSibling, _el$50 = _el$49.firstChild, _el$51 = _el$50.nextSibling, _el$52 = _el$51.nextSibling, _el$53 = _el$52.nextSibling;
2964
+ addEventListener(_el$5, "click", (e) => e.stopPropagation());
2965
+ insert(_el$7, () => props.author || "Pinpoint");
2966
+ insert(_el$6, (() => {
2967
+ var _c$3 = memo(() => props.queue.length > 0);
2968
+ return () => _c$3() && (() => {
2969
+ var _el$54 = _tmpl$0();
2970
+ insert(_el$54, () => props.queue.length);
2971
+ return _el$54;
2972
+ })();
2973
+ })(), null);
2974
+ addEventListener(_el$9, "click", () => props.onModeChange("select"));
2975
+ addEventListener(_el$1, "click", () => props.onModeChange("draw"));
2976
+ addEventListener(_el$11, "click", () => props.onModeChange("queue"));
2977
+ insert(_el$11, (() => {
2978
+ var _c$4 = memo(() => props.queue.length > 0);
2979
+ return () => _c$4() && (() => {
2980
+ var _el$55 = _tmpl$1();
2981
+ insert(_el$55, () => props.queue.length);
2982
+ return _el$55;
2983
+ })();
2984
+ })(), null);
2985
+ insert(_el$5, createComponent(Show, {
2986
+ get when() {
2987
+ return props.mode === "select";
2988
+ },
2989
+ get children() {
2990
+ return [memo(() => memo(() => props.pins.length === 0)() && (() => {
2991
+ var _el$56 = _tmpl$102(), _el$57 = _el$56.firstChild;
2992
+ createRenderEffect(() => _el$57.innerHTML = icons.crosshair);
2993
+ return _el$56;
2994
+ })()), memo(() => memo(() => props.pins.length > 0)() && (() => {
2995
+ var _el$58 = _tmpl$112();
2996
+ insert(_el$58, createComponent(For, {
2997
+ get each() {
2998
+ return props.pins;
2999
+ },
3000
+ children: (pin, index) => (() => {
3001
+ var _el$59 = _tmpl$122(), _el$60 = _el$59.firstChild, _el$61 = _el$60.nextSibling, _el$62 = _el$61.nextSibling, _el$63 = _el$62.firstChild, _el$64 = _el$62.nextSibling, _el$65 = _el$64.nextSibling;
3002
+ addEventListener(_el$59, "click", () => props.onEditPin(pin));
3003
+ insert(_el$61, () => index() + 1);
3004
+ insert(_el$63, () => pin.comment || _tmpl$13());
3005
+ addEventListener(_el$64, "click", (e) => {
3006
+ e.stopPropagation();
3007
+ props.onTogglePinSelect(pin);
3008
+ });
3009
+ addEventListener(_el$65, "click", (e) => {
3010
+ e.stopPropagation();
3011
+ props.onRemovePin(pin.id);
3012
+ });
3013
+ createRenderEffect((_p$) => {
3014
+ var _v$32 = `pp-pin-item__status pp-pin-item__status--${pin.status.state}`, _v$33 = props.selectedPinIds.has(pin.id) ? "Deselect" : "Select for send", _v$34 = props.selectedPinIds.has(pin.id) ? "Deselect" : "Select for send", _v$35 = props.selectedPinIds.has(pin.id) ? icons.checkSquare : icons.squareEmpty, _v$36 = props.selectedPinIds.has(pin.id) ? "var(--pp-accent)" : "var(--pp-text-muted)", _v$37 = icons.minus;
3015
+ _v$32 !== _p$.e && className(_el$60, _p$.e = _v$32);
3016
+ _v$33 !== _p$.t && setAttribute(_el$64, "title", _p$.t = _v$33);
3017
+ _v$34 !== _p$.a && setAttribute(_el$64, "aria-label", _p$.a = _v$34);
3018
+ _v$35 !== _p$.o && (_el$64.innerHTML = _p$.o = _v$35);
3019
+ _v$36 !== _p$.i && setStyleProperty(_el$64, "color", _p$.i = _v$36);
3020
+ _v$37 !== _p$.n && (_el$65.innerHTML = _p$.n = _v$37);
3021
+ return _p$;
3022
+ }, {
3023
+ e: void 0,
3024
+ t: void 0,
3025
+ a: void 0,
3026
+ o: void 0,
3027
+ i: void 0,
3028
+ n: void 0
3029
+ });
3030
+ return _el$59;
3031
+ })()
3032
+ }));
3033
+ return _el$58;
3034
+ })()), createComponent(Show, {
3035
+ get when() {
3036
+ return props.selectedPinIds.size > 0;
3037
+ },
3038
+ get children() {
3039
+ var _el$14 = _tmpl$42(), _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling, _el$18 = _el$16.nextSibling, _el$17 = _el$18.nextSibling;
3040
+ addEventListener(_el$14, "click", () => props.onSendSelected());
3041
+ insert(_el$14, () => props.selectedPinIds.size, _el$18);
3042
+ createRenderEffect(() => _el$15.innerHTML = icons.send);
3043
+ return _el$14;
3044
+ }
3045
+ })];
3046
+ }
3047
+ }), _el$49);
3048
+ insert(_el$5, createComponent(Show, {
3826
3049
  get when() {
3827
- return props.context.framework?.sourceFile;
3050
+ return props.mode === "draw";
3828
3051
  },
3829
- children: (file) => (() => {
3830
- var _el$14 = _tmpl$42(), _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling;
3831
- addEventListener(_el$14, "click", openFileHandler);
3832
- insert(_el$14, () => file().split("/").pop(), null);
3052
+ get children() {
3053
+ return [(() => {
3054
+ var _el$19 = _tmpl$52(), _el$20 = _el$19.firstChild, _el$21 = _el$20.nextSibling, _el$22 = _el$21.nextSibling, _el$23 = _el$22.nextSibling, _el$24 = _el$23.nextSibling, _el$25 = _el$24.nextSibling, _el$26 = _el$25.nextSibling, _el$27 = _el$26.nextSibling;
3055
+ addEventListener(_el$20, "click", () => props.onDrawToolChange("freehand"));
3056
+ addEventListener(_el$21, "click", () => props.onDrawToolChange("arrow"));
3057
+ addEventListener(_el$22, "click", () => props.onDrawToolChange("circle"));
3058
+ addEventListener(_el$23, "click", () => props.onDrawToolChange("rect"));
3059
+ addEventListener(_el$24, "click", () => props.onDrawToolChange("text"));
3060
+ addEventListener(_el$26, "click", () => props.onDrawUndo());
3061
+ addEventListener(_el$27, "click", () => props.onDrawClear());
3062
+ createRenderEffect((_p$) => {
3063
+ var _v$3 = `pp-draw-tool ${props.drawTool === "freehand" ? "pp-draw-tool--active" : ""}`, _v$4 = icons.pencil, _v$5 = `pp-draw-tool ${props.drawTool === "arrow" ? "pp-draw-tool--active" : ""}`, _v$6 = icons.arrowUpRight, _v$7 = `pp-draw-tool ${props.drawTool === "circle" ? "pp-draw-tool--active" : ""}`, _v$8 = icons.circle, _v$9 = `pp-draw-tool ${props.drawTool === "rect" ? "pp-draw-tool--active" : ""}`, _v$0 = icons.square, _v$1 = `pp-draw-tool ${props.drawTool === "text" ? "pp-draw-tool--active" : ""}`, _v$10 = icons.typography, _v$11 = icons.undo, _v$12 = props.drawStrokeCount === 0, _v$13 = icons.trash, _v$14 = props.drawStrokeCount === 0;
3064
+ _v$3 !== _p$.e && className(_el$20, _p$.e = _v$3);
3065
+ _v$4 !== _p$.t && (_el$20.innerHTML = _p$.t = _v$4);
3066
+ _v$5 !== _p$.a && className(_el$21, _p$.a = _v$5);
3067
+ _v$6 !== _p$.o && (_el$21.innerHTML = _p$.o = _v$6);
3068
+ _v$7 !== _p$.i && className(_el$22, _p$.i = _v$7);
3069
+ _v$8 !== _p$.n && (_el$22.innerHTML = _p$.n = _v$8);
3070
+ _v$9 !== _p$.s && className(_el$23, _p$.s = _v$9);
3071
+ _v$0 !== _p$.h && (_el$23.innerHTML = _p$.h = _v$0);
3072
+ _v$1 !== _p$.r && className(_el$24, _p$.r = _v$1);
3073
+ _v$10 !== _p$.d && (_el$24.innerHTML = _p$.d = _v$10);
3074
+ _v$11 !== _p$.l && (_el$26.innerHTML = _p$.l = _v$11);
3075
+ _v$12 !== _p$.u && (_el$26.disabled = _p$.u = _v$12);
3076
+ _v$13 !== _p$.c && (_el$27.innerHTML = _p$.c = _v$13);
3077
+ _v$14 !== _p$.w && (_el$27.disabled = _p$.w = _v$14);
3078
+ return _p$;
3079
+ }, {
3080
+ e: void 0,
3081
+ t: void 0,
3082
+ a: void 0,
3083
+ o: void 0,
3084
+ i: void 0,
3085
+ n: void 0,
3086
+ s: void 0,
3087
+ h: void 0,
3088
+ r: void 0,
3089
+ d: void 0,
3090
+ l: void 0,
3091
+ u: void 0,
3092
+ c: void 0,
3093
+ w: void 0
3094
+ });
3095
+ return _el$19;
3096
+ })(), (() => {
3097
+ var _el$28 = _tmpl$62(), _el$29 = _el$28.firstChild, _el$30 = _el$29.nextSibling;
3098
+ insert(_el$29, createComponent(For, {
3099
+ each: DRAW_COLORS,
3100
+ children: (c) => (() => {
3101
+ var _el$67 = _tmpl$14();
3102
+ addEventListener(_el$67, "click", () => props.onDrawColorChange(c.color));
3103
+ createRenderEffect((_p$) => {
3104
+ var _v$38 = `pp-color-swatch ${props.drawColor === c.color ? "pp-color-swatch--active" : ""}`, _v$39 = c.color, _v$40 = c.name;
3105
+ _v$38 !== _p$.e && className(_el$67, _p$.e = _v$38);
3106
+ _v$39 !== _p$.t && setStyleProperty(_el$67, "background", _p$.t = _v$39);
3107
+ _v$40 !== _p$.a && setAttribute(_el$67, "title", _p$.a = _v$40);
3108
+ return _p$;
3109
+ }, {
3110
+ e: void 0,
3111
+ t: void 0,
3112
+ a: void 0
3113
+ });
3114
+ return _el$67;
3115
+ })()
3116
+ }));
3117
+ insert(_el$30, createComponent(For, {
3118
+ each: LINE_WIDTHS,
3119
+ children: (w) => (() => {
3120
+ var _el$68 = _tmpl$15(), _el$69 = _el$68.firstChild;
3121
+ addEventListener(_el$68, "click", () => props.onDrawLineWidthChange(w.width));
3122
+ createRenderEffect((_p$) => {
3123
+ var _v$41 = `pp-width-btn ${props.drawLineWidth === w.width ? "pp-width-btn--active" : ""}`, _v$42 = w.name, _v$43 = `${w.width}px`, _v$44 = props.drawColor, _v$45 = `${w.width / 2}px`;
3124
+ _v$41 !== _p$.e && className(_el$68, _p$.e = _v$41);
3125
+ _v$42 !== _p$.t && setAttribute(_el$68, "title", _p$.t = _v$42);
3126
+ _v$43 !== _p$.a && setStyleProperty(_el$69, "height", _p$.a = _v$43);
3127
+ _v$44 !== _p$.o && setStyleProperty(_el$69, "background", _p$.o = _v$44);
3128
+ _v$45 !== _p$.i && setStyleProperty(_el$69, "border-radius", _p$.i = _v$45);
3129
+ return _p$;
3130
+ }, {
3131
+ e: void 0,
3132
+ t: void 0,
3133
+ a: void 0,
3134
+ o: void 0,
3135
+ i: void 0
3136
+ });
3137
+ return _el$68;
3138
+ })()
3139
+ }));
3140
+ return _el$28;
3141
+ })(), createComponent(Show, {
3142
+ get when() {
3143
+ return props.drawStrokeCount > 0;
3144
+ },
3145
+ get children() {
3146
+ var _el$31 = _tmpl$72(), _el$32 = _el$31.firstChild;
3147
+ insert(_el$31, () => props.drawStrokeCount, _el$32);
3148
+ insert(_el$31, () => props.drawStrokeCount !== 1 ? "s" : "", null);
3149
+ return _el$31;
3150
+ }
3151
+ })];
3152
+ }
3153
+ }), _el$49);
3154
+ insert(_el$5, createComponent(Show, {
3155
+ get when() {
3156
+ return props.mode === "queue";
3157
+ },
3158
+ get children() {
3159
+ return memo(() => props.queue.length === 0)() ? _tmpl$16() : [(() => {
3160
+ var _el$71 = _tmpl$17();
3161
+ insert(_el$71, queueSummary);
3162
+ return _el$71;
3163
+ })(), (() => {
3164
+ var _el$72 = _tmpl$112();
3165
+ insert(_el$72, createComponent(For, {
3166
+ get each() {
3167
+ return props.queue;
3168
+ },
3169
+ children: (item, index) => (() => {
3170
+ var _el$77 = _tmpl$19(), _el$78 = _el$77.firstChild, _el$79 = _el$78.nextSibling, _el$80 = _el$79.firstChild;
3171
+ insert(_el$78, () => index() + 1);
3172
+ insert(_el$80, (() => {
3173
+ var _c$6 = memo(() => !!item.pin);
3174
+ return () => _c$6() ? item.pin.comment || "Pin annotation" : `Drawing (${(item.drawings?.length || 0) + (item.textNotes?.length || 0)} items)`;
3175
+ })());
3176
+ return _el$77;
3177
+ })()
3178
+ }));
3179
+ return _el$72;
3180
+ })(), (() => {
3181
+ var _el$73 = _tmpl$18(), _el$74 = _el$73.firstChild, _el$75 = _el$74.nextSibling, _el$76 = _el$75.firstChild;
3182
+ addEventListener(_el$74, "click", () => props.onQueueClear());
3183
+ addEventListener(_el$75, "click", () => props.onQueueSend());
3184
+ createRenderEffect(() => _el$76.innerHTML = icons.send);
3185
+ return _el$73;
3186
+ })()];
3187
+ }
3188
+ }), _el$49);
3189
+ insert(_el$5, createComponent(Show, {
3190
+ get when() {
3191
+ return props.showSettings;
3192
+ },
3193
+ get children() {
3194
+ var _el$33 = _tmpl$82(), _el$34 = _el$33.firstChild, _el$35 = _el$34.firstChild, _el$36 = _el$35.nextSibling, _el$37 = _el$34.nextSibling, _el$38 = _el$37.firstChild, _el$39 = _el$38.nextSibling, _el$40 = _el$37.nextSibling, _el$41 = _el$40.firstChild, _el$42 = _el$41.nextSibling, _el$43 = _el$40.nextSibling, _el$44 = _el$43.firstChild, _el$45 = _el$44.nextSibling, _el$46 = _el$43.nextSibling, _el$47 = _el$46.firstChild, _el$48 = _el$47.nextSibling;
3195
+ _el$36.addEventListener("change", (e) => props.onOutputFormatChange(e.currentTarget.value));
3196
+ addEventListener(_el$39, "click", () => props.onAutoSubmitChange(!props.autoSubmit));
3197
+ addEventListener(_el$42, "click", () => props.onClearOnSendChange(!props.clearOnSend));
3198
+ addEventListener(_el$45, "click", () => props.onBlockInteractionsChange(!props.blockInteractions));
3199
+ addEventListener(_el$48, "click", () => props.onCompactPopupChange(!props.compactPopup));
3833
3200
  createRenderEffect((_p$) => {
3834
- var _v$8 = file(), _v$9 = icons.fileCode;
3835
- _v$8 !== _p$.e && setAttribute(_el$14, "title", _p$.e = _v$8);
3836
- _v$9 !== _p$.t && (_el$15.innerHTML = _p$.t = _v$9);
3201
+ var _v$15 = `pp-toggle ${props.autoSubmit ? "pp-toggle--active" : ""}`, _v$16 = `pp-toggle ${props.clearOnSend ? "pp-toggle--active" : ""}`, _v$17 = `pp-toggle ${props.blockInteractions ? "pp-toggle--active" : ""}`, _v$18 = `pp-toggle ${props.compactPopup ? "pp-toggle--active" : ""}`;
3202
+ _v$15 !== _p$.e && className(_el$39, _p$.e = _v$15);
3203
+ _v$16 !== _p$.t && className(_el$42, _p$.t = _v$16);
3204
+ _v$17 !== _p$.a && className(_el$45, _p$.a = _v$17);
3205
+ _v$18 !== _p$.o && className(_el$48, _p$.o = _v$18);
3837
3206
  return _p$;
3838
3207
  }, {
3839
3208
  e: void 0,
3840
- t: void 0
3209
+ t: void 0,
3210
+ a: void 0,
3211
+ o: void 0
3841
3212
  });
3842
- return _el$14;
3843
- })()
3844
- }), null);
3845
- createRenderEffect(() => className(_el$11, `pp-popup__details ${showDetails() ? "pp-popup__details--open" : ""}`));
3846
- return _el$11;
3847
- })()]
3848
- ) : (
3849
- /* Expanded mode all info visible */
3850
- [(() => {
3851
- var _el$17 = _tmpl$52();
3852
- insert(_el$17, displayName);
3853
- return _el$17;
3854
- })(), (() => {
3855
- var _el$18 = _tmpl$62();
3856
- insert(_el$18, () => props.context.cssSelector);
3857
- return _el$18;
3858
- })(), createComponent(Show, {
3859
- get when() {
3860
- return props.context.framework?.sourceFile;
3861
- },
3862
- children: (file) => (() => {
3863
- var _el$19 = _tmpl$42(), _el$20 = _el$19.firstChild, _el$21 = _el$20.nextSibling;
3864
- addEventListener(_el$19, "click", openFileHandler);
3865
- insert(_el$19, () => file().split("/").pop(), null);
3866
- createRenderEffect((_p$) => {
3867
- var _v$0 = file(), _v$1 = icons.fileCode;
3868
- _v$0 !== _p$.e && setAttribute(_el$19, "title", _p$.e = _v$0);
3869
- _v$1 !== _p$.t && (_el$20.innerHTML = _p$.t = _v$1);
3870
- return _p$;
3871
- }, {
3872
- e: void 0,
3873
- t: void 0
3874
- });
3875
- return _el$19;
3876
- })()
3877
- })]
3213
+ createRenderEffect(() => _el$36.value = props.outputFormat);
3214
+ return _el$33;
3215
+ }
3216
+ }), _el$49);
3217
+ addEventListener(_el$50, "click", () => props.onSend());
3218
+ addEventListener(_el$51, "click", () => props.onCopy());
3219
+ insert(_el$49, (() => {
3220
+ var _c$5 = memo(() => props.pins.length > 0);
3221
+ return () => _c$5() && (() => {
3222
+ var _el$81 = _tmpl$20();
3223
+ addEventListener(_el$81, "click", () => props.onClear());
3224
+ createRenderEffect(() => _el$81.innerHTML = icons.trash);
3225
+ return _el$81;
3226
+ })();
3227
+ })(), _el$52);
3228
+ addEventListener(_el$52, "click", () => props.onToggleSettings());
3229
+ addEventListener(_el$53, "click", () => props.onToggleExpand());
3230
+ createRenderEffect((_p$) => {
3231
+ var _v$19 = `pp-mode-tab ${props.mode === "select" ? "pp-mode-tab--active" : ""}`, _v$20 = props.mode === "select", _v$21 = icons.crosshair, _v$22 = `pp-mode-tab ${props.mode === "draw" ? "pp-mode-tab--active" : ""}`, _v$23 = props.mode === "draw", _v$24 = icons.pencil, _v$25 = `pp-mode-tab ${props.mode === "queue" ? "pp-mode-tab--active" : ""}`, _v$26 = props.mode === "queue", _v$27 = icons.stack, _v$28 = icons.send, _v$29 = icons.copy, _v$30 = icons.settings, _v$31 = icons.x;
3232
+ _v$19 !== _p$.e && className(_el$9, _p$.e = _v$19);
3233
+ _v$20 !== _p$.t && setAttribute(_el$9, "aria-selected", _p$.t = _v$20);
3234
+ _v$21 !== _p$.a && (_el$0.innerHTML = _p$.a = _v$21);
3235
+ _v$22 !== _p$.o && className(_el$1, _p$.o = _v$22);
3236
+ _v$23 !== _p$.i && setAttribute(_el$1, "aria-selected", _p$.i = _v$23);
3237
+ _v$24 !== _p$.n && (_el$10.innerHTML = _p$.n = _v$24);
3238
+ _v$25 !== _p$.s && className(_el$11, _p$.s = _v$25);
3239
+ _v$26 !== _p$.h && setAttribute(_el$11, "aria-selected", _p$.h = _v$26);
3240
+ _v$27 !== _p$.r && (_el$12.innerHTML = _p$.r = _v$27);
3241
+ _v$28 !== _p$.d && (_el$50.innerHTML = _p$.d = _v$28);
3242
+ _v$29 !== _p$.l && (_el$51.innerHTML = _p$.l = _v$29);
3243
+ _v$30 !== _p$.u && (_el$52.innerHTML = _p$.u = _v$30);
3244
+ _v$31 !== _p$.c && (_el$53.innerHTML = _p$.c = _v$31);
3245
+ return _p$;
3246
+ }, {
3247
+ e: void 0,
3248
+ t: void 0,
3249
+ a: void 0,
3250
+ o: void 0,
3251
+ i: void 0,
3252
+ n: void 0,
3253
+ s: void 0,
3254
+ h: void 0,
3255
+ r: void 0,
3256
+ d: void 0,
3257
+ l: void 0,
3258
+ u: void 0,
3259
+ c: void 0
3260
+ });
3261
+ return _el$5;
3262
+ })()
3878
3263
  );
3879
- })(), _el$2);
3880
- addEventListener(_el$3, "keydown", handleKeyDown);
3881
- addEventListener(_el$3, "input", handleAutoGrow);
3882
- var _ref$ = textareaRef;
3883
- typeof _ref$ === "function" ? use(_ref$, _el$3) : textareaRef = _el$3;
3884
- insert(_el$2, hasSpeechAPI && (() => {
3885
- var _el$22 = _tmpl$72();
3886
- addEventListener(_el$22, "click", toggleRecording);
3887
- createRenderEffect((_p$) => {
3888
- var _v$10 = `pp-btn--icon pp-popup__mic ${isRecording() ? "pp-popup__mic--recording" : ""}`, _v$11 = isRecording() ? "Stop recording" : "Voice input", _v$12 = isRecording() ? "Stop recording" : "Voice input", _v$13 = isRecording() ? icons.microphoneOff : icons.microphone;
3889
- _v$10 !== _p$.e && className(_el$22, _p$.e = _v$10);
3890
- _v$11 !== _p$.t && setAttribute(_el$22, "title", _p$.t = _v$11);
3891
- _v$12 !== _p$.a && setAttribute(_el$22, "aria-label", _p$.a = _v$12);
3892
- _v$13 !== _p$.o && (_el$22.innerHTML = _p$.o = _v$13);
3893
- return _p$;
3894
- }, {
3895
- e: void 0,
3896
- t: void 0,
3897
- a: void 0,
3898
- o: void 0
3899
- });
3900
- return _el$22;
3901
- })(), null);
3902
- addEventListener(_el$5, "click", handleFixThis);
3903
- addEventListener(_el$8, "click", () => props.onCancel());
3904
- insert(_el$4, (() => {
3905
- var _c$2 = memo(() => !!(props.queueMode && props.onQueue));
3906
- return () => _c$2() && (() => {
3907
- var _el$23 = _tmpl$82(), _el$24 = _el$23.firstChild;
3908
- addEventListener(_el$23, "click", handleQueue);
3909
- createRenderEffect((_p$) => {
3910
- var _v$14 = !comment().trim(), _v$15 = icons.plus;
3911
- _v$14 !== _p$.e && (_el$23.disabled = _p$.e = _v$14);
3912
- _v$15 !== _p$.t && (_el$24.innerHTML = _p$.t = _v$15);
3913
- return _p$;
3914
- }, {
3915
- e: void 0,
3916
- t: void 0
3917
- });
3918
- return _el$23;
3919
- })();
3920
- })(), _el$9);
3921
- addEventListener(_el$9, "click", () => handleSubmit());
3922
- insert(_el$9, () => props.isEditing ? "Save" : "Add Pin");
3923
- createRenderEffect((_p$) => {
3924
- var _v$ = `${popupPosition().x}px`, _v$2 = `${popupPosition().y}px`, _v$3 = icons.bolt, _v$4 = !comment().trim();
3925
- _v$ !== _p$.e && setStyleProperty(_el$, "left", _p$.e = _v$);
3926
- _v$2 !== _p$.t && setStyleProperty(_el$, "top", _p$.t = _v$2);
3927
- _v$3 !== _p$.a && (_el$6.innerHTML = _p$.a = _v$3);
3928
- _v$4 !== _p$.o && (_el$9.disabled = _p$.o = _v$4);
3929
- return _p$;
3930
- }, {
3931
- e: void 0,
3932
- t: void 0,
3933
- a: void 0,
3934
- o: void 0
3935
- });
3936
- createRenderEffect(() => _el$3.value = comment());
3937
- return _el$;
3938
- })();
3939
- };
3940
-
3941
- // src/ui/components/ContextMenu.tsx
3942
- var _tmpl$24 = /* @__PURE__ */ template(`<div class=pp-context-menu><div class=pp-context-menu__item><span></span>Add Annotation</div><div class=pp-context-menu__item><span></span>Quick Prompt</div><div class=pp-context-menu__separator></div><div class=pp-context-menu__item><span></span>Copy Element Context</div><div class=pp-context-menu__item><span></span>Copy HTML Snippet</div><div class=pp-context-menu__item><span></span>Copy Computed Styles`);
3943
- var ContextMenu = (props) => {
3944
- let menuRef;
3945
- onMount(() => {
3946
- const handleClick = (e) => {
3947
- if (menuRef && !e.composedPath().includes(menuRef)) {
3948
- props.onClose();
3949
- }
3950
- };
3951
- const handleKeyDown = (e) => {
3952
- if (e.key === "Escape") props.onClose();
3953
- };
3954
- setTimeout(() => {
3955
- document.addEventListener("click", handleClick, true);
3956
- document.addEventListener("keydown", handleKeyDown, true);
3957
- }, 0);
3958
- onCleanup(() => {
3959
- document.removeEventListener("click", handleClick, true);
3960
- document.removeEventListener("keydown", handleKeyDown, true);
3961
- });
3962
- });
3963
- const x = Math.min(props.position.x, window.innerWidth - 200);
3964
- const y = Math.min(props.position.y, window.innerHeight - 250);
3965
- return (() => {
3966
- var _el$ = _tmpl$24(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$2.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$4.nextSibling, _el$7 = _el$6.nextSibling, _el$8 = _el$7.firstChild, _el$9 = _el$7.nextSibling, _el$0 = _el$9.firstChild, _el$1 = _el$9.nextSibling, _el$10 = _el$1.firstChild;
3967
- var _ref$ = menuRef;
3968
- typeof _ref$ === "function" ? use(_ref$, _el$) : menuRef = _el$;
3969
- setStyleProperty(_el$, "left", `${x}px`);
3970
- setStyleProperty(_el$, "top", `${y}px`);
3971
- addEventListener(_el$2, "click", () => props.onAnnotate());
3972
- addEventListener(_el$4, "click", () => props.onPrompt());
3973
- addEventListener(_el$7, "click", () => props.onCopyContext());
3974
- addEventListener(_el$9, "click", async () => {
3975
- const html = props.element.outerHTML.replace(/\s+/g, " ").trim().slice(0, 500);
3976
- await navigator.clipboard.writeText(html);
3977
- props.onClose();
3978
- });
3979
- addEventListener(_el$1, "click", async () => {
3980
- const styles = window.getComputedStyle(props.element);
3981
- const relevant = ["color", "background-color", "font-size", "font-family", "padding", "margin", "border", "display", "position", "width", "height"];
3982
- const result = relevant.map((key) => `${key}: ${styles.getPropertyValue(key)}`).join("\n");
3983
- await navigator.clipboard.writeText(result);
3984
- props.onClose();
3985
- });
3264
+ })());
3986
3265
  createRenderEffect((_p$) => {
3987
- var _v$ = icons.pin, _v$2 = icons.messageSquare, _v$3 = icons.copy, _v$4 = icons.fileCode, _v$5 = icons.eye;
3988
- _v$ !== _p$.e && (_el$3.innerHTML = _p$.e = _v$);
3989
- _v$2 !== _p$.t && (_el$5.innerHTML = _p$.t = _v$2);
3990
- _v$3 !== _p$.a && (_el$8.innerHTML = _p$.a = _v$3);
3991
- _v$4 !== _p$.o && (_el$0.innerHTML = _p$.o = _v$4);
3992
- _v$5 !== _p$.i && (_el$10.innerHTML = _p$.i = _v$5);
3266
+ var _v$ = `pp-toolbar ${props.expanded ? "pp-toolbar--expanded" : "pp-toolbar--collapsed"}`, _v$2 = {
3267
+ ...props.expanded ? {
3268
+ bottom: `${EDGE_GAP}px`,
3269
+ right: `${toolbarRight()}px`
3270
+ } : {
3271
+ right: `${toolbarRight()}px`,
3272
+ bottom: `${pos().bottom}px`
3273
+ }
3274
+ };
3275
+ _v$ !== _p$.e && className(_el$, _p$.e = _v$);
3276
+ _p$.t = style(_el$, _v$2, _p$.t);
3993
3277
  return _p$;
3994
3278
  }, {
3995
3279
  e: void 0,
3996
- t: void 0,
3997
- a: void 0,
3998
- o: void 0,
3999
- i: void 0
3280
+ t: void 0
4000
3281
  });
4001
3282
  return _el$;
4002
3283
  })();
4003
3284
  };
4004
-
4005
- // src/ui/components/SelectionLabel.tsx
4006
- var _tmpl$25 = /* @__PURE__ */ template(`<div class=pp-selection-label>`);
4007
- var SelectionLabel = (props) => {
4008
- return createComponent(Show, {
4009
- get when() {
4010
- return props.info;
4011
- },
4012
- children: (info) => {
4013
- const {
4014
- text,
4015
- rect
4016
- } = info();
4017
- const y = rect.top > 30 ? rect.top - 24 : rect.bottom + 4;
4018
- const x = Math.max(4, Math.min(rect.left, window.innerWidth - 300));
4019
- return (() => {
4020
- var _el$ = _tmpl$25();
4021
- setStyleProperty(_el$, "left", `${x}px`);
4022
- setStyleProperty(_el$, "top", `${y}px`);
4023
- insert(_el$, text);
4024
- return _el$;
4025
- })();
4026
- }
4027
- });
4028
- };
4029
-
4030
- // src/ui/components/PromptMode.tsx
4031
- var _tmpl$26 = /* @__PURE__ */ template(`<div class=pp-prompt><input class=pp-prompt__input type=text placeholder="Tell the agent what to do..."><button class="pp-btn pp-btn--primary pp-btn--sm"><span>`);
4032
- var PromptMode = (props) => {
4033
- const [instruction, setInstruction] = createSignal("");
4034
- let inputRef;
4035
- onMount(() => inputRef?.focus());
4036
- function handleSubmit() {
4037
- const text = instruction().trim();
4038
- if (!text) return;
4039
- props.onSend(text);
4040
- }
4041
- const rect = props.element.getBoundingClientRect();
4042
- const x = Math.max(8, Math.min(rect.left, window.innerWidth - 300));
4043
- const y = rect.bottom + 8 > window.innerHeight - 40 ? rect.top - 40 : rect.bottom + 8;
4044
- return (() => {
4045
- var _el$ = _tmpl$26(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild;
4046
- setStyleProperty(_el$, "left", `${x}px`);
4047
- setStyleProperty(_el$, "top", `${y}px`);
4048
- _el$2.$$keydown = (e) => {
4049
- if (e.key === "Enter") handleSubmit();
4050
- if (e.key === "Escape") props.onCancel();
4051
- };
4052
- _el$2.$$input = (e) => setInstruction(e.currentTarget.value);
4053
- var _ref$ = inputRef;
4054
- typeof _ref$ === "function" ? use(_ref$, _el$2) : inputRef = _el$2;
4055
- _el$3.$$click = handleSubmit;
4056
- createRenderEffect(() => _el$4.innerHTML = icons.send);
4057
- createRenderEffect(() => _el$2.value = instruction());
4058
- return _el$;
4059
- })();
4060
- };
4061
- delegateEvents(["input", "keydown", "click"]);
4062
-
4063
- // src/ui/components/TextInputPopup.tsx
4064
- var _tmpl$27 = /* @__PURE__ */ template(`<div class=pp-text-input-popup><div class=pp-text-input-popup__indicator></div><input class=pp-text-input-popup__input type=text placeholder="Add text note...">`);
4065
- var TextInputPopup = (props) => {
4066
- const [text, setText] = createSignal("");
4067
- let inputRef;
4068
- onMount(() => inputRef?.focus());
4069
- function handleSubmit() {
4070
- const t = text().trim();
4071
- if (t) props.onSubmit(t);
4072
- else props.onCancel();
4073
- }
4074
- const x = Math.max(8, Math.min(props.x, window.innerWidth - 260));
4075
- const y = Math.max(8, Math.min(props.y + 8, window.innerHeight - 50));
4076
- return (() => {
4077
- var _el$ = _tmpl$27(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
4078
- setStyleProperty(_el$, "left", `${x}px`);
4079
- setStyleProperty(_el$, "top", `${y}px`);
4080
- _el$3.addEventListener("blur", handleSubmit);
4081
- _el$3.$$keydown = (e) => {
4082
- if (e.key === "Enter") handleSubmit();
4083
- if (e.key === "Escape") props.onCancel();
4084
- };
4085
- _el$3.$$input = (e) => setText(e.currentTarget.value);
4086
- var _ref$ = inputRef;
4087
- typeof _ref$ === "function" ? use(_ref$, _el$3) : inputRef = _el$3;
4088
- createRenderEffect((_$p) => setStyleProperty(_el$2, "background", props.color));
4089
- createRenderEffect(() => _el$3.value = text());
4090
- return _el$;
4091
- })();
4092
- };
4093
- delegateEvents(["input", "keydown"]);
3285
+ delegateEvents(["mousedown"]);
4094
3286
 
4095
3287
  // src/ui/components/PinpointApp.tsx
4096
3288
  var PinpointApp = (props) => {
@@ -4852,6 +4044,817 @@ var PinpointApp = (props) => {
4852
4044
  }))];
4853
4045
  };
4854
4046
 
4047
+ // src/ui/styles/theme.ts
4048
+ var overlayStyles = `
4049
+ :host {
4050
+ all: initial;
4051
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
4052
+ font-size: 13px;
4053
+ line-height: 1.4;
4054
+ color: var(--pp-text);
4055
+ pointer-events: none;
4056
+ }
4057
+
4058
+ *,
4059
+ *::before,
4060
+ *::after {
4061
+ box-sizing: border-box;
4062
+ margin: 0;
4063
+ padding: 0;
4064
+ }
4065
+
4066
+ /* Theme variables */
4067
+ :host {
4068
+ --pp-bg: rgba(24, 24, 27, 0.92);
4069
+ --pp-bg-solid: #18181b;
4070
+ --pp-text: #fafafa;
4071
+ --pp-text-muted: #a1a1aa;
4072
+ --pp-border: rgba(63, 63, 70, 0.6);
4073
+ --pp-accent: #3b82f6;
4074
+ --pp-accent-hover: #60a5fa;
4075
+ --pp-success: #22c55e;
4076
+ --pp-warning: #eab308;
4077
+ --pp-danger: #ef4444;
4078
+ --pp-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.06);
4079
+ --pp-radius: 10px;
4080
+ --pp-radius-sm: 6px;
4081
+ }
4082
+
4083
+ :host([data-theme="light"]) {
4084
+ --pp-bg: rgba(255, 255, 255, 0.92);
4085
+ --pp-bg-solid: #ffffff;
4086
+ --pp-text: #18181b;
4087
+ --pp-text-muted: #71717a;
4088
+ --pp-border: rgba(228, 228, 231, 0.8);
4089
+ --pp-accent: #2563eb;
4090
+ --pp-accent-hover: #3b82f6;
4091
+ --pp-shadow: 0 4px 24px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.06);
4092
+ }
4093
+
4094
+ :host([data-theme="light"]) .pp-popup__textarea {
4095
+ background: rgba(0, 0, 0, 0.06);
4096
+ }
4097
+
4098
+ /* Toolbar */
4099
+ .pp-toolbar {
4100
+ position: fixed;
4101
+ z-index: 2147483646;
4102
+ pointer-events: auto;
4103
+ backdrop-filter: blur(12px) saturate(180%);
4104
+ -webkit-backdrop-filter: blur(12px) saturate(180%);
4105
+ background: var(--pp-bg);
4106
+ border: 1px solid var(--pp-border);
4107
+ border-radius: var(--pp-radius);
4108
+ box-shadow: var(--pp-shadow);
4109
+ transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
4110
+ user-select: none;
4111
+ cursor: default;
4112
+ }
4113
+
4114
+ .pp-toolbar--collapsed {
4115
+ padding: 10px;
4116
+ display: flex;
4117
+ align-items: center;
4118
+ justify-content: center;
4119
+ gap: 6px;
4120
+ cursor: pointer;
4121
+ }
4122
+
4123
+ .pp-toolbar--expanded {
4124
+ padding: 12px;
4125
+ width: 320px;
4126
+ max-height: 420px;
4127
+ display: flex;
4128
+ flex-direction: column;
4129
+ gap: 8px;
4130
+ }
4131
+
4132
+ .pp-toolbar__badge {
4133
+ display: inline-flex;
4134
+ align-items: center;
4135
+ justify-content: center;
4136
+ min-width: 18px;
4137
+ height: 18px;
4138
+ padding: 0 5px;
4139
+ border-radius: 9px;
4140
+ background: var(--pp-accent);
4141
+ color: #fff;
4142
+ font-size: 11px;
4143
+ font-weight: 600;
4144
+ }
4145
+
4146
+ /* Buttons */
4147
+ .pp-btn {
4148
+ display: inline-flex;
4149
+ align-items: center;
4150
+ justify-content: center;
4151
+ gap: 4px;
4152
+ padding: 5px 10px;
4153
+ border: 1px solid var(--pp-border);
4154
+ border-radius: var(--pp-radius-sm);
4155
+ background: transparent;
4156
+ color: var(--pp-text);
4157
+ font-size: 12px;
4158
+ font-weight: 500;
4159
+ cursor: pointer;
4160
+ transition: all 0.15s ease;
4161
+ white-space: nowrap;
4162
+ }
4163
+
4164
+ .pp-btn:hover {
4165
+ background: rgba(255, 255, 255, 0.06);
4166
+ border-color: var(--pp-accent);
4167
+ }
4168
+
4169
+ .pp-btn--primary {
4170
+ background: var(--pp-accent);
4171
+ border-color: var(--pp-accent);
4172
+ color: #fff;
4173
+ }
4174
+
4175
+ .pp-btn--primary:hover {
4176
+ background: var(--pp-accent-hover);
4177
+ }
4178
+
4179
+ .pp-btn--sm {
4180
+ padding: 3px 6px;
4181
+ font-size: 11px;
4182
+ }
4183
+
4184
+ .pp-btn--icon {
4185
+ padding: 4px;
4186
+ border: none;
4187
+ background: transparent;
4188
+ color: var(--pp-text-muted);
4189
+ cursor: pointer;
4190
+ border-radius: var(--pp-radius-sm);
4191
+ }
4192
+
4193
+ .pp-btn--icon:hover {
4194
+ background: rgba(255, 255, 255, 0.06);
4195
+ color: var(--pp-text);
4196
+ }
4197
+
4198
+ .pp-btn--icon-sm {
4199
+ padding: 2px;
4200
+ opacity: 0;
4201
+ pointer-events: none;
4202
+ transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease;
4203
+ }
4204
+
4205
+ .pp-pin-item:hover .pp-btn--icon-sm,
4206
+ .pp-pin-item:focus-within .pp-btn--icon-sm {
4207
+ opacity: 1;
4208
+ pointer-events: auto;
4209
+ }
4210
+
4211
+ .pp-btn--icon-sm:hover {
4212
+ background: rgba(239, 68, 68, 0.15);
4213
+ color: var(--pp-danger);
4214
+ }
4215
+
4216
+ @media (hover: none) {
4217
+ .pp-btn--icon-sm {
4218
+ opacity: 0.6;
4219
+ pointer-events: auto;
4220
+ }
4221
+ }
4222
+
4223
+ @media (prefers-reduced-motion: reduce) {
4224
+ .pp-btn--icon-sm { transition: none; }
4225
+ }
4226
+
4227
+ /* Pin list */
4228
+ .pp-pin-list {
4229
+ display: flex;
4230
+ flex-direction: column;
4231
+ gap: 4px;
4232
+ overflow-y: auto;
4233
+ max-height: 240px;
4234
+ scrollbar-width: thin;
4235
+ scrollbar-color: var(--pp-border) transparent;
4236
+ }
4237
+
4238
+ .pp-pin-item {
4239
+ display: flex;
4240
+ align-items: center;
4241
+ gap: 8px;
4242
+ padding: 6px 8px;
4243
+ border-radius: var(--pp-radius-sm);
4244
+ cursor: pointer;
4245
+ transition: background 0.1s;
4246
+ }
4247
+
4248
+ .pp-pin-item:hover {
4249
+ background: rgba(255, 255, 255, 0.04);
4250
+ }
4251
+
4252
+ .pp-pin-item__number {
4253
+ display: flex;
4254
+ align-items: center;
4255
+ justify-content: center;
4256
+ width: 22px;
4257
+ height: 22px;
4258
+ min-width: 22px;
4259
+ padding: 0 4px;
4260
+ border-radius: 11px;
4261
+ background: var(--pp-accent);
4262
+ color: #fff;
4263
+ font-size: 11px;
4264
+ font-weight: 600;
4265
+ font-variant-numeric: tabular-nums;
4266
+ flex-shrink: 0;
4267
+ }
4268
+
4269
+ .pp-pin-item__content {
4270
+ flex: 1;
4271
+ min-width: 0;
4272
+ }
4273
+
4274
+ .pp-pin-item__comment {
4275
+ font-size: 12px;
4276
+ color: var(--pp-text);
4277
+ display: -webkit-box;
4278
+ -webkit-line-clamp: 2;
4279
+ -webkit-box-orient: vertical;
4280
+ overflow: hidden;
4281
+ word-break: break-word;
4282
+ }
4283
+
4284
+ .pp-pin-item__status {
4285
+ width: 6px;
4286
+ height: 6px;
4287
+ border-radius: 50%;
4288
+ flex-shrink: 0;
4289
+ }
4290
+
4291
+ .pp-pin-item__status--open { background: var(--pp-danger); }
4292
+ .pp-pin-item__status--acknowledged { background: var(--pp-warning); }
4293
+ .pp-pin-item__status--resolved { background: var(--pp-success); }
4294
+ .pp-pin-item__status--dismissed { background: var(--pp-text-muted); }
4295
+
4296
+ /* Action bar \u2014 horizontal icon bar at bottom */
4297
+ .pp-actions {
4298
+ display: flex;
4299
+ align-items: center;
4300
+ justify-content: center;
4301
+ gap: 6px;
4302
+ padding-top: 8px;
4303
+ border-top: 1px solid var(--pp-border);
4304
+ }
4305
+
4306
+ .pp-actions .pp-btn--icon {
4307
+ width: 32px;
4308
+ height: 32px;
4309
+ border-radius: 50%;
4310
+ display: flex;
4311
+ align-items: center;
4312
+ justify-content: center;
4313
+ }
4314
+
4315
+ .pp-actions .pp-btn--icon:focus-visible {
4316
+ outline: 2px solid var(--pp-accent);
4317
+ outline-offset: 2px;
4318
+ }
4319
+
4320
+ /* Popup */
4321
+ .pp-popup {
4322
+ position: fixed;
4323
+ z-index: 2147483647;
4324
+ pointer-events: auto;
4325
+ backdrop-filter: blur(12px) saturate(180%);
4326
+ -webkit-backdrop-filter: blur(12px) saturate(180%);
4327
+ background: var(--pp-bg);
4328
+ border: 1px solid var(--pp-border);
4329
+ border-radius: var(--pp-radius);
4330
+ box-shadow: var(--pp-shadow);
4331
+ padding: 10px;
4332
+ min-width: 280px;
4333
+ max-width: 360px;
4334
+ display: flex;
4335
+ flex-direction: column;
4336
+ gap: 6px;
4337
+ }
4338
+
4339
+ .pp-popup__element-info {
4340
+ font-size: 11px;
4341
+ font-family: 'SF Mono', 'Fira Code', monospace;
4342
+ color: var(--pp-accent);
4343
+ word-break: break-all;
4344
+ }
4345
+
4346
+ .pp-popup__component {
4347
+ font-size: 12px;
4348
+ color: var(--pp-text-muted);
4349
+ }
4350
+
4351
+ .pp-popup__source {
4352
+ font-size: 11px;
4353
+ color: var(--pp-text-muted);
4354
+ cursor: pointer;
4355
+ display: flex;
4356
+ align-items: center;
4357
+ gap: 4px;
4358
+ }
4359
+
4360
+ .pp-popup__source:hover {
4361
+ color: var(--pp-accent);
4362
+ text-decoration: underline;
4363
+ }
4364
+
4365
+ /* Popup header with chevron toggle */
4366
+ .pp-popup__header {
4367
+ display: flex;
4368
+ align-items: center;
4369
+ justify-content: space-between;
4370
+ cursor: pointer;
4371
+ padding: 2px 0;
4372
+ }
4373
+
4374
+ .pp-popup__name {
4375
+ font-size: 12px;
4376
+ font-weight: 500;
4377
+ color: var(--pp-text);
4378
+ overflow: hidden;
4379
+ text-overflow: ellipsis;
4380
+ white-space: nowrap;
4381
+ max-width: 280px;
4382
+ }
4383
+
4384
+ .pp-popup__chevron {
4385
+ color: var(--pp-text-muted);
4386
+ transition: transform 0.15s ease;
4387
+ display: flex;
4388
+ align-items: center;
4389
+ flex-shrink: 0;
4390
+ transform: rotate(-90deg);
4391
+ }
4392
+
4393
+ .pp-popup__chevron--open {
4394
+ transform: rotate(0deg);
4395
+ }
4396
+
4397
+ /* CSS-based collapsible \u2014 keeps DOM, animates height */
4398
+ .pp-popup__details {
4399
+ display: grid;
4400
+ grid-template-rows: 0fr;
4401
+ transition: grid-template-rows 0.2s ease-out;
4402
+ }
4403
+
4404
+ .pp-popup__details--open {
4405
+ grid-template-rows: 1fr;
4406
+ }
4407
+
4408
+ .pp-popup__details-inner {
4409
+ overflow: hidden;
4410
+ display: flex;
4411
+ flex-direction: column;
4412
+ gap: 3px;
4413
+ }
4414
+
4415
+ @media (prefers-reduced-motion: reduce) {
4416
+ .pp-popup__chevron,
4417
+ .pp-popup__details {
4418
+ transition: none;
4419
+ }
4420
+ }
4421
+
4422
+ .pp-popup__textarea {
4423
+ width: 100%;
4424
+ min-height: 48px;
4425
+ max-height: 120px;
4426
+ padding: 8px;
4427
+ border: 1px solid var(--pp-border);
4428
+ border-radius: var(--pp-radius-sm);
4429
+ background: rgba(0, 0, 0, 0.2);
4430
+ color: var(--pp-text);
4431
+ font-size: 13px;
4432
+ font-family: inherit;
4433
+ resize: none;
4434
+ overflow-y: auto;
4435
+ outline: none;
4436
+ }
4437
+
4438
+ .pp-popup__textarea:focus {
4439
+ border-color: var(--pp-accent);
4440
+ }
4441
+
4442
+ .pp-popup__actions {
4443
+ display: flex;
4444
+ gap: 6px;
4445
+ justify-content: flex-end;
4446
+ }
4447
+
4448
+ .pp-popup__actions .pp-btn {
4449
+ height: 26px;
4450
+ padding: 0 10px;
4451
+ font-size: 12px;
4452
+ }
4453
+
4454
+ /* Selection label */
4455
+ .pp-selection-label {
4456
+ position: fixed;
4457
+ z-index: 2147483646;
4458
+ pointer-events: none;
4459
+ padding: 3px 8px;
4460
+ border-radius: 4px;
4461
+ background: var(--pp-accent);
4462
+ color: #fff;
4463
+ font-size: 11px;
4464
+ font-weight: 500;
4465
+ white-space: nowrap;
4466
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
4467
+ }
4468
+
4469
+ /* Context menu */
4470
+ .pp-context-menu {
4471
+ position: fixed;
4472
+ z-index: 2147483647;
4473
+ pointer-events: auto;
4474
+ background: var(--pp-bg-solid);
4475
+ border: 1px solid var(--pp-border);
4476
+ border-radius: var(--pp-radius-sm);
4477
+ box-shadow: var(--pp-shadow);
4478
+ padding: 4px;
4479
+ min-width: 180px;
4480
+ }
4481
+
4482
+ .pp-context-menu__item {
4483
+ display: flex;
4484
+ align-items: center;
4485
+ gap: 8px;
4486
+ padding: 6px 8px;
4487
+ border-radius: 4px;
4488
+ cursor: pointer;
4489
+ font-size: 12px;
4490
+ color: var(--pp-text);
4491
+ transition: background 0.1s;
4492
+ }
4493
+
4494
+ .pp-context-menu__item:hover {
4495
+ background: rgba(255, 255, 255, 0.06);
4496
+ }
4497
+
4498
+ .pp-context-menu__separator {
4499
+ height: 1px;
4500
+ background: var(--pp-border);
4501
+ margin: 4px 0;
4502
+ }
4503
+
4504
+ /* Prompt mode */
4505
+ .pp-prompt {
4506
+ position: fixed;
4507
+ z-index: 2147483647;
4508
+ pointer-events: auto;
4509
+ display: flex;
4510
+ gap: 6px;
4511
+ align-items: center;
4512
+ }
4513
+
4514
+ .pp-prompt__input {
4515
+ padding: 6px 10px;
4516
+ border: 1px solid var(--pp-accent);
4517
+ border-radius: var(--pp-radius-sm);
4518
+ background: var(--pp-bg);
4519
+ color: var(--pp-text);
4520
+ font-size: 13px;
4521
+ font-family: inherit;
4522
+ min-width: 240px;
4523
+ outline: none;
4524
+ backdrop-filter: blur(12px) saturate(180%);
4525
+ }
4526
+
4527
+ /* Settings panel */
4528
+ .pp-settings {
4529
+ display: flex;
4530
+ flex-direction: column;
4531
+ gap: 8px;
4532
+ padding-top: 8px;
4533
+ border-top: 1px solid var(--pp-border);
4534
+ }
4535
+
4536
+ .pp-settings__row {
4537
+ display: flex;
4538
+ align-items: center;
4539
+ justify-content: space-between;
4540
+ gap: 8px;
4541
+ }
4542
+
4543
+ .pp-settings__label {
4544
+ font-size: 12px;
4545
+ color: var(--pp-text);
4546
+ }
4547
+
4548
+ .pp-settings__value {
4549
+ font-size: 11px;
4550
+ color: var(--pp-text-muted);
4551
+ }
4552
+
4553
+ /* Toggle switch */
4554
+ .pp-toggle {
4555
+ position: relative;
4556
+ width: 32px;
4557
+ height: 18px;
4558
+ border-radius: 9px;
4559
+ background: var(--pp-border);
4560
+ cursor: pointer;
4561
+ transition: background 0.2s;
4562
+ }
4563
+
4564
+ .pp-toggle--active {
4565
+ background: var(--pp-accent);
4566
+ }
4567
+
4568
+ .pp-toggle__thumb {
4569
+ position: absolute;
4570
+ top: 2px;
4571
+ left: 2px;
4572
+ width: 14px;
4573
+ height: 14px;
4574
+ border-radius: 50%;
4575
+ background: #fff;
4576
+ transition: transform 0.2s;
4577
+ }
4578
+
4579
+ .pp-toggle--active .pp-toggle__thumb {
4580
+ transform: translateX(14px);
4581
+ }
4582
+
4583
+ /* Kbd hints */
4584
+ .pp-kbd {
4585
+ display: inline-flex;
4586
+ align-items: center;
4587
+ justify-content: center;
4588
+ padding: 1px 4px;
4589
+ border: 1px solid var(--pp-border);
4590
+ border-radius: 3px;
4591
+ background: rgba(255, 255, 255, 0.04);
4592
+ font-size: 10px;
4593
+ font-family: inherit;
4594
+ color: var(--pp-text-muted);
4595
+ line-height: 1;
4596
+ }
4597
+
4598
+ /* Mode tabs */
4599
+ .pp-mode-tabs {
4600
+ display: flex;
4601
+ gap: 2px;
4602
+ padding: 2px;
4603
+ background: rgba(255, 255, 255, 0.04);
4604
+ border-radius: var(--pp-radius-sm);
4605
+ }
4606
+
4607
+ .pp-mode-tab {
4608
+ flex: 1;
4609
+ display: flex;
4610
+ align-items: center;
4611
+ justify-content: center;
4612
+ gap: 4px;
4613
+ padding: 5px 8px;
4614
+ border: none;
4615
+ border-radius: 4px;
4616
+ background: transparent;
4617
+ color: var(--pp-text-muted);
4618
+ font-size: 11px;
4619
+ font-weight: 500;
4620
+ cursor: pointer;
4621
+ white-space: nowrap;
4622
+ }
4623
+
4624
+ .pp-mode-tab:hover {
4625
+ color: var(--pp-text);
4626
+ background: rgba(255, 255, 255, 0.04);
4627
+ }
4628
+
4629
+ .pp-mode-tab--active {
4630
+ background: rgba(255, 255, 255, 0.08);
4631
+ color: var(--pp-text);
4632
+ }
4633
+
4634
+ .pp-mode-tab__count {
4635
+ display: inline-flex;
4636
+ align-items: center;
4637
+ justify-content: center;
4638
+ min-width: 16px;
4639
+ height: 16px;
4640
+ padding: 0 4px;
4641
+ border-radius: 8px;
4642
+ background: var(--pp-accent);
4643
+ color: #fff;
4644
+ font-size: 10px;
4645
+ font-weight: 600;
4646
+ }
4647
+
4648
+ /* Draw tools bar */
4649
+ .pp-draw-tools {
4650
+ display: flex;
4651
+ align-items: center;
4652
+ gap: 2px;
4653
+ }
4654
+
4655
+ .pp-draw-tool {
4656
+ display: flex;
4657
+ align-items: center;
4658
+ justify-content: center;
4659
+ width: 32px;
4660
+ height: 32px;
4661
+ border: none;
4662
+ border-radius: var(--pp-radius-sm);
4663
+ background: transparent;
4664
+ color: var(--pp-text-muted);
4665
+ cursor: pointer;
4666
+ }
4667
+
4668
+ .pp-draw-tool:hover {
4669
+ background: rgba(255, 255, 255, 0.06);
4670
+ color: var(--pp-text);
4671
+ }
4672
+
4673
+ .pp-draw-tool--active {
4674
+ background: rgba(59, 130, 246, 0.15);
4675
+ color: var(--pp-accent);
4676
+ }
4677
+
4678
+ .pp-draw-tool:disabled {
4679
+ opacity: 0.3;
4680
+ cursor: default;
4681
+ }
4682
+
4683
+ /* Draw options row */
4684
+ .pp-draw-options {
4685
+ display: flex;
4686
+ align-items: center;
4687
+ justify-content: space-between;
4688
+ gap: 8px;
4689
+ }
4690
+
4691
+ .pp-draw-colors {
4692
+ display: flex;
4693
+ gap: 4px;
4694
+ }
4695
+
4696
+ .pp-color-swatch {
4697
+ width: 20px;
4698
+ height: 20px;
4699
+ border-radius: 50%;
4700
+ border: 2px solid transparent;
4701
+ cursor: pointer;
4702
+ padding: 0;
4703
+ }
4704
+
4705
+ .pp-color-swatch:hover {
4706
+ opacity: 0.85;
4707
+ }
4708
+
4709
+ .pp-color-swatch--active {
4710
+ border-color: #fff;
4711
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
4712
+ }
4713
+
4714
+ .pp-draw-widths {
4715
+ display: flex;
4716
+ gap: 4px;
4717
+ }
4718
+
4719
+ .pp-width-btn {
4720
+ display: flex;
4721
+ align-items: center;
4722
+ justify-content: center;
4723
+ width: 28px;
4724
+ height: 28px;
4725
+ border: none;
4726
+ border-radius: var(--pp-radius-sm);
4727
+ background: transparent;
4728
+ cursor: pointer;
4729
+ padding: 0;
4730
+ }
4731
+
4732
+ .pp-width-btn:hover {
4733
+ background: rgba(255, 255, 255, 0.06);
4734
+ }
4735
+
4736
+ .pp-width-btn--active {
4737
+ background: rgba(255, 255, 255, 0.1);
4738
+ outline: 1px solid var(--pp-border);
4739
+ }
4740
+
4741
+ /* Queue badge in toolbar header */
4742
+ .pp-toolbar__queue-badge {
4743
+ display: inline-flex;
4744
+ align-items: center;
4745
+ justify-content: center;
4746
+ min-width: 18px;
4747
+ height: 18px;
4748
+ padding: 0 5px;
4749
+ border-radius: 9px;
4750
+ background: var(--pp-warning);
4751
+ color: #000;
4752
+ font-size: 10px;
4753
+ font-weight: 700;
4754
+ }
4755
+
4756
+ /* Popup input row with mic */
4757
+ .pp-popup__input-row {
4758
+ position: relative;
4759
+ display: flex;
4760
+ align-items: flex-start;
4761
+ gap: 4px;
4762
+ }
4763
+
4764
+ .pp-popup__input-row .pp-popup__textarea {
4765
+ flex: 1;
4766
+ }
4767
+
4768
+ .pp-popup__mic {
4769
+ flex-shrink: 0;
4770
+ width: 32px;
4771
+ height: 32px;
4772
+ display: flex;
4773
+ align-items: center;
4774
+ justify-content: center;
4775
+ border-radius: 50%;
4776
+ margin-top: 4px;
4777
+ }
4778
+
4779
+ .pp-popup__mic--recording {
4780
+ color: var(--pp-danger) !important;
4781
+ background: rgba(239, 68, 68, 0.15) !important;
4782
+ animation: pp-mic-pulse 1.2s ease-in-out infinite;
4783
+ }
4784
+
4785
+ @keyframes pp-mic-pulse {
4786
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
4787
+ 50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
4788
+ }
4789
+
4790
+ /* Ghost button (Fix this) */
4791
+ .pp-btn--ghost {
4792
+ display: inline-flex;
4793
+ align-items: center;
4794
+ gap: 4px;
4795
+ padding: 3px 8px;
4796
+ border: none;
4797
+ border-radius: var(--pp-radius-sm);
4798
+ background: transparent;
4799
+ color: var(--pp-warning);
4800
+ font-size: 11px;
4801
+ font-weight: 500;
4802
+ cursor: pointer;
4803
+ }
4804
+
4805
+ .pp-btn--ghost:hover {
4806
+ background: rgba(234, 179, 8, 0.1);
4807
+ }
4808
+
4809
+ /* Text input popup for draw-mode text annotations */
4810
+ .pp-text-input-popup {
4811
+ position: fixed;
4812
+ z-index: 2147483647;
4813
+ pointer-events: auto;
4814
+ display: flex;
4815
+ align-items: center;
4816
+ gap: 6px;
4817
+ padding: 4px 8px;
4818
+ background: var(--pp-bg);
4819
+ border: 1px solid var(--pp-border);
4820
+ border-radius: var(--pp-radius-sm);
4821
+ box-shadow: var(--pp-shadow);
4822
+ backdrop-filter: blur(12px) saturate(180%);
4823
+ -webkit-backdrop-filter: blur(12px) saturate(180%);
4824
+ }
4825
+
4826
+ .pp-text-input-popup__indicator {
4827
+ width: 8px;
4828
+ height: 8px;
4829
+ border-radius: 50%;
4830
+ flex-shrink: 0;
4831
+ }
4832
+
4833
+ .pp-text-input-popup__input {
4834
+ border: none;
4835
+ background: transparent;
4836
+ color: var(--pp-text);
4837
+ font-size: 13px;
4838
+ font-family: inherit;
4839
+ outline: none;
4840
+ min-width: 200px;
4841
+ }
4842
+
4843
+ /* Scrollbar */
4844
+ ::-webkit-scrollbar {
4845
+ width: 4px;
4846
+ }
4847
+
4848
+ ::-webkit-scrollbar-track {
4849
+ background: transparent;
4850
+ }
4851
+
4852
+ ::-webkit-scrollbar-thumb {
4853
+ background: var(--pp-border);
4854
+ border-radius: 2px;
4855
+ }
4856
+ `;
4857
+
4855
4858
  // src/ui/mount.ts
4856
4859
  var CONTAINER_ID = "pinpoint-root";
4857
4860
  function mountPinpoint(config = {}, target = document.body) {
@@ -4921,4 +4924,4 @@ export {
4921
4924
  mountPinpoint,
4922
4925
  unmountPinpoint
4923
4926
  };
4924
- //# sourceMappingURL=chunk-6YK47AB5.js.map
4927
+ //# sourceMappingURL=chunk-HC724C43.js.map