sataruz-captcha 0.1.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/LICENSE +21 -0
- package/README.md +58 -0
- package/assets/sataruz/cao_yanbing.png +0 -0
- package/assets/sataruz/frok.png +0 -0
- package/assets/sataruz/irelia.png +0 -0
- package/assets/sataruz/jormungandr.png +0 -0
- package/assets/sataruz/netherworld.png +0 -0
- package/assets/sataruz/nine.png +0 -0
- package/assets/sataruz/qingluan.png +0 -0
- package/assets/sataruz/ratu_salju.png +0 -0
- package/assets/sataruz/samael.png +0 -0
- package/assets/sataruz/titan.png +0 -0
- package/assets/sataruz/uriel.png +0 -0
- package/assets/sataruz/zhuqing.png +0 -0
- package/assets/sataruz-captcha.svg +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +1043 -0
- package/dist/sataruz-captcha.css +1131 -0
- package/package.json +42 -0
|
@@ -0,0 +1,1131 @@
|
|
|
1
|
+
/* ── SataruzCaptcha — required styles ─────────────────────────────────────────
|
|
2
|
+
iOS-register surfaces: white card, flat grouped-gray panels, hairlines,
|
|
3
|
+
capsule button, segmented-control steps. No gradients on chrome surfaces;
|
|
4
|
+
depth comes from a few precise shadows, not texture.
|
|
5
|
+
|
|
6
|
+
Theme via custom properties on any ancestor:
|
|
7
|
+
--clawcap-bg card surface
|
|
8
|
+
--clawcap-ink primary text
|
|
9
|
+
--clawcap-muted secondary text
|
|
10
|
+
--clawcap-accent action button / success
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.clawcap {
|
|
14
|
+
--cc-bg: var(--clawcap-bg, #ffffff);
|
|
15
|
+
--cc-ink: var(--clawcap-ink, #1c1c1e);
|
|
16
|
+
--cc-muted: var(--clawcap-muted, #8a8a8e);
|
|
17
|
+
--cc-line: rgba(60, 60, 67, 0.1);
|
|
18
|
+
--cc-fill: #f2f2f7; /* iOS grouped fill */
|
|
19
|
+
--cc-fill-2: #e9e9ee;
|
|
20
|
+
--cc-accent: var(--clawcap-accent, #1c1c1e);
|
|
21
|
+
--cc-green: #34c759;
|
|
22
|
+
|
|
23
|
+
position: relative;
|
|
24
|
+
width: 440px;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
background: var(--cc-bg);
|
|
27
|
+
color: var(--cc-ink);
|
|
28
|
+
border-radius: 32px;
|
|
29
|
+
padding: 24px 24px 20px; /* 4px-grid rhythm */
|
|
30
|
+
box-shadow:
|
|
31
|
+
0 0 0 0.5px rgba(60, 60, 67, 0.08),
|
|
32
|
+
0 2px 6px rgba(20, 20, 30, 0.04),
|
|
33
|
+
0 28px 70px -28px rgba(20, 20, 30, 0.22);
|
|
34
|
+
/* Inter first (variable: real 500/600/650 weights everywhere, incl. Windows),
|
|
35
|
+
then the native stacks. cv11 = single-storey a — the cleaner UI voice. */
|
|
36
|
+
font-family:
|
|
37
|
+
'Inter',
|
|
38
|
+
-apple-system,
|
|
39
|
+
BlinkMacSystemFont,
|
|
40
|
+
'SF Pro Text',
|
|
41
|
+
'Segoe UI',
|
|
42
|
+
Roboto,
|
|
43
|
+
sans-serif;
|
|
44
|
+
font-feature-settings: 'cv11';
|
|
45
|
+
-webkit-font-smoothing: antialiased;
|
|
46
|
+
-moz-osx-font-smoothing: grayscale;
|
|
47
|
+
user-select: none;
|
|
48
|
+
-webkit-tap-highlight-color: transparent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.clawcap:focus-visible {
|
|
52
|
+
outline: 2px solid var(--cc-accent);
|
|
53
|
+
outline-offset: 4px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* header icons */
|
|
57
|
+
.clawcap-top {
|
|
58
|
+
display: flex;
|
|
59
|
+
justify-content: space-between;
|
|
60
|
+
color: var(--cc-muted);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.clawcap-shield,
|
|
64
|
+
.clawcap-help {
|
|
65
|
+
display: inline-flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
justify-content: center;
|
|
68
|
+
width: 30px;
|
|
69
|
+
height: 30px;
|
|
70
|
+
border-radius: 50%;
|
|
71
|
+
background: var(--cc-fill);
|
|
72
|
+
transition:
|
|
73
|
+
background 0.3s ease,
|
|
74
|
+
color 0.3s ease;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.clawcap-shield--ok {
|
|
78
|
+
color: #fff;
|
|
79
|
+
background: var(--cc-green);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* the help icon is a real button */
|
|
83
|
+
button.clawcap-help {
|
|
84
|
+
border: none;
|
|
85
|
+
padding: 0;
|
|
86
|
+
color: var(--cc-muted);
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
-webkit-tap-highlight-color: transparent;
|
|
89
|
+
transition:
|
|
90
|
+
background 0.2s ease,
|
|
91
|
+
color 0.2s ease,
|
|
92
|
+
transform 0.12s ease;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (hover: hover) {
|
|
96
|
+
button.clawcap-help:hover {
|
|
97
|
+
background: var(--cc-fill-2);
|
|
98
|
+
color: var(--cc-ink);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
button.clawcap-help:active {
|
|
103
|
+
transform: scale(0.97); /* felt, not seen — anything deeper collapses */
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
button.clawcap-help:focus-visible {
|
|
107
|
+
outline: 2px solid var(--cc-accent);
|
|
108
|
+
outline-offset: 2px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* ── info modal ─────────────────────────────────────────────────────────── */
|
|
112
|
+
.clawcap-info {
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: 0;
|
|
115
|
+
z-index: 100;
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
padding: 16px;
|
|
120
|
+
border-radius: inherit;
|
|
121
|
+
background: rgba(20, 20, 30, 0.32);
|
|
122
|
+
backdrop-filter: blur(3px);
|
|
123
|
+
-webkit-backdrop-filter: blur(3px);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.clawcap-info-card {
|
|
127
|
+
position: relative;
|
|
128
|
+
width: 322px;
|
|
129
|
+
max-width: 100%;
|
|
130
|
+
padding: 22px 20px 18px;
|
|
131
|
+
border-radius: 24px;
|
|
132
|
+
background: var(--cc-bg);
|
|
133
|
+
color: var(--cc-ink);
|
|
134
|
+
text-align: center;
|
|
135
|
+
box-shadow:
|
|
136
|
+
0 0 0 0.5px rgba(60, 60, 67, 0.08),
|
|
137
|
+
0 18px 50px -16px rgba(20, 20, 30, 0.4);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.clawcap-info-x {
|
|
141
|
+
position: absolute;
|
|
142
|
+
top: 12px;
|
|
143
|
+
right: 12px;
|
|
144
|
+
display: inline-flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
width: 26px;
|
|
148
|
+
height: 26px;
|
|
149
|
+
border: none;
|
|
150
|
+
border-radius: 50%;
|
|
151
|
+
background: var(--cc-fill);
|
|
152
|
+
color: var(--cc-muted);
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
transition:
|
|
155
|
+
background 0.2s ease,
|
|
156
|
+
color 0.2s ease;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@media (hover: hover) {
|
|
160
|
+
.clawcap-info-x:hover {
|
|
161
|
+
background: var(--cc-fill-2);
|
|
162
|
+
color: var(--cc-ink);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.clawcap-info-x:active {
|
|
167
|
+
transform: scale(0.94);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* header: framed icon tile + title + one-line tagline */
|
|
171
|
+
.clawcap-info-head {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
align-items: center;
|
|
175
|
+
margin: 4px 0 18px;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.clawcap-info-tile {
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
justify-content: center;
|
|
182
|
+
width: 60px;
|
|
183
|
+
height: 60px;
|
|
184
|
+
margin-bottom: 12px;
|
|
185
|
+
border-radius: 17px;
|
|
186
|
+
background: var(--cc-fill);
|
|
187
|
+
box-shadow:
|
|
188
|
+
inset 0 0 0 0.5px rgba(60, 60, 67, 0.1),
|
|
189
|
+
0 4px 12px -4px rgba(20, 20, 30, 0.18);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.clawcap-info-tile img {
|
|
193
|
+
display: block;
|
|
194
|
+
width: 40px;
|
|
195
|
+
height: 40px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.clawcap-info-title {
|
|
199
|
+
margin: 0;
|
|
200
|
+
font-size: 1.125rem; /* 18px — one step under the card title */
|
|
201
|
+
font-weight: 700;
|
|
202
|
+
letter-spacing: -0.022em;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.clawcap-info-ver {
|
|
206
|
+
margin-left: 3px;
|
|
207
|
+
padding: 1px 5px;
|
|
208
|
+
border-radius: 5px;
|
|
209
|
+
background: var(--cc-fill-2);
|
|
210
|
+
font-size: 0.625rem; /* 10px */
|
|
211
|
+
font-weight: 700;
|
|
212
|
+
letter-spacing: 0.02em;
|
|
213
|
+
color: var(--cc-muted);
|
|
214
|
+
vertical-align: 0.28em;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.clawcap-info-tag {
|
|
218
|
+
margin: 5px 0 0;
|
|
219
|
+
font-size: 0.8125rem; /* 13px body */
|
|
220
|
+
letter-spacing: -0.006em;
|
|
221
|
+
color: var(--cc-muted);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* steps: numbered rows, hairline-separated */
|
|
225
|
+
.clawcap-info-list {
|
|
226
|
+
margin: 0 0 16px;
|
|
227
|
+
padding: 4px 14px;
|
|
228
|
+
list-style: none;
|
|
229
|
+
text-align: left;
|
|
230
|
+
background: var(--cc-fill);
|
|
231
|
+
border-radius: 16px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.clawcap-info-list li {
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
gap: 12px;
|
|
238
|
+
padding: 11px 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.clawcap-info-list li + li {
|
|
242
|
+
border-top: 0.5px solid var(--cc-line);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.clawcap-info-n {
|
|
246
|
+
display: inline-flex;
|
|
247
|
+
flex: none;
|
|
248
|
+
align-items: center;
|
|
249
|
+
justify-content: center;
|
|
250
|
+
width: 22px;
|
|
251
|
+
height: 22px;
|
|
252
|
+
border-radius: 50%;
|
|
253
|
+
background: var(--cc-ink);
|
|
254
|
+
color: #fff;
|
|
255
|
+
font-size: 0.7rem;
|
|
256
|
+
font-weight: 650;
|
|
257
|
+
font-variant-numeric: tabular-nums;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.clawcap-info-list strong {
|
|
261
|
+
display: block;
|
|
262
|
+
font-size: 0.8125rem; /* 13px body */
|
|
263
|
+
font-weight: 600;
|
|
264
|
+
letter-spacing: -0.008em;
|
|
265
|
+
color: var(--cc-ink);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.clawcap-info-d {
|
|
269
|
+
display: block;
|
|
270
|
+
margin-top: 2px;
|
|
271
|
+
font-size: 0.75rem; /* 12px label */
|
|
272
|
+
line-height: 1.5; /* room for the kbd chips to sit without crowding */
|
|
273
|
+
letter-spacing: -0.004em;
|
|
274
|
+
color: var(--cc-muted);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.clawcap-info-d kbd {
|
|
278
|
+
display: inline-block;
|
|
279
|
+
min-width: 16px;
|
|
280
|
+
padding: 0 4px;
|
|
281
|
+
border-radius: 4px;
|
|
282
|
+
background: var(--cc-bg);
|
|
283
|
+
box-shadow: inset 0 0 0 0.5px rgba(60, 60, 67, 0.2);
|
|
284
|
+
font-family: inherit;
|
|
285
|
+
font-size: 0.6875rem; /* 11px caption */
|
|
286
|
+
font-weight: 600;
|
|
287
|
+
line-height: 1.5;
|
|
288
|
+
text-align: center;
|
|
289
|
+
color: var(--cc-ink);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.clawcap-info-done {
|
|
293
|
+
width: 100%;
|
|
294
|
+
padding: 11px 0;
|
|
295
|
+
border: none;
|
|
296
|
+
border-radius: 13px;
|
|
297
|
+
background: var(--cc-accent);
|
|
298
|
+
color: #fff;
|
|
299
|
+
font-family: inherit;
|
|
300
|
+
font-size: 0.8125rem; /* 13px body */
|
|
301
|
+
font-weight: 600;
|
|
302
|
+
letter-spacing: -0.005em;
|
|
303
|
+
cursor: pointer;
|
|
304
|
+
transition:
|
|
305
|
+
filter 0.2s ease,
|
|
306
|
+
transform 0.12s ease;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
@media (hover: hover) {
|
|
310
|
+
.clawcap-info-done:hover {
|
|
311
|
+
filter: brightness(1.12);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.clawcap-info-done:active {
|
|
316
|
+
transform: scale(0.97); /* press feedback on a meaningful button */
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* title + challenge — SF optical rhythm: tight display, quiet caption.
|
|
320
|
+
TYPE SCALE (whole card): 20px title · 13px body · 12px label · 11px caption */
|
|
321
|
+
.clawcap-title {
|
|
322
|
+
margin: 12px 0 4px;
|
|
323
|
+
text-align: center;
|
|
324
|
+
font-size: 1.25rem; /* 20px */
|
|
325
|
+
font-weight: 650;
|
|
326
|
+
letter-spacing: -0.024em;
|
|
327
|
+
line-height: 1.25;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.clawcap-sub {
|
|
331
|
+
margin: 0 0 20px;
|
|
332
|
+
text-align: center;
|
|
333
|
+
font-size: 0.8125rem; /* 13px body */
|
|
334
|
+
letter-spacing: -0.006em;
|
|
335
|
+
line-height: 1.4;
|
|
336
|
+
color: var(--cc-muted);
|
|
337
|
+
min-height: 1.4em;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.clawcap-sub em {
|
|
341
|
+
font-style: normal;
|
|
342
|
+
font-weight: 600;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* tiny thumbnail of the requested toy inline in the challenge line */
|
|
346
|
+
.clawcap-sub-toy {
|
|
347
|
+
width: 20px;
|
|
348
|
+
height: 20px;
|
|
349
|
+
object-fit: contain;
|
|
350
|
+
vertical-align: -5px;
|
|
351
|
+
margin: 0 3px 0 2px;
|
|
352
|
+
filter: drop-shadow(0 1px 1px rgba(30, 30, 40, 0.16));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* steps — a true segmented control: equal segments, ONE pill that slides */
|
|
356
|
+
.clawcap-steps {
|
|
357
|
+
position: relative;
|
|
358
|
+
display: grid;
|
|
359
|
+
grid-template-columns: repeat(3, 1fr);
|
|
360
|
+
width: 280px;
|
|
361
|
+
max-width: 100%;
|
|
362
|
+
margin: 0 auto 20px;
|
|
363
|
+
padding: 2px;
|
|
364
|
+
list-style: none;
|
|
365
|
+
background: var(--cc-fill);
|
|
366
|
+
border-radius: 10px;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.clawcap-steps-pill {
|
|
370
|
+
position: absolute;
|
|
371
|
+
top: 2px;
|
|
372
|
+
bottom: 2px;
|
|
373
|
+
left: 2px;
|
|
374
|
+
width: calc((100% - 4px) / 3);
|
|
375
|
+
border-radius: 8px;
|
|
376
|
+
background: #fff;
|
|
377
|
+
box-shadow:
|
|
378
|
+
0 0 0 0.5px rgba(60, 60, 67, 0.04),
|
|
379
|
+
0 1.5px 4px rgba(20, 20, 30, 0.08);
|
|
380
|
+
/* springy glide with a whisper of overshoot, iOS-style — kept snappy so a
|
|
381
|
+
small indicator doesn't feel swimmy */
|
|
382
|
+
transition: transform 0.34s cubic-bezier(0.3, 1.25, 0.35, 1);
|
|
383
|
+
pointer-events: none;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.clawcap-steps li {
|
|
387
|
+
position: relative;
|
|
388
|
+
z-index: 1;
|
|
389
|
+
display: flex;
|
|
390
|
+
align-items: center;
|
|
391
|
+
justify-content: center;
|
|
392
|
+
gap: 6px;
|
|
393
|
+
padding: 7px 0;
|
|
394
|
+
font-size: 0.8125rem; /* 13px body */
|
|
395
|
+
line-height: 1.25; /* → ~34px control height, the iOS segmented standard */
|
|
396
|
+
letter-spacing: -0.006em;
|
|
397
|
+
color: var(--cc-muted);
|
|
398
|
+
transition: color 0.3s ease;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.clawcap-steps li.is-active {
|
|
402
|
+
color: var(--cc-ink);
|
|
403
|
+
font-weight: 600;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.clawcap-step-n {
|
|
407
|
+
display: inline-flex;
|
|
408
|
+
align-items: center;
|
|
409
|
+
justify-content: center;
|
|
410
|
+
width: 15px;
|
|
411
|
+
height: 15px;
|
|
412
|
+
border-radius: 50%;
|
|
413
|
+
background: var(--cc-fill-2);
|
|
414
|
+
font-size: 0.625rem; /* 10px digit in a 15px coin */
|
|
415
|
+
font-weight: 650;
|
|
416
|
+
font-variant-numeric: tabular-nums;
|
|
417
|
+
transition:
|
|
418
|
+
background 0.25s ease,
|
|
419
|
+
color 0.25s ease;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.clawcap-steps li.is-active .clawcap-step-n {
|
|
423
|
+
background: var(--cc-ink);
|
|
424
|
+
color: #fff;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/* machine */
|
|
428
|
+
.clawcap-machine {
|
|
429
|
+
position: relative;
|
|
430
|
+
width: 380px;
|
|
431
|
+
max-width: 100%;
|
|
432
|
+
margin: 0 auto;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.clawcap-case {
|
|
436
|
+
border-radius: 24px;
|
|
437
|
+
background: var(--cc-fill);
|
|
438
|
+
padding: 8px;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.clawcap-glass {
|
|
442
|
+
position: relative;
|
|
443
|
+
height: 320px;
|
|
444
|
+
border-radius: 16px; /* concentric: case 24 − 8 padding */
|
|
445
|
+
overflow: hidden;
|
|
446
|
+
background: linear-gradient(180deg, #fcfcfd 0%, #f4f4f8 100%);
|
|
447
|
+
box-shadow:
|
|
448
|
+
inset 0 0 0 0.5px rgba(60, 60, 67, 0.09),
|
|
449
|
+
inset 0 1px 8px rgba(30, 30, 40, 0.05),
|
|
450
|
+
inset 0 -18px 26px -22px rgba(30, 30, 40, 0.14);
|
|
451
|
+
transition:
|
|
452
|
+
opacity 1.1s ease,
|
|
453
|
+
filter 1.1s ease;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/* the show is over: the machine softly steps back */
|
|
457
|
+
.clawcap-glass--dim {
|
|
458
|
+
opacity: 0.55;
|
|
459
|
+
filter: saturate(0.75);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* one quiet diagonal sheen, nothing stripey */
|
|
463
|
+
.cc-glass-shine {
|
|
464
|
+
position: absolute;
|
|
465
|
+
inset: 0;
|
|
466
|
+
pointer-events: none;
|
|
467
|
+
background: linear-gradient(118deg, transparent 30%, rgba(255, 255, 255, 0.28) 42%, rgba(255, 255, 255, 0) 55%);
|
|
468
|
+
z-index: 30;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.cc-rail {
|
|
472
|
+
position: absolute;
|
|
473
|
+
top: 9px;
|
|
474
|
+
left: 16px;
|
|
475
|
+
right: 16px;
|
|
476
|
+
height: 5px;
|
|
477
|
+
border-radius: 2.5px;
|
|
478
|
+
background: #d7d8de;
|
|
479
|
+
box-shadow:
|
|
480
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.85),
|
|
481
|
+
inset 0 -1px 1px rgba(30, 30, 40, 0.12);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/* the carriage the cable hangs from — a chrome capsule riding the rail, with
|
|
485
|
+
two darker bolt heads. Driven by the rAF (translateX), never re-rendered. */
|
|
486
|
+
.cc-trolley {
|
|
487
|
+
position: absolute;
|
|
488
|
+
top: 4px;
|
|
489
|
+
left: 0;
|
|
490
|
+
width: 28px;
|
|
491
|
+
height: 13px;
|
|
492
|
+
border-radius: 6.5px;
|
|
493
|
+
background: linear-gradient(180deg, #f4f5f8 0%, #c9ccd4 100%);
|
|
494
|
+
box-shadow:
|
|
495
|
+
0 0 0 0.5px rgba(60, 60, 67, 0.18),
|
|
496
|
+
0 2px 3px rgba(30, 30, 40, 0.16),
|
|
497
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
|
498
|
+
z-index: 21;
|
|
499
|
+
will-change: transform;
|
|
500
|
+
pointer-events: none;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.cc-trolley::before,
|
|
504
|
+
.cc-trolley::after {
|
|
505
|
+
content: '';
|
|
506
|
+
position: absolute;
|
|
507
|
+
top: 4px;
|
|
508
|
+
width: 5px;
|
|
509
|
+
height: 5px;
|
|
510
|
+
border-radius: 50%;
|
|
511
|
+
background: radial-gradient(circle at 35% 30%, #8c919c, #4d525c);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.cc-trolley::before {
|
|
515
|
+
left: 4.5px;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.cc-trolley::after {
|
|
519
|
+
right: 4.5px;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/* contact shadow under the claw: position, width and opacity are all written
|
|
523
|
+
by the rAF — it tightens and darkens as the claw nears the floor, which both
|
|
524
|
+
grounds the rig in the scene and quietly shows where a grab will land */
|
|
525
|
+
.cc-claw-shadow {
|
|
526
|
+
position: absolute;
|
|
527
|
+
bottom: 7px;
|
|
528
|
+
left: 0;
|
|
529
|
+
width: 90px;
|
|
530
|
+
height: 13px;
|
|
531
|
+
border-radius: 50%;
|
|
532
|
+
background: radial-gradient(50% 50% at 50% 50%, rgba(30, 30, 40, 0.42), transparent 72%);
|
|
533
|
+
z-index: 1;
|
|
534
|
+
opacity: 0.1;
|
|
535
|
+
will-change: transform, opacity;
|
|
536
|
+
pointer-events: none;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* prize pile */
|
|
540
|
+
.cc-toy {
|
|
541
|
+
position: absolute;
|
|
542
|
+
pointer-events: none;
|
|
543
|
+
filter: drop-shadow(0 4px 5px rgba(30, 30, 40, 0.12));
|
|
544
|
+
will-change: transform;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.cc-pile-shadow {
|
|
548
|
+
position: absolute;
|
|
549
|
+
left: 0;
|
|
550
|
+
right: 0;
|
|
551
|
+
bottom: 0;
|
|
552
|
+
height: 22px;
|
|
553
|
+
background: radial-gradient(60% 130% at 50% 100%, rgba(30, 30, 40, 0.1), transparent 70%);
|
|
554
|
+
z-index: 0;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* the rig: cable + claw as ONE svg pendulum, pivoting at the rail point */
|
|
558
|
+
.cc-rig {
|
|
559
|
+
position: absolute;
|
|
560
|
+
top: 14px;
|
|
561
|
+
left: -18px;
|
|
562
|
+
width: 36px;
|
|
563
|
+
overflow: visible;
|
|
564
|
+
transform-origin: 18px 0;
|
|
565
|
+
z-index: 20;
|
|
566
|
+
will-change: transform;
|
|
567
|
+
filter: drop-shadow(0 3px 3px rgba(30, 30, 40, 0.14));
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.cc-carried {
|
|
571
|
+
position: absolute;
|
|
572
|
+
top: 0;
|
|
573
|
+
left: 0;
|
|
574
|
+
z-index: 40;
|
|
575
|
+
pointer-events: none;
|
|
576
|
+
filter: drop-shadow(0 8px 10px rgba(30, 30, 40, 0.18));
|
|
577
|
+
will-change: transform;
|
|
578
|
+
transform-origin: 50% 12%; /* swings from the grip point, not its belly */
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/* control panel — one flat grouped surface, evenly spaced */
|
|
582
|
+
.clawcap-panel {
|
|
583
|
+
position: relative;
|
|
584
|
+
display: flex;
|
|
585
|
+
align-items: center;
|
|
586
|
+
gap: 16px;
|
|
587
|
+
margin-top: 8px;
|
|
588
|
+
padding: 16px 18px;
|
|
589
|
+
min-height: 92px;
|
|
590
|
+
border-radius: 16px; /* concentric: case 24 − 8 padding */
|
|
591
|
+
background: linear-gradient(180deg, #fcfcfd 0%, #f4f4f8 100%);
|
|
592
|
+
box-shadow: inset 0 0 0 0.5px rgba(60, 60, 67, 0.09);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/* joystick: recessed socket + chrome stick, sized to stay INSIDE the panel
|
|
596
|
+
(socket 44px, shaft 16px, ball 18px → max height 56px incl. tilt) */
|
|
597
|
+
.cc-joy {
|
|
598
|
+
position: relative;
|
|
599
|
+
width: 60px;
|
|
600
|
+
height: 58px;
|
|
601
|
+
flex: none;
|
|
602
|
+
cursor: grab;
|
|
603
|
+
touch-action: none;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.cc-joy:active {
|
|
607
|
+
cursor: grabbing;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* the socket the stick sits in */
|
|
611
|
+
.cc-joy-base {
|
|
612
|
+
position: absolute;
|
|
613
|
+
left: 50%;
|
|
614
|
+
bottom: 2px;
|
|
615
|
+
transform: translateX(-50%);
|
|
616
|
+
width: 44px;
|
|
617
|
+
height: 44px;
|
|
618
|
+
border-radius: 50%;
|
|
619
|
+
background: var(--cc-fill);
|
|
620
|
+
box-shadow:
|
|
621
|
+
inset 0 1.5px 4px rgba(30, 30, 40, 0.12),
|
|
622
|
+
inset 0 -1px 0 rgba(255, 255, 255, 0.9);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/* dark gasket where the shaft enters */
|
|
626
|
+
.cc-joy-base::after {
|
|
627
|
+
content: '';
|
|
628
|
+
position: absolute;
|
|
629
|
+
left: 50%;
|
|
630
|
+
top: 50%;
|
|
631
|
+
transform: translate(-50%, -50%);
|
|
632
|
+
width: 17px;
|
|
633
|
+
height: 11px;
|
|
634
|
+
border-radius: 50%;
|
|
635
|
+
background: radial-gradient(ellipse at 50% 35%, #4a4a52, #232328 70%);
|
|
636
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.cc-joy-stick {
|
|
640
|
+
position: absolute;
|
|
641
|
+
left: 50%;
|
|
642
|
+
bottom: 22px;
|
|
643
|
+
width: 0;
|
|
644
|
+
transform-origin: bottom center;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.cc-joy-shaft {
|
|
648
|
+
position: absolute;
|
|
649
|
+
left: -2.5px;
|
|
650
|
+
bottom: 0;
|
|
651
|
+
width: 5px;
|
|
652
|
+
height: 18px;
|
|
653
|
+
border-radius: 2.5px;
|
|
654
|
+
background: linear-gradient(90deg, #aeb2bb, #eef0f4 45%, #999fa9);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* classic arcade ball-top: candy red to match the action button, with a hard
|
|
658
|
+
catch-light and a soft cast shadow so it sits IN the room, not on it */
|
|
659
|
+
.cc-joy-ball {
|
|
660
|
+
position: absolute;
|
|
661
|
+
left: -9.5px;
|
|
662
|
+
bottom: 14px;
|
|
663
|
+
width: 19px;
|
|
664
|
+
height: 19px;
|
|
665
|
+
border-radius: 50%;
|
|
666
|
+
background: radial-gradient(circle at 33% 26%, #ff9da3, #ff5159 52%, #cf2c36 100%);
|
|
667
|
+
box-shadow:
|
|
668
|
+
0 0 0 0.5px rgba(120, 10, 20, 0.25),
|
|
669
|
+
0 2px 3px rgba(120, 10, 20, 0.28),
|
|
670
|
+
0 5px 6px -2px rgba(20, 20, 30, 0.22),
|
|
671
|
+
inset 0 -2px 3px rgba(120, 10, 20, 0.35);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/* the hard specular dot that sells the gloss */
|
|
675
|
+
.cc-joy-ball::after {
|
|
676
|
+
content: '';
|
|
677
|
+
position: absolute;
|
|
678
|
+
top: 3px;
|
|
679
|
+
left: 4.5px;
|
|
680
|
+
width: 5px;
|
|
681
|
+
height: 4px;
|
|
682
|
+
border-radius: 50%;
|
|
683
|
+
background: rgba(255, 255, 255, 0.85);
|
|
684
|
+
filter: blur(0.4px);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/* drop tray = a HATCH: a raised lid split down the middle, sitting in a recessed
|
|
688
|
+
bezel over a dark chute. The doors part to swallow a correct catch; a wrong
|
|
689
|
+
toy meets them closed and is rejected. Built in the iOS-register (grouped
|
|
690
|
+
surfaces, hairlines, precise inset shadows) so it reads as one machine. */
|
|
691
|
+
.cc-tray {
|
|
692
|
+
position: relative;
|
|
693
|
+
flex: 1;
|
|
694
|
+
height: 60px;
|
|
695
|
+
border-radius: 14px;
|
|
696
|
+
/* a true hairline, not an outline — the tray should sit IN the panel */
|
|
697
|
+
box-shadow:
|
|
698
|
+
inset 0 0 0 0.5px rgba(60, 60, 67, 0.07),
|
|
699
|
+
0 1px 2px -1px rgba(30, 30, 40, 0.06);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/* clipped frame so the sliding doors disappear off the sides */
|
|
703
|
+
.cc-tray-hatch {
|
|
704
|
+
position: absolute;
|
|
705
|
+
inset: 0;
|
|
706
|
+
border-radius: 14px;
|
|
707
|
+
overflow: hidden;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* the chute, revealed once the doors slide open — not a flat black box but a
|
|
711
|
+
recessed slot with depth: a rim catch-light at the top edge, charcoal walls
|
|
712
|
+
falling away into the dark, and a vignette so the centre reads DEEPEST */
|
|
713
|
+
.cc-tray-mouth {
|
|
714
|
+
position: absolute;
|
|
715
|
+
inset: 0;
|
|
716
|
+
background:
|
|
717
|
+
radial-gradient(130% 100% at 50% 0%, rgba(255, 255, 255, 0.07), transparent 42%),
|
|
718
|
+
radial-gradient(85% 90% at 50% 78%, rgba(0, 0, 0, 0.55), transparent 75%),
|
|
719
|
+
linear-gradient(180deg, #35363d 0%, #1e1f25 48%, #14151a 100%);
|
|
720
|
+
box-shadow:
|
|
721
|
+
inset 0 10px 14px -6px rgba(0, 0, 0, 0.8),
|
|
722
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.07),
|
|
723
|
+
inset 4px 0 8px -5px rgba(0, 0, 0, 0.7),
|
|
724
|
+
inset -4px 0 8px -5px rgba(0, 0, 0, 0.7);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/* while the hatch waits for the catch, a soft green glow breathes up from the
|
|
728
|
+
bottom of the chute — "in here" — and disappears when the doors shut */
|
|
729
|
+
.cc-tray-mouth::after {
|
|
730
|
+
content: '';
|
|
731
|
+
position: absolute;
|
|
732
|
+
inset: 0;
|
|
733
|
+
background: radial-gradient(70% 95% at 50% 88%, rgba(52, 199, 89, 0.28), transparent 68%);
|
|
734
|
+
opacity: 0;
|
|
735
|
+
transition: opacity 0.35s ease;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.cc-tray--open .cc-tray-mouth::after {
|
|
739
|
+
opacity: 1;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/* the two doors form ONE seamless lid when shut — a top catch-light and a soft
|
|
743
|
+
underside shadow give it thickness, with NO centre seam line (the split only
|
|
744
|
+
appears when the doors actually part, so closed it reads as a clean panel). */
|
|
745
|
+
.cc-tray-door {
|
|
746
|
+
position: absolute;
|
|
747
|
+
top: 0;
|
|
748
|
+
bottom: 0;
|
|
749
|
+
width: 51%; /* slight overlap so the two halves never show a hairline gap */
|
|
750
|
+
background: linear-gradient(180deg, #fdfdfe 0%, #edeef2 100%);
|
|
751
|
+
box-shadow:
|
|
752
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.9),
|
|
753
|
+
inset 0 -10px 13px -10px rgba(30, 30, 40, 0.2);
|
|
754
|
+
transition:
|
|
755
|
+
transform 0.42s cubic-bezier(0.645, 0.045, 0.355, 1),
|
|
756
|
+
background 0.25s ease;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.cc-tray-door--l {
|
|
760
|
+
left: 0;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.cc-tray-door--r {
|
|
764
|
+
right: 0;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/* one seamless skin laid over the closed doors: while shut the lid is a single
|
|
768
|
+
uninterrupted panel (no centre seam, no door edges). It fades out fast as the
|
|
769
|
+
doors part, and fades back in late so the shutting slide still reads. */
|
|
770
|
+
.cc-tray-skin {
|
|
771
|
+
position: absolute;
|
|
772
|
+
inset: 0;
|
|
773
|
+
background: linear-gradient(180deg, #fdfdfe 0%, #edeef2 100%);
|
|
774
|
+
box-shadow:
|
|
775
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.9),
|
|
776
|
+
inset 0 -10px 13px -10px rgba(30, 30, 40, 0.2);
|
|
777
|
+
transition:
|
|
778
|
+
background 0.25s ease,
|
|
779
|
+
opacity 0.2s ease 0.3s;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
.cc-tray--open .cc-tray-skin {
|
|
783
|
+
opacity: 0;
|
|
784
|
+
transition:
|
|
785
|
+
background 0.25s ease,
|
|
786
|
+
opacity 0.12s ease;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
.cc-tray--hot .cc-tray-skin {
|
|
790
|
+
background: linear-gradient(180deg, #f5fbf7 0%, #e9f6ee 100%);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
.cc-tray--win .cc-tray-skin {
|
|
794
|
+
background: linear-gradient(180deg, #f0faf3 0%, #ddf2e4 100%);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
.cc-tray--no .cc-tray-skin {
|
|
798
|
+
background: linear-gradient(180deg, #fff7ee 0%, #fdecd8 100%);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/* the label rides on top of the closed doors */
|
|
802
|
+
.cc-tray-label {
|
|
803
|
+
position: absolute;
|
|
804
|
+
inset: 0;
|
|
805
|
+
z-index: 2;
|
|
806
|
+
display: flex;
|
|
807
|
+
flex-direction: column;
|
|
808
|
+
align-items: center;
|
|
809
|
+
justify-content: center;
|
|
810
|
+
gap: 4px;
|
|
811
|
+
color: var(--cc-muted);
|
|
812
|
+
font-size: 0.75rem; /* 12px label */
|
|
813
|
+
font-weight: 500;
|
|
814
|
+
letter-spacing: -0.004em;
|
|
815
|
+
pointer-events: none;
|
|
816
|
+
transition:
|
|
817
|
+
opacity 0.18s ease,
|
|
818
|
+
color 0.25s ease;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/* verdict labels carry a touch more weight than the resting hint */
|
|
822
|
+
.cc-tray--hot .cc-tray-label,
|
|
823
|
+
.cc-tray--win .cc-tray-label,
|
|
824
|
+
.cc-tray--no .cc-tray-label {
|
|
825
|
+
font-weight: 600;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/* a single thin accent ring expresses each state — restrained, themed, never a
|
|
829
|
+
flooded colour block */
|
|
830
|
+
.cc-tray::before {
|
|
831
|
+
content: '';
|
|
832
|
+
position: absolute;
|
|
833
|
+
inset: 0;
|
|
834
|
+
z-index: 3;
|
|
835
|
+
border-radius: 14px;
|
|
836
|
+
box-shadow: inset 0 0 0 1.5px transparent;
|
|
837
|
+
transition: box-shadow 0.25s ease;
|
|
838
|
+
pointer-events: none;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/* OPEN — doors part, chute shows, label clears out of the way */
|
|
842
|
+
.cc-tray--open .cc-tray-door--l {
|
|
843
|
+
transform: translateX(-101%);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
.cc-tray--open .cc-tray-door--r {
|
|
847
|
+
transform: translateX(101%);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.cc-tray--open .cc-tray-label {
|
|
851
|
+
opacity: 0;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/* HOT — a toy hovers over the closed hatch: ready. Green ring + label, only a
|
|
855
|
+
whisper of tint on the lid (no generic green box). */
|
|
856
|
+
.cc-tray--hot .cc-tray-door {
|
|
857
|
+
background: linear-gradient(180deg, #f5fbf7 0%, #e9f6ee 100%);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
.cc-tray--hot .cc-tray-label {
|
|
861
|
+
color: #1f8a3b;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.cc-tray--hot::before {
|
|
865
|
+
box-shadow: inset 0 0 0 1.5px rgba(52, 199, 89, 0.5);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/* WIN — the hatch has snapped shut on the catch: green ring + a single ripple */
|
|
869
|
+
.cc-tray--win .cc-tray-door {
|
|
870
|
+
background: linear-gradient(180deg, #f0faf3 0%, #ddf2e4 100%);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
.cc-tray--win .cc-tray-label {
|
|
874
|
+
color: #1f8a3b;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.cc-tray--win::before {
|
|
878
|
+
box-shadow: inset 0 0 0 1.5px rgba(52, 199, 89, 0.62);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/* two waves rolling off the tray, box-shadow spread so they follow the
|
|
882
|
+
rounded shape exactly — scaling a border warps the corner radii */
|
|
883
|
+
.cc-tray--win::after {
|
|
884
|
+
content: '';
|
|
885
|
+
position: absolute;
|
|
886
|
+
inset: 0;
|
|
887
|
+
z-index: 3;
|
|
888
|
+
border-radius: 14px;
|
|
889
|
+
animation: cc-ring 1s cubic-bezier(0.2, 0.6, 0.35, 1) 0.08s both;
|
|
890
|
+
pointer-events: none;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
@keyframes cc-ring {
|
|
894
|
+
0% {
|
|
895
|
+
box-shadow:
|
|
896
|
+
0 0 0 0 rgba(52, 199, 89, 0.5),
|
|
897
|
+
0 0 0 0 rgba(52, 199, 89, 0.35);
|
|
898
|
+
}
|
|
899
|
+
45% {
|
|
900
|
+
box-shadow:
|
|
901
|
+
0 0 0 9px rgba(52, 199, 89, 0.15),
|
|
902
|
+
0 0 0 3px rgba(52, 199, 89, 0.3);
|
|
903
|
+
}
|
|
904
|
+
100% {
|
|
905
|
+
box-shadow:
|
|
906
|
+
0 0 0 15px rgba(52, 199, 89, 0),
|
|
907
|
+
0 0 0 10px rgba(52, 199, 89, 0);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/* a single restrained confetti burst out of the hatch on a correct catch */
|
|
912
|
+
.cc-confetti {
|
|
913
|
+
position: absolute;
|
|
914
|
+
left: 50%;
|
|
915
|
+
top: 32%;
|
|
916
|
+
z-index: 4;
|
|
917
|
+
pointer-events: none;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
.cc-confetti i {
|
|
921
|
+
position: absolute;
|
|
922
|
+
width: 5px;
|
|
923
|
+
height: 8px;
|
|
924
|
+
border-radius: 2px;
|
|
925
|
+
opacity: 0;
|
|
926
|
+
animation: cc-pop 1.05s cubic-bezier(0.3, 0.55, 0.45, 1) both;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/* every other piece is a round dot, a size down — a mixed handful, not a grid */
|
|
930
|
+
.cc-confetti i:nth-child(even) {
|
|
931
|
+
width: 4.5px;
|
|
932
|
+
height: 4.5px;
|
|
933
|
+
border-radius: 50%;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/* a real toss: up to an apex (--dy) by mid-flight, then gravity wins and the
|
|
937
|
+
piece falls back past most of its rise while it fades and keeps spinning */
|
|
938
|
+
@keyframes cc-pop {
|
|
939
|
+
0% {
|
|
940
|
+
opacity: 0;
|
|
941
|
+
transform: translate(0, 2px) rotate(0deg) scale(0.4);
|
|
942
|
+
}
|
|
943
|
+
12% {
|
|
944
|
+
opacity: 1;
|
|
945
|
+
}
|
|
946
|
+
50% {
|
|
947
|
+
transform: translate(calc(var(--dx) * 0.65), var(--dy)) rotate(calc(var(--dr) * 0.6)) scale(1);
|
|
948
|
+
}
|
|
949
|
+
100% {
|
|
950
|
+
opacity: 0;
|
|
951
|
+
transform: translate(var(--dx), calc(var(--dy) * 0.2)) rotate(var(--dr)) scale(0.85);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/* NO — the doors stayed shut: an amber ring + label and one apologetic shake.
|
|
956
|
+
Amber (not red) — it's "try again", not an error. */
|
|
957
|
+
.cc-tray--no .cc-tray-door {
|
|
958
|
+
background: linear-gradient(180deg, #fff7ee 0%, #fdecd8 100%);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
.cc-tray--no .cc-tray-label {
|
|
962
|
+
color: #c2620e;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.cc-tray--no::before {
|
|
966
|
+
box-shadow: inset 0 0 0 1.5px rgba(255, 149, 0, 0.55);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.cc-tray--no {
|
|
970
|
+
animation: cc-sorry 0.85s ease 0.02s;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
@keyframes cc-sorry {
|
|
974
|
+
18% {
|
|
975
|
+
transform: translateX(-3.5px);
|
|
976
|
+
}
|
|
977
|
+
42% {
|
|
978
|
+
transform: translateX(2.5px);
|
|
979
|
+
}
|
|
980
|
+
66% {
|
|
981
|
+
transform: translateX(-1.5px);
|
|
982
|
+
}
|
|
983
|
+
100% {
|
|
984
|
+
transform: translateX(0);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/* action: a real arcade button — glossy convex dome in a recessed bezel */
|
|
989
|
+
.cc-action {
|
|
990
|
+
--btn: var(--clawcap-action, #ff5159);
|
|
991
|
+
position: relative;
|
|
992
|
+
flex: none;
|
|
993
|
+
width: 56px;
|
|
994
|
+
height: 56px;
|
|
995
|
+
border: none;
|
|
996
|
+
border-radius: 50%;
|
|
997
|
+
background:
|
|
998
|
+
radial-gradient(circle at 50% 30%, #ff8a90, var(--btn) 55%, #e23740 100%);
|
|
999
|
+
color: #fff;
|
|
1000
|
+
font-family: inherit;
|
|
1001
|
+
font-size: 0.75rem; /* 12px label, same step as the tray */
|
|
1002
|
+
font-weight: 700;
|
|
1003
|
+
letter-spacing: 0.01em;
|
|
1004
|
+
text-shadow: 0 1px 1px rgba(120, 10, 20, 0.35);
|
|
1005
|
+
cursor: pointer;
|
|
1006
|
+
/* bezel ring it sits in + lift + inner shading that makes it convex */
|
|
1007
|
+
box-shadow:
|
|
1008
|
+
0 0 0 5px var(--cc-fill),
|
|
1009
|
+
0 0 0 5.5px rgba(60, 60, 67, 0.1),
|
|
1010
|
+
0 5px 10px -2px rgba(190, 30, 45, 0.45),
|
|
1011
|
+
inset 0 2px 3px rgba(255, 255, 255, 0.45),
|
|
1012
|
+
inset 0 -4px 7px rgba(150, 10, 25, 0.4);
|
|
1013
|
+
transition:
|
|
1014
|
+
transform 0.12s ease,
|
|
1015
|
+
box-shadow 0.12s ease,
|
|
1016
|
+
filter 0.2s ease;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/* the glossy catch-light that makes it look like candy */
|
|
1020
|
+
.cc-action::before {
|
|
1021
|
+
content: '';
|
|
1022
|
+
position: absolute;
|
|
1023
|
+
top: 6px;
|
|
1024
|
+
left: 50%;
|
|
1025
|
+
transform: translateX(-50%);
|
|
1026
|
+
width: 60%;
|
|
1027
|
+
height: 30%;
|
|
1028
|
+
border-radius: 50%;
|
|
1029
|
+
background: linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0));
|
|
1030
|
+
pointer-events: none;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
.cc-action:active:not(:disabled) {
|
|
1034
|
+
transform: translateY(2px);
|
|
1035
|
+
box-shadow:
|
|
1036
|
+
0 0 0 5px var(--cc-fill),
|
|
1037
|
+
0 0 0 5.5px rgba(60, 60, 67, 0.1),
|
|
1038
|
+
0 2px 4px -1px rgba(190, 30, 45, 0.4),
|
|
1039
|
+
inset 0 2px 3px rgba(255, 255, 255, 0.35),
|
|
1040
|
+
inset 0 -2px 4px rgba(150, 10, 25, 0.45);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
/* disabled: a clean matte-grey dome — still a button, just powered down.
|
|
1044
|
+
(A desaturating filter over red turned it a muddy brown — never that.) */
|
|
1045
|
+
.cc-action:disabled {
|
|
1046
|
+
background: radial-gradient(circle at 50% 30%, #f7f8fa, #e2e4e9 55%, #c8ccd4 100%);
|
|
1047
|
+
color: #9a9da6;
|
|
1048
|
+
text-shadow: none;
|
|
1049
|
+
cursor: default;
|
|
1050
|
+
box-shadow:
|
|
1051
|
+
0 0 0 5px var(--cc-fill),
|
|
1052
|
+
0 0 0 5.5px rgba(60, 60, 67, 0.1),
|
|
1053
|
+
0 4px 8px -3px rgba(30, 30, 40, 0.18),
|
|
1054
|
+
inset 0 2px 3px rgba(255, 255, 255, 0.7),
|
|
1055
|
+
inset 0 -4px 7px rgba(90, 95, 105, 0.22);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.cc-action:disabled::before {
|
|
1059
|
+
opacity: 0.55; /* the catch-light dims with the button */
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/* "release now" — a soft green pulse rings the button while the catch hovers
|
|
1063
|
+
over the tray, pointing the player at the one control that finishes the job */
|
|
1064
|
+
.cc-action::after {
|
|
1065
|
+
content: '';
|
|
1066
|
+
position: absolute;
|
|
1067
|
+
inset: -9px;
|
|
1068
|
+
border-radius: 50%;
|
|
1069
|
+
border: 2px solid rgba(52, 199, 89, 0.55);
|
|
1070
|
+
opacity: 0;
|
|
1071
|
+
pointer-events: none;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.cc-action--ready::after {
|
|
1075
|
+
animation: cc-ready 1.3s ease-out infinite;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
@keyframes cc-ready {
|
|
1079
|
+
0% {
|
|
1080
|
+
opacity: 0;
|
|
1081
|
+
transform: scale(0.8);
|
|
1082
|
+
}
|
|
1083
|
+
35% {
|
|
1084
|
+
opacity: 0.9;
|
|
1085
|
+
}
|
|
1086
|
+
100% {
|
|
1087
|
+
opacity: 0;
|
|
1088
|
+
transform: scale(1.16);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
.clawcap-hint {
|
|
1093
|
+
margin: 14px 0 0;
|
|
1094
|
+
text-align: center;
|
|
1095
|
+
font-size: 0.6875rem; /* 11px caption */
|
|
1096
|
+
letter-spacing: -0.004em;
|
|
1097
|
+
color: rgba(60, 60, 67, 0.48); /* iOS tertiary label */
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/* ── reduced motion ──────────────────────────────────────────────────────────
|
|
1101
|
+
Drop the DECORATIVE flourishes — the success ring, the apologetic shake, the
|
|
1102
|
+
pill's springy glide, the hatch-door slide — to instant/none. Keep colour &
|
|
1103
|
+
opacity (allowed) and the user-driven claw interaction (meaningful motion).
|
|
1104
|
+
The Motion-powered transforms are handled by <MotionConfig reducedMotion>. */
|
|
1105
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1106
|
+
.clawcap-steps-pill {
|
|
1107
|
+
transition: none; /* the active segment snaps, no glide */
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
.cc-tray-door {
|
|
1111
|
+
transition: background 0.2s ease; /* doors snap open/shut, no slide */
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
.cc-tray--win::after {
|
|
1115
|
+
animation: none; /* no rippling ring */
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
.cc-tray--no {
|
|
1119
|
+
animation: none; /* no apologetic shake — the amber colour still reads */
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
.cc-confetti i {
|
|
1123
|
+
animation: none; /* no confetti burst */
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
.cc-action--ready::after {
|
|
1127
|
+
animation: none; /* steady ring instead of a pulse — the cue still reads */
|
|
1128
|
+
opacity: 0.7;
|
|
1129
|
+
transform: none;
|
|
1130
|
+
}
|
|
1131
|
+
}
|