@jjlmoya/utils-developer 1.31.0 → 1.32.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 (53) hide show
  1. package/package.json +1 -1
  2. package/src/category/i18n/en.ts +1 -1
  3. package/src/category/i18n/es.ts +1 -1
  4. package/src/category/index.ts +2 -1
  5. package/src/entries.ts +2 -0
  6. package/src/index.ts +1 -0
  7. package/src/pages/[locale]/[slug].astro +3 -3
  8. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  9. package/src/tests/category_seo_quality.test.ts +76 -0
  10. package/src/tests/locale_completeness.test.ts +1 -1
  11. package/src/tests/seo_translation_completeness.test.ts +69 -0
  12. package/src/tests/seo_wellformed_export.test.ts +65 -0
  13. package/src/tests/tool_validation.test.ts +1 -1
  14. package/src/tool/dualOsIconPreview/assets/day-check.webp +0 -0
  15. package/src/tool/dualOsIconPreview/assets/fast-task.webp +0 -0
  16. package/src/tool/dualOsIconPreview/assets/fortune-cookie.webp +0 -0
  17. package/src/tool/dualOsIconPreview/assets/lexi-crash.webp +0 -0
  18. package/src/tool/dualOsIconPreview/assets/pizzametrics.webp +0 -0
  19. package/src/tool/dualOsIconPreview/assets/sauce-lab.webp +0 -0
  20. package/src/tool/dualOsIconPreview/assets/vesp.webp +0 -0
  21. package/src/tool/dualOsIconPreview/bibliography.astro +6 -0
  22. package/src/tool/dualOsIconPreview/bibliography.ts +7 -0
  23. package/src/tool/dualOsIconPreview/component.astro +117 -0
  24. package/src/tool/dualOsIconPreview/controller.ts +157 -0
  25. package/src/tool/dualOsIconPreview/dom-views.ts +82 -0
  26. package/src/tool/dualOsIconPreview/dual-ios-android-app-icon-preview.css +861 -0
  27. package/src/tool/dualOsIconPreview/entry.ts +31 -0
  28. package/src/tool/dualOsIconPreview/evaluator.ts +20 -0
  29. package/src/tool/dualOsIconPreview/i18n/de.ts +56 -0
  30. package/src/tool/dualOsIconPreview/i18n/en.ts +46 -0
  31. package/src/tool/dualOsIconPreview/i18n/es.ts +56 -0
  32. package/src/tool/dualOsIconPreview/i18n/fr.ts +56 -0
  33. package/src/tool/dualOsIconPreview/i18n/id.ts +56 -0
  34. package/src/tool/dualOsIconPreview/i18n/it.ts +56 -0
  35. package/src/tool/dualOsIconPreview/i18n/ja.ts +56 -0
  36. package/src/tool/dualOsIconPreview/i18n/ko.ts +56 -0
  37. package/src/tool/dualOsIconPreview/i18n/nl.ts +56 -0
  38. package/src/tool/dualOsIconPreview/i18n/pl.ts +56 -0
  39. package/src/tool/dualOsIconPreview/i18n/pt.ts +56 -0
  40. package/src/tool/dualOsIconPreview/i18n/ru.ts +56 -0
  41. package/src/tool/dualOsIconPreview/i18n/sv.ts +56 -0
  42. package/src/tool/dualOsIconPreview/i18n/tr.ts +43 -0
  43. package/src/tool/dualOsIconPreview/i18n/zh.ts +43 -0
  44. package/src/tool/dualOsIconPreview/index.ts +11 -0
  45. package/src/tool/dualOsIconPreview/logic.test.ts +63 -0
  46. package/src/tool/dualOsIconPreview/logic.ts +135 -0
  47. package/src/tool/dualOsIconPreview/seo.astro +15 -0
  48. package/src/tool/dualOsIconPreview/storage.ts +18 -0
  49. package/src/tool/dualOsIconPreview/ui.ts +52 -0
  50. package/src/tool/promoteThisWebsite/i18n/pl.ts +1 -1
  51. package/src/tool/promoteThisWebsite/i18n/ru.ts +1 -1
  52. package/src/tool/promoteThisWebsite/i18n/tr.ts +1 -1
  53. package/src/tools.ts +2 -1
@@ -0,0 +1,861 @@
1
+ .dual-os-icon-preview {
2
+ --n-ink: #171717;
3
+ --n-muted: #6b6b69;
4
+ --n-paper: #f3efe6;
5
+ --n-card: #fffdf8;
6
+ --n-line: #d8d1c3;
7
+ --n-accent: #f4b942;
8
+ --n-accent-ink: #2b2008;
9
+ --n-stage: #d5d9d5;
10
+ --n-phone: #181a1b;
11
+ --n-phone-edge: #3c4143;
12
+ --n-screen: #f4f1e9;
13
+ --n-wallpaper: #718a80;
14
+ --n-wallpaper-alt: #53627e;
15
+ --n-shadow: #17171735;
16
+ --n-white: #fff;
17
+ --n-danger: #a52f2f;
18
+ --n-pass: #245d4d;
19
+ --n-ios-dark: #2d3442;
20
+
21
+ width: 100%;
22
+ display: grid;
23
+ align-items: start;
24
+ grid-template-columns: minmax(255px, 0.72fr) minmax(600px, 1.8fr);
25
+ overflow: hidden;
26
+ border: 1px solid var(--n-line);
27
+ border-radius: 28px;
28
+ background: var(--n-card);
29
+ color: var(--n-ink);
30
+ box-shadow: 0 24px 55px var(--n-shadow);
31
+ }
32
+
33
+ .theme-dark .dual-os-icon-preview {
34
+ --n-ink: #f4f1e9;
35
+ --n-muted: #b6b1a7;
36
+ --n-paper: #242421;
37
+ --n-card: #302f2b;
38
+ --n-line: #504d46;
39
+ --n-accent-ink: #201707;
40
+ --n-stage: #1f211f;
41
+ --n-phone: #090909;
42
+ --n-phone-edge: #4b4b48;
43
+ --n-screen: #d8ddd6;
44
+ --n-wallpaper: #597066;
45
+ --n-wallpaper-alt: #596278;
46
+ --n-shadow: #0008;
47
+ --n-pass: #9bd3bb;
48
+ }
49
+
50
+ .theme-dark .dual-os-icon-preview .choice-grid button[aria-pressed="true"] {
51
+ background: #ffd56a;
52
+ color: #211805;
53
+ border-color: #ffe5a1;
54
+ box-shadow: inset 0 0 0 1px #211805;
55
+ }
56
+
57
+ .preview-controls {
58
+ display: flex;
59
+ flex-direction: column;
60
+ background: var(--n-paper);
61
+ border-right: 1px solid var(--n-line);
62
+ }
63
+
64
+ .control-block {
65
+ padding: 22px;
66
+ border-bottom: 1px solid var(--n-line);
67
+ }
68
+
69
+ .control-heading {
70
+ display: flex;
71
+ align-items: flex-start;
72
+ gap: 12px;
73
+ margin-bottom: 15px;
74
+ }
75
+
76
+ .control-heading strong,
77
+ .control-heading small,
78
+ .upload-button strong,
79
+ .upload-button small,
80
+ .toggle-row strong,
81
+ .toggle-row small {
82
+ display: block;
83
+ }
84
+
85
+ .control-heading strong {
86
+ font-size: 0.88rem;
87
+ }
88
+
89
+ .control-heading small,
90
+ .upload-button small,
91
+ .toggle-row small,
92
+ .audit-heading small {
93
+ margin-top: 4px;
94
+ color: var(--n-muted);
95
+ font-size: 0.72rem;
96
+ line-height: 1.4;
97
+ }
98
+
99
+ .step-number {
100
+ padding-top: 3px;
101
+ color: var(--n-accent-ink);
102
+ font: 800 0.68rem/1 "Courier New", monospace;
103
+ }
104
+
105
+ .upload-button,
106
+ .choice-grid button,
107
+ .text-input,
108
+ .color-row,
109
+ .toggle-row {
110
+ border: 1px solid var(--n-line);
111
+ background: var(--n-card);
112
+ color: var(--n-ink);
113
+ font: inherit;
114
+ }
115
+
116
+ .upload-button {
117
+ width: 100%;
118
+ display: flex;
119
+ align-items: center;
120
+ gap: 12px;
121
+ padding: 13px;
122
+ border-style: dashed;
123
+ border-color: var(--n-accent-ink);
124
+ border-radius: 14px;
125
+ text-align: left;
126
+ cursor: pointer;
127
+ }
128
+
129
+ .upload-button:hover,
130
+ .upload-button:focus-visible {
131
+ background: var(--n-accent);
132
+ }
133
+
134
+ .upload-glyph {
135
+ display: grid;
136
+ width: 30px;
137
+ height: 30px;
138
+ place-items: center;
139
+ border-radius: 9px;
140
+ background: var(--n-accent);
141
+ color: var(--n-accent-ink);
142
+ font-size: 1.3rem;
143
+ }
144
+
145
+ .field-error {
146
+ min-height: 16px;
147
+ margin: 8px 0 0;
148
+ color: var(--n-danger);
149
+ font-size: 0.72rem;
150
+ }
151
+
152
+ .text-input {
153
+ width: 100%;
154
+ min-height: 42px;
155
+ padding: 10px 12px;
156
+ border-radius: 10px;
157
+ outline: none;
158
+ }
159
+
160
+ .text-input:focus-visible,
161
+ .choice-grid button:focus-visible,
162
+ .upload-button:focus-visible,
163
+ .toggle-row:focus-within,
164
+ .color-row:focus-within {
165
+ border-color: var(--n-accent-ink);
166
+ box-shadow: 0 0 0 3px var(--n-accent);
167
+ }
168
+
169
+ .color-row,
170
+ .toggle-row {
171
+ display: flex;
172
+ align-items: center;
173
+ justify-content: space-between;
174
+ gap: 12px;
175
+ margin-top: 10px;
176
+ padding: 8px 11px;
177
+ border-radius: 10px;
178
+ font-size: 0.72rem;
179
+ }
180
+
181
+ .color-row input {
182
+ width: 34px;
183
+ height: 25px;
184
+ padding: 0;
185
+ border: 0;
186
+ background: transparent;
187
+ cursor: pointer;
188
+ }
189
+
190
+ .toggle-row {
191
+ justify-content: flex-start;
192
+ align-items: flex-start;
193
+ cursor: pointer;
194
+ }
195
+
196
+ .toggle-row input {
197
+ accent-color: var(--n-accent-ink);
198
+ margin-top: 3px;
199
+ }
200
+
201
+ .choice-grid {
202
+ display: grid;
203
+ grid-template-columns: repeat(2, minmax(0, 1fr));
204
+ gap: 7px;
205
+ }
206
+
207
+ .choice-grid button {
208
+ min-height: 36px;
209
+ padding: 7px 5px;
210
+ border-radius: 9px;
211
+ color: var(--n-muted);
212
+ font-size: 0.7rem;
213
+ cursor: pointer;
214
+ }
215
+
216
+ .choice-grid button:hover {
217
+ color: var(--n-ink);
218
+ border-color: var(--n-accent-ink);
219
+ }
220
+
221
+ .choice-grid button[aria-pressed="true"] {
222
+ border-color: var(--n-accent-ink);
223
+ background: var(--n-accent);
224
+ color: var(--n-accent-ink);
225
+ font-weight: 800;
226
+ }
227
+
228
+ .preview-stage {
229
+ align-self: start;
230
+ min-width: 0;
231
+ height: max-content;
232
+ padding: 22px clamp(18px, 3.2vw, 40px) 25px;
233
+ background: var(--n-stage);
234
+ }
235
+
236
+ .stage-topline,
237
+ .device-caption,
238
+ .device-caption strong {
239
+ display: flex;
240
+ align-items: center;
241
+ justify-content: space-between;
242
+ gap: 12px;
243
+ }
244
+
245
+ .stage-topline {
246
+ margin-bottom: 18px;
247
+ color: var(--n-muted);
248
+ font-size: 0.68rem;
249
+ text-transform: uppercase;
250
+ letter-spacing: 0.08em;
251
+ }
252
+
253
+ .stage-kicker {
254
+ color: var(--n-ink);
255
+ font-weight: 800;
256
+ }
257
+
258
+ .device-pair {
259
+ display: flex;
260
+ align-items: flex-start;
261
+ justify-content: center;
262
+ gap: clamp(14px, 3.4vw, 38px);
263
+ }
264
+
265
+ .device-card {
266
+ min-width: 0;
267
+ flex: 1;
268
+ }
269
+
270
+ .device-shell {
271
+ position: relative;
272
+ width: min(100%, 230px);
273
+ height: 455px;
274
+ margin: 0 auto;
275
+ padding: 8px;
276
+ border: 2px solid var(--n-phone-edge);
277
+ border-radius: 34px;
278
+ background: var(--n-phone);
279
+ box-shadow: 12px 16px 0 var(--n-shadow);
280
+ }
281
+
282
+ .device-screen {
283
+ position: relative;
284
+ height: 100%;
285
+ overflow: hidden;
286
+ border-radius: 27px;
287
+ background: var(--n-screen);
288
+ }
289
+
290
+ .device-island,
291
+ .device-camera {
292
+ position: absolute;
293
+ z-index: 3;
294
+ top: 14px;
295
+ left: 50%;
296
+ width: 34%;
297
+ height: 18px;
298
+ transform: translateX(-50%);
299
+ border-radius: 20px;
300
+ background: var(--n-phone);
301
+ }
302
+
303
+ .device-camera {
304
+ top: 13px;
305
+ width: 18px;
306
+ height: 18px;
307
+ border: 4px solid var(--n-phone);
308
+ background: var(--n-accent);
309
+ }
310
+
311
+ .system-status {
312
+ position: absolute;
313
+ z-index: 4;
314
+ top: 9px;
315
+ right: 15px;
316
+ left: 15px;
317
+ display: flex;
318
+ justify-content: space-between;
319
+ color: var(--n-ink);
320
+ font: 700 0.52rem/1 "Courier New", monospace;
321
+ }
322
+
323
+ .home-wallpaper {
324
+ position: relative;
325
+ isolation: isolate;
326
+ overflow: hidden;
327
+ display: flex;
328
+ height: 100%;
329
+ flex-direction: column;
330
+ align-items: center;
331
+ }
332
+
333
+ .ios-wallpaper {
334
+ background: #394f96;
335
+ }
336
+
337
+ .ios-wallpaper::before,
338
+ .ios-wallpaper::after {
339
+ position: absolute;
340
+ z-index: -1;
341
+ display: block;
342
+ content: "";
343
+ pointer-events: none;
344
+ }
345
+
346
+ .ios-wallpaper::before {
347
+ inset: -22% -35%;
348
+ background:
349
+ radial-gradient(ellipse at 19% 14%, #ffd1db 0 11%, transparent 30%),
350
+ radial-gradient(ellipse at 78% 18%, #9ce6db 0 13%, transparent 31%),
351
+ radial-gradient(ellipse at 66% 65%, #ffb58c 0 16%, transparent 33%),
352
+ radial-gradient(ellipse at 23% 82%, #71d2c2 0 17%, transparent 35%),
353
+ linear-gradient(145deg, #263b91 8%, #5668bd 46%, #764f92 100%);
354
+ filter: blur(9px) saturate(1.12);
355
+ transform: rotate(-9deg) scale(1.08);
356
+ }
357
+
358
+ .ios-wallpaper::after {
359
+ top: 20%;
360
+ left: -35%;
361
+ width: 170%;
362
+ height: 38%;
363
+ border: 12px solid #ffffff2e;
364
+ border-radius: 50%;
365
+ box-shadow: 0 0 35px #ffffff26, inset 0 0 35px #ffffff1c;
366
+ transform: rotate(-18deg);
367
+ }
368
+
369
+ .android-wallpaper {
370
+ background: #a9c6bd;
371
+ }
372
+
373
+ .android-wallpaper::before,
374
+ .android-wallpaper::after {
375
+ position: absolute;
376
+ display: block;
377
+ content: "";
378
+ pointer-events: none;
379
+ }
380
+
381
+ .android-wallpaper::before {
382
+ inset: -12%;
383
+ background:
384
+ radial-gradient(ellipse at 78% 18%, #f4d28e 0 12%, transparent 30%),
385
+ radial-gradient(ellipse at 16% 72%, #6f9d95 0 18%, transparent 37%),
386
+ linear-gradient(125deg, #d8e5c5 0 36%, #93bbb2 37% 66%, #607f8b 67%);
387
+ filter: blur(8px) saturate(.9);
388
+ transform: rotate(12deg);
389
+ }
390
+
391
+ .android-wallpaper::after {
392
+ right: -28%;
393
+ bottom: 15%;
394
+ width: 145%;
395
+ height: 22%;
396
+ border: 8px solid #ffffff30;
397
+ border-radius: 50%;
398
+ transform: rotate(-20deg);
399
+ }
400
+
401
+ .wallpaper-glow {
402
+ position: absolute;
403
+ width: 130%;
404
+ height: 25%;
405
+ border: 1px solid var(--n-white);
406
+ border-radius: 50%;
407
+ opacity: 0.45;
408
+ transform: rotate(-22deg);
409
+ }
410
+
411
+ .glow-one {
412
+ top: 22%;
413
+ left: -20%;
414
+ }
415
+
416
+ .glow-two {
417
+ top: 39%;
418
+ left: 6%;
419
+ transform: rotate(18deg);
420
+ }
421
+
422
+ .home-grid {
423
+ position: relative;
424
+ z-index: 1;
425
+ display: grid;
426
+ width: 92%;
427
+ margin-top: 64px;
428
+ gap: 15px 7px;
429
+ }
430
+
431
+ .ios-grid {
432
+ grid-template-columns: repeat(4, 1fr);
433
+ }
434
+
435
+ .android-grid {
436
+ grid-template-columns: repeat(5, 1fr);
437
+ margin-top: 104px;
438
+ gap: 14px 5px;
439
+ }
440
+
441
+ .launcher-item {
442
+ min-width: 0;
443
+ display: flex;
444
+ flex-direction: column;
445
+ align-items: center;
446
+ gap: 3px;
447
+ }
448
+
449
+ .launcher-item small {
450
+ max-width: 100%;
451
+ overflow: hidden;
452
+ color: var(--n-white);
453
+ font-size: 0.48rem;
454
+ text-overflow: ellipsis;
455
+ text-shadow: 0 1px 2px var(--n-shadow);
456
+ white-space: nowrap;
457
+ }
458
+
459
+ .app-tile {
460
+ position: relative;
461
+ overflow: hidden;
462
+ display: grid;
463
+ width: 39px;
464
+ height: 39px;
465
+ place-items: center;
466
+ border-radius: 11px;
467
+ color: var(--n-white);
468
+ font-size: 1.08rem;
469
+ font-weight: 700;
470
+ box-shadow: 0 4px 8px var(--n-shadow);
471
+ }
472
+
473
+ .audited-icon {
474
+ overflow: hidden;
475
+ background: var(--n-brand);
476
+ color: var(--n-accent-ink);
477
+ text-align: center;
478
+ }
479
+
480
+ .audited-icon img {
481
+ width: 100%;
482
+ height: 100%;
483
+ object-fit: cover;
484
+ }
485
+
486
+ .launcher-icon img {
487
+ width: 100%;
488
+ height: 100%;
489
+ object-fit: cover;
490
+ }
491
+
492
+ .audited-icon img[hidden],
493
+ .audited-icon [data-empty-logo][hidden] {
494
+ display: none;
495
+ }
496
+
497
+ .ios-icon {
498
+ border-radius: 12px;
499
+ }
500
+
501
+ .android-icon {
502
+ border-radius: 11px;
503
+ }
504
+
505
+ [data-android-shape="circle"] .device-android .launcher-icon {
506
+ border-radius: 50%;
507
+ }
508
+
509
+ [data-android-shape="rounded"] .device-android .launcher-icon {
510
+ border-radius: 7px;
511
+ }
512
+
513
+ [data-android-shape="teardrop"] .device-android .launcher-icon {
514
+ border-radius: 50% 50% 50% 7px;
515
+ }
516
+
517
+ [data-android-shape="squircle"] .device-android .launcher-icon {
518
+ border-radius: 11px;
519
+ }
520
+
521
+ [data-android-themed="true"] .device-android .launcher-icon {
522
+ background: var(--n-brand);
523
+ box-shadow: 0 4px 8px var(--n-shadow), inset 0 0 0 1px #ffffff38;
524
+ }
525
+
526
+ [data-android-themed="true"] .device-android .launcher-icon img {
527
+ filter: grayscale(1) brightness(.62) contrast(1.28);
528
+ mix-blend-mode: multiply;
529
+ opacity: .9;
530
+ }
531
+
532
+ [data-ios-appearance="dark"] .device-ios .ios-wallpaper {
533
+ background: #121c4b;
534
+ }
535
+
536
+ [data-ios-appearance="dark"] .device-ios .ios-wallpaper::before {
537
+ filter: brightness(.52) saturate(.88) blur(10px);
538
+ }
539
+
540
+ [data-ios-appearance="clear"] .device-ios .ios-wallpaper {
541
+ background: #c3d5e2;
542
+ }
543
+
544
+ [data-ios-appearance="clear"] .device-ios .ios-wallpaper::before {
545
+ filter: brightness(1.22) saturate(.62) blur(9px);
546
+ }
547
+
548
+ [data-ios-appearance="clear"] .device-ios .ios-icon {
549
+ border: 1px solid #ffffffad;
550
+ background: #ffffff4a;
551
+ box-shadow: 0 4px 12px #1a355333, inset 0 0 0 1px #ffffff4d;
552
+ backdrop-filter: blur(6px);
553
+ }
554
+
555
+ [data-ios-appearance="tinted"] .device-ios .ios-wallpaper {
556
+ background: #594f75;
557
+ }
558
+
559
+ [data-ios-appearance="tinted"] .device-ios .ios-wallpaper::before {
560
+ filter: hue-rotate(18deg) saturate(.75) brightness(.78) blur(10px);
561
+ }
562
+
563
+ [data-ios-appearance="tinted"] .device-ios .ios-icon,
564
+ [data-ios-appearance="tinted"] .device-ios .ios-icon img {
565
+ filter: grayscale(1) saturate(0) contrast(.92);
566
+ }
567
+
568
+ [data-ios-appearance="tinted"] .device-ios .ios-icon {
569
+ background: color-mix(in srgb, var(--n-brand) 72%, #fff 28%);
570
+ }
571
+
572
+ [data-ios-appearance="dark"] .device-ios .ios-icon img {
573
+ filter: brightness(.78) saturate(.8);
574
+ }
575
+
576
+ .tile-blue { background: #3974c9; }
577
+ .tile-green { background: #3d996d; }
578
+ .tile-orange { background: #e47f39; }
579
+ .tile-purple { background: #8365c7; }
580
+ .tile-red { background: #d95155; }
581
+ .tile-teal { background: #258f9a; }
582
+ .tile-yellow { background: #d9ad38; }
583
+ .tile-pink { background: #d86390; }
584
+ .tile-navy { background: #3c5279; }
585
+ .tile-cyan { background: #3ca4bd; }
586
+ .tile-slate { background: #65727e; }
587
+
588
+ .device-dock,
589
+ .android-dock {
590
+ position: absolute;
591
+ z-index: 2;
592
+ bottom: 25px;
593
+ display: flex;
594
+ gap: 8px;
595
+ padding: 7px 9px;
596
+ border: 1px solid var(--n-white);
597
+ border-radius: 16px;
598
+ background: var(--n-white);
599
+ opacity: 0.88;
600
+ }
601
+
602
+ .android-dock {
603
+ bottom: 27px;
604
+ gap: 9px;
605
+ padding: 0;
606
+ border: 0;
607
+ background: transparent;
608
+ }
609
+
610
+ .device-dock .app-tile,
611
+ .android-dock .app-tile {
612
+ width: 34px;
613
+ height: 34px;
614
+ border-radius: 10px;
615
+ box-shadow: 0 3px 5px var(--n-shadow);
616
+ font-size: 0.85rem;
617
+ }
618
+
619
+ [data-android-shape="circle"] .android-dock .launcher-icon { border-radius: 50%; }
620
+ [data-android-shape="squircle"] .android-dock .launcher-icon { border-radius: 11px; }
621
+ [data-android-shape="rounded"] .android-dock .launcher-icon { border-radius: 7px; }
622
+ [data-android-shape="teardrop"] .android-dock .launcher-icon { border-radius: 50% 50% 50% 7px; }
623
+
624
+ .android-search {
625
+ position: absolute;
626
+ top: 61px;
627
+ right: 10%;
628
+ left: 10%;
629
+ z-index: 2;
630
+ display: flex;
631
+ align-items: center;
632
+ gap: 8px;
633
+ padding: 7px 9px;
634
+ border-radius: 20px;
635
+ background: var(--n-white);
636
+ color: var(--n-muted);
637
+ font-size: 0.62rem;
638
+ opacity: 0.9;
639
+ }
640
+
641
+ .android-search span {
642
+ color: #3d74c9;
643
+ font-weight: 900;
644
+ }
645
+
646
+ .android-search small {
647
+ flex: 1;
648
+ }
649
+
650
+ .android-search b {
651
+ color: var(--n-muted);
652
+ font-size: 0.9rem;
653
+ }
654
+
655
+ .home-indicator,
656
+ .android-navigation {
657
+ position: absolute;
658
+ z-index: 4;
659
+ bottom: 9px;
660
+ left: 50%;
661
+ width: 34%;
662
+ height: 3px;
663
+ transform: translateX(-50%);
664
+ border-radius: 4px;
665
+ background: var(--n-ink);
666
+ }
667
+
668
+ .android-navigation {
669
+ right: 17%;
670
+ bottom: 8px;
671
+ left: 17%;
672
+ width: auto;
673
+ height: 14px;
674
+ display: flex;
675
+ justify-content: space-between;
676
+ background: transparent;
677
+ }
678
+
679
+ .android-navigation span {
680
+ width: 5px;
681
+ height: 5px;
682
+ margin-top: 4px;
683
+ border: 1px solid var(--n-white);
684
+ border-radius: 50%;
685
+ }
686
+
687
+ .device-caption {
688
+ margin-top: 12px;
689
+ color: var(--n-muted);
690
+ font-size: 0.62rem;
691
+ }
692
+
693
+ .device-caption strong {
694
+ color: var(--n-ink);
695
+ font-size: 0.7rem;
696
+ }
697
+
698
+ .platform-dot {
699
+ display: inline-block;
700
+ width: 7px;
701
+ height: 7px;
702
+ margin-right: 5px;
703
+ border-radius: 50%;
704
+ }
705
+
706
+ .dot-ios { background: var(--n-ink); }
707
+ .dot-android { background: var(--n-accent-ink); }
708
+ .audit-report {
709
+ margin-top: 22px;
710
+ padding: 15px;
711
+ border: 1px solid var(--n-line);
712
+ border-radius: 15px;
713
+ background: var(--n-card);
714
+ }
715
+
716
+ .audit-heading {
717
+ display: flex;
718
+ align-items: center;
719
+ justify-content: space-between;
720
+ gap: 14px;
721
+ padding-bottom: 12px;
722
+ border-bottom: 1px solid var(--n-line);
723
+ }
724
+
725
+ .audit-heading strong {
726
+ display: block;
727
+ font-size: 0.82rem;
728
+ }
729
+
730
+ .audit-score {
731
+ padding: 7px 10px;
732
+ border-radius: 8px;
733
+ background: var(--n-paper);
734
+ color: var(--n-muted);
735
+ font: 800 0.75rem/1 "Courier New", monospace;
736
+ }
737
+
738
+ [data-audit-state="ready"] .audit-score {
739
+ background: var(--n-accent);
740
+ color: var(--n-accent-ink);
741
+ }
742
+
743
+ .audit-grid {
744
+ display: grid;
745
+ grid-template-columns: repeat(7, minmax(0, 1fr));
746
+ gap: 10px;
747
+ padding-top: 13px;
748
+ }
749
+
750
+ .audit-metric {
751
+ min-width: 0;
752
+ padding-right: 9px;
753
+ border-right: 1px solid var(--n-line);
754
+ }
755
+
756
+ .audit-metric:last-child { border-right: 0; }
757
+ .audit-metric small, .audit-metric strong { display: block; }
758
+ .audit-metric small {
759
+ color: var(--n-muted);
760
+ font-size: 0.59rem;
761
+ line-height: 1.35;
762
+ }
763
+ .audit-metric strong {
764
+ margin-top: 5px;
765
+ color: var(--n-ink);
766
+ font: 800 0.7rem/1.2 "Courier New", monospace;
767
+ }
768
+ .audit-metric strong[data-audit-status="pass"] { color: var(--n-pass); }
769
+ .audit-metric strong[data-audit-status="review"] { color: var(--n-danger); }
770
+
771
+ .visually-hidden {
772
+ position: absolute;
773
+ width: 1px;
774
+ height: 1px;
775
+ overflow: hidden;
776
+ white-space: nowrap;
777
+ clip-path: inset(50%);
778
+ }
779
+
780
+ @media (max-width: 980px) {
781
+ .dual-os-icon-preview {
782
+ grid-template-columns: 1fr;
783
+ }
784
+ .preview-controls {
785
+ border-right: 0;
786
+ }
787
+ }
788
+
789
+ @media (max-width: 620px) {
790
+ .preview-stage {
791
+ padding: 18px 12px 20px;
792
+ }
793
+ .stage-topline {
794
+ align-items: flex-start;
795
+ flex-direction: column;
796
+ gap: 5px;
797
+ }
798
+ .device-pair {
799
+ gap: 4px;
800
+ }
801
+ .device-shell {
802
+ height: 325px;
803
+ padding: 5px;
804
+ border-radius: 25px;
805
+ }
806
+ .device-screen {
807
+ border-radius: 19px;
808
+ }
809
+ .device-island {
810
+ top: 9px;
811
+ }
812
+ .device-camera {
813
+ top: 8px;
814
+ width: 14px;
815
+ height: 14px;
816
+ border-width: 3px;
817
+ }
818
+ .system-status {
819
+ top: 6px;
820
+ right: 9px;
821
+ left: 9px;
822
+ font-size: 0.4rem;
823
+ }
824
+ .home-grid {
825
+ margin-top: 44px;
826
+ gap: 10px 3px;
827
+ }
828
+ .android-grid {
829
+ margin-top: 75px;
830
+ gap: 9px 2px;
831
+ }
832
+ .app-tile {
833
+ width: 29px;
834
+ height: 29px;
835
+ border-radius: 8px;
836
+ font-size: 0.8rem;
837
+ }
838
+ .device-dock .app-tile,
839
+ .android-dock .app-tile {
840
+ width: 25px;
841
+ height: 25px;
842
+ font-size: 0.65rem;
843
+ }
844
+ .device-dock,
845
+ .android-dock {
846
+ bottom: 18px;
847
+ gap: 4px;
848
+ padding: 5px;
849
+ }
850
+ .android-search {
851
+ top: 39px;
852
+ padding: 5px 7px;
853
+ font-size: 0.45rem;
854
+ }
855
+ .audit-grid {
856
+ grid-template-columns: repeat(2, minmax(0, 1fr));
857
+ }
858
+ .audit-metric {
859
+ border-right: 0;
860
+ }
861
+ }