@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/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
- .cf-pin {
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
- /* Agent-pushed pins pulse a ring so reviewers spot what the agent added. */
101
- .cf-pin.agent { border-style: dashed; }
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-bg);
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(16px) saturate(140%);
128
- box-shadow: 0 8px 28px rgba(0,0,0,0.5);
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
- background: var(--cf-bg);
150
- border: 1px solid var(--cf-border);
151
- border-radius: 14px;
152
- padding: 10px;
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(16px) saturate(140%);
155
- box-shadow: 0 16px 48px rgba(0,0,0,0.5);
156
- min-width: 220px;
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
- font-weight: 700; letter-spacing: 0.02em;
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: 8px; height: 8px; border-radius: 50%;
165
- background: var(--cf-accent);
166
- box-shadow: 0 0 10px var(--cf-accent);
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.06);
180
- border-radius: 9px; padding: 2px;
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 10px; border-radius: 7px; font: 600 12px -apple-system, system-ui;
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 4px rgba(0,0,0,0.3);
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
- background: var(--cf-bg);
217
- border: 1px solid var(--cf-border);
218
- border-radius: 14px;
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(16px) saturate(140%);
222
- box-shadow: 0 16px 48px rgba(0,0,0,0.55);
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 { font-size: 12px; }
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
  }