@jjlmoya/utils-hardware 1.16.0 → 1.18.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 (111) hide show
  1. package/package.json +1 -1
  2. package/src/category/i18n/de.ts +4 -4
  3. package/src/category/i18n/id.ts +3 -3
  4. package/src/category/i18n/it.ts +3 -3
  5. package/src/category/i18n/nl.ts +3 -3
  6. package/src/category/i18n/pl.ts +4 -4
  7. package/src/category/i18n/pt.ts +3 -3
  8. package/src/category/i18n/ru.ts +6 -6
  9. package/src/category/i18n/sv.ts +3 -3
  10. package/src/category/i18n/tr.ts +3 -3
  11. package/src/category/i18n/zh.ts +3 -3
  12. package/src/category/index.ts +2 -1
  13. package/src/entries.ts +4 -1
  14. package/src/index.ts +1 -0
  15. package/src/layouts/PreviewLayout.astro +1 -0
  16. package/src/tests/diacritics_density.test.ts +118 -0
  17. package/src/tests/inverted_punctuation.test.ts +84 -0
  18. package/src/tests/locale_completeness.test.ts +2 -2
  19. package/src/tests/no_en_dash.test.ts +70 -0
  20. package/src/tests/no_h1_in_components.test.ts +1 -1
  21. package/src/tests/script_density.test.ts +94 -0
  22. package/src/tests/tool_validation.test.ts +2 -2
  23. package/src/tool/batteryHealthEstimator/bibliography.ts +8 -8
  24. package/src/tool/batteryHealthEstimator/i18n/de.ts +1 -1
  25. package/src/tool/batteryHealthEstimator/i18n/en.ts +1 -1
  26. package/src/tool/batteryHealthEstimator/i18n/fr.ts +5 -5
  27. package/src/tool/batteryHealthEstimator/i18n/id.ts +1 -1
  28. package/src/tool/batteryHealthEstimator/i18n/nl.ts +1 -1
  29. package/src/tool/batteryHealthEstimator/i18n/pl.ts +2 -2
  30. package/src/tool/batteryHealthEstimator/i18n/pt.ts +1 -1
  31. package/src/tool/batteryHealthEstimator/i18n/ru.ts +5 -5
  32. package/src/tool/batteryHealthEstimator/i18n/sv.ts +1 -1
  33. package/src/tool/batteryHealthEstimator/i18n/tr.ts +1 -1
  34. package/src/tool/batteryHealthEstimator/i18n/zh.ts +1 -1
  35. package/src/tool/colorAccuracyTest/bibliography.astro +14 -0
  36. package/src/tool/colorAccuracyTest/bibliography.ts +16 -0
  37. package/src/tool/colorAccuracyTest/color-accuracy-test.css +841 -0
  38. package/src/tool/colorAccuracyTest/component.astro +157 -0
  39. package/src/tool/colorAccuracyTest/entry.ts +29 -0
  40. package/src/tool/colorAccuracyTest/i18n/de.ts +284 -0
  41. package/src/tool/colorAccuracyTest/i18n/en.ts +284 -0
  42. package/src/tool/colorAccuracyTest/i18n/es.ts +284 -0
  43. package/src/tool/colorAccuracyTest/i18n/fr.ts +284 -0
  44. package/src/tool/colorAccuracyTest/i18n/id.ts +284 -0
  45. package/src/tool/colorAccuracyTest/i18n/it.ts +284 -0
  46. package/src/tool/colorAccuracyTest/i18n/ja.ts +284 -0
  47. package/src/tool/colorAccuracyTest/i18n/ko.ts +284 -0
  48. package/src/tool/colorAccuracyTest/i18n/nl.ts +284 -0
  49. package/src/tool/colorAccuracyTest/i18n/pl.ts +284 -0
  50. package/src/tool/colorAccuracyTest/i18n/pt.ts +284 -0
  51. package/src/tool/colorAccuracyTest/i18n/ru.ts +284 -0
  52. package/src/tool/colorAccuracyTest/i18n/sv.ts +284 -0
  53. package/src/tool/colorAccuracyTest/i18n/tr.ts +284 -0
  54. package/src/tool/colorAccuracyTest/i18n/zh.ts +284 -0
  55. package/src/tool/colorAccuracyTest/index.ts +9 -0
  56. package/src/tool/colorAccuracyTest/logic.ts +226 -0
  57. package/src/tool/colorAccuracyTest/seo.astro +15 -0
  58. package/src/tool/colorAccuracyTest/ui.ts +27 -0
  59. package/src/tool/deadPixelTest/i18n/ru.ts +6 -6
  60. package/src/tool/deadPixelTest/i18n/sv.ts +1 -1
  61. package/src/tool/deadPixelTest/i18n/zh.ts +5 -5
  62. package/src/tool/gamepadTest/gamepad-test.css +171 -3
  63. package/src/tool/gamepadTest/i18n/es.ts +4 -4
  64. package/src/tool/gamepadTest/i18n/ru.ts +2 -2
  65. package/src/tool/gamepadTest/i18n/zh.ts +1 -1
  66. package/src/tool/gamepadVibrationTester/bibliography.ts +8 -8
  67. package/src/tool/gamepadVibrationTester/i18n/es.ts +1 -1
  68. package/src/tool/gamepadVibrationTester/i18n/fr.ts +2 -2
  69. package/src/tool/gamepadVibrationTester/i18n/ru.ts +3 -3
  70. package/src/tool/keyboardTest/keyboard-test.css +115 -2
  71. package/src/tool/mousePollingTest/bibliography.ts +8 -8
  72. package/src/tool/mousePollingTest/i18n/de.ts +1 -1
  73. package/src/tool/mousePollingTest/i18n/en.ts +1 -1
  74. package/src/tool/mousePollingTest/i18n/es.ts +1 -1
  75. package/src/tool/mousePollingTest/i18n/fr.ts +3 -3
  76. package/src/tool/mousePollingTest/i18n/id.ts +1 -1
  77. package/src/tool/mousePollingTest/i18n/it.ts +1 -1
  78. package/src/tool/mousePollingTest/i18n/ja.ts +1 -1
  79. package/src/tool/mousePollingTest/i18n/ko.ts +1 -1
  80. package/src/tool/mousePollingTest/i18n/nl.ts +1 -1
  81. package/src/tool/mousePollingTest/i18n/pl.ts +2 -2
  82. package/src/tool/mousePollingTest/i18n/pt.ts +1 -1
  83. package/src/tool/mousePollingTest/i18n/ru.ts +3 -3
  84. package/src/tool/mousePollingTest/i18n/sv.ts +1 -1
  85. package/src/tool/mousePollingTest/i18n/tr.ts +1 -1
  86. package/src/tool/mousePollingTest/i18n/zh.ts +2 -2
  87. package/src/tool/refreshRateDetector/bibliography.ts +3 -11
  88. package/src/tool/refreshRateDetector/i18n/de.ts +3 -3
  89. package/src/tool/refreshRateDetector/i18n/en.ts +3 -3
  90. package/src/tool/refreshRateDetector/i18n/fr.ts +7 -7
  91. package/src/tool/refreshRateDetector/i18n/id.ts +3 -3
  92. package/src/tool/refreshRateDetector/i18n/nl.ts +3 -3
  93. package/src/tool/refreshRateDetector/i18n/pl.ts +2 -2
  94. package/src/tool/refreshRateDetector/i18n/pt.ts +3 -3
  95. package/src/tool/refreshRateDetector/i18n/ru.ts +4 -4
  96. package/src/tool/refreshRateDetector/i18n/sv.ts +3 -3
  97. package/src/tool/refreshRateDetector/i18n/tr.ts +2 -2
  98. package/src/tool/refreshRateDetector/i18n/zh.ts +2 -2
  99. package/src/tool/toneGenerator/bibliography.ts +8 -8
  100. package/src/tool/toneGenerator/i18n/de.ts +1 -1
  101. package/src/tool/toneGenerator/i18n/en.ts +1 -1
  102. package/src/tool/toneGenerator/i18n/fr.ts +3 -3
  103. package/src/tool/toneGenerator/i18n/id.ts +1 -1
  104. package/src/tool/toneGenerator/i18n/it.ts +1 -1
  105. package/src/tool/toneGenerator/i18n/nl.ts +1 -1
  106. package/src/tool/toneGenerator/i18n/pl.ts +2 -2
  107. package/src/tool/toneGenerator/i18n/pt.ts +1 -1
  108. package/src/tool/toneGenerator/i18n/ru.ts +4 -4
  109. package/src/tool/toneGenerator/i18n/sv.ts +1 -1
  110. package/src/tool/toneGenerator/i18n/zh.ts +3 -3
  111. package/src/tools.ts +2 -1
@@ -0,0 +1,841 @@
1
+ .sc-wrapper {
2
+ --sc-accent: #ec4899;
3
+ --sc-accent-hover: #be185d;
4
+ --sc-accent-bg: #fce7f3;
5
+ --sc-accent-text: #be185d;
6
+ --sc-accent-light: #fbcfe8;
7
+ --sc-surface: #fff;
8
+ --sc-surface-alt: #f8fafc;
9
+ --sc-border: #e2e8f0;
10
+ --sc-text: #0f172a;
11
+ --sc-text-muted: #64748b;
12
+ --sc-text-light: #94a3b8;
13
+ --sc-kbd-bg: #f1f5f9;
14
+ --sc-shadow: rgba(0, 0, 0, 0.1);
15
+ --sc-shadow-lg: rgba(0, 0, 0, 0.15);
16
+ --sc-glow: rgba(236, 72, 153, 0.2);
17
+
18
+ width: 100%;
19
+ max-width: 80rem;
20
+ margin: 0 auto;
21
+ padding: 1rem;
22
+ color: var(--sc-text);
23
+ overflow-x: clip;
24
+ }
25
+
26
+ .sc-wrapper *,
27
+ .sc-wrapper *::before,
28
+ .sc-wrapper *::after {
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ .theme-dark .sc-wrapper {
33
+ --sc-surface: #0f172a;
34
+ --sc-surface-alt: #1e293b;
35
+ --sc-border: #334155;
36
+ --sc-text: #f1f5f9;
37
+ --sc-text-muted: #94a3b8;
38
+ --sc-text-light: #64748b;
39
+ --sc-kbd-bg: #1e293b;
40
+ --sc-accent-bg: rgba(236, 72, 153, 0.15);
41
+ --sc-accent-text: #f472b6;
42
+ --sc-glow: rgba(236, 72, 153, 0.3);
43
+ }
44
+
45
+ .sc-dashboard {
46
+ background: var(--sc-surface);
47
+ border-radius: 1.5rem;
48
+ padding: 2.5rem;
49
+ box-shadow: 0 20px 45px -10px var(--sc-shadow), 0 0 60px var(--sc-glow);
50
+ border: 1px solid var(--sc-border);
51
+ transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
52
+ position: relative;
53
+ overflow: hidden;
54
+ max-width: 100%;
55
+ }
56
+
57
+ .sc-dashboard::before {
58
+ content: '';
59
+ position: absolute;
60
+ top: 0;
61
+ left: 0;
62
+ right: 0;
63
+ bottom: 0;
64
+ background: linear-gradient(135deg, rgba(236, 72, 153, 0.05) 0%, transparent 100%);
65
+ pointer-events: none;
66
+ border-radius: 1.5rem;
67
+ }
68
+
69
+ .sc-grid {
70
+ display: grid;
71
+ grid-template-columns: 1fr 1fr;
72
+ gap: 4rem;
73
+ align-items: center;
74
+ position: relative;
75
+ z-index: 1;
76
+ }
77
+
78
+ @media (max-width: 768px) {
79
+ .sc-wrapper {
80
+ padding: 0;
81
+ }
82
+
83
+ .sc-grid {
84
+ grid-template-columns: 1fr;
85
+ gap: 1.25rem;
86
+ }
87
+
88
+ .sc-dashboard {
89
+ border-radius: 0.875rem;
90
+ padding: 1rem;
91
+ }
92
+ }
93
+
94
+ .sc-badge-container {
95
+ margin-bottom: 1.5rem;
96
+ animation: fade-in-down 0.8s ease-out;
97
+ }
98
+
99
+ .sc-badge {
100
+ display: inline-flex;
101
+ align-items: center;
102
+ gap: 0.5rem;
103
+ padding: 0.375rem 1rem;
104
+ border-radius: 9999px;
105
+ background: var(--sc-accent-bg);
106
+ color: var(--sc-accent-text);
107
+ font-size: 0.75rem;
108
+ font-weight: 700;
109
+ letter-spacing: 0.08em;
110
+ text-transform: uppercase;
111
+ box-shadow: 0 2px 8px var(--sc-shadow);
112
+ border: 1px solid var(--sc-accent-text);
113
+ }
114
+
115
+ .sc-badge-icon {
116
+ width: 1rem;
117
+ height: 1rem;
118
+ animation: spin 3s linear infinite;
119
+ }
120
+
121
+ @keyframes spin {
122
+ from { transform: rotate(0deg); }
123
+ to { transform: rotate(360deg); }
124
+ }
125
+
126
+ .sc-title {
127
+ font-size: 2.5rem;
128
+ font-weight: 800;
129
+ line-height: 1.2;
130
+ margin: 0 0 1rem;
131
+ background: linear-gradient(135deg, var(--sc-text) 0%, var(--sc-accent) 100%);
132
+ -webkit-background-clip: text;
133
+ -webkit-text-fill-color: transparent;
134
+ background-clip: text;
135
+ animation: fade-in-down 0.8s ease-out 0.1s both;
136
+ }
137
+
138
+ .sc-description {
139
+ font-size: 1.1rem;
140
+ line-height: 1.6;
141
+ color: var(--sc-text-muted);
142
+ margin: 0 0 2rem;
143
+ animation: fade-in-down 0.8s ease-out 0.2s both;
144
+ }
145
+
146
+ .sc-config {
147
+ display: flex;
148
+ flex-direction: column;
149
+ gap: 1.5rem;
150
+ margin-bottom: 2rem;
151
+ animation: fade-in-up 0.8s ease-out 0.3s both;
152
+ }
153
+
154
+ .sc-gamut-selector {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 0.75rem;
158
+ }
159
+
160
+ .sc-gamut-label {
161
+ font-size: 0.875rem;
162
+ font-weight: 600;
163
+ color: var(--sc-text);
164
+ text-transform: uppercase;
165
+ letter-spacing: 0.05em;
166
+ }
167
+
168
+ .sc-gamut-toggle {
169
+ display: grid;
170
+ grid-template-columns: 1fr 1fr;
171
+ gap: 0.75rem;
172
+ background: var(--sc-surface-alt);
173
+ padding: 0.5rem;
174
+ border-radius: 0.875rem;
175
+ border: 1px solid var(--sc-border);
176
+ min-width: 0;
177
+ }
178
+
179
+ .sc-gamut-btn {
180
+ padding: 0.75rem 1rem;
181
+ border: none;
182
+ border-radius: 0.75rem;
183
+ font-size: 0.875rem;
184
+ font-weight: 600;
185
+ cursor: pointer;
186
+ transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
187
+ background: transparent;
188
+ color: var(--sc-text-muted);
189
+ position: relative;
190
+ min-width: 0;
191
+ }
192
+
193
+ .sc-gamut-btn.sc-gamut-active {
194
+ background: var(--sc-surface);
195
+ color: var(--sc-accent);
196
+ box-shadow: 0 4px 15px rgba(236, 72, 153, 0.15);
197
+ }
198
+
199
+ .sc-gamut-btn:hover:not(.sc-gamut-active) {
200
+ color: var(--sc-text);
201
+ }
202
+
203
+ .sc-hardware-input {
204
+ display: flex;
205
+ flex-direction: column;
206
+ gap: 0.5rem;
207
+ }
208
+
209
+ .sc-input-label {
210
+ font-size: 0.875rem;
211
+ font-weight: 600;
212
+ color: var(--sc-text);
213
+ text-transform: uppercase;
214
+ letter-spacing: 0.05em;
215
+ }
216
+
217
+ .sc-input {
218
+ padding: 0.875rem 1rem;
219
+ border: 2px solid var(--sc-border);
220
+ border-radius: 0.75rem;
221
+ font-size: 0.9375rem;
222
+ background: var(--sc-surface-alt);
223
+ color: var(--sc-text);
224
+ transition: all 0.3s ease;
225
+ }
226
+
227
+ .sc-input:focus {
228
+ outline: none;
229
+ border-color: var(--sc-accent);
230
+ background: var(--sc-surface);
231
+ box-shadow: 0 0 0 3px var(--sc-glow);
232
+ }
233
+
234
+ .sc-buttons {
235
+ display: flex;
236
+ gap: 1rem;
237
+ animation: fade-in-up 0.8s ease-out 0.4s both;
238
+ width: 100%;
239
+ }
240
+
241
+ .sc-btn {
242
+ padding: 1rem 1.5rem;
243
+ border: none;
244
+ border-radius: 0.875rem;
245
+ font-size: 0.95rem;
246
+ font-weight: 700;
247
+ cursor: pointer;
248
+ transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ gap: 0.5rem;
253
+ position: relative;
254
+ overflow: hidden;
255
+ min-width: 0;
256
+ }
257
+
258
+ .sc-btn::before {
259
+ content: '';
260
+ position: absolute;
261
+ top: 50%;
262
+ left: 50%;
263
+ width: 0;
264
+ height: 0;
265
+ border-radius: 50%;
266
+ background: rgba(255, 255, 255, 0.3);
267
+ transform: translate(-50%, -50%);
268
+ transition: width 0.6s, height 0.6s;
269
+ }
270
+
271
+ .sc-btn:active::before {
272
+ width: 300px;
273
+ height: 300px;
274
+ }
275
+
276
+ .sc-btn-primary {
277
+ background: linear-gradient(135deg, var(--sc-accent) 0%, var(--sc-accent-hover) 100%);
278
+ color: white;
279
+ box-shadow: 0 8px 20px rgba(236, 72, 153, 0.35);
280
+ }
281
+
282
+ .sc-btn-primary:hover {
283
+ box-shadow: 0 12px 30px rgba(236, 72, 153, 0.45);
284
+ transform: translateY(-2px);
285
+ }
286
+
287
+ .sc-btn-secondary {
288
+ background: var(--sc-surface-alt);
289
+ color: var(--sc-text);
290
+ border: 2px solid var(--sc-border);
291
+ }
292
+
293
+ .sc-btn-secondary:hover {
294
+ border-color: var(--sc-accent);
295
+ color: var(--sc-accent);
296
+ box-shadow: 0 4px 15px rgba(236, 72, 153, 0.2);
297
+ }
298
+
299
+ .sc-btn-icon {
300
+ width: 1.25rem;
301
+ height: 1.25rem;
302
+ }
303
+
304
+ .sc-shortcuts {
305
+ display: flex;
306
+ align-items: center;
307
+ gap: 1rem;
308
+ font-size: 0.85rem;
309
+ color: var(--sc-text-light);
310
+ margin-top: 1.5rem;
311
+ animation: fade-in-up 0.8s ease-out 0.5s both;
312
+ flex-wrap: wrap;
313
+ }
314
+
315
+ .sc-shortcut {
316
+ display: flex;
317
+ align-items: center;
318
+ gap: 0.5rem;
319
+ }
320
+
321
+ .sc-kbd {
322
+ padding: 0.25rem 0.5rem;
323
+ background: var(--sc-kbd-bg);
324
+ border: 1px solid var(--sc-border);
325
+ border-radius: 0.375rem;
326
+ font-size: 0.75rem;
327
+ font-weight: 600;
328
+ color: var(--sc-text-muted);
329
+ }
330
+
331
+ .sc-preview-wrapper {
332
+ display: flex;
333
+ justify-content: center;
334
+ align-items: center;
335
+ animation: fade-in-right 0.8s ease-out 0.3s both;
336
+ min-width: 0;
337
+ }
338
+
339
+ .sc-preview-canvas {
340
+ width: 100%;
341
+ aspect-ratio: 1;
342
+ border-radius: 1rem;
343
+ background: linear-gradient(135deg, #1e1b4b 0%, #0f172a 50%, #1e1b4b 100%);
344
+ border: 2px solid var(--sc-border);
345
+ position: relative;
346
+ overflow: hidden;
347
+ box-shadow: 0 20px 50px var(--sc-shadow), inset 0 0 30px rgba(236, 72, 153, 0.1);
348
+ display: flex;
349
+ flex-direction: column;
350
+ justify-content: center;
351
+ align-items: center;
352
+ max-width: min(350px, 100%);
353
+ }
354
+
355
+ .sc-preview-gradient {
356
+ width: 90%;
357
+ height: 90%;
358
+ border-radius: 0.75rem;
359
+ background: conic-gradient(
360
+ from 0deg,
361
+ #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00
362
+ );
363
+ animation: rotate 8s linear infinite;
364
+ opacity: 0.8;
365
+ filter: blur(0.5px);
366
+ }
367
+
368
+ @keyframes rotate {
369
+ from { transform: rotate(0deg); }
370
+ to { transform: rotate(360deg); }
371
+ }
372
+
373
+ .sc-preview-label {
374
+ position: absolute;
375
+ bottom: 1rem;
376
+ left: 50%;
377
+ transform: translateX(-50%);
378
+ color: rgba(255, 255, 255, 0.7);
379
+ font-size: 0.875rem;
380
+ font-weight: 600;
381
+ letter-spacing: 0.05em;
382
+ text-transform: uppercase;
383
+ z-index: 10;
384
+ width: calc(100% - 2rem);
385
+ text-align: center;
386
+ }
387
+
388
+ #test-overlay {
389
+ position: fixed;
390
+ top: 0;
391
+ left: 0;
392
+ right: 0;
393
+ bottom: 0;
394
+ z-index: 1000;
395
+ display: flex;
396
+ flex-direction: column;
397
+ width: 100%;
398
+ height: 100%;
399
+ }
400
+
401
+ .sc-overlay-bg {
402
+ position: absolute;
403
+ top: 0;
404
+ left: 0;
405
+ right: 0;
406
+ bottom: 0;
407
+ background: white;
408
+ animation: fade-in 0.3s ease;
409
+ z-index: 999;
410
+ flex: 1;
411
+ }
412
+
413
+ .sc-controls {
414
+ position: fixed;
415
+ bottom: 0;
416
+ left: 0;
417
+ right: 0;
418
+ background: rgba(15, 23, 42, 0.98);
419
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
420
+ padding: 1rem;
421
+ color: white;
422
+ text-align: center;
423
+ z-index: 1001;
424
+ backdrop-filter: blur(10px);
425
+ animation: slide-up 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
426
+ max-height: 55vh;
427
+ overflow-y: auto;
428
+ }
429
+
430
+ @media (min-width: 768px) {
431
+ .sc-controls {
432
+ bottom: 2rem;
433
+ left: 50%;
434
+ right: auto;
435
+ transform: translateX(-50%);
436
+ border-radius: 1rem;
437
+ padding: 1.5rem;
438
+ width: fit-content;
439
+ }
440
+ }
441
+
442
+ @keyframes slide-up {
443
+ from {
444
+ opacity: 0;
445
+ transform: translateY(20px);
446
+ }
447
+ to {
448
+ opacity: 1;
449
+ transform: translateY(0);
450
+ }
451
+ }
452
+
453
+ @media (min-width: 768px) {
454
+ @keyframes slide-up {
455
+ from {
456
+ opacity: 0;
457
+ transform: translateX(-50%) translateY(20px);
458
+ }
459
+ to {
460
+ opacity: 1;
461
+ transform: translateX(-50%) translateY(0);
462
+ }
463
+ }
464
+ }
465
+
466
+ .sc-test-header {
467
+ display: flex;
468
+ justify-content: space-between;
469
+ align-items: center;
470
+ margin-bottom: 1rem;
471
+ }
472
+
473
+ .sc-test-title {
474
+ font-size: 1.25rem;
475
+ font-weight: 700;
476
+ margin: 0;
477
+ background: linear-gradient(135deg, #ec4899, #f472b6);
478
+ -webkit-background-clip: text;
479
+ -webkit-text-fill-color: transparent;
480
+ background-clip: text;
481
+ }
482
+
483
+ .sc-test-description {
484
+ margin: 0.75rem 0 0;
485
+ font-size: 0.9rem;
486
+ line-height: 1.4;
487
+ color: rgba(255, 255, 255, 0.8);
488
+ }
489
+
490
+ .sc-close-test {
491
+ position: absolute;
492
+ top: 1rem;
493
+ right: 1rem;
494
+ background: rgba(0, 0, 0, 0.3);
495
+ border: none;
496
+ color: white;
497
+ font-size: 2rem;
498
+ cursor: pointer;
499
+ width: 3rem;
500
+ height: 3rem;
501
+ display: flex;
502
+ align-items: center;
503
+ justify-content: center;
504
+ border-radius: 50%;
505
+ transition: all 0.2s;
506
+ z-index: 1002;
507
+ }
508
+
509
+ .sc-close-test:hover {
510
+ background: rgba(0, 0, 0, 0.5);
511
+ }
512
+
513
+ .sc-test-progress {
514
+ width: 100%;
515
+ height: 4px;
516
+ background: rgba(255, 255, 255, 0.1);
517
+ border-radius: 2px;
518
+ overflow: hidden;
519
+ margin: 1rem 0;
520
+ }
521
+
522
+ .sc-progress-bar {
523
+ height: 100%;
524
+ background: linear-gradient(90deg, #ec4899, #f472b6);
525
+ width: 0%;
526
+ animation: progress 1s ease-in-out;
527
+ }
528
+
529
+ @keyframes progress {
530
+ from { width: 0%; }
531
+ to { width: 100%; }
532
+ }
533
+
534
+ .sc-keyboard-hints {
535
+ display: none;
536
+ }
537
+
538
+ .sc-kbd-desktop {
539
+ display: none;
540
+ }
541
+
542
+ @media (min-width: 768px) {
543
+ .sc-kbd-desktop {
544
+ display: flex;
545
+ justify-content: center;
546
+ gap: 2rem;
547
+ font-size: 0.875rem;
548
+ margin-top: 1rem;
549
+ }
550
+ }
551
+
552
+ .sc-hint {
553
+ display: flex;
554
+ align-items: center;
555
+ gap: 0.5rem;
556
+ }
557
+
558
+ .sc-hint kbd {
559
+ padding: 0.25rem 0.5rem;
560
+ background: rgba(255, 255, 255, 0.1);
561
+ border: 1px solid rgba(255, 255, 255, 0.2);
562
+ border-radius: 0.25rem;
563
+ font-size: 0.75rem;
564
+ }
565
+
566
+ #results-overlay {
567
+ position: fixed;
568
+ top: 0;
569
+ left: 0;
570
+ right: 0;
571
+ bottom: 0;
572
+ background: rgba(0, 0, 0, 0.7);
573
+ display: flex;
574
+ justify-content: center;
575
+ align-items: center;
576
+ z-index: 1002;
577
+ backdrop-filter: blur(4px);
578
+ animation: fadeIn 0.3s ease;
579
+ }
580
+
581
+ @keyframes fade-in {
582
+ from { opacity: 0; }
583
+ to { opacity: 1; }
584
+ }
585
+
586
+ @keyframes fade-in-down {
587
+ from {
588
+ opacity: 0;
589
+ transform: translateY(-20px);
590
+ }
591
+ to {
592
+ opacity: 1;
593
+ transform: translateY(0);
594
+ }
595
+ }
596
+
597
+ @keyframes fade-in-right {
598
+ from {
599
+ opacity: 0;
600
+ transform: translateX(20px);
601
+ }
602
+ to {
603
+ opacity: 1;
604
+ transform: translateX(0);
605
+ }
606
+ }
607
+
608
+ @keyframes fade-in-up {
609
+ from {
610
+ opacity: 0;
611
+ transform: translateY(20px);
612
+ }
613
+ to {
614
+ opacity: 1;
615
+ transform: translateY(0);
616
+ }
617
+ }
618
+
619
+ .sc-results-panel {
620
+ background: var(--sc-surface);
621
+ border-radius: 1.5rem;
622
+ padding: 2rem;
623
+ max-width: 90%;
624
+ max-height: 90%;
625
+ overflow-y: auto;
626
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
627
+ animation: scale-in 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
628
+ }
629
+
630
+ @keyframes scale-in {
631
+ from {
632
+ opacity: 0;
633
+ transform: scale(0.95);
634
+ }
635
+ to {
636
+ opacity: 1;
637
+ transform: scale(1);
638
+ }
639
+ }
640
+
641
+ .sc-results-header {
642
+ display: flex;
643
+ justify-content: space-between;
644
+ align-items: center;
645
+ margin-bottom: 1.5rem;
646
+ border-bottom: 1px solid var(--sc-border);
647
+ padding-bottom: 1rem;
648
+ }
649
+
650
+ .sc-results-header h2 {
651
+ margin: 0;
652
+ font-size: 1.75rem;
653
+ background: linear-gradient(135deg, var(--sc-text) 0%, var(--sc-accent) 100%);
654
+ -webkit-background-clip: text;
655
+ -webkit-text-fill-color: transparent;
656
+ background-clip: text;
657
+ }
658
+
659
+ .sc-close-results {
660
+ background: none;
661
+ border: none;
662
+ font-size: 2rem;
663
+ cursor: pointer;
664
+ color: var(--sc-text-muted);
665
+ transition: color 0.2s;
666
+ }
667
+
668
+ .sc-close-results:hover {
669
+ color: var(--sc-accent);
670
+ }
671
+
672
+ .sc-results-content {
673
+ display: grid;
674
+ grid-template-columns: 1fr 1fr;
675
+ gap: 2rem;
676
+ margin-bottom: 2rem;
677
+ }
678
+
679
+ @media (max-width: 768px) {
680
+ .sc-results-content {
681
+ grid-template-columns: 1fr;
682
+ }
683
+ }
684
+
685
+ .sc-results-gamut {
686
+ display: flex;
687
+ justify-content: center;
688
+ align-items: center;
689
+ min-height: 300px;
690
+ background: var(--sc-surface-alt);
691
+ border-radius: 1rem;
692
+ border: 1px solid var(--sc-border);
693
+ position: relative;
694
+ overflow: hidden;
695
+ }
696
+
697
+ .sc-results-metrics {
698
+ display: flex;
699
+ flex-direction: column;
700
+ gap: 1.5rem;
701
+ }
702
+
703
+ .sc-results-footer {
704
+ display: flex;
705
+ gap: 1rem;
706
+ padding-top: 1.5rem;
707
+ border-top: 1px solid var(--sc-border);
708
+ }
709
+
710
+ .sc-test-actions {
711
+ display: flex;
712
+ gap: 0.5rem;
713
+ margin-top: 0.75rem;
714
+ width: 100%;
715
+ }
716
+
717
+ @media (min-width: 768px) {
718
+ .sc-test-actions {
719
+ gap: 0.75rem;
720
+ margin-top: 1.5rem;
721
+ }
722
+ }
723
+
724
+ .sc-action-btn {
725
+ flex: 1;
726
+ padding: 0.5rem 0.75rem;
727
+ border: 1px solid rgba(255, 255, 255, 0.2);
728
+ border-radius: 0.375rem;
729
+ background: rgba(255, 255, 255, 0.1);
730
+ color: white;
731
+ font-size: 0.8rem;
732
+ font-weight: 600;
733
+ cursor: pointer;
734
+ transition: all 0.2s ease;
735
+ min-width: 0;
736
+ }
737
+
738
+ @media (min-width: 768px) {
739
+ .sc-action-btn {
740
+ padding: 0.75rem 1rem;
741
+ border-radius: 0.5rem;
742
+ font-size: 0.9rem;
743
+ }
744
+ }
745
+
746
+ .sc-action-btn:hover {
747
+ background: rgba(255, 255, 255, 0.2);
748
+ border-color: rgba(255, 255, 255, 0.4);
749
+ }
750
+
751
+ .sc-action-primary {
752
+ background: linear-gradient(135deg, #ec4899, #f472b6);
753
+ border-color: #ec4899;
754
+ }
755
+
756
+ .sc-action-primary:hover {
757
+ background: linear-gradient(135deg, #f472b6, #ec4899);
758
+ }
759
+
760
+ .sc-action-secondary {
761
+ background: rgba(255, 255, 255, 0.1);
762
+ }
763
+
764
+ .sc-action-secondary:hover {
765
+ background: rgba(255, 255, 255, 0.15);
766
+ }
767
+
768
+ @media (max-width: 640px) {
769
+ .sc-content {
770
+ min-width: 0;
771
+ }
772
+
773
+ .sc-gamut-toggle {
774
+ gap: 0.375rem;
775
+ padding: 0.375rem;
776
+ }
777
+
778
+ .sc-gamut-btn {
779
+ padding: 0.65rem 0.5rem;
780
+ font-size: 0.8rem;
781
+ }
782
+
783
+ .sc-buttons {
784
+ display: grid;
785
+ grid-template-columns: 1fr;
786
+ }
787
+
788
+ .sc-btn {
789
+ width: 100%;
790
+ padding: 0.875rem 1rem;
791
+ }
792
+
793
+ .sc-shortcuts {
794
+ gap: 0.5rem;
795
+ font-size: 0.75rem;
796
+ }
797
+
798
+ .sc-shortcuts > span {
799
+ display: none;
800
+ }
801
+
802
+ .sc-shortcut {
803
+ flex: 1 1 8rem;
804
+ }
805
+
806
+ .sc-preview-canvas {
807
+ max-width: min(18rem, 100%);
808
+ }
809
+
810
+ .sc-preview-label {
811
+ bottom: 0.75rem;
812
+ font-size: 0.7rem;
813
+ }
814
+
815
+ .sc-controls {
816
+ padding: 3.75rem 0.75rem 0.75rem;
817
+ max-height: 70vh;
818
+ }
819
+
820
+ .sc-close-test {
821
+ top: 0.75rem;
822
+ right: 0.75rem;
823
+ width: 2.5rem;
824
+ height: 2.5rem;
825
+ font-size: 1.6rem;
826
+ }
827
+
828
+ .sc-test-description {
829
+ margin-top: 0;
830
+ font-size: 0.82rem;
831
+ }
832
+
833
+ .sc-test-actions {
834
+ display: grid;
835
+ grid-template-columns: 1fr 1fr;
836
+ }
837
+
838
+ .sc-action-btn {
839
+ padding: 0.7rem 0.5rem;
840
+ }
841
+ }