@vobs/captcha 1.0.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.
@@ -0,0 +1,437 @@
1
+ /*
2
+ * Default styles for the provider-agnostic Captcha UI primitive.
3
+ *
4
+ * The challenge renderer owns the appearance and interaction of the actual
5
+ * captcha (slider, puzzle, third-party widget, etc.). These rules only style
6
+ * the Vobs container, messages, and actions supplied by @vobs/captcha.
7
+ */
8
+
9
+ .vobs-captcha {
10
+ --vobs-captcha-bg: var(--vobs-captcha-surface, #ffffff);
11
+ --vobs-captcha-border: var(--vobs-captcha-border-color, #d9dee8);
12
+ --vobs-captcha-text: var(--vobs-captcha-text-color, #1f2937);
13
+ --vobs-captcha-muted: var(--vobs-captcha-muted-color, #667085);
14
+ --vobs-captcha-danger: var(--vobs-captcha-danger-color, #c93636);
15
+ --vobs-captcha-primary: var(--vobs-captcha-primary-color, #2563eb);
16
+ --vobs-captcha-primary-hover: var(--vobs-captcha-primary-hover-color, #1d4ed8);
17
+ --vobs-captcha-focus: var(--vobs-captcha-focus-color, #2563eb);
18
+ --vobs-captcha-radius: var(--vobs-captcha-radius-value, 8px);
19
+ --vobs-captcha-spacing: var(--vobs-captcha-spacing-value, 12px);
20
+
21
+ display: flex;
22
+ flex-direction: column;
23
+ gap: var(--vobs-captcha-spacing);
24
+ width: min(100%, 520px);
25
+ min-width: 0;
26
+ padding: 16px;
27
+ border: 1px solid var(--vobs-captcha-border);
28
+ border-radius: var(--vobs-captcha-radius);
29
+ color: var(--vobs-captcha-text);
30
+ background: var(--vobs-captcha-bg);
31
+ font: 400 14px/1.45 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
32
+ }
33
+
34
+ .vobs-captcha__header {
35
+ color: var(--vobs-captcha-text);
36
+ font-weight: 600;
37
+ }
38
+
39
+ .vobs-captcha__header:empty {
40
+ display: none;
41
+ }
42
+
43
+ .vobs-captcha__message-host:empty {
44
+ display: none;
45
+ }
46
+
47
+ .vobs-captcha__message-host .vobs-captcha__message {
48
+ margin-top: -2px;
49
+ text-align: left;
50
+ }
51
+
52
+ .vobs-captcha__challenge {
53
+ display: flex;
54
+ min-width: 0;
55
+ min-height: 48px;
56
+ align-items: center;
57
+ justify-content: center;
58
+ }
59
+
60
+ .vobs-captcha__challenge > * {
61
+ max-width: 100%;
62
+ }
63
+
64
+ .vobs-captcha__message {
65
+ margin: 0;
66
+ color: var(--vobs-captcha-muted);
67
+ text-align: center;
68
+ }
69
+
70
+ .vobs-captcha[data-status="error"] .vobs-captcha__message {
71
+ color: var(--vobs-captcha-danger);
72
+ }
73
+
74
+ .vobs-captcha[data-status="verified"] .vobs-captcha__message {
75
+ color: var(--vobs-captcha-primary);
76
+ }
77
+
78
+ .vobs-captcha[data-status="loading"] .vobs-captcha__challenge,
79
+ .vobs-captcha[data-status="verifying"] .vobs-captcha__challenge {
80
+ opacity: 0.72;
81
+ }
82
+
83
+ .vobs-captcha__actions {
84
+ display: flex;
85
+ flex-wrap: wrap;
86
+ gap: 8px;
87
+ justify-content: flex-end;
88
+ }
89
+
90
+ .vobs-captcha__action {
91
+ min-height: 36px;
92
+ padding: 7px 14px;
93
+ border: 1px solid var(--vobs-captcha-border);
94
+ border-radius: calc(var(--vobs-captcha-radius) - 2px);
95
+ color: var(--vobs-captcha-text);
96
+ background: transparent;
97
+ font: inherit;
98
+ cursor: pointer;
99
+ transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease;
100
+ }
101
+
102
+ .vobs-captcha__action-icon {
103
+ display: inline-flex;
104
+ width: 16px;
105
+ height: 16px;
106
+ margin-right: 6px;
107
+ align-items: center;
108
+ justify-content: center;
109
+ }
110
+
111
+ .vobs-captcha__action-icon > svg {
112
+ width: 100%;
113
+ height: 100%;
114
+ }
115
+
116
+ .vobs-captcha__action:hover:not(:disabled) {
117
+ border-color: var(--vobs-captcha-primary);
118
+ color: var(--vobs-captcha-primary-hover);
119
+ background: color-mix(in srgb, var(--vobs-captcha-primary) 8%, transparent);
120
+ }
121
+
122
+ .vobs-captcha__action:focus-visible {
123
+ outline: 2px solid var(--vobs-captcha-focus);
124
+ outline-offset: 2px;
125
+ }
126
+
127
+ .vobs-captcha__action:disabled,
128
+ .vobs-captcha[aria-disabled="true"] .vobs-captcha__action {
129
+ opacity: 0.55;
130
+ cursor: not-allowed;
131
+ }
132
+
133
+ .vobs-slider-captcha {
134
+ position: relative;
135
+ display: grid;
136
+ grid-template-columns: minmax(0, 1fr);
137
+ width: max-content;
138
+ max-width: none;
139
+ gap: 10px 12px;
140
+ padding: 12px;
141
+ background: var(--vobs-captcha-surface, var(--bg-base-secondary, #ffffff));
142
+ }
143
+
144
+ .vobs-slider-captcha--dismissed { display: none; }
145
+
146
+ .vobs-slider-captcha .vobs-captcha__header {
147
+ grid-column: 1;
148
+ grid-row: 1;
149
+ display: none;
150
+ min-height: 0;
151
+ }
152
+
153
+ .vobs-slider-captcha .vobs-captcha__actions {
154
+ display: contents;
155
+ }
156
+
157
+ .vobs-slider-captcha .vobs-captcha__action {
158
+ position: absolute;
159
+ z-index: 5;
160
+ display: inline-flex;
161
+ width: 28px;
162
+ min-width: 28px;
163
+ min-height: 28px;
164
+ padding: 0;
165
+ border-radius: 4px;
166
+ align-items: center;
167
+ justify-content: center;
168
+ font-size: 0;
169
+ }
170
+
171
+ .vobs-slider-captcha .vobs-captcha__action--retry {
172
+ top: 176px;
173
+ right: 20px;
174
+ }
175
+
176
+ .vobs-slider-captcha .vobs-captcha__action--cancel {
177
+ top: 20px;
178
+ right: 20px;
179
+ font-size: 18px;
180
+ line-height: 1;
181
+ }
182
+
183
+ .vobs-slider-captcha .vobs-captcha__action-icon {
184
+ width: 14px;
185
+ height: 14px;
186
+ margin: 0;
187
+ }
188
+
189
+ .vobs-slider-captcha .vobs-captcha__challenge {
190
+ grid-column: 1;
191
+ grid-row: 1;
192
+ }
193
+
194
+ .vobs-slider-captcha .vobs-captcha__challenge > .vobs-slider-captcha__challenge {
195
+ max-width: none;
196
+ }
197
+
198
+ .vobs-slider-captcha__challenge {
199
+ display: grid;
200
+ width: max-content;
201
+ gap: 10px;
202
+ }
203
+
204
+ .vobs-slider-captcha__visual {
205
+ position: relative;
206
+ overflow: hidden;
207
+ width: 480px;
208
+ height: 260px;
209
+ max-width: none;
210
+ border-radius: 6px;
211
+ background:
212
+ linear-gradient(135deg, rgba(255, 255, 255, .14), transparent 45%),
213
+ linear-gradient(45deg, rgba(0, 0, 0, .1), transparent 55%),
214
+ #8aa3b8;
215
+ background-repeat: no-repeat;
216
+ background-size: cover;
217
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .16);
218
+ }
219
+
220
+ .vobs-slider-captcha__visual::after {
221
+ position: absolute;
222
+ inset: 0;
223
+ content: '';
224
+ pointer-events: none;
225
+ background: repeating-linear-gradient(112deg, transparent 0 17px, rgba(255, 255, 255, .07) 18px 19px);
226
+ }
227
+
228
+ .vobs-slider-captcha__target,
229
+ .vobs-slider-captcha__piece,
230
+ .vobs-slider-captcha__decoy {
231
+ position: absolute;
232
+ z-index: 1;
233
+ box-sizing: border-box;
234
+ overflow: hidden;
235
+ border: 0;
236
+ }
237
+
238
+ .vobs-slider-captcha__target {
239
+ }
240
+
241
+ .vobs-slider-captcha__decoy {
242
+ pointer-events: none;
243
+ }
244
+
245
+ .vobs-slider-captcha__image {
246
+ width: 100%;
247
+ height: 100%;
248
+ background-repeat: no-repeat;
249
+ pointer-events: none;
250
+ transform-origin: center;
251
+ }
252
+
253
+ .vobs-slider-captcha__target::after,
254
+ .vobs-slider-captcha__decoy::after {
255
+ position: absolute;
256
+ inset: 0;
257
+ content: '';
258
+ pointer-events: none;
259
+ }
260
+
261
+ .vobs-slider-captcha__target::after {
262
+ background: rgba(8, 19, 34, .2);
263
+ box-shadow: inset 0 0 14px rgba(4, 12, 24, .78);
264
+ }
265
+
266
+ .vobs-slider-captcha__decoy::after {
267
+ background: rgba(8, 19, 34, .16);
268
+ box-shadow: inset 0 0 12px rgba(4, 12, 24, .66);
269
+ }
270
+
271
+ .vobs-slider-captcha__target--puzzle,
272
+ .vobs-slider-captcha__piece--puzzle,
273
+ .vobs-slider-captcha__decoy--puzzle {
274
+ clip-path: polygon(0 0, 38% 0, 43% 12%, 57% 12%, 62% 0, 100% 0, 100% 38%, 88% 43%, 88% 57%, 100% 62%, 100% 100%, 62% 100%, 57% 88%, 43% 88%, 38% 100%, 0 100%);
275
+ }
276
+
277
+ .vobs-slider-captcha__target--circle,
278
+ .vobs-slider-captcha__piece--circle,
279
+ .vobs-slider-captcha__decoy--circle {
280
+ clip-path: polygon(48% 1%, 61% 7%, 73% 3%, 82% 15%, 96% 22%, 92% 36%, 99% 48%, 91% 60%, 94% 75%, 80% 82%, 70% 96%, 56% 91%, 46% 99%, 35% 89%, 19% 94%, 14% 80%, 1% 70%, 8% 56%, 1% 44%, 9% 32%, 5% 18%, 21% 15%, 31% 3%, 42% 9%);
281
+ }
282
+
283
+ .vobs-slider-captcha__target--square,
284
+ .vobs-slider-captcha__piece--square,
285
+ .vobs-slider-captcha__decoy--square {
286
+ clip-path: polygon(0 0, 34% 0, 38% 10%, 55% 10%, 60% 0, 100% 0, 100% 32%, 89% 38%, 89% 57%, 100% 63%, 100% 100%, 63% 100%, 57% 89%, 40% 89%, 34% 100%, 0 100%, 0 65%, 11% 59%, 11% 42%, 0 35%);
287
+ }
288
+
289
+ .vobs-slider-captcha__target--triangle,
290
+ .vobs-slider-captcha__piece--triangle,
291
+ .vobs-slider-captcha__decoy--triangle {
292
+ clip-path: polygon(50% 0, 59% 14%, 72% 12%, 76% 26%, 100% 100%, 65% 94%, 56% 100%, 47% 90%, 35% 96%, 0 100%, 24% 27%, 38% 24%, 41% 11%);
293
+ }
294
+
295
+ .vobs-slider-captcha__piece {
296
+ z-index: 2;
297
+ pointer-events: auto;
298
+ border: 0;
299
+ background-repeat: no-repeat;
300
+ box-shadow: 0 10px 24px rgba(0, 0, 0, .66), 0 3px 7px rgba(0, 0, 0, .48), 0 1px 2px rgba(255, 255, 255, .28) inset;
301
+ will-change: left, transform;
302
+ cursor: grab;
303
+ touch-action: none;
304
+ }
305
+
306
+ .vobs-slider-captcha__piece:active { cursor: grabbing; }
307
+
308
+ .vobs-slider-captcha__track {
309
+ position: relative;
310
+ height: 33px;
311
+ box-sizing: border-box;
312
+ border: 1px solid var(--vobs-captcha-border);
313
+ border-radius: 6px;
314
+ background: color-mix(in srgb, var(--vobs-captcha-text) 5%, transparent);
315
+ }
316
+
317
+ .vobs-slider-captcha__track-prompt {
318
+ position: absolute;
319
+ inset: 0;
320
+ display: flex;
321
+ align-items: center;
322
+ justify-content: center;
323
+ color: var(--vobs-captcha-muted);
324
+ font-size: 12px;
325
+ pointer-events: none;
326
+ transition: opacity 120ms ease;
327
+ }
328
+
329
+ .vobs-slider-captcha__track[data-has-moved="true"] .vobs-slider-captcha__track-prompt {
330
+ opacity: 0;
331
+ }
332
+
333
+ .vobs-slider-captcha__handle {
334
+ position: absolute;
335
+ top: 1px;
336
+ z-index: 1;
337
+ width: 50px;
338
+ height: 29px;
339
+ padding: 0 10px;
340
+ border: 1px solid var(--vobs-captcha-primary);
341
+ border-radius: 6px;
342
+ color: var(--vobs-captcha-primary);
343
+ background: var(--vobs-captcha-bg);
344
+ box-shadow: 0 2px 7px rgba(0, 0, 0, .2);
345
+ font: 600 13px/1.2 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
346
+ cursor: grab;
347
+ touch-action: none;
348
+ transition: box-shadow 120ms ease, background-color 120ms ease;
349
+ }
350
+
351
+ .vobs-slider-captcha__handle:hover,
352
+ .vobs-slider-captcha__challenge[data-dragging="true"] .vobs-slider-captcha__handle {
353
+ background: color-mix(in srgb, var(--vobs-captcha-primary) 10%, var(--vobs-captcha-bg));
354
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--vobs-captcha-focus) 20%, transparent), 0 3px 8px rgba(0, 0, 0, .24);
355
+ }
356
+
357
+ .vobs-slider-captcha__handle:focus-visible {
358
+ outline: 2px solid var(--vobs-captcha-focus);
359
+ outline-offset: 2px;
360
+ }
361
+
362
+ .vobs-slider-captcha__handle:disabled {
363
+ opacity: .55;
364
+ cursor: not-allowed;
365
+ }
366
+
367
+ .vobs-slider-captcha__handle--verified,
368
+ .vobs-slider-captcha__handle--verified:disabled {
369
+ border-color: #1f9d55;
370
+ color: #ffffff;
371
+ background: #1f9d55;
372
+ box-shadow: 0 3px 8px rgba(20, 126, 70, .38);
373
+ opacity: 1;
374
+ }
375
+
376
+ .vobs-slider-captcha__error {
377
+ position: absolute;
378
+ right: 0;
379
+ bottom: 0;
380
+ left: 0;
381
+ z-index: 4;
382
+ margin: 0;
383
+ padding: 7px 10px;
384
+ color: #ffffff;
385
+ background: rgba(166, 35, 35, .9);
386
+ font-size: 12px;
387
+ line-height: 1.35;
388
+ text-align: center;
389
+ }
390
+
391
+ .vobs-slider-captcha__notice {
392
+ position: absolute;
393
+ right: 0;
394
+ bottom: 0;
395
+ left: 0;
396
+ z-index: 4;
397
+ margin: 0;
398
+ padding: 7px 10px;
399
+ color: #ffffff;
400
+ background: rgba(15, 23, 42, .78);
401
+ font-size: 12px;
402
+ line-height: 1.35;
403
+ text-align: center;
404
+ }
405
+
406
+ .vobs-slider-captcha__prompt,
407
+ .vobs-slider-captcha__success {
408
+ margin: 0;
409
+ text-align: center;
410
+ }
411
+
412
+ .vobs-slider-captcha__prompt { color: var(--vobs-captcha-muted); }
413
+ .vobs-slider-captcha__success {
414
+ padding: 20px 12px;
415
+ color: var(--vobs-captcha-primary);
416
+ font-weight: 600;
417
+ }
418
+
419
+ @media (prefers-color-scheme: dark) {
420
+ .vobs-captcha {
421
+ --vobs-captcha-bg: var(--vobs-captcha-surface, #1f2937);
422
+ --vobs-captcha-border: var(--vobs-captcha-border-color, #465166);
423
+ --vobs-captcha-text: var(--vobs-captcha-text-color, #f3f4f6);
424
+ --vobs-captcha-muted: var(--vobs-captcha-muted-color, #aab3c2);
425
+ --vobs-captcha-danger: var(--vobs-captcha-danger-color, #ff8b8b);
426
+ --vobs-captcha-primary: var(--vobs-captcha-primary-color, #78a9ff);
427
+ --vobs-captcha-primary-hover: var(--vobs-captcha-primary-hover-color, #a7c7ff);
428
+ --vobs-captcha-focus: var(--vobs-captcha-focus-color, #9bc1ff);
429
+ }
430
+ }
431
+
432
+ @media (prefers-reduced-motion: reduce) {
433
+ .vobs-captcha__action,
434
+ .vobs-slider-captcha__handle {
435
+ transition: none;
436
+ }
437
+ }