@jjlmoya/utils-hardware 1.17.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 (61) 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 +3 -3
  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/layouts/PreviewLayout.astro +1 -0
  13. package/src/tests/diacritics_density.test.ts +118 -0
  14. package/src/tests/inverted_punctuation.test.ts +84 -0
  15. package/src/tests/no_en_dash.test.ts +70 -0
  16. package/src/tests/script_density.test.ts +94 -0
  17. package/src/tool/batteryHealthEstimator/i18n/fr.ts +4 -4
  18. package/src/tool/batteryHealthEstimator/i18n/pl.ts +1 -1
  19. package/src/tool/colorAccuracyTest/color-accuracy-test.css +118 -5
  20. package/src/tool/colorAccuracyTest/i18n/de.ts +7 -7
  21. package/src/tool/colorAccuracyTest/i18n/en.ts +3 -3
  22. package/src/tool/colorAccuracyTest/i18n/es.ts +2 -2
  23. package/src/tool/colorAccuracyTest/i18n/fr.ts +9 -9
  24. package/src/tool/colorAccuracyTest/i18n/id.ts +3 -3
  25. package/src/tool/colorAccuracyTest/i18n/it.ts +3 -3
  26. package/src/tool/colorAccuracyTest/i18n/ja.ts +1 -1
  27. package/src/tool/colorAccuracyTest/i18n/ko.ts +2 -2
  28. package/src/tool/colorAccuracyTest/i18n/nl.ts +3 -3
  29. package/src/tool/colorAccuracyTest/i18n/pl.ts +5 -5
  30. package/src/tool/colorAccuracyTest/i18n/pt.ts +3 -3
  31. package/src/tool/colorAccuracyTest/i18n/ru.ts +15 -15
  32. package/src/tool/colorAccuracyTest/i18n/sv.ts +3 -3
  33. package/src/tool/colorAccuracyTest/i18n/tr.ts +2 -2
  34. package/src/tool/colorAccuracyTest/i18n/zh.ts +7 -7
  35. package/src/tool/deadPixelTest/i18n/ru.ts +6 -6
  36. package/src/tool/deadPixelTest/i18n/sv.ts +1 -1
  37. package/src/tool/deadPixelTest/i18n/zh.ts +5 -5
  38. package/src/tool/gamepadTest/gamepad-test.css +171 -3
  39. package/src/tool/gamepadTest/i18n/es.ts +4 -4
  40. package/src/tool/gamepadTest/i18n/ru.ts +1 -1
  41. package/src/tool/gamepadTest/i18n/zh.ts +1 -1
  42. package/src/tool/gamepadVibrationTester/i18n/es.ts +1 -1
  43. package/src/tool/gamepadVibrationTester/i18n/fr.ts +2 -2
  44. package/src/tool/keyboardTest/keyboard-test.css +115 -2
  45. package/src/tool/mousePollingTest/i18n/fr.ts +3 -3
  46. package/src/tool/mousePollingTest/i18n/pl.ts +1 -1
  47. package/src/tool/mousePollingTest/i18n/ru.ts +1 -1
  48. package/src/tool/mousePollingTest/i18n/zh.ts +1 -1
  49. package/src/tool/refreshRateDetector/i18n/de.ts +3 -3
  50. package/src/tool/refreshRateDetector/i18n/en.ts +3 -3
  51. package/src/tool/refreshRateDetector/i18n/fr.ts +4 -4
  52. package/src/tool/refreshRateDetector/i18n/id.ts +3 -3
  53. package/src/tool/refreshRateDetector/i18n/pl.ts +2 -2
  54. package/src/tool/refreshRateDetector/i18n/pt.ts +3 -3
  55. package/src/tool/refreshRateDetector/i18n/sv.ts +3 -3
  56. package/src/tool/refreshRateDetector/i18n/tr.ts +2 -2
  57. package/src/tool/refreshRateDetector/i18n/zh.ts +2 -2
  58. package/src/tool/toneGenerator/i18n/fr.ts +2 -2
  59. package/src/tool/toneGenerator/i18n/pl.ts +1 -1
  60. package/src/tool/toneGenerator/i18n/ru.ts +2 -2
  61. package/src/tool/toneGenerator/i18n/zh.ts +3 -3
@@ -0,0 +1,94 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+
4
+ type ScriptLocale = keyof typeof SCRIPT_RULES;
5
+
6
+ const SCRIPT_RULES = {
7
+ ja: {
8
+ language: 'Japanese',
9
+ scriptName: 'kana/kanji',
10
+ scriptCharacters: /[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}]/gu,
11
+ minScriptRatio: 0.45,
12
+ },
13
+ ko: {
14
+ language: 'Korean',
15
+ scriptName: 'hangul',
16
+ scriptCharacters: /\p{Script=Hangul}/gu,
17
+ minScriptRatio: 0.55,
18
+ },
19
+ ru: {
20
+ language: 'Russian',
21
+ scriptName: 'cyrillic',
22
+ scriptCharacters: /\p{Script=Cyrillic}/gu,
23
+ minScriptRatio: 0.65,
24
+ },
25
+ zh: {
26
+ language: 'Chinese',
27
+ scriptName: 'han',
28
+ scriptCharacters: /\p{Script=Han}/gu,
29
+ minScriptRatio: 0.45,
30
+ },
31
+ } as const;
32
+
33
+ const LETTERS = /\p{L}/gu;
34
+ const TRANSLATABLE_KEYS = ['title', 'description', 'ui', 'seo', 'faq', 'howTo'] as const;
35
+
36
+ function collectStrings(value: unknown): string[] {
37
+ if (typeof value === 'string') return [value];
38
+ if (!value || typeof value !== 'object') return [];
39
+ if (Array.isArray(value)) return value.flatMap(collectStrings);
40
+ return Object.values(value).flatMap(collectStrings);
41
+ }
42
+
43
+ function normalizeText(value: unknown): string {
44
+ return collectStrings(value).join(' ').normalize('NFC');
45
+ }
46
+
47
+ function translatableContent(content: Record<string, unknown>) {
48
+ return TRANSLATABLE_KEYS.map((key) => content[key]);
49
+ }
50
+
51
+ function letterCount(text: string): number {
52
+ return text.match(LETTERS)?.length ?? 0;
53
+ }
54
+
55
+ function scriptCount(text: string, locale: ScriptLocale): number {
56
+ return text.match(SCRIPT_RULES[locale].scriptCharacters)?.length ?? 0;
57
+ }
58
+
59
+ function scriptRatio(text: string, locale: ScriptLocale): number {
60
+ const letters = letterCount(text);
61
+ if (letters === 0) return 0;
62
+ return scriptCount(text, locale) / letters;
63
+ }
64
+
65
+ describe('Native script density validation', () => {
66
+ ALL_TOOLS.forEach((tool) => {
67
+ describe(`Tool: ${tool.entry.id}`, () => {
68
+ Object.keys(SCRIPT_RULES).forEach((locale) => {
69
+ it(`${locale} keeps most translated text in its native script`, async () => {
70
+ const typedLocale = locale as ScriptLocale;
71
+ const loader = tool.entry.i18n[typedLocale];
72
+ if (!loader) return;
73
+
74
+ const content = await loader();
75
+ const rule = SCRIPT_RULES[typedLocale];
76
+ const text = normalizeText(translatableContent(content as Record<string, unknown>));
77
+ const letters = letterCount(text);
78
+ const matches = scriptCount(text, typedLocale);
79
+ const ratio = scriptRatio(text, typedLocale);
80
+
81
+ expect(
82
+ ratio,
83
+ [
84
+ `Possible broken translation detected in ${tool.entry.id}/${typedLocale} (${rule.language}).`,
85
+ `The text has ${matches} ${rule.scriptName} characters out of ${letters} analyzed letters (${(ratio * 100).toFixed(1)}%).`,
86
+ `Most translatable content should be written in ${rule.scriptName} script.`,
87
+ 'Non-translatable fields such as slug, bibliography, and schemas are ignored to avoid false positives.',
88
+ ].join(' '),
89
+ ).toBeGreaterThanOrEqual(rule.minScriptRatio);
90
+ });
91
+ });
92
+ });
93
+ });
94
+ });
@@ -93,7 +93,7 @@ export const content: ToolLocaleContent<EstimadorSaludBateriaUI> = {
93
93
  schemas: [faqSchema, howToSchema, appSchema],
94
94
  bibliography,
95
95
  seo: [
96
- { type: 'title', text: 'La chimie du temps : pourquoi les batteries lithium meurent', level: 2 },
96
+ { type: 'title', text: 'La chimie du temps: pourquoi les batteries lithium meurent', level: 2 },
97
97
  {
98
98
  type: 'paragraph',
99
99
  html: "Une batterie lithium-ion n'est pas une boîte d'énergie statique, mais un écosystème chimique dynamique en dégradation constante depuis sa fabrication. Chaque cycle de charge et décharge, chaque variation de température et chaque minute à des tensions extrêmes contribue à la formation de sous-produits qui entravent le flux d'ions.",
@@ -103,7 +103,7 @@ export const content: ToolLocaleContent<EstimadorSaludBateriaUI> = {
103
103
  type: 'paragraph',
104
104
  html: "<strong>Couche SEI :</strong> l'interface électrolyte solide croît avec le temps, consomme du lithium actif et augmente la résistance interne. <strong>Oxydation de l'électrolyte :</strong> des tensions supérieures à 4,1V accélèrent l'oxydation et peuvent gonfler la batterie. <strong>Lithium Plating :</strong> charger à basse température dépose du lithium sous forme métallique, créant des dendrites qui peuvent percer le séparateur.",
105
105
  },
106
- { type: 'title', text: "Le mythe des 100% : pourquoi charger toute la nuit est une erreur", level: 3 },
106
+ { type: 'title', text: "Le mythe des 100%: pourquoi charger toute la nuit est une erreur", level: 3 },
107
107
  {
108
108
  type: 'paragraph',
109
109
  html: "Pour un ion lithium, être à 100% de charge (4,2V) est un état de haute tension. Les recherches montrent que la durée de vie double ou triple si l'on maintient l'appareil entre <strong>20% et 80%</strong>. De plus, pour chaque hausse de 10°C au-dessus de 25°C, la vitesse de dégradation chimique double approximativement.",
@@ -111,7 +111,7 @@ export const content: ToolLocaleContent<EstimadorSaludBateriaUI> = {
111
111
  { type: 'title', text: 'Protocole de survie énergétique', level: 3 },
112
112
  {
113
113
  type: 'paragraph',
114
- html: "Ne chargez jamais une batterie en dessous de 0°C : le lithium se dépose sur l'anode, causant des dommages permanents. La charge rapide génère de la chaleur localisée et du stress mécanique ; utilisez-la uniquement en cas de stricte nécessité. Pour un stockage prolongé, conservez la batterie à 50% dans un endroit frais.",
114
+ html: "Ne chargez jamais une batterie en dessous de 0°C: le lithium se dépose sur l'anode, causant des dommages permanents. La charge rapide génère de la chaleur localisée et du stress mécanique ; utilisez-la uniquement en cas de stricte nécessité. Pour un stockage prolongé, conservez la batterie à 50% dans un endroit frais.",
115
115
  },
116
116
  ],
117
117
  ui: {
@@ -122,7 +122,7 @@ export const content: ToolLocaleContent<EstimadorSaludBateriaUI> = {
122
122
  voltageLabel: 'Tension Actuelle',
123
123
  cyclesLabel: 'Cycles de Charge',
124
124
  tempLabel: 'Température',
125
- voltageHint: 'Plage nominale : 3,0V (vide) à 4,2V (plein).',
125
+ voltageHint: 'Plage nominale: 3,0V (vide) à 4,2V (plein).',
126
126
  labelUsefulLife: 'Durée de Vie',
127
127
  yearsPrefix: 'Est.',
128
128
  yearsSuffix: 'ans',
@@ -106,7 +106,7 @@ export const content: ToolLocaleContent<EstimadorSaludBateriaUI> = {
106
106
  { type: 'title', text: 'Mit 100%: dlaczego ładowanie przez noc to błąd', level: 3 },
107
107
  {
108
108
  type: 'paragraph',
109
- html: 'Dla jonu litu stan naładowania 100% (4.2V) jest stanem wysokiego stresu. Badania pokazują, że żywotność cyklu wzrasta dwu- lub trzykrotnie przy utrzymywaniu urządzenia w zakresie <strong>20% 80%</strong>. Ponadto na każde 10°C powyżej 25°C tempo degradacji chemicznej wzrasta około dwukrotnie.',
109
+ html: 'Dla jonu litu stan naładowania 100% (4.2V) jest stanem wysokiego stresu. Badania pokazują, że żywotność cyklu wzrasta dwu- lub trzykrotnie przy utrzymywaniu urządzenia w zakresie <strong>20% - 80%</strong>. Ponadto na każde 10°C powyżej 25°C tempo degradacji chemicznej wzrasta około dwukrotnie.',
110
110
  },
111
111
  { type: 'title', text: 'Protokół przetrwania energii', level: 3 },
112
112
  {
@@ -20,6 +20,13 @@
20
20
  margin: 0 auto;
21
21
  padding: 1rem;
22
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;
23
30
  }
24
31
 
25
32
  .theme-dark .sc-wrapper {
@@ -44,6 +51,7 @@
44
51
  transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
45
52
  position: relative;
46
53
  overflow: hidden;
54
+ max-width: 100%;
47
55
  }
48
56
 
49
57
  .sc-dashboard::before {
@@ -68,13 +76,18 @@
68
76
  }
69
77
 
70
78
  @media (max-width: 768px) {
79
+ .sc-wrapper {
80
+ padding: 0;
81
+ }
82
+
71
83
  .sc-grid {
72
84
  grid-template-columns: 1fr;
73
- gap: 2rem;
85
+ gap: 1.25rem;
74
86
  }
75
87
 
76
88
  .sc-dashboard {
77
- padding: 1.5rem;
89
+ border-radius: 0.875rem;
90
+ padding: 1rem;
78
91
  }
79
92
  }
80
93
 
@@ -160,6 +173,7 @@
160
173
  padding: 0.5rem;
161
174
  border-radius: 0.875rem;
162
175
  border: 1px solid var(--sc-border);
176
+ min-width: 0;
163
177
  }
164
178
 
165
179
  .sc-gamut-btn {
@@ -173,6 +187,7 @@
173
187
  background: transparent;
174
188
  color: var(--sc-text-muted);
175
189
  position: relative;
190
+ min-width: 0;
176
191
  }
177
192
 
178
193
  .sc-gamut-btn.sc-gamut-active {
@@ -220,6 +235,7 @@
220
235
  display: flex;
221
236
  gap: 1rem;
222
237
  animation: fade-in-up 0.8s ease-out 0.4s both;
238
+ width: 100%;
223
239
  }
224
240
 
225
241
  .sc-btn {
@@ -236,6 +252,7 @@
236
252
  gap: 0.5rem;
237
253
  position: relative;
238
254
  overflow: hidden;
255
+ min-width: 0;
239
256
  }
240
257
 
241
258
  .sc-btn::before {
@@ -292,6 +309,7 @@
292
309
  color: var(--sc-text-light);
293
310
  margin-top: 1.5rem;
294
311
  animation: fade-in-up 0.8s ease-out 0.5s both;
312
+ flex-wrap: wrap;
295
313
  }
296
314
 
297
315
  .sc-shortcut {
@@ -315,12 +333,12 @@
315
333
  justify-content: center;
316
334
  align-items: center;
317
335
  animation: fade-in-right 0.8s ease-out 0.3s both;
336
+ min-width: 0;
318
337
  }
319
338
 
320
339
  .sc-preview-canvas {
321
340
  width: 100%;
322
341
  aspect-ratio: 1;
323
- max-width: 350px;
324
342
  border-radius: 1rem;
325
343
  background: linear-gradient(135deg, #1e1b4b 0%, #0f172a 50%, #1e1b4b 100%);
326
344
  border: 2px solid var(--sc-border);
@@ -331,6 +349,7 @@
331
349
  flex-direction: column;
332
350
  justify-content: center;
333
351
  align-items: center;
352
+ max-width: min(350px, 100%);
334
353
  }
335
354
 
336
355
  .sc-preview-gradient {
@@ -362,6 +381,8 @@
362
381
  letter-spacing: 0.05em;
363
382
  text-transform: uppercase;
364
383
  z-index: 10;
384
+ width: calc(100% - 2rem);
385
+ text-align: center;
365
386
  }
366
387
 
367
388
  #test-overlay {
@@ -402,6 +423,8 @@
402
423
  z-index: 1001;
403
424
  backdrop-filter: blur(10px);
404
425
  animation: slide-up 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
426
+ max-height: 55vh;
427
+ overflow-y: auto;
405
428
  }
406
429
 
407
430
  @media (min-width: 768px) {
@@ -419,11 +442,24 @@
419
442
  @keyframes slide-up {
420
443
  from {
421
444
  opacity: 0;
422
- transform: translateX(-50%) translateY(20px);
445
+ transform: translateY(20px);
423
446
  }
424
447
  to {
425
448
  opacity: 1;
426
- transform: translateX(-50%) translateY(0);
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
+ }
427
463
  }
428
464
  }
429
465
 
@@ -675,6 +711,7 @@
675
711
  display: flex;
676
712
  gap: 0.5rem;
677
713
  margin-top: 0.75rem;
714
+ width: 100%;
678
715
  }
679
716
 
680
717
  @media (min-width: 768px) {
@@ -695,6 +732,7 @@
695
732
  font-weight: 600;
696
733
  cursor: pointer;
697
734
  transition: all 0.2s ease;
735
+ min-width: 0;
698
736
  }
699
737
 
700
738
  @media (min-width: 768px) {
@@ -726,3 +764,78 @@
726
764
  .sc-action-secondary:hover {
727
765
  background: rgba(255, 255, 255, 0.15);
728
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
+ }
@@ -43,7 +43,7 @@ const howToData = [
43
43
  },
44
44
  {
45
45
  name: 'Hardware benennen (optional)',
46
- text: 'Geben Sie einen aussagekräftigen Namen für Ihren Monitor oder Ihr Gerät ein (z. B. MacBook Pro 16 M1). Dies personalisiert Ihren Bericht.',
46
+ text: 'Geben Sie einen aussagekräftigen Namen für Ihren Monitor oder Ihr Gerät ein (z. B. "MacBook Pro 16 M1"). Dies personalisiert Ihren Bericht.',
47
47
  },
48
48
  {
49
49
  name: 'Vollbildmodus aktivieren',
@@ -118,7 +118,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
118
118
  },
119
119
  {
120
120
  type: 'paragraph',
121
- html: 'Schon ein Unterschied von einem Prozentpunkt bei der Farbwiedergabe kann den Unterschied zwischen einem Wow“-Moment und einer Reaktion wie das sieht irgendwie falsch aus ausmachen. Professionelle Displays liefern eine Genauigkeit innerhalb von <strong>Delta E &lt; 2</strong>. Consumer-Displays driften oft in einen Bereich von Delta E 4-6+ ab, was folgendes verursacht:',
121
+ html: 'Schon ein Unterschied von einem Prozentpunkt bei der Farbwiedergabe kann den Unterschied zwischen einem "Wow"-Moment und einer Reaktion wie "das sieht irgendwie falsch aus" ausmachen. Professionelle Displays liefern eine Genauigkeit innerhalb von <strong>Delta E &lt; 2</strong>. Consumer-Displays driften oft in einen Bereich von Delta E 4-6+ ab, was folgendes verursacht:',
122
122
  },
123
123
  {
124
124
  type: 'paragraph',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Delta-E-Skala (CIE 1976):</strong><ul><li>01: Vom menschlichen Auge nicht wahrnehmbar</li><li>12: Kaum wahrnehmbar</li><li>24: Wahrnehmbar, aber für den allgemeinen Gebrauch akzeptabel</li><li>46: Deutliche Farbverschiebung</li><li>&gt;6: Sehr offensichtlicher Unterschied</li></ul>',
169
+ html: '<strong>Delta-E-Skala (CIE 1976):</strong><ul><li>0-1: Vom menschlichen Auge nicht wahrnehmbar</li><li>1-2: Kaum wahrnehmbar</li><li>2-4: Wahrnehmbar, aber für den allgemeinen Gebrauch akzeptabel</li><li>4-6: Deutliche Farbverschiebung</li><li>&gt;6: Sehr offensichtlicher Unterschied</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -184,7 +184,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
184
184
  },
185
185
  {
186
186
  type: 'paragraph',
187
- html: 'Zeigt reine Primär- und Sekundärfarben (Rot, Grün, Blau, Cyan, Magenta, Gelb) an und misst, wie Ihr Monitor diese wiedergibt. Farb-„Flut“-Animationen zeigen eine konsistente Farbwiedergabe auf dem gesamten Bildschirm.',
187
+ html: 'Zeigt reine Primär- und Sekundärfarben (Rot, Grün, Blau, Cyan, Magenta, Gelb) an und misst, wie Ihr Monitor diese wiedergibt. Farb-"Flut"-Animationen zeigen eine konsistente Farbwiedergabe auf dem gesamten Bildschirm.',
188
188
  },
189
189
  {
190
190
  type: 'title',
@@ -202,7 +202,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
202
202
  },
203
203
  {
204
204
  type: 'paragraph',
205
- html: 'Reiner schwarzer (0,0,0) Hintergrund mit kaum sichtbaren, fast schwarzen Tönen. Wenn Schattendetails zerquetscht werden, verliert Ihr Monitor Informationen in dunklen Tönen häufig bei Mobilgeräten und günstigen Panels.',
205
+ html: 'Reiner schwarzer (0,0,0) Hintergrund mit kaum sichtbaren, fast schwarzen Tönen. Wenn Schattendetails "zerquetscht" werden, verliert Ihr Monitor Informationen in dunklen Tönen - häufig bei Mobilgeräten und günstigen Panels.',
206
206
  },
207
207
  {
208
208
  type: 'title',
@@ -224,7 +224,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>3D-Gamut-Visualisierung:</strong> Ein rotierender 3D-Plot, der das tatsächliche Farbvolumen Ihres Displays im Vergleich zum Referenzstandard zeigt</li><li><strong>Delta-E-Heatmap:</strong> Wo im Spektrum Ihr Display abweicht</li><li><strong>Gammakurve:</strong> Helligkeitslinearität über den Bereich von 0255</li><li><strong>Kalibrierungs-Score:</strong> Eine einzige Spectrum Grade (Elite, Cinematic, Studio, Standard) basierend auf der Gesamtgenauigkeit</li></ul>',
227
+ html: '<ul><li><strong>3D-Gamut-Visualisierung:</strong> Ein rotierender 3D-Plot, der das tatsächliche Farbvolumen Ihres Displays im Vergleich zum Referenzstandard zeigt</li><li><strong>Delta-E-Heatmap:</strong> Wo im Spektrum Ihr Display abweicht</li><li><strong>Gammakurve:</strong> Helligkeitslinearität über den Bereich von 0-255</li><li><strong>Kalibrierungs-Score:</strong> Eine einzige "Spectrum Grade" (Elite, Cinematic, Studio, Standard) basierend auf der Gesamtgenauigkeit</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
@@ -237,7 +237,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
237
237
  },
238
238
  {
239
239
  type: 'paragraph',
240
- html: '<ul><li><strong>Farbtemperatur:</strong> In Richtung Warm verschieben, wenn die Farben zu kühl/blau wirken; in Richtung Kühl“, wenn sie zu warm/gelb wirken</li><li><strong>Kontrast:</strong> Erhöhen, wenn Schwarztöne verwaschen aussehen; verringern, wenn Details zerquetscht werden</li><li><strong>Helligkeit:</strong> So einstellen, dass ein neutrales Grau ohne Farbstich bei 50 % Helligkeit erreicht wird</li><li><strong>Sättigung:</strong> Wenn Farben übersättigt sind, verringern; wenn sie stumpf wirken, erhöhen</li></ul>',
240
+ html: '<ul><li><strong>Farbtemperatur:</strong> In Richtung "Warm" verschieben, wenn die Farben zu kühl/blau wirken; in Richtung "Kühl", wenn sie zu warm/gelb wirken</li><li><strong>Kontrast:</strong> Erhöhen, wenn Schwarztöne verwaschen aussehen; verringern, wenn Details "zerquetscht" werden</li><li><strong>Helligkeit:</strong> So einstellen, dass ein neutrales Grau ohne Farbstich bei 50 % Helligkeit erreicht wird</li><li><strong>Sättigung:</strong> Wenn Farben übersättigt sind, verringern; wenn sie stumpf wirken, erhöhen</li></ul>',
241
241
  },
242
242
  {
243
243
  type: 'title',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Delta E Scale (CIE 1976):</strong><ul><li>01: Imperceptible by human eye</li><li>12: Barely perceptible</li><li>24: Perceptible but acceptable for general use</li><li>46: Noticeable color shift</li><li>&gt;6: Very obvious difference</li></ul>',
169
+ html: '<strong>Delta E Scale (CIE 1976):</strong><ul><li>0-1: Imperceptible by human eye</li><li>1-2: Barely perceptible</li><li>2-4: Perceptible but acceptable for general use</li><li>4-6: Noticeable color shift</li><li>&gt;6: Very obvious difference</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -202,7 +202,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
202
202
  },
203
203
  {
204
204
  type: 'paragraph',
205
- html: 'Pure black (0,0,0) background with barely-visible near-black shades. If shadow detail "crushes" together, your monitor is losing information in dark tonescommon in mobile displays and cheap panels.',
205
+ html: 'Pure black (0,0,0) background with barely-visible near-black shades. If shadow detail "crushes" together, your monitor is losing information in dark tones-common in mobile displays and cheap panels.',
206
206
  },
207
207
  {
208
208
  type: 'title',
@@ -224,7 +224,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>3D Gamut Visualization:</strong> A rotating 3D plot showing your display\'s actual color volume versus the reference standard</li><li><strong>Delta E Heatmap:</strong> Where on the spectrum your display drifts</li><li><strong>Gamma Curve:</strong> Brightness linearity across the 0255 range</li><li><strong>Calibration Score:</strong> A single "Spectrum Grade" (Elite, Cinematic, Studio, Standard) based on overall accuracy</li></ul>',
227
+ html: '<ul><li><strong>3D Gamut Visualization:</strong> A rotating 3D plot showing your display\'s actual color volume versus the reference standard</li><li><strong>Delta E Heatmap:</strong> Where on the spectrum your display drifts</li><li><strong>Gamma Curve:</strong> Brightness linearity across the 0-255 range</li><li><strong>Calibration Score:</strong> A single "Spectrum Grade" (Elite, Cinematic, Studio, Standard) based on overall accuracy</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Escala Delta E (CIE 1976):</strong><ul><li>01: Imperceptible por el ojo humano</li><li>12: Apenas perceptible</li><li>24: Perceptible pero aceptable para uso general</li><li>46: Desviación de color notable</li><li>&gt;6: Diferencia muy obvia</li></ul>',
169
+ html: '<strong>Escala Delta E (CIE 1976):</strong><ul><li>0-1: Imperceptible por el ojo humano</li><li>1-2: Apenas perceptible</li><li>2-4: Perceptible pero aceptable para uso general</li><li>4-6: Desviación de color notable</li><li>&gt;6: Diferencia muy obvia</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -224,7 +224,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>Visualización de Gama 3D:</strong> Un gráfico 3D giratorio que muestra el volumen de color real de tu pantalla frente al estándar de referencia</li><li><strong>Mapa de Calor Delta E:</strong> En qué parte del espectro se desvía tu pantalla</li><li><strong>Curva Gamma:</strong> Linealidad del brillo en el rango 0255</li><li><strong>Puntuación de Calibración:</strong> Una única "Calificación Spectrum" (Élite, Cinematográfica, Estudio, Estándar) basada en la precisión general</li></ul>',
227
+ html: '<ul><li><strong>Visualización de Gama 3D:</strong> Un gráfico 3D giratorio que muestra el volumen de color real de tu pantalla frente al estándar de referencia</li><li><strong>Mapa de Calor Delta E:</strong> En qué parte del espectro se desvía tu pantalla</li><li><strong>Curva Gamma:</strong> Linealidad del brillo en el rango 0-255</li><li><strong>Puntuación de Calibración:</strong> Una única "Calificación Spectrum" (Élite, Cinematográfica, Estudio, Estándar) basada en la precisión general</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
@@ -104,7 +104,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
104
104
  seo: [
105
105
  {
106
106
  type: 'title',
107
- text: 'Test de Précision des Couleurs Professionnel : Calibrez votre Écran avec Précision',
107
+ text: 'Test de Précision des Couleurs Professionnel: Calibrez votre Écran avec Précision',
108
108
  level: 2,
109
109
  },
110
110
  {
@@ -126,7 +126,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
126
126
  },
127
127
  {
128
128
  type: 'title',
129
- text: 'Comprendre les espaces colorimétriques : sRGB vs DCI-P3',
129
+ text: 'Comprendre les espaces colorimétriques: sRGB vs DCI-P3',
130
130
  level: 3,
131
131
  },
132
132
  {
@@ -136,11 +136,11 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
136
136
  },
137
137
  {
138
138
  type: 'paragraph',
139
- html: 'Établi par Microsoft et HP en 1996, le sRGB est la <strong>norme universelle pour l\'électronique grand public</strong> et le web. Il utilise un gamut de couleurs triangulaire défini par trois couleurs primaires (Rouge : 0.6400x 0.3300, Vert : 0.3000 0.6000, Bleu : 0.1500 0.0600).',
139
+ html: 'Établi par Microsoft et HP en 1996, le sRGB est la <strong>norme universelle pour l\'électronique grand public</strong> et le web. Il utilise un gamut de couleurs triangulaire défini par trois couleurs primaires (Rouge: 0.6400x 0.3300, Vert: 0.3000 0.6000, Bleu: 0.1500 0.0600).',
140
140
  },
141
141
  {
142
142
  type: 'paragraph',
143
- html: '<strong>Caractéristiques :</strong><ul><li>Couvre ~35 % du spectre de couleurs visibles</li><li>Optimisé pour les conditions d\'éclairage ambiant typiques</li><li>Gamma : 2.2 (correspond à la plupart des écrans grand public)</li><li>Adapté pour : web, réseaux sociaux, photos grand public</li></ul>',
143
+ html: '<strong>Caractéristiques :</strong><ul><li>Couvre ~35 % du spectre de couleurs visibles</li><li>Optimisé pour les conditions d\'éclairage ambiant typiques</li><li>Gamma: 2.2 (correspond à la plupart des écrans grand public)</li><li>Adapté pour: web, réseaux sociaux, photos grand public</li></ul>',
144
144
  },
145
145
  {
146
146
  type: 'title',
@@ -153,7 +153,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
153
153
  },
154
154
  {
155
155
  type: 'paragraph',
156
- html: '<strong>Caractéristiques :</strong><ul><li>Couvre ~53 % du spectre de couleurs visibles</li><li>Optimisé pour les environnements de cinéma sombres</li><li>Gamma : 2.6 (corrigé en gamma pour un contraste élevé)</li><li>Adapté pour : réalisation de films, photographie professionnelle, contenu HDR</li></ul>',
156
+ html: '<strong>Caractéristiques :</strong><ul><li>Couvre ~53 % du spectre de couleurs visibles</li><li>Optimisé pour les environnements de cinéma sombres</li><li>Gamma: 2.6 (corrigé en gamma pour un contraste élevé)</li><li>Adapté pour: réalisation de films, photographie professionnelle, contenu HDR</li></ul>',
157
157
  },
158
158
  {
159
159
  type: 'title',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Échelle Delta E (CIE 1976) :</strong><ul><li>01 : Imperceptible par l\'œil humain</li><li>12 : À peine perceptible</li><li>24 : Perceptible mais acceptable pour un usage général</li><li>46 : Dérive de couleur notable</li><li>&gt;6 : Différence très évidente</li></ul>',
169
+ html: '<strong>Échelle Delta E (CIE 1976) :</strong><ul><li>0-1: Imperceptible par l\'œil humain</li><li>1-2: À peine perceptible</li><li>2-4: Perceptible mais acceptable pour un usage général</li><li>4-6: Dérive de couleur notable</li><li>&gt;6: Différence très évidente</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -202,7 +202,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
202
202
  },
203
203
  {
204
204
  type: 'paragraph',
205
- html: 'Fond noir pur (0,0,0) avec des nuances de gris sombre à peine visibles. Si les détails des ombres se "télescopent", votre moniteur perd des informations dans les tons sombres courant sur les écrans mobiles et les dalles bon marché.',
205
+ html: 'Fond noir pur (0,0,0) avec des nuances de gris sombre à peine visibles. Si les détails des ombres se "télescopent", votre moniteur perd des informations dans les tons sombres - courant sur les écrans mobiles et les dalles bon marché.',
206
206
  },
207
207
  {
208
208
  type: 'title',
@@ -224,11 +224,11 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>Visualisation du Gamut 3D :</strong> Un graphique 3D rotatif montrant le volume de couleur réel de votre écran par rapport à la norme de référence</li><li><strong>Carte thermique Delta E :</strong> Les zones du spectre où votre écran dérive</li><li><strong>Courbe Gamma :</strong> Linéarité de la luminosité sur la plage 0255</li><li><strong>Score de calibrage :</strong> Une "Note Spectrum" unique (Élite, Cinématique, Studio, Standard) basée sur la précision globale</li></ul>',
227
+ html: '<ul><li><strong>Visualisation du Gamut 3D :</strong> Un graphique 3D rotatif montrant le volume de couleur réel de votre écran par rapport à la norme de référence</li><li><strong>Carte thermique Delta E :</strong> Les zones du spectre où votre écran dérive</li><li><strong>Courbe Gamma :</strong> Linéarité de la luminosité sur la plage 0-255</li><li><strong>Score de calibrage :</strong> Une "Note Spectrum" unique (Élite, Cinématique, Studio, Standard) basée sur la précision globale</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
231
- text: 'Avancé : Conseils de calibrage manuel',
231
+ text: 'Avancé: Conseils de calibrage manuel',
232
232
  level: 3,
233
233
  },
234
234
  {
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Skala Delta E (CIE 1976):</strong><ul><li>01: Tidak terlihat oleh mata manusia</li><li>12: Nyaris tidak terlihat</li><li>24: Terlihat tetapi dapat diterima untuk penggunaan umum</li><li>46: Pergeseran warna yang nyata</li><li>&gt;6: Perbedaan yang sangat jelas</li></ul>',
169
+ html: '<strong>Skala Delta E (CIE 1976):</strong><ul><li>0-1: Tidak terlihat oleh mata manusia</li><li>1-2: Nyaris tidak terlihat</li><li>2-4: Terlihat tetapi dapat diterima untuk penggunaan umum</li><li>4-6: Pergeseran warna yang nyata</li><li>&gt;6: Perbedaan yang sangat jelas</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -202,7 +202,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
202
202
  },
203
203
  {
204
204
  type: 'paragraph',
205
- html: 'Latar belakang hitam murni (0,0,0) dengan nuansa nyaris hitam yang hampir tidak terlihat. Jika detail bayangan "hancur" bersama-sama, monitor Anda kehilangan informasi dalam nada gelapumum pada layar ponsel dan panel murah.',
205
+ html: 'Latar belakang hitam murni (0,0,0) dengan nuansa nyaris hitam yang hampir tidak terlihat. Jika detail bayangan "hancur" bersama-sama, monitor Anda kehilangan informasi dalam nada gelap-umum pada layar ponsel dan panel murah.',
206
206
  },
207
207
  {
208
208
  type: 'title',
@@ -224,7 +224,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>Visualisasi Gamut 3D:</strong> Plot 3D berputar yang menunjukkan volume warna aktual layar Anda versus standar referensi</li><li><strong>Heatmap Delta E:</strong> Di bagian spektrum mana layar Anda bergeser</li><li><strong>Kurva Gamma:</strong> Linearitas kecerahan di seluruh rentang 0255</li><li><strong>Skor Kalibrasi:</strong> Sebuah "Spectrum Grade" tunggal (Elite, Cinematic, Studio, Standard) berdasarkan akurasi keseluruhan</li></ul>',
227
+ html: '<ul><li><strong>Visualisasi Gamut 3D:</strong> Plot 3D berputar yang menunjukkan volume warna aktual layar Anda versus standar referensi</li><li><strong>Heatmap Delta E:</strong> Di bagian spektrum mana layar Anda bergeser</li><li><strong>Kurva Gamma:</strong> Linearitas kecerahan di seluruh rentang 0-255</li><li><strong>Skor Kalibrasi:</strong> Sebuah "Spectrum Grade" tunggal (Elite, Cinematic, Studio, Standard) berdasarkan akurasi keseluruhan</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Scala Delta E (CIE 1976):</strong><ul><li>01: Impercettibile all\'occhio umano</li><li>12: Appena percettibile</li><li>24: Percettibile ma accettabile per uso generale</li><li>46: Deriva cromatica evidente</li><li>&gt;6: Differenza molto ovvia</li></ul>',
169
+ html: '<strong>Scala Delta E (CIE 1976):</strong><ul><li>0-1: Impercettibile all\'occhio umano</li><li>1-2: Appena percettibile</li><li>2-4: Percettibile ma accettabile per uso generale</li><li>4-6: Deriva cromatica evidente</li><li>&gt;6: Differenza molto ovvia</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
@@ -202,7 +202,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
202
202
  },
203
203
  {
204
204
  type: 'paragraph',
205
- html: 'Sfondo nero puro (0,0,0) con sfumature quasi nere appena visibili. Se il dettaglio delle ombre si "schiaccia", il monitor sta perdendo informazioni nei toni scuri comune nei display mobile e nei pannelli economici.',
205
+ html: 'Sfondo nero puro (0,0,0) con sfumature quasi nere appena visibili. Se il dettaglio delle ombre si "schiaccia", il monitor sta perdendo informazioni nei toni scuri - comune nei display mobile e nei pannelli economici.',
206
206
  },
207
207
  {
208
208
  type: 'title',
@@ -224,7 +224,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
224
224
  },
225
225
  {
226
226
  type: 'paragraph',
227
- html: '<ul><li><strong>Visualizzazione Gamma 3D:</strong> Un grafico 3D rotante che mostra il volume di colore effettivo del display rispetto allo standard di riferimento</li><li><strong>Mappa di calore Delta E:</strong> Dove nello spettro il tuo display deriva</li><li><strong>Curva Gamma:</strong> Linearità della luminosità nell\'intervallo 0255</li><li><strong>Punteggio di calibrazione:</strong> Un unico "Spectrum Grade" (Elite, Cinematic, Studio, Standard) basato sulla precisione complessiva</li></ul>',
227
+ html: '<ul><li><strong>Visualizzazione Gamma 3D:</strong> Un grafico 3D rotante che mostra il volume di colore effettivo del display rispetto allo standard di riferimento</li><li><strong>Mappa di calore Delta E:</strong> Dove nello spettro il tuo display deriva</li><li><strong>Curva Gamma:</strong> Linearità della luminosità nell\'intervallo 0-255</li><li><strong>Punteggio di calibrazione:</strong> Un unico "Spectrum Grade" (Elite, Cinematic, Studio, Standard) basato sulla precisione complessiva</li></ul>',
228
228
  },
229
229
  {
230
230
  type: 'title',
@@ -166,7 +166,7 @@ export const content: ToolLocaleContent<SpectrumCanvasUI> = {
166
166
  },
167
167
  {
168
168
  type: 'paragraph',
169
- html: '<strong>Delta Eスケール(CIE 1976):</strong><ul><li>01:人間の目では知覚不能</li><li>12:かろうじて知覚可能</li><li>24:知覚可能だが一般的な用途には許容範囲内</li><li>46:目立つ色ずれ</li><li>&gt;6:非常に明らかな違い</li></ul>',
169
+ html: '<strong>Delta Eスケール(CIE 1976):</strong><ul><li>0-1:人間の目では知覚不能</li><li>1-2:かろうじて知覚可能</li><li>2-4:知覚可能だが一般的な用途には許容範囲内</li><li>4-6:目立つ色ずれ</li><li>&gt;6:非常に明らかな違い</li></ul>',
170
170
  },
171
171
  {
172
172
  type: 'paragraph',