@spawnite/assets 0.1.0-beta.15

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.
@@ -0,0 +1,620 @@
1
+ {
2
+ "version": "2026-10-03",
3
+ "units": {
4
+ "time": "ms from the start of the state or moment",
5
+ "move": "cw = card widths (works in world units), pt = points on a 390 by 844 phone screen (for 2D overlay layers)",
6
+ "rotate": "degrees",
7
+ "easing": "names refer to tokens.json easing"
8
+ },
9
+ "reducedMotion": "Stop loops, jump moments to their end state, make slides instant. Turn changes still show through the timer ring, the spotlight position and the is playing pill.",
10
+
11
+ "cardStates": {
12
+ "idle": {
13
+ "static": true,
14
+ "note": "Resting in the fan. Only the top left index has to read."
15
+ },
16
+
17
+ "hint": {
18
+ "loop": true,
19
+ "layers": {
20
+ "edge": {
21
+ "type": "outline",
22
+ "color": "#FFFFFF",
23
+ "widthCw": 0.036
24
+ },
25
+ "glow": {
26
+ "type": "glow behind card",
27
+ "color": "#8AA6FF",
28
+ "durationMs": 1600,
29
+ "easing": "inOut",
30
+ "keys": [
31
+ {
32
+ "t": 0,
33
+ "radiusCw": 0.36,
34
+ "spreadCw": 0.07,
35
+ "opacity": 0.65
36
+ },
37
+ {
38
+ "t": 800,
39
+ "radiusCw": 0.62,
40
+ "spreadCw": 0.19,
41
+ "opacity": 0.42
42
+ },
43
+ {
44
+ "t": 1600,
45
+ "radiusCw": 0.36,
46
+ "spreadCw": 0.07,
47
+ "opacity": 0.65
48
+ }
49
+ ]
50
+ },
51
+ "arrow": {
52
+ "type": "sprite",
53
+ "file": "svg/hint-arrow.svg",
54
+ "anchor": "above card centre, 0.25 cw gap",
55
+ "durationMs": 1000,
56
+ "easing": "inOut",
57
+ "keys": [
58
+ { "t": 0, "y": 0 },
59
+ { "t": 500, "y": "8pt down" },
60
+ { "t": 1000, "y": 0 }
61
+ ]
62
+ }
63
+ },
64
+ "note": "No orbit ring around the card."
65
+ },
66
+
67
+ "selected": {
68
+ "durationMs": 320,
69
+ "easing": "lift",
70
+ "to": { "y": 0.3, "scale": 1.06 },
71
+ "layers": {
72
+ "ring": { "color": "#4D78FF", "widthCw": 0.024 },
73
+ "shadow": { "color": "#4D78FF", "opacity": 0.45, "under": true }
74
+ },
75
+ "note": "Tap again to play."
76
+ },
77
+
78
+ "dragging": {
79
+ "live": true,
80
+ "scale": 1.08,
81
+ "tiltDegMax": 12,
82
+ "tiltFrom": "horizontal finger speed, eased back to 0 when still",
83
+ "layers": {
84
+ "ring": { "color": "#4D78FF", "widthCw": 0.024 },
85
+ "shadow": { "opacity": 0.8, "offsetCw": 0.3, "blurCw": 0.4 },
86
+ "slot": {
87
+ "type": "dashed outline where the card came from",
88
+ "color": "#8AA6FF",
89
+ "opacity": 0.5
90
+ }
91
+ }
92
+ },
93
+
94
+ "draggingTrail": {
95
+ "status": "option to explore",
96
+ "extends": "dragging",
97
+ "ghosts": [
98
+ { "delayMs": 70, "opacity": 0.35 },
99
+ { "delayMs": 140, "opacity": 0.15 }
100
+ ]
101
+ },
102
+
103
+ "dropTarget": {
104
+ "loop": true,
105
+ "durationMs": 1200,
106
+ "easing": "inOut",
107
+ "keys": [
108
+ { "t": 0, "scale": 1.0, "glowOpacity": 0.4 },
109
+ { "t": 600, "scale": 1.03, "glowOpacity": 0.9 },
110
+ { "t": 1200, "scale": 1.0, "glowOpacity": 0.4 }
111
+ ],
112
+ "layers": { "ring": { "color": "#4D78FF", "widthCw": 0.024 } },
113
+ "onLand": {
114
+ "durationMs": 420,
115
+ "easing": "lift",
116
+ "keys": [
117
+ { "t": 0, "scale": 1.08 },
118
+ { "t": 180, "scaleX": 1.03, "scaleY": 0.97 },
119
+ { "t": 420, "scale": 1.0 }
120
+ ],
121
+ "flash": {
122
+ "type": "white outline growing outward",
123
+ "fromScale": 1.0,
124
+ "toScale": 1.35,
125
+ "fromOpacity": 0.9,
126
+ "toOpacity": 0,
127
+ "durationMs": 420
128
+ }
129
+ }
130
+ },
131
+
132
+ "played": {
133
+ "travel": {
134
+ "durationMs": 520,
135
+ "easing": "glide",
136
+ "path": "arc to the pile, apex 0.8 cw above the straight line"
137
+ },
138
+ "spin": {
139
+ "axis": "vertical (local Y)",
140
+ "turns": 1,
141
+ "durationMs": 520,
142
+ "easing": "glide"
143
+ },
144
+ "land": { "rotateZDeg": "random 6 to 10, either direction" },
145
+ "sparks": {
146
+ "count": 10,
147
+ "colors": "tokens.color.sparks",
148
+ "angleStepDeg": 36,
149
+ "distancePt": 92,
150
+ "durationMs": 780,
151
+ "startAtMs": 520,
152
+ "easing": "glide",
153
+ "fromScale": 1,
154
+ "toScale": 0.2,
155
+ "toOpacity": 0
156
+ }
157
+ },
158
+
159
+ "cannotPlay": {
160
+ "onlyWhen": "it is your turn",
161
+ "look": {
162
+ "grayscale": 0.8,
163
+ "brightness": 0.55,
164
+ "hatching": {
165
+ "color": "#FF6B5E",
166
+ "opacity": 0.18,
167
+ "angleDeg": -45,
168
+ "stripeCw": 0.07,
169
+ "gapCw": 0.1
170
+ },
171
+ "badge": "svg/lock.svg on a dark #0C1017 rounded tile with a 2pt #FF6B5E border, centred on the card"
172
+ },
173
+ "onTap": {
174
+ "shake": {
175
+ "durationMs": 600,
176
+ "keys": [
177
+ { "t": 0, "rotateZ": 0 },
178
+ { "t": 120, "rotateZ": -7 },
179
+ { "t": 260, "rotateZ": 6 },
180
+ { "t": 400, "rotateZ": -4 },
181
+ { "t": 500, "rotateZ": 2 },
182
+ { "t": 600, "rotateZ": 0 }
183
+ ]
184
+ },
185
+ "toast": "one line saying why, placeholder copy, for example Needs a heart or a 7"
186
+ }
187
+ },
188
+
189
+ "drawn": {
190
+ "durationMs": 1600,
191
+ "easing": "lift",
192
+ "keys": [
193
+ {
194
+ "t": 0,
195
+ "from": "deck",
196
+ "faceDown": true,
197
+ "rotateYDeg": 180,
198
+ "rotateZDeg": 22,
199
+ "scale": 0.7
200
+ },
201
+ {
202
+ "t": 610,
203
+ "at": "0.55 cw above its hand slot",
204
+ "rotateYDeg": 0,
205
+ "rotateZDeg": -5,
206
+ "scale": 1.18
207
+ },
208
+ {
209
+ "t": 800,
210
+ "at": "hand slot, 0.07 cw low",
211
+ "scaleX": 1.04,
212
+ "scaleY": 0.94,
213
+ "rotateZDeg": 0
214
+ },
215
+ { "t": 930, "at": "hand slot", "scale": 1.0 }
216
+ ],
217
+ "sparkles": {
218
+ "count": 4,
219
+ "color": "#FFBA3A",
220
+ "startsMs": [450, 520, 600, 700],
221
+ "twinkleMs": 600,
222
+ "positions": "around the card, roughly its four corners"
223
+ },
224
+ "note": "No +1 label."
225
+ },
226
+
227
+ "waiting": {
228
+ "durationMs": 450,
229
+ "easing": "lift",
230
+ "to": { "handYpt": 34, "brightness": 0.6 },
231
+ "note": "Whole hand sinks and dims while a friend plays. Reverse on your turn."
232
+ }
233
+ },
234
+
235
+ "whoseTurn": {
236
+ "spotlight": {
237
+ "type": "soft radial light under the active seat",
238
+ "color": "#8AA6FF",
239
+ "radiusPt": 190,
240
+ "moveMs": 600,
241
+ "easing": "glide"
242
+ },
243
+ "activeAvatar": {
244
+ "scale": [1.12, 1.18],
245
+ "timerRing": {
246
+ "color": "#4D78FF",
247
+ "drains": "with the player's turn time"
248
+ }
249
+ },
250
+ "otherSeats": { "opacity": 0.55 },
251
+ "pill": {
252
+ "position": "top of table",
253
+ "friend": "<name> is playing",
254
+ "you": "Your turn, text in #8AA6FF"
255
+ },
256
+ "yourTurnBeat": [
257
+ "Your turn band (see moments.turnPasses at 4000 ms)",
258
+ "hand rises back up",
259
+ "cobalt glow comes up from the bottom edge"
260
+ ],
261
+ "buttons": "Big, at most two per row: one dark (Hint, Draw, Fold, Let it go), one cobalt or amber"
262
+ },
263
+
264
+ "moments": {
265
+ "turnPasses": {
266
+ "totalMs": 5200,
267
+ "tracks": [
268
+ {
269
+ "what": "spotlight",
270
+ "keys": [
271
+ { "t": 0, "seat": "friend 1" },
272
+ { "t": 1300, "seat": "friend 2" },
273
+ { "t": 2600, "seat": "friend 3" },
274
+ { "t": 4000, "seat": "you" }
275
+ ],
276
+ "moveMs": 600,
277
+ "easing": "glide"
278
+ },
279
+ {
280
+ "what": "active seat",
281
+ "scale": 1.18,
282
+ "timerRing": { "from": 1.0, "to": 0.2, "overMs": 1300 }
283
+ },
284
+ {
285
+ "what": "name bar per friend",
286
+ "from": "left screen edge",
287
+ "look": "6pt stripe in the friend colour, dark bar, <name> is playing",
288
+ "inMs": 300,
289
+ "inEasing": "lift",
290
+ "holdMs": 800,
291
+ "outMs": 200,
292
+ "repeatEveryMs": 1300
293
+ },
294
+ {
295
+ "what": "Your turn band",
296
+ "startMs": 4000,
297
+ "durationMs": 1600,
298
+ "look": "cobalt #4D78FF, full width, rotated -8 deg",
299
+ "keys": [
300
+ { "t": 0, "x": "-100%" },
301
+ { "t": 350, "x": "0" },
302
+ { "t": 1250, "x": "0" },
303
+ { "t": 1600, "x": "100%" }
304
+ ],
305
+ "easing": "glide"
306
+ },
307
+ {
308
+ "what": "your hand",
309
+ "startMs": 4600,
310
+ "durationMs": 600,
311
+ "easing": "lift",
312
+ "from": { "yPt": 46, "brightness": 0.55 },
313
+ "to": { "yPt": 0, "brightness": 1 }
314
+ }
315
+ ]
316
+ },
317
+
318
+ "specialCard": {
319
+ "totalMs": 3500,
320
+ "tracks": [
321
+ {
322
+ "what": "dim and sunburst",
323
+ "startMs": 0,
324
+ "durationMs": 350,
325
+ "dim": 0.8,
326
+ "sunburst": "#FF6B5E"
327
+ },
328
+ {
329
+ "what": "hero card",
330
+ "startMs": 0,
331
+ "durationMs": 2400,
332
+ "easing": "lift",
333
+ "keys": [
334
+ { "t": 0, "faceDown": true, "scale": 0.2 },
335
+ { "t": 600, "faceUp": true, "scale": 2.3 },
336
+ { "t": 1700, "scale": 2.3 },
337
+ { "t": 2000, "at": "pile", "scale": 1, "rotateZDeg": 8 }
338
+ ]
339
+ },
340
+ {
341
+ "what": "shock rings",
342
+ "startMs": 2000,
343
+ "durationMs": 700,
344
+ "rings": [
345
+ { "color": "#FFBA3A", "delayMs": 0 },
346
+ { "color": "#FFFFFF", "delayMs": 120 }
347
+ ],
348
+ "fromScale": 0.4,
349
+ "toScale": 2.6,
350
+ "toOpacity": 0,
351
+ "easing": "glide"
352
+ },
353
+ {
354
+ "what": "screen shake",
355
+ "startMs": 2000,
356
+ "durationMs": 400,
357
+ "amplitudePt": 9,
358
+ "keysX": [-9, 8, -6, 4, 0]
359
+ },
360
+ {
361
+ "what": "card rain on the hit friend",
362
+ "startMs": 2600,
363
+ "count": 4,
364
+ "staggerMs": 120,
365
+ "eachMs": 450,
366
+ "easing": "glide",
367
+ "avatar": "wobbles"
368
+ },
369
+ {
370
+ "what": "+4 label",
371
+ "startMs": 2700,
372
+ "durationMs": 900,
373
+ "color": "#FF6B5E",
374
+ "riseYpt": -40,
375
+ "toOpacity": 0
376
+ },
377
+ {
378
+ "what": "card count",
379
+ "startMs": 3200,
380
+ "durationMs": 300,
381
+ "countFrom": 5,
382
+ "countTo": 9
383
+ }
384
+ ]
385
+ },
386
+
387
+ "lastCard": {
388
+ "totalMs": 3500,
389
+ "tracks": [
390
+ {
391
+ "what": "Last card button",
392
+ "startMs": 500,
393
+ "keys": [
394
+ { "t": 0, "scale": 1 },
395
+ { "t": 120, "scale": 0.92 },
396
+ { "t": 320, "scale": 1.06 },
397
+ { "t": 480, "scale": 1 }
398
+ ],
399
+ "ripple": {
400
+ "color": "#FFBA3A",
401
+ "toScale": 2.2,
402
+ "durationMs": 600
403
+ }
404
+ },
405
+ {
406
+ "what": "screen edge pulse",
407
+ "startMs": 700,
408
+ "color": "#FFBA3A",
409
+ "type": "inset glow",
410
+ "pulses": 2,
411
+ "eachMs": 1400
412
+ },
413
+ {
414
+ "what": "ribbon",
415
+ "startMs": 750,
416
+ "text": "Last card",
417
+ "color": "#FFBA3A",
418
+ "rotateZDeg": -5,
419
+ "keys": [
420
+ { "t": 0, "scaleX": 0 },
421
+ { "t": 400, "scaleX": 1 },
422
+ { "t": 1700, "scaleX": 1, "y": 0 },
423
+ { "t": 2200, "y": "-40pt", "opacity": 0 }
424
+ ],
425
+ "easing": "lift"
426
+ },
427
+ {
428
+ "what": "friend avatars shake",
429
+ "startMs": 1000,
430
+ "durationMs": 500
431
+ },
432
+ {
433
+ "what": "reply bubbles",
434
+ "startsMs": [1500, 1650, 1800],
435
+ "text": "placeholder chat lines",
436
+ "popEasing": "lift",
437
+ "popMs": 300
438
+ },
439
+ {
440
+ "what": "your last card glow",
441
+ "startMs": 1400,
442
+ "color": "#FFBA3A",
443
+ "breaths": 2,
444
+ "eachMs": 600
445
+ },
446
+ {
447
+ "what": "your last card outline tick",
448
+ "startMs": 2600,
449
+ "color": "#FFBA3A",
450
+ "count": 2,
451
+ "fromScale": 1,
452
+ "toScale": 1.3,
453
+ "eachMs": 400
454
+ }
455
+ ]
456
+ },
457
+
458
+ "roundOver": {
459
+ "totalMs": 5500,
460
+ "tracks": [
461
+ {
462
+ "what": "table cards fly to winner",
463
+ "startMs": 0,
464
+ "durationMs": 1100,
465
+ "staggerMs": 60,
466
+ "easing": "glide",
467
+ "toScale": 0.2,
468
+ "into": "winner avatar"
469
+ },
470
+ {
471
+ "what": "+35 score label",
472
+ "startMs": 900,
473
+ "color": "#FFBA3A",
474
+ "riseYpt": -36,
475
+ "durationMs": 900
476
+ },
477
+ {
478
+ "what": "winner stamp",
479
+ "startMs": 1150,
480
+ "durationMs": 300,
481
+ "easing": "lift",
482
+ "text": "<name> wins",
483
+ "look": "white, amber #FFBA3A border, rotated -4 deg",
484
+ "fromScale": 2.4,
485
+ "toScale": 1
486
+ },
487
+ { "what": "screen shake", "startMs": 1450, "durationMs": 300 },
488
+ { "what": "winner amber ring", "startMs": 1450 },
489
+ {
490
+ "what": "stamp and seats fade",
491
+ "startMs": 2500,
492
+ "durationMs": 300
493
+ },
494
+ {
495
+ "what": "Round 1 results title",
496
+ "startMs": 2700,
497
+ "durationMs": 400
498
+ },
499
+ {
500
+ "what": "podium blocks",
501
+ "order": [3, 2, 1],
502
+ "startsMs": [2600, 2900, 3200],
503
+ "heightsPt": [46, 70, 110],
504
+ "riseMs": 500,
505
+ "easing": "lift",
506
+ "colors": { "1": "#FFBA3A", "2": "navy", "3": "navy" }
507
+ },
508
+ {
509
+ "what": "avatars land on podium",
510
+ "delayAfterBlockMs": 500,
511
+ "easing": "lift"
512
+ },
513
+ {
514
+ "what": "scores count up",
515
+ "from": 0,
516
+ "durationMs": 1200,
517
+ "startsWithAvatar": true
518
+ },
519
+ {
520
+ "what": "rays behind first place",
521
+ "startMs": 4000,
522
+ "rotateSecPerTurn": 14
523
+ }
524
+ ]
525
+ },
526
+
527
+ "nextRound": {
528
+ "totalMs": 4500,
529
+ "tracks": [
530
+ {
531
+ "what": "sweep table cards to middle",
532
+ "startMs": 0,
533
+ "durationMs": 700,
534
+ "staggerMs": 70,
535
+ "spinTurns": 2,
536
+ "toScale": 0.3,
537
+ "easing": "glide"
538
+ },
539
+ {
540
+ "what": "shuffle ring",
541
+ "startMs": 1000,
542
+ "durationMs": 1600,
543
+ "cards": 8,
544
+ "faceDown": true,
545
+ "keys": [
546
+ { "t": 0, "radiusPt": 0 },
547
+ { "t": 500, "radiusPt": 70 },
548
+ { "t": 1100, "radiusPt": 70, "rotateDeg": 180 },
549
+ { "t": 1600, "radiusPt": 0 }
550
+ ],
551
+ "easing": "glide"
552
+ },
553
+ {
554
+ "what": "round digit flip",
555
+ "startMs": 2700,
556
+ "durationMs": 400,
557
+ "axis": "horizontal (local X)",
558
+ "from": "1",
559
+ "to": "2"
560
+ },
561
+ {
562
+ "what": "deal",
563
+ "startMs": 3100,
564
+ "staggerMs": 130,
565
+ "rounds": 2,
566
+ "order": "each seat in turn",
567
+ "eachMs": 380,
568
+ "easing": "glide"
569
+ }
570
+ ]
571
+ },
572
+
573
+ "winScreen": {
574
+ "trigger": "you empty your hand",
575
+ "tracks": [
576
+ {
577
+ "what": "dark radial overlay",
578
+ "startMs": 0,
579
+ "durationMs": 300
580
+ },
581
+ { "what": "rays behind your avatar", "rotateSecPerTurn": 14 },
582
+ {
583
+ "what": "avatar pop with amber ring",
584
+ "startMs": 200,
585
+ "durationMs": 450,
586
+ "easing": "lift",
587
+ "fromScale": 0.4
588
+ },
589
+ {
590
+ "what": "title",
591
+ "text": "You won the round",
592
+ "startMs": 400
593
+ },
594
+ {
595
+ "what": "score count up",
596
+ "startMs": 500,
597
+ "durationMs": 1100
598
+ },
599
+ {
600
+ "what": "confetti",
601
+ "bursts": 2,
602
+ "startsMs": [300, 800],
603
+ "colors": [
604
+ "#E4A672",
605
+ "#7FB3D9",
606
+ "#B59AE0",
607
+ "#8FCF9F",
608
+ "#4D78FF",
609
+ "#FFBA3A"
610
+ ]
611
+ },
612
+ {
613
+ "what": "Next round button",
614
+ "color": "#FFBA3A",
615
+ "then": "moments.nextRound"
616
+ }
617
+ ]
618
+ }
619
+ }
620
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "default": "midnight",
3
+ "styles": {
4
+ "midnight": {
5
+ "name": "Midnight",
6
+ "status": "approved",
7
+ "face": "#252F43 to #192131 gradient, 1px #33405A border",
8
+ "red": "#FF6B5E",
9
+ "black": "#E8EDF5",
10
+ "back": "deep navy radial #1B2A52 to #0B1020, thin #8AA6FF frame at 35 percent, gem with cobalt halo"
11
+ },
12
+ "ivory": {
13
+ "name": "Ivory classic",
14
+ "status": "approved",
15
+ "face": "#FBF8F1 to #EFE8DA, border #D9CFBC",
16
+ "red": "#C8322B",
17
+ "black": "#1B1F27",
18
+ "back": "red lattice on cream, gem on a cream round plate with red ring"
19
+ },
20
+ "neon": {
21
+ "name": "Neon",
22
+ "status": "approved",
23
+ "face": "#05060B with outline and inner glow in suit colour, outlined pips",
24
+ "red": "#FF4FA3",
25
+ "black": "#5CE8FF",
26
+ "back": "black with violet #9B6BFF grid, gem on a black rounded plate with violet ring"
27
+ },
28
+ "four-colour": {
29
+ "name": "Four colour",
30
+ "status": "approved",
31
+ "face": "full colour per suit, white index and thin white inner frame",
32
+ "suits": {
33
+ "S": ["#3A4050", "#23272F"],
34
+ "H": ["#F0594B", "#C93427"],
35
+ "D": ["#4B82FF", "#2257D9"],
36
+ "C": ["#2DB872", "#178A50"]
37
+ },
38
+ "back": "small four colour suit pattern on #161B26, gem on a dark plate"
39
+ },
40
+ "big-number": {
41
+ "name": "Big number",
42
+ "status": "revised, waiting on the maintainer",
43
+ "face": "#F2EFE8, small index and bar top left, huge condensed rank cropped bottom right",
44
+ "red": "#E3412F",
45
+ "black": "#11151D",
46
+ "back": "#11151D with cream inner frame, large gem"
47
+ },
48
+ "gold-luxe": {
49
+ "name": "Gold luxe",
50
+ "status": "approved",
51
+ "face": "dark green radial #123128 to #0A1A15, gold #D9B66A double frame, Playfair Display ranks",
52
+ "red": "#F0A58F",
53
+ "black": "#E9CF8C",
54
+ "back": "dotted gold pattern on green, gem on a dark round plate with gold ring"
55
+ }
56
+ },
57
+ "files": "<style>.webp beside this file, one atlas for each style: 52 faces and a back, laid out by atlas.json. Ranks A 2 3 4 5 6 7 8 9 10 J Q K, suits S H D C."
58
+ }