@ericrisco/rsc 3.3.1 β†’ 3.5.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.
Files changed (61) hide show
  1. package/README.md +3 -3
  2. package/manifest.json +43 -22
  3. package/package.json +1 -1
  4. package/scripts/lib/default-skill-floor.js +5 -1
  5. package/scripts/lib/domains.js +2 -2
  6. package/scripts/lib/retired-skills.js +4 -0
  7. package/scripts/rsc.js +1 -1
  8. package/skills/design/SKILL.md +4 -3
  9. package/skills/design/evals/cases.yaml +2 -2
  10. package/skills/ftd/SKILL.md +1 -1
  11. package/skills/react/SKILL.md +2 -1
  12. package/skills/ux/SKILL.md +149 -0
  13. package/skills/ux/THIRD_PARTY.md +32 -0
  14. package/skills/ux/evals/cases.yaml +40 -0
  15. package/skills/ux/references/flows.md +124 -0
  16. package/skills/ux/upstream/UPSTREAM.json +59 -0
  17. package/skills/ux/upstream/ux-designer/GUIDE.md +180 -0
  18. package/skills/ux/upstream/ux-designer/LICENSE +21 -0
  19. package/skills/ux/upstream/ux-designer/references/01-core-principles.md +251 -0
  20. package/skills/ux/upstream/ux-designer/references/02-laws-of-ux.md +330 -0
  21. package/skills/ux/upstream/ux-designer/references/03-accessibility.md +411 -0
  22. package/skills/ux/upstream/ux-designer/references/04-visual-design.md +433 -0
  23. package/skills/ux/upstream/ux-designer/references/05-information-architecture.md +432 -0
  24. package/skills/ux/upstream/ux-designer/references/06-interaction-design.md +495 -0
  25. package/skills/ux/upstream/ux-designer/references/07-forms-and-inputs.md +491 -0
  26. package/skills/ux/upstream/ux-designer/references/08-mobile-ux.md +539 -0
  27. package/skills/ux/upstream/ux-designer/references/09-ux-writing.md +493 -0
  28. package/skills/ux/upstream/ux-designer/references/10-user-research.md +533 -0
  29. package/skills/ux/upstream/ux-designer/references/11-design-systems.md +618 -0
  30. package/skills/ux/upstream/ux-designer/references/12a-presence-awareness.md +395 -0
  31. package/skills/ux/upstream/ux-designer/references/12b-conflict-resolution-sync.md +420 -0
  32. package/skills/ux/upstream/ux-designer/references/13a-canvas-navigation.md +388 -0
  33. package/skills/ux/upstream/ux-designer/references/13b-canvas-objects-performance.md +559 -0
  34. package/skills/ux/upstream/ux-designer/references/14-ai-ux-patterns.md +511 -0
  35. package/skills/ux/upstream/ux-designer/references/15-ethical-design.md +419 -0
  36. package/skills/ux/upstream/ux-designer/references/16-onboarding.md +430 -0
  37. package/skills/ux/upstream/ux-designer/references/17-notifications.md +461 -0
  38. package/skills/ux/upstream/ux-designer/references/18-data-visualization.md +453 -0
  39. package/skills/ux/upstream/ux-designer/references/19-search-ux.md +479 -0
  40. package/skills/ux/upstream/ux-designer/references/20-emotional-design.md +382 -0
  41. package/skills/ux/upstream/ux-designer/references/21-data-tables.md +629 -0
  42. package/skills/ux/upstream/ux-designer/references/22-performance-ux.md +626 -0
  43. package/skills/ux/upstream/ux-designer/references/23-internationalization.md +347 -0
  44. package/skills/ux/upstream/ux-designer/references/24-voice-and-multimodal.md +308 -0
  45. package/skills/ux/upstream/ux-designer/references/25a-barcode-camera-scanning.md +342 -0
  46. package/skills/ux/upstream/ux-designer/references/25b-barcode-scanner-workflows.md +412 -0
  47. package/skills/ux/upstream/ux-designer/references/25c-barcode-display.md +277 -0
  48. package/skills/ux/upstream/ux-usability-foundations/GUIDE.md +285 -0
  49. package/skills/ux/upstream/ux-usability-foundations/LICENSE +21 -0
  50. package/skills/ux/upstream/ux-usability-foundations/references/anti-patterns.md +267 -0
  51. package/skills/ux/upstream/ux-usability-foundations/references/checklists.md +130 -0
  52. package/skills/ux/upstream/ux-usability-foundations/references/decision-prompts.md +340 -0
  53. package/skills/ux/upstream/ux-usability-foundations/references/principle-cards.md +449 -0
  54. package/skills/worktrees/SKILL.md +19 -5
  55. package/targets/branch-guard.mjs +59 -4
  56. package/targets/clone-bootstrap.mjs +1 -1
  57. package/targets/session-memory-adapter.mjs +2 -2
  58. package/targets/team-safe-start.mjs +1 -0
  59. package/targets/worktree-reaper.mjs +14 -1
  60. package/skills/ui-engineering/SKILL.md +0 -113
  61. package/skills/ui-engineering/evals/cases.yaml +0 -38
@@ -0,0 +1,395 @@
1
+ # Collaborative UX: Presence & Awareness
2
+
3
+ Real-time collaboration UX focuses on enabling multiple users to work together seamlessly in shared digital spaces. Good collaborative UX creates "social translucence"β€”the ability to see and feel others' activities within digital environments.
4
+
5
+ ---
6
+
7
+ ## Contents
8
+
9
+ - Presence & Awareness
10
+ - Communication Features
11
+ - Viewport Coordination
12
+ - Key Metrics
13
+ - Anti-Patterns
14
+ - Sources
15
+
16
+ ---
17
+
18
+ ## Presence & Awareness
19
+
20
+ Awareness is "an understanding of the activities of others, which provides a context for your own activity" (Dourish & Bellotti, 1992).
21
+
22
+ ### Live Cursors
23
+
24
+ Live cursors show the real-time pointer position of collaborators, creating a sense of shared presence.
25
+
26
+ ```css
27
+ /* Live cursor component */
28
+ .live-cursor {
29
+ position: absolute;
30
+ pointer-events: none;
31
+ z-index: 1000;
32
+ transition: transform 50ms linear; /* Smooth interpolation */
33
+ }
34
+
35
+ .live-cursor__pointer {
36
+ width: 20px;
37
+ height: 20px;
38
+ /* Each user gets unique color */
39
+ }
40
+
41
+ .live-cursor__label {
42
+ position: absolute;
43
+ left: 16px;
44
+ top: 16px;
45
+ padding: 2px 8px;
46
+ border-radius: 4px;
47
+ font-size: 12px;
48
+ font-weight: 500;
49
+ white-space: nowrap;
50
+ max-width: 100px;
51
+ overflow: hidden;
52
+ text-overflow: ellipsis;
53
+ color: white;
54
+ /* Background matches cursor color */
55
+ }
56
+ ```
57
+
58
+ #### Best Practices
59
+
60
+ | Aspect | Recommendation |
61
+ |--------|---------------|
62
+ | Label length | Max 12 characters, truncate with ellipsis |
63
+ | Color assignment | Unique per user, consistent across session |
64
+ | Update frequency | 50-100ms for smooth movement |
65
+ | Visibility | Hide after 30-60s of inactivity |
66
+ | Scaling | Consider hiding cursors at extreme zoom levels |
67
+
68
+ #### When Cursors Become Too Many
69
+
70
+ ```
71
+ 1-5 users β†’ Show all cursors with labels
72
+ 6-10 users β†’ Show cursors, abbreviated labels
73
+ 11-20 users β†’ Show cursors without labels
74
+ 20+ users β†’ Consider hiding distant cursors or showing only nearby
75
+ ```
76
+
77
+ ### Avatar Stacks
78
+
79
+ Show who's currently viewing or editing a document.
80
+
81
+ ```html
82
+ <div class="avatar-stack">
83
+ <div class="avatar" style="background: #e63946;" title="Alice">A</div>
84
+ <div class="avatar" style="background: #2a9d8f;" title="Bob">B</div>
85
+ <div class="avatar" style="background: #e9c46a;" title="Carol">C</div>
86
+ <div class="avatar-overflow">+3</div>
87
+ </div>
88
+ ```
89
+
90
+ ```css
91
+ .avatar-stack {
92
+ display: flex;
93
+ flex-direction: row-reverse; /* Newest on left */
94
+ }
95
+
96
+ .avatar {
97
+ width: 32px;
98
+ height: 32px;
99
+ border-radius: 50%;
100
+ border: 2px solid white;
101
+ margin-left: -8px; /* Overlap */
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ font-size: 14px;
106
+ font-weight: 600;
107
+ color: white;
108
+ }
109
+
110
+ .avatar-overflow {
111
+ background: #6b7280;
112
+ /* Same styling as .avatar */
113
+ }
114
+ ```
115
+
116
+ #### Guidelines
117
+
118
+ - Show 3-5 avatars maximum before overflow
119
+ - Use "+N" pattern for additional users
120
+ - Clicking should reveal full list
121
+ - Consider adding online/away status indicators
122
+
123
+ ### Typing Indicators
124
+
125
+ Show when collaborators are actively editing.
126
+
127
+ ```javascript
128
+ // Typing indicator with debounce
129
+ let typingTimeout;
130
+
131
+ function handleInput() {
132
+ broadcastTyping(true);
133
+ clearTimeout(typingTimeout);
134
+ typingTimeout = setTimeout(() => {
135
+ broadcastTyping(false);
136
+ }, 2000); // Stop after 2s of inactivity
137
+ }
138
+ ```
139
+
140
+ ```css
141
+ /* Typing indicator animation */
142
+ .typing-indicator {
143
+ display: flex;
144
+ gap: 4px;
145
+ padding: 8px 12px;
146
+ }
147
+
148
+ .typing-indicator__dot {
149
+ width: 8px;
150
+ height: 8px;
151
+ border-radius: 50%;
152
+ background: #6b7280;
153
+ animation: typing-bounce 1.4s infinite ease-in-out both;
154
+ }
155
+
156
+ .typing-indicator__dot:nth-child(1) { animation-delay: 0s; }
157
+ .typing-indicator__dot:nth-child(2) { animation-delay: 0.16s; }
158
+ .typing-indicator__dot:nth-child(3) { animation-delay: 0.32s; }
159
+
160
+ @keyframes typing-bounce {
161
+ 0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
162
+ 40% { transform: scale(1); opacity: 1; }
163
+ }
164
+ ```
165
+
166
+ ### Activity Feeds
167
+
168
+ Show recent changes and who made them.
169
+
170
+ ```
171
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
172
+ β”‚ Activity β”‚
173
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
174
+ β”‚ 🟒 Alice edited "Header component" 2m ago β”‚
175
+ β”‚ πŸ”΅ Bob added comment on "Login flow" 5m ago β”‚
176
+ β”‚ 🟑 Carol joined the document 12m ago β”‚
177
+ β”‚ 🟒 Alice created "Footer component" 15m ago β”‚
178
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Communication Features
184
+
185
+ ### Threaded Comments
186
+
187
+ ```css
188
+ /* Comment thread styling */
189
+ .comment-thread {
190
+ border-left: 3px solid #3b82f6;
191
+ padding-left: 12px;
192
+ margin: 8px 0;
193
+ }
194
+
195
+ .comment {
196
+ padding: 8px;
197
+ margin-bottom: 4px;
198
+ background: #f3f4f6;
199
+ border-radius: 8px;
200
+ }
201
+
202
+ .comment__header {
203
+ display: flex;
204
+ justify-content: space-between;
205
+ font-size: 12px;
206
+ color: #6b7280;
207
+ margin-bottom: 4px;
208
+ }
209
+
210
+ .comment__reply-form {
211
+ margin-top: 8px;
212
+ padding-top: 8px;
213
+ border-top: 1px solid #e5e7eb;
214
+ }
215
+ ```
216
+
217
+ ### Contextual Comments (Annotations)
218
+
219
+ Pin comments to specific elements or canvas positions.
220
+
221
+ ```javascript
222
+ // Attach comment to element
223
+ const annotation = {
224
+ id: "comment-123",
225
+ targetElement: "component-456",
226
+ position: { x: 100, y: 50 }, // Relative to target
227
+ thread: [
228
+ { author: "alice", text: "Should this be blue?", timestamp: "..." },
229
+ { author: "bob", text: "Good idea, updating now", timestamp: "..." }
230
+ ],
231
+ resolved: false
232
+ };
233
+ ```
234
+
235
+ ### Emoji Reactions
236
+
237
+ Quick feedback without requiring a full comment.
238
+
239
+ ```html
240
+ <div class="reaction-bar">
241
+ <button class="reaction" data-emoji="πŸ‘">πŸ‘ <span>3</span></button>
242
+ <button class="reaction" data-emoji="❀️">❀️ <span>1</span></button>
243
+ <button class="reaction" data-emoji="πŸŽ‰">πŸŽ‰ <span>2</span></button>
244
+ <button class="reaction reaction--add">+</button>
245
+ </div>
246
+ ```
247
+
248
+ ### @Mentions
249
+
250
+ Notify specific collaborators.
251
+
252
+ ```javascript
253
+ // Mention autocomplete
254
+ function handleMentionTrigger(text) {
255
+ if (text.includes('@')) {
256
+ const query = text.split('@').pop();
257
+ const matches = collaborators.filter(c =>
258
+ c.name.toLowerCase().includes(query.toLowerCase())
259
+ );
260
+ showMentionSuggestions(matches);
261
+ }
262
+ }
263
+ ```
264
+
265
+ ### Anonymous Voting
266
+
267
+ Prevent groupthink by hiding voter identity.
268
+
269
+ ```
270
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
271
+ β”‚ Vote: Which design direction? β”‚
272
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
273
+ β”‚ Option A: Bold colors β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘ 4 β”‚
274
+ β”‚ Option B: Minimal β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 5 β”‚
275
+ β”‚ Option C: Playful β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘ 2 β”‚
276
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
277
+ β”‚ 11 votes total β€’ Voting ends in 5:00 β”‚
278
+ β”‚ Your vote: Option B β”‚
279
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Viewport Coordination
285
+
286
+ ### Follow Mode
287
+
288
+ Lock your viewport to follow another user's view.
289
+
290
+ ```javascript
291
+ // Follow mode implementation
292
+ class ViewportFollower {
293
+ constructor() {
294
+ this.following = null;
295
+ }
296
+
297
+ follow(userId) {
298
+ this.following = userId;
299
+ this.showFollowingIndicator(userId);
300
+
301
+ // Subscribe to their viewport changes
302
+ subscribeToViewport(userId, (viewport) => {
303
+ animateToViewport(viewport, { duration: 300 });
304
+ });
305
+ }
306
+
307
+ stopFollowing() {
308
+ this.following = null;
309
+ this.hideFollowingIndicator();
310
+ unsubscribeFromViewport();
311
+ }
312
+ }
313
+ ```
314
+
315
+ ```css
316
+ /* Following indicator */
317
+ .viewport--following {
318
+ border: 3px solid var(--user-color);
319
+ border-radius: 8px;
320
+ }
321
+
322
+ .following-banner {
323
+ position: fixed;
324
+ top: 60px;
325
+ left: 50%;
326
+ transform: translateX(-50%);
327
+ padding: 8px 16px;
328
+ background: var(--user-color);
329
+ color: white;
330
+ border-radius: 20px;
331
+ font-size: 14px;
332
+ }
333
+ ```
334
+
335
+ ### Spotlight / Presenter Mode
336
+
337
+ Present to collaborators by controlling their view.
338
+
339
+ ```
340
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
341
+ β”‚ 🎯 Alice is presenting β”‚
342
+ β”‚ Following her view β€’ Click anywhere to stop [Stop] β”‚
343
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
344
+ ```
345
+
346
+ **Implementation:**
347
+ 1. Presenter clicks "Spotlight me"
348
+ 2. All viewers receive notification
349
+ 3. Viewers have 3-5 seconds to opt out
350
+ 4. Non-opted-out viewers' viewports lock to presenter
351
+ 5. Presenter's cursor becomes more prominent
352
+
353
+ ### Jump to User
354
+
355
+ Navigate to where a collaborator is working.
356
+
357
+ ```javascript
358
+ function jumpToUser(userId) {
359
+ const userViewport = getUserViewport(userId);
360
+ animateToViewport(userViewport, {
361
+ duration: 500,
362
+ easing: 'ease-out'
363
+ });
364
+ highlightUserCursor(userId, { duration: 2000 });
365
+ }
366
+ ```
367
+
368
+ ---
369
+
370
+ ## Key Metrics
371
+
372
+ | Metric | Value | Context |
373
+ |--------|-------|---------|
374
+ | Cursor update rate | 50-100ms | Smooth movement perception |
375
+ | Typing indicator timeout | 2-3s | After last keystroke |
376
+ | Avatar stack max | 3-5 visible | Before "+N" overflow |
377
+ | Cursor label max | 12 chars | Truncate longer names |
378
+
379
+ ---
380
+
381
+ ## Anti-Patterns
382
+
383
+ 1. **No presence indicators** - Users feel alone, cause conflicts
384
+ 2. **Cursor overload** - Too many cursors create visual noise
385
+ 3. **Forced following** - Lock users to presenter without consent
386
+ 4. **Comment spam** - No way to resolve or archive discussions
387
+
388
+ ---
389
+
390
+ ## Sources
391
+
392
+ - [Liveblocks - Presence Documentation](https://liveblocks.io/presence)
393
+ - [Ably - Collaborative UX Best Practices](https://ably.com/blog/collaborative-ux-best-practices)
394
+ - [Figma - How Multiplayer Technology Works](https://www.figma.com/blog/how-figmas-multiplayer-technology-works/)
395
+ - Dourish, P. & Bellotti, V. (1992). "Awareness and Coordination in Shared Workspaces"