@coframe-gtm/annotations 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/inject/bundle-source.generated.ts +1 -1
- package/src/output.ts +1 -1
- package/src/picker.ts +23 -5
- package/src/store.ts +34 -0
- package/src/ui/Avatar.ts +62 -0
- package/src/ui/Composer.ts +51 -11
- package/src/ui/Cursors.ts +1 -5
- package/src/ui/Pins.ts +91 -21
- package/src/ui/ThreadPanel.ts +22 -10
- package/src/ui/Toolbar.ts +202 -20
- package/src/ui/brand.ts +16 -0
- package/src/ui/helpers.ts +89 -0
- package/src/ui/overlay.ts +8 -0
- package/src/ui/styles.ts +194 -39
package/src/ui/styles.ts
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export const STYLES = `
|
|
9
|
+
/* Box-sizing reset — the host page's reset is scoped to its own tree and
|
|
10
|
+
doesn't reach the overlay, so width:100% controls + padding would
|
|
11
|
+
otherwise overflow their popups. Keep everything border-box. */
|
|
12
|
+
.cf-overlay, .cf-overlay *, .cf-overlay *::before, .cf-overlay *::after {
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
}
|
|
9
15
|
.cf-overlay {
|
|
10
16
|
position: fixed;
|
|
11
17
|
inset: 0;
|
|
@@ -17,12 +23,18 @@ export const STYLES = `
|
|
|
17
23
|
--cf-border: rgba(255, 255, 255, 0.1);
|
|
18
24
|
--cf-muted: rgba(255, 255, 255, 0.55);
|
|
19
25
|
--cf-accent: #a78bfa;
|
|
26
|
+
/* Liquid-glass fill for popups/panels — low alpha so the backdrop blur
|
|
27
|
+
actually reads as frosted glass instead of a solid black box. */
|
|
28
|
+
--cf-glass: rgba(24, 24, 34, 0.55);
|
|
29
|
+
--cf-glass-border: rgba(255, 255, 255, 0.14);
|
|
20
30
|
}
|
|
21
31
|
.cf-overlay[data-theme="light"] {
|
|
22
32
|
color: #18181b;
|
|
23
33
|
--cf-bg: rgba(252, 252, 253, 0.97);
|
|
24
34
|
--cf-border: rgba(0, 0, 0, 0.1);
|
|
25
35
|
--cf-muted: rgba(0, 0, 0, 0.5);
|
|
36
|
+
--cf-glass: rgba(252, 252, 253, 0.60);
|
|
37
|
+
--cf-glass-border: rgba(0, 0, 0, 0.10);
|
|
26
38
|
}
|
|
27
39
|
|
|
28
40
|
/* Hover highlight + multi-select boxes */
|
|
@@ -77,8 +89,29 @@ export const STYLES = `
|
|
|
77
89
|
.cf-cursor-agent .cf-cursor-label { color: #0b0b0f; }
|
|
78
90
|
|
|
79
91
|
/* Pins */
|
|
80
|
-
|
|
92
|
+
/* Outline box hugging the annotated element (so it's obvious what the
|
|
93
|
+
annotation refers to). Colour-coded per author via --cf-pin. */
|
|
94
|
+
/* A multi-element annotation renders several .cf-anno outlines wrapped in
|
|
95
|
+
one group — display:contents so the wrapper itself adds no layout box and
|
|
96
|
+
the fixed-positioned outlines anchor straight to the viewport. */
|
|
97
|
+
.cf-anno-group { display: contents; }
|
|
98
|
+
.cf-anno {
|
|
81
99
|
position: fixed;
|
|
100
|
+
pointer-events: none;
|
|
101
|
+
border: 1.5px solid var(--cf-pin, #a78bfa);
|
|
102
|
+
border-radius: 7px;
|
|
103
|
+
background: color-mix(in srgb, var(--cf-pin, #a78bfa) 9%, transparent);
|
|
104
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--cf-pin, #a78bfa) 15%, transparent);
|
|
105
|
+
z-index: 2;
|
|
106
|
+
}
|
|
107
|
+
/* Entrance animation plays only on first render (.cf-fresh), never on the
|
|
108
|
+
scroll/resize re-renders — otherwise the box flickers while scrolling. */
|
|
109
|
+
.cf-anno.cf-fresh { animation: cf-rise .18s cubic-bezier(.16,1,.3,1) both; }
|
|
110
|
+
.cf-anno.agent { border-style: dashed; }
|
|
111
|
+
.cf-anno.resolved { opacity: 0.4; }
|
|
112
|
+
.cf-pin {
|
|
113
|
+
position: absolute;
|
|
114
|
+
top: -11px; left: -11px;
|
|
82
115
|
width: 22px; height: 22px;
|
|
83
116
|
border-radius: 50% 50% 50% 2px;
|
|
84
117
|
background: var(--cf-pin, #a78bfa);
|
|
@@ -92,21 +125,14 @@ export const STYLES = `
|
|
|
92
125
|
z-index: 3;
|
|
93
126
|
transition: transform .12s cubic-bezier(.34,1.56,.64,1);
|
|
94
127
|
padding: 0;
|
|
95
|
-
/* Pop in when a pin first renders so new annotations are obvious. */
|
|
96
|
-
animation: cf-pin-pop .32s cubic-bezier(.34,1.56,.64,1) both;
|
|
97
128
|
}
|
|
129
|
+
/* Pop in only when a pin first renders (.cf-fresh) — not on the scroll
|
|
130
|
+
re-renders, which would otherwise replay the pop on every tick. */
|
|
131
|
+
.cf-pin.cf-fresh { animation: cf-pin-pop .32s cubic-bezier(.34,1.56,.64,1) both; }
|
|
98
132
|
.cf-pin:hover { transform: scale(1.2); }
|
|
99
133
|
.cf-pin.resolved { opacity: 0.45; }
|
|
100
|
-
/*
|
|
101
|
-
|
|
102
|
-
.cf-pin.agent::after {
|
|
103
|
-
content: "";
|
|
104
|
-
position: absolute; inset: -4px;
|
|
105
|
-
border-radius: inherit;
|
|
106
|
-
border: 2px solid var(--cf-pin, #a78bfa);
|
|
107
|
-
animation: cf-pin-ring 1.6s ease-out 3;
|
|
108
|
-
pointer-events: none;
|
|
109
|
-
}
|
|
134
|
+
/* Human vs agent reads from the box outline (solid vs dashed) + the pin
|
|
135
|
+
glyph (number vs initial) + colour — no extra per-pin chrome. */
|
|
110
136
|
|
|
111
137
|
/* Hover-to-preview card — shown next to a pin on mouseenter. */
|
|
112
138
|
.cf-pin-preview {
|
|
@@ -115,8 +141,8 @@ export const STYLES = `
|
|
|
115
141
|
max-width: 240px;
|
|
116
142
|
width: max-content;
|
|
117
143
|
pointer-events: none;
|
|
118
|
-
background: var(--cf-
|
|
119
|
-
border: 1px solid var(--cf-border);
|
|
144
|
+
background: var(--cf-glass);
|
|
145
|
+
border: 1px solid var(--cf-glass-border);
|
|
120
146
|
border-radius: 9px;
|
|
121
147
|
padding: 7px 10px;
|
|
122
148
|
font: 500 12px -apple-system, system-ui;
|
|
@@ -124,8 +150,11 @@ export const STYLES = `
|
|
|
124
150
|
color: #f4f4f5;
|
|
125
151
|
white-space: normal;
|
|
126
152
|
overflow-wrap: anywhere;
|
|
127
|
-
backdrop-filter: blur(
|
|
128
|
-
|
|
153
|
+
-webkit-backdrop-filter: blur(24px) saturate(180%);
|
|
154
|
+
backdrop-filter: blur(24px) saturate(180%);
|
|
155
|
+
box-shadow:
|
|
156
|
+
0 8px 28px rgba(0,0,0,0.4),
|
|
157
|
+
inset 0 1px 0 rgba(255,255,255,0.18);
|
|
129
158
|
z-index: 7;
|
|
130
159
|
animation: cf-rise .14s cubic-bezier(.16,1,.3,1) both;
|
|
131
160
|
}
|
|
@@ -146,24 +175,83 @@ export const STYLES = `
|
|
|
146
175
|
position: fixed;
|
|
147
176
|
left: 16px; bottom: 16px;
|
|
148
177
|
pointer-events: auto;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
border
|
|
152
|
-
|
|
178
|
+
/* Liquid glass — translucent, frosted, with a bright top edge. */
|
|
179
|
+
background: rgba(24,24,34,0.52);
|
|
180
|
+
border: 1px solid rgba(255,255,255,0.14);
|
|
181
|
+
border-radius: 17px;
|
|
182
|
+
padding: 9px;
|
|
153
183
|
display: flex; flex-direction: column; gap: 8px;
|
|
154
|
-
backdrop-filter: blur(
|
|
155
|
-
|
|
156
|
-
|
|
184
|
+
-webkit-backdrop-filter: blur(30px) saturate(185%);
|
|
185
|
+
backdrop-filter: blur(30px) saturate(185%);
|
|
186
|
+
box-shadow:
|
|
187
|
+
0 18px 50px rgba(0,0,0,0.34),
|
|
188
|
+
inset 0 1px 0 rgba(255,255,255,0.22),
|
|
189
|
+
inset 0 -1px 0 rgba(0,0,0,0.22);
|
|
157
190
|
z-index: 4;
|
|
158
191
|
}
|
|
159
192
|
.cf-toolbar-head {
|
|
160
193
|
display: flex; align-items: center; gap: 7px;
|
|
161
|
-
|
|
194
|
+
cursor: grab; user-select: none; touch-action: none;
|
|
195
|
+
}
|
|
196
|
+
.cf-toolbar-head:active { cursor: grabbing; }
|
|
197
|
+
/* Visible drag affordance — signals the panel can be moved. */
|
|
198
|
+
.cf-grip {
|
|
199
|
+
flex: 0 0 auto; color: var(--cf-muted);
|
|
200
|
+
font-size: 13px; line-height: 1; letter-spacing: -2px; opacity: 0.5;
|
|
201
|
+
}
|
|
202
|
+
.cf-toolbar-head:hover .cf-grip { opacity: 0.85; }
|
|
203
|
+
/* Logo button — tap to collapse back to the puck. */
|
|
204
|
+
.cf-collapse {
|
|
205
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
206
|
+
width: 26px; height: 26px; flex: 0 0 auto; padding: 0;
|
|
207
|
+
border: 0; border-radius: 8px; cursor: pointer;
|
|
208
|
+
/* Light tile so a dark brand logo reads on the dark panel. */
|
|
209
|
+
background: #fff;
|
|
210
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
|
|
211
|
+
}
|
|
212
|
+
.cf-collapse:hover { filter: brightness(0.94); }
|
|
213
|
+
.cf-brand {
|
|
214
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
215
|
+
width: 22px; height: 22px; flex: 0 0 auto; pointer-events: none;
|
|
216
|
+
}
|
|
217
|
+
.cf-brand svg { width: 18px; height: 18px; display: block; }
|
|
218
|
+
.cf-toolbar.cf-dragging {
|
|
219
|
+
box-shadow: 0 24px 64px rgba(0,0,0,0.6);
|
|
220
|
+
transition: none;
|
|
162
221
|
}
|
|
163
222
|
.cf-logo-dot {
|
|
164
|
-
width:
|
|
165
|
-
background: var(--cf-accent);
|
|
166
|
-
|
|
223
|
+
width: 9px; height: 9px; border-radius: 50%;
|
|
224
|
+
background: var(--cf-accent); box-shadow: 0 0 10px var(--cf-accent);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Collapsed FAB — a draggable logo puck; tap to expand. */
|
|
228
|
+
.cf-fab {
|
|
229
|
+
position: fixed; left: 16px; bottom: 16px;
|
|
230
|
+
width: 48px; height: 48px; border-radius: 16px;
|
|
231
|
+
pointer-events: auto; cursor: grab; user-select: none; touch-action: none;
|
|
232
|
+
display: flex; align-items: center; justify-content: center;
|
|
233
|
+
/* Liquid glass puck — frosted light so the dark mark reads. */
|
|
234
|
+
background: rgba(255,255,255,0.66);
|
|
235
|
+
-webkit-backdrop-filter: blur(22px) saturate(185%);
|
|
236
|
+
backdrop-filter: blur(22px) saturate(185%);
|
|
237
|
+
box-shadow:
|
|
238
|
+
0 12px 34px rgba(0,0,0,0.20),
|
|
239
|
+
inset 0 1px 0 rgba(255,255,255,0.95),
|
|
240
|
+
0 0 0 0.5px rgba(0,0,0,0.06);
|
|
241
|
+
z-index: 4;
|
|
242
|
+
transition: transform .13s cubic-bezier(.34,1.56,.64,1), box-shadow .15s ease;
|
|
243
|
+
}
|
|
244
|
+
.cf-fab:hover { transform: scale(1.06); }
|
|
245
|
+
.cf-fab.cf-dragging { cursor: grabbing; transition: none; box-shadow: 0 18px 44px rgba(0,0,0,0.42); }
|
|
246
|
+
.cf-fab .cf-brand { width: 28px; height: 28px; cursor: inherit; }
|
|
247
|
+
.cf-fab .cf-brand svg { width: 24px; height: 24px; }
|
|
248
|
+
.cf-fab-badge {
|
|
249
|
+
position: absolute; top: -5px; right: -5px;
|
|
250
|
+
min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box;
|
|
251
|
+
border-radius: 9px; background: var(--cf-accent); color: #fff;
|
|
252
|
+
font: 800 10px -apple-system, system-ui;
|
|
253
|
+
display: flex; align-items: center; justify-content: center;
|
|
254
|
+
box-shadow: 0 0 0 2px var(--cf-bg);
|
|
167
255
|
}
|
|
168
256
|
.cf-count {
|
|
169
257
|
margin-left: auto;
|
|
@@ -174,24 +262,45 @@ export const STYLES = `
|
|
|
174
262
|
}
|
|
175
263
|
.cf-overlay[data-theme="light"] .cf-count { background: rgba(0,0,0,0.06); }
|
|
176
264
|
|
|
265
|
+
/* View / Comment reads as a pill switch — rounded track + sliding pill. */
|
|
177
266
|
.cf-seg {
|
|
178
267
|
display: flex; gap: 2px;
|
|
179
|
-
background: rgba(255,255,255,0.
|
|
180
|
-
border-radius:
|
|
268
|
+
background: rgba(255,255,255,0.07);
|
|
269
|
+
border-radius: 999px; padding: 3px;
|
|
181
270
|
}
|
|
182
271
|
.cf-overlay[data-theme="light"] .cf-seg { background: rgba(0,0,0,0.05); }
|
|
183
272
|
.cf-seg-btn {
|
|
184
273
|
flex: 1; border: none; background: transparent; color: var(--cf-muted);
|
|
185
|
-
padding: 5px
|
|
274
|
+
padding: 5px 14px; border-radius: 999px; cursor: pointer;
|
|
275
|
+
font: 600 12px -apple-system, system-ui;
|
|
276
|
+
transition: color .15s ease, background .2s ease;
|
|
186
277
|
}
|
|
278
|
+
.cf-seg-btn:hover { color: #fff; }
|
|
187
279
|
.cf-seg-btn.on {
|
|
188
280
|
background: var(--cf-accent); color: #fff;
|
|
189
|
-
box-shadow: 0 1px
|
|
281
|
+
box-shadow: 0 1px 5px rgba(124,92,255,0.45);
|
|
282
|
+
}
|
|
283
|
+
/* Suggestions navigator — count + jump to each annotation. */
|
|
284
|
+
.cf-nav {
|
|
285
|
+
display: flex; align-items: center; justify-content: space-between; gap: 6px;
|
|
286
|
+
background: rgba(255,255,255,0.05); border-radius: 10px; padding: 2px 3px;
|
|
190
287
|
}
|
|
288
|
+
.cf-nav-btn {
|
|
289
|
+
border: 0; background: transparent; color: var(--cf-muted); cursor: pointer;
|
|
290
|
+
width: 24px; height: 22px; border-radius: 7px; font-size: 16px; line-height: 1; padding: 0;
|
|
291
|
+
}
|
|
292
|
+
.cf-nav-btn:hover { background: rgba(255,255,255,0.1); color: #fff; }
|
|
293
|
+
.cf-nav-label { font: 700 11px -apple-system, system-ui; color: var(--cf-muted); }
|
|
191
294
|
.cf-tools .cf-seg-btn.on { background: rgba(255,255,255,0.16); color: #fff; }
|
|
192
295
|
.cf-overlay[data-theme="light"] .cf-tools .cf-seg-btn.on { background: rgba(0,0,0,0.12); color: #111; }
|
|
193
296
|
.cf-hint { font-size: 11px; color: var(--cf-muted); padding: 0 2px; }
|
|
194
297
|
.cf-commit { width: 100%; }
|
|
298
|
+
.cf-launch {
|
|
299
|
+
width: 100%; border: 0; margin-top: 2px;
|
|
300
|
+
background: linear-gradient(135deg, #7c5cff, #3ecf8e);
|
|
301
|
+
box-shadow: 0 6px 18px rgba(124,92,255,0.35);
|
|
302
|
+
}
|
|
303
|
+
.cf-launch:hover { filter: brightness(1.07); }
|
|
195
304
|
|
|
196
305
|
/* Buttons */
|
|
197
306
|
.cf-btn {
|
|
@@ -213,13 +322,20 @@ export const STYLES = `
|
|
|
213
322
|
left: 16px; bottom: 92px;
|
|
214
323
|
width: 320px;
|
|
215
324
|
pointer-events: auto;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
325
|
+
/* Liquid glass — translucent + heavily frosted with a bright top edge,
|
|
326
|
+
matching the toolbar/FAB. The low-alpha fill is what lets the blur
|
|
327
|
+
read as glass rather than a solid black box. */
|
|
328
|
+
background: var(--cf-glass);
|
|
329
|
+
border: 1px solid var(--cf-glass-border);
|
|
330
|
+
border-radius: 16px;
|
|
219
331
|
padding: 12px;
|
|
220
332
|
display: flex; flex-direction: column; gap: 10px;
|
|
221
|
-
backdrop-filter: blur(
|
|
222
|
-
|
|
333
|
+
-webkit-backdrop-filter: blur(30px) saturate(185%);
|
|
334
|
+
backdrop-filter: blur(30px) saturate(185%);
|
|
335
|
+
box-shadow:
|
|
336
|
+
0 18px 50px rgba(0,0,0,0.40),
|
|
337
|
+
inset 0 1px 0 rgba(255,255,255,0.22),
|
|
338
|
+
inset 0 -1px 0 rgba(0,0,0,0.22);
|
|
223
339
|
z-index: 5;
|
|
224
340
|
animation: cf-rise .2s cubic-bezier(.16,1,.3,1) both;
|
|
225
341
|
}
|
|
@@ -241,6 +357,13 @@ export const STYLES = `
|
|
|
241
357
|
width: 22px; height: 22px; border-radius: 6px;
|
|
242
358
|
}
|
|
243
359
|
.cf-icon-btn:hover { background: rgba(255,255,255,0.08); }
|
|
360
|
+
/* Clear / erase-board — small text button after the count. */
|
|
361
|
+
.cf-clear {
|
|
362
|
+
margin-left: 4px; width: auto; height: auto; padding: 3px 8px;
|
|
363
|
+
font: 700 10px -apple-system, system-ui; text-transform: uppercase;
|
|
364
|
+
letter-spacing: 0.05em;
|
|
365
|
+
}
|
|
366
|
+
.cf-clear:hover { color: #fff; }
|
|
244
367
|
|
|
245
368
|
.cf-textarea {
|
|
246
369
|
width: 100%; min-height: 72px; resize: vertical;
|
|
@@ -269,7 +392,29 @@ export const STYLES = `
|
|
|
269
392
|
border-color: var(--cf-chip, var(--cf-accent));
|
|
270
393
|
color: #fff;
|
|
271
394
|
}
|
|
272
|
-
.cf-popup-actions { display: flex; gap: 8px; justify-content: flex-end; }
|
|
395
|
+
.cf-popup-actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; }
|
|
396
|
+
|
|
397
|
+
/* Composer grows out of the floater — the WAAPI morph drives it, so drop
|
|
398
|
+
the CSS keyframe to avoid a double animation. */
|
|
399
|
+
.cf-popup.cf-morph { animation: none; }
|
|
400
|
+
/* The logo in the popup head — the floater mark that flew over + opened. */
|
|
401
|
+
.cf-popup-brand {
|
|
402
|
+
width: 20px; height: 20px; flex: 0 0 auto;
|
|
403
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
404
|
+
background: #fff; border-radius: 6px; box-shadow: 0 1px 2px rgba(0,0,0,0.25);
|
|
405
|
+
}
|
|
406
|
+
.cf-popup-brand svg { width: 15px; height: 15px; display: block; }
|
|
407
|
+
/* Intent/severity disclosure — minimal by default. */
|
|
408
|
+
.cf-details { display: flex; flex-direction: column; gap: 10px; }
|
|
409
|
+
.cf-details[hidden] { display: none; }
|
|
410
|
+
.cf-disclose {
|
|
411
|
+
margin-right: auto; border: 0; background: transparent; color: var(--cf-muted);
|
|
412
|
+
font: 600 11px -apple-system, system-ui; cursor: pointer;
|
|
413
|
+
padding: 6px 6px; border-radius: 7px;
|
|
414
|
+
}
|
|
415
|
+
.cf-disclose:hover, .cf-disclose.on { color: #fff; background: rgba(255,255,255,0.06); }
|
|
416
|
+
.cf-overlay[data-theme="light"] .cf-disclose:hover,
|
|
417
|
+
.cf-overlay[data-theme="light"] .cf-disclose.on { color: #111; background: rgba(0,0,0,0.05); }
|
|
273
418
|
|
|
274
419
|
/* Thread */
|
|
275
420
|
.cf-thread-body {
|
|
@@ -278,7 +423,17 @@ export const STYLES = `
|
|
|
278
423
|
}
|
|
279
424
|
.cf-msg { display: flex; flex-direction: column; gap: 3px; }
|
|
280
425
|
.cf-msg-meta { display: flex; align-items: center; gap: 6px; }
|
|
281
|
-
.cf-avatar {
|
|
426
|
+
.cf-avatar {
|
|
427
|
+
width: 20px; height: 20px; flex: 0 0 auto;
|
|
428
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
429
|
+
border-radius: 50%; overflow: hidden;
|
|
430
|
+
font: 800 9px -apple-system, system-ui; letter-spacing: 0.02em;
|
|
431
|
+
color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,0.25);
|
|
432
|
+
box-shadow: 0 0 0 1.5px rgba(255,255,255,0.14), 0 1px 2px rgba(0,0,0,0.3);
|
|
433
|
+
}
|
|
434
|
+
/* Agents read as a distinct rounded "logo" tile; humans stay round. */
|
|
435
|
+
.cf-avatar-agent { border-radius: 7px; }
|
|
436
|
+
.cf-avatar-img { width: 100%; height: 100%; object-fit: cover; }
|
|
282
437
|
.cf-msg-name {
|
|
283
438
|
font: 700 11px -apple-system, system-ui; color: var(--cf-muted);
|
|
284
439
|
}
|