@jjlmoya/utils-developer 1.13.0 → 1.15.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 (184) hide show
  1. package/package.json +1 -1
  2. package/src/category/i18n/fr.ts +1 -1
  3. package/src/category/i18n/ru.ts +1 -1
  4. package/src/layouts/PreviewLayout.astro +1 -0
  5. package/src/pages/[locale]/[slug].astro +29 -12
  6. package/src/tests/diacritics_density.test.ts +118 -0
  7. package/src/tests/inverted_punctuation.test.ts +113 -0
  8. package/src/tests/no_en_dash.test.ts +73 -0
  9. package/src/tests/script_density.test.ts +94 -0
  10. package/src/tests/shared-test-helpers.ts +56 -0
  11. package/src/tests/tool_exports.test.ts +34 -0
  12. package/src/tool/aspectRatio/aspect-ratio-calculator.css +1 -1
  13. package/src/tool/aspectRatio/i18n/de.ts +1 -1
  14. package/src/tool/aspectRatio/i18n/fr.ts +1 -1
  15. package/src/tool/aspectRatio/i18n/pl.ts +2 -2
  16. package/src/tool/aspectRatio/i18n/ru.ts +4 -4
  17. package/src/tool/aspectRatio/i18n/zh.ts +1 -1
  18. package/src/tool/aspectRatio/seo.astro +2 -1
  19. package/src/tool/calculadoraTiempoDatos/data-time-calculator-web-speed-impact.css +26 -26
  20. package/src/tool/calculadoraTiempoDatos/i18n/de.ts +1 -1
  21. package/src/tool/calculadoraTiempoDatos/i18n/pl.ts +1 -1
  22. package/src/tool/calculadoraTiempoDatos/i18n/ru.ts +5 -5
  23. package/src/tool/calculadoraTiempoDatos/i18n/sv.ts +5 -5
  24. package/src/tool/calculadoraTiempoDatos/i18n/zh.ts +1 -1
  25. package/src/tool/calculadoraTiempoDatos/seo.astro +2 -1
  26. package/src/tool/colorConverter/color-converter-rgb-hex-hsl.css +9 -9
  27. package/src/tool/colorConverter/i18n/de.ts +1 -1
  28. package/src/tool/colorConverter/i18n/ru.ts +2 -2
  29. package/src/tool/colorConverter/seo.astro +2 -1
  30. package/src/tool/conversorExcelCsvHtml/excel-csv-html-table-converter.css +24 -24
  31. package/src/tool/conversorExcelCsvHtml/i18n/es.ts +1 -1
  32. package/src/tool/conversorExcelCsvHtml/i18n/pl.ts +1 -1
  33. package/src/tool/conversorExcelCsvHtml/i18n/ru.ts +2 -2
  34. package/src/tool/conversorExcelCsvHtml/i18n/zh.ts +2 -2
  35. package/src/tool/conversorExcelCsvHtml/seo.astro +2 -1
  36. package/src/tool/cronGenerator/cron.css +5 -5
  37. package/src/tool/cronGenerator/i18n/de.ts +4 -4
  38. package/src/tool/cronGenerator/i18n/en.ts +1 -1
  39. package/src/tool/cronGenerator/i18n/es.ts +2 -2
  40. package/src/tool/cronGenerator/i18n/fr.ts +5 -5
  41. package/src/tool/cronGenerator/i18n/id.ts +1 -1
  42. package/src/tool/cronGenerator/i18n/nl.ts +1 -1
  43. package/src/tool/cronGenerator/i18n/pl.ts +8 -8
  44. package/src/tool/cronGenerator/i18n/pt.ts +1 -1
  45. package/src/tool/cronGenerator/i18n/ru.ts +9 -9
  46. package/src/tool/cronGenerator/i18n/sv.ts +1 -1
  47. package/src/tool/cronGenerator/i18n/zh.ts +3 -3
  48. package/src/tool/cronGenerator/seo.astro +2 -1
  49. package/src/tool/cssSpecificityCalculator/css-specificity-calculator.css +1 -1
  50. package/src/tool/cssSpecificityCalculator/i18n/de.ts +1 -1
  51. package/src/tool/cssSpecificityCalculator/i18n/fr.ts +3 -3
  52. package/src/tool/cssSpecificityCalculator/i18n/pl.ts +2 -2
  53. package/src/tool/cssSpecificityCalculator/i18n/ru.ts +2 -2
  54. package/src/tool/cssSpecificityCalculator/seo.astro +2 -1
  55. package/src/tool/cssToInlineConverter/css-to-inline-converter.css +1 -1
  56. package/src/tool/cssToInlineConverter/i18n/de.ts +6 -6
  57. package/src/tool/cssToInlineConverter/i18n/es.ts +1 -1
  58. package/src/tool/cssToInlineConverter/i18n/fr.ts +3 -3
  59. package/src/tool/cssToInlineConverter/seo.astro +2 -1
  60. package/src/tool/duplicateCssRemover/duplicate-css-remover.css +2 -2
  61. package/src/tool/duplicateCssRemover/i18n/de.ts +7 -7
  62. package/src/tool/duplicateCssRemover/i18n/fr.ts +1 -1
  63. package/src/tool/duplicateCssRemover/i18n/id.ts +1 -1
  64. package/src/tool/duplicateCssRemover/i18n/nl.ts +1 -1
  65. package/src/tool/duplicateCssRemover/i18n/pl.ts +1 -1
  66. package/src/tool/duplicateCssRemover/i18n/pt.ts +1 -1
  67. package/src/tool/duplicateCssRemover/i18n/ru.ts +3 -3
  68. package/src/tool/duplicateCssRemover/i18n/sv.ts +1 -1
  69. package/src/tool/duplicateCssRemover/seo.astro +2 -1
  70. package/src/tool/generadorSecurityTxt/i18n/de.ts +5 -5
  71. package/src/tool/generadorSecurityTxt/i18n/ru.ts +2 -2
  72. package/src/tool/generadorSecurityTxt/security-txt-generator-rfc-9116.css +9 -9
  73. package/src/tool/generadorSecurityTxt/seo.astro +2 -1
  74. package/src/tool/hashGenerator/hash-generator.css +10 -10
  75. package/src/tool/hashGenerator/i18n/ru.ts +5 -5
  76. package/src/tool/hashGenerator/i18n/zh.ts +2 -2
  77. package/src/tool/hashGenerator/seo.astro +2 -1
  78. package/src/tool/inspectorCertificadosSsl/i18n/de.ts +6 -6
  79. package/src/tool/inspectorCertificadosSsl/i18n/ru.ts +5 -5
  80. package/src/tool/inspectorCertificadosSsl/seo.astro +2 -1
  81. package/src/tool/inspectorCertificadosSsl/ssl-tls-certificate-inspector.css +9 -9
  82. package/src/tool/jsonFormatter/i18n/de.ts +4 -4
  83. package/src/tool/jsonFormatter/i18n/en.ts +4 -4
  84. package/src/tool/jsonFormatter/i18n/es.ts +4 -4
  85. package/src/tool/jsonFormatter/i18n/fr.ts +4 -4
  86. package/src/tool/jsonFormatter/i18n/id.ts +4 -4
  87. package/src/tool/jsonFormatter/i18n/it.ts +4 -4
  88. package/src/tool/jsonFormatter/i18n/ja.ts +4 -4
  89. package/src/tool/jsonFormatter/i18n/ko.ts +4 -4
  90. package/src/tool/jsonFormatter/i18n/nl.ts +4 -4
  91. package/src/tool/jsonFormatter/i18n/pl.ts +4 -4
  92. package/src/tool/jsonFormatter/i18n/pt.ts +4 -4
  93. package/src/tool/jsonFormatter/i18n/ru.ts +5 -5
  94. package/src/tool/jsonFormatter/i18n/sv.ts +4 -4
  95. package/src/tool/jsonFormatter/i18n/tr.ts +4 -4
  96. package/src/tool/jsonFormatter/i18n/zh.ts +5 -5
  97. package/src/tool/jsonFormatter/json-formatter.css +33 -33
  98. package/src/tool/jsonFormatter/seo.astro +2 -1
  99. package/src/tool/keycode/i18n/de.ts +7 -7
  100. package/src/tool/keycode/i18n/en.ts +5 -5
  101. package/src/tool/keycode/i18n/es.ts +5 -5
  102. package/src/tool/keycode/i18n/fr.ts +7 -7
  103. package/src/tool/keycode/i18n/id.ts +5 -5
  104. package/src/tool/keycode/i18n/it.ts +5 -5
  105. package/src/tool/keycode/i18n/ja.ts +5 -5
  106. package/src/tool/keycode/i18n/ko.ts +5 -5
  107. package/src/tool/keycode/i18n/nl.ts +5 -5
  108. package/src/tool/keycode/i18n/pl.ts +7 -7
  109. package/src/tool/keycode/i18n/pt.ts +5 -5
  110. package/src/tool/keycode/i18n/ru.ts +6 -6
  111. package/src/tool/keycode/i18n/sv.ts +5 -5
  112. package/src/tool/keycode/i18n/tr.ts +5 -5
  113. package/src/tool/keycode/i18n/zh.ts +5 -5
  114. package/src/tool/keycode/keycode.css +1 -1
  115. package/src/tool/keycode/seo.astro +2 -1
  116. package/src/tool/llmCostCalculator/i18n/de.ts +4 -4
  117. package/src/tool/llmCostCalculator/i18n/en.ts +3 -3
  118. package/src/tool/llmCostCalculator/i18n/fr.ts +3 -3
  119. package/src/tool/llmCostCalculator/i18n/id.ts +3 -3
  120. package/src/tool/llmCostCalculator/i18n/pt.ts +3 -3
  121. package/src/tool/llmCostCalculator/i18n/ru.ts +3 -3
  122. package/src/tool/llmCostCalculator/i18n/sv.ts +3 -3
  123. package/src/tool/llmCostCalculator/i18n/tr.ts +3 -3
  124. package/src/tool/llmCostCalculator/i18n/zh.ts +3 -3
  125. package/src/tool/llmCostCalculator/llm-cost-calculator.css +1 -1
  126. package/src/tool/llmCostCalculator/seo.astro +2 -1
  127. package/src/tool/mobileMockupGenerator/i18n/es.ts +1 -1
  128. package/src/tool/mobileMockupGenerator/mobile-mockup-generator.css +68 -68
  129. package/src/tool/mobileMockupGenerator/seo.astro +2 -1
  130. package/src/tool/musicalTypography/i18n/de.ts +1 -1
  131. package/src/tool/musicalTypography/i18n/fr.ts +1 -1
  132. package/src/tool/musicalTypography/i18n/id.ts +1 -1
  133. package/src/tool/musicalTypography/i18n/it.ts +1 -1
  134. package/src/tool/musicalTypography/i18n/ko.ts +1 -1
  135. package/src/tool/musicalTypography/i18n/ru.ts +3 -3
  136. package/src/tool/musicalTypography/musical-typography.css +8 -8
  137. package/src/tool/musicalTypography/seo.astro +2 -1
  138. package/src/tool/placeholderGenerator/i18n/de.ts +4 -4
  139. package/src/tool/placeholderGenerator/i18n/ru.ts +1 -1
  140. package/src/tool/placeholderGenerator/placeholder-image-generator.css +2 -2
  141. package/src/tool/placeholderGenerator/seo.astro +2 -1
  142. package/src/tool/promptLibrary/i18n/de.ts +1 -1
  143. package/src/tool/promptLibrary/prompt-library.css +30 -30
  144. package/src/tool/promptLibrary/seo.astro +2 -1
  145. package/src/tool/readabilityCalculator/i18n/de.ts +2 -2
  146. package/src/tool/readabilityCalculator/seo.astro +2 -1
  147. package/src/tool/readabilityCalculator/visual-readability-calculator-wcag-apca.css +98 -14
  148. package/src/tool/svgSanitizer/i18n/de.ts +2 -2
  149. package/src/tool/svgSanitizer/i18n/id.ts +1 -1
  150. package/src/tool/svgSanitizer/i18n/pl.ts +1 -1
  151. package/src/tool/svgSanitizer/i18n/ru.ts +7 -7
  152. package/src/tool/svgSanitizer/i18n/sv.ts +3 -3
  153. package/src/tool/svgSanitizer/i18n/tr.ts +3 -3
  154. package/src/tool/svgSanitizer/i18n/zh.ts +3 -3
  155. package/src/tool/svgSanitizer/seo.astro +2 -1
  156. package/src/tool/svgSanitizer/svg-sanitizer.css +7 -7
  157. package/src/tool/svgToCss/i18n/de.ts +2 -2
  158. package/src/tool/svgToCss/i18n/es.ts +1 -1
  159. package/src/tool/svgToCss/i18n/fr.ts +1 -1
  160. package/src/tool/svgToCss/i18n/pl.ts +1 -1
  161. package/src/tool/svgToCss/i18n/ru.ts +2 -2
  162. package/src/tool/svgToCss/i18n/zh.ts +2 -2
  163. package/src/tool/svgToCss/seo.astro +2 -1
  164. package/src/tool/svgToCss/svg-to-css-converter.css +2 -2
  165. package/src/tool/urlCleaner/component.astro +23 -5
  166. package/src/tool/urlCleaner/i18n/de.ts +3 -3
  167. package/src/tool/urlCleaner/i18n/es.ts +1 -1
  168. package/src/tool/urlCleaner/i18n/id.ts +1 -1
  169. package/src/tool/urlCleaner/i18n/nl.ts +1 -1
  170. package/src/tool/urlCleaner/seo.astro +2 -1
  171. package/src/tool/urlCleaner/url-tracking-cleaner.css +104 -14
  172. package/src/tool/urlEncoderDecoder/i18n/de.ts +5 -5
  173. package/src/tool/urlEncoderDecoder/i18n/fr.ts +2 -2
  174. package/src/tool/urlEncoderDecoder/i18n/pl.ts +5 -5
  175. package/src/tool/urlEncoderDecoder/i18n/ru.ts +8 -8
  176. package/src/tool/urlEncoderDecoder/i18n/sv.ts +5 -5
  177. package/src/tool/urlEncoderDecoder/i18n/zh.ts +5 -5
  178. package/src/tool/urlEncoderDecoder/seo.astro +2 -1
  179. package/src/tool/urlEncoderDecoder/url-encoder-decoder.css +1 -1
  180. package/src/tool/utmGenerator/i18n/de.ts +2 -2
  181. package/src/tool/utmGenerator/i18n/pl.ts +5 -5
  182. package/src/tool/utmGenerator/i18n/ru.ts +6 -6
  183. package/src/tool/utmGenerator/seo.astro +2 -1
  184. package/src/tool/utmGenerator/utm-generator.css +6 -6
@@ -16,7 +16,7 @@ const faqData = [
16
16
  {
17
17
  question: 'Kann ich im Generator jede beliebige Auflösung verwenden?',
18
18
  answer:
19
- 'Ja, Sie können beliebige numerische Werte für Breite und Höhe eingeben. Der Generator erstellt eine Arbeitsfläche mit exakt den angeforderten Abmessungen ideal für präzise Raster oder spezifische Werbeformate.',
19
+ 'Ja, Sie können beliebige numerische Werte für Breite und Höhe eingeben. Der Generator erstellt eine Arbeitsfläche mit exakt den angeforderten Abmessungen - ideal für präzise Raster oder spezifische Werbeformate.',
20
20
  },
21
21
  {
22
22
  question: 'In welchem Format werden die Bilder heruntergeladen?',
@@ -45,7 +45,7 @@ const howToData = [
45
45
  },
46
46
  {
47
47
  name: 'Bild herunterladen',
48
- text: 'Klicken Sie auf die Schaltfläche Herunterladen", um das erstellte Platzhalterbild direkt auf Ihrem Gerät zu speichern.',
48
+ text: 'Klicken Sie auf die Schaltfläche "Herunterladen", um das erstellte Platzhalterbild direkt auf Ihrem Gerät zu speichern.',
49
49
  },
50
50
  ];
51
51
 
@@ -159,7 +159,7 @@ export const content: ToolLocaleContent<PlaceholderGeneratorUI> = {
159
159
  type: 'list',
160
160
  items: [
161
161
  '<strong>Pixel-genaue Auflösung:</strong> Der native HTML5 Canvas stellt sicher, dass die exportierte Arbeitsfläche arithmetisch exakt den vom Nutzer angegebenen Koordinaten entspricht.',
162
- '<strong>Typografisches Autoscaling:</strong> Im automatischen Modus berechnet die Schriftgröße die Umfangsfläche und Zeichenanzahl, um den Text elegant einzupassen ohne unerwünschte <em>Overflows</em>.',
162
+ '<strong>Typografisches Autoscaling:</strong> Im automatischen Modus berechnet die Schriftgröße die Umfangsfläche und Zeichenanzahl, um den Text elegant einzupassen - ohne unerwünschte <em>Overflows</em>.',
163
163
  '<strong>Hexadezimale Synchronisation:</strong> Bidirektionale Zustandskontrolle zwischen nativen HTML-Farbwählern und Texteingaben sorgt für präzise Kontraste, die Ihrer Figma- oder Penpot-Palette entsprechen.',
164
164
  ],
165
165
  },
@@ -170,7 +170,7 @@ export const content: ToolLocaleContent<PlaceholderGeneratorUI> = {
170
170
  },
171
171
  {
172
172
  type: 'paragraph',
173
- html: 'Kein monolithisches Projekt und kein Micro-Frontend kommt ohne Grundlagenarbeit aus erst recht nicht bei anspruchsvollen Kunden oder Product Managern mit klarer Vision. Wer grafische Iterationen zügig durchführen kann, ohne fertige <em>Assets</em> mitschleppen zu müssen, hat einen klaren Vorteil. Dieser Generator greift direkt auf die moderne JS-API <code>toDataURL()</code> auf Ihrer lokalen Maschine zurück und liefert ein professionelles Ergebnis ohne fragwürdige Zwischenverarbeitung.',
173
+ html: 'Kein monolithisches Projekt und kein Micro-Frontend kommt ohne Grundlagenarbeit aus - erst recht nicht bei anspruchsvollen Kunden oder Product Managern mit klarer Vision. Wer grafische Iterationen zügig durchführen kann, ohne fertige <em>Assets</em> mitschleppen zu müssen, hat einen klaren Vorteil. Dieser Generator greift direkt auf die moderne JS-API <code>toDataURL()</code> auf Ihrer lokalen Maschine zurück und liefert ein professionelles Ergebnis ohne fragwürdige Zwischenverarbeitung.',
174
174
  },
175
175
  ],
176
176
  };
@@ -11,7 +11,7 @@ const faqData = [
11
11
  {
12
12
  question: 'Что такое плейсхолдер-изображение?',
13
13
  answer:
14
- 'Плейсхолдер или заполняющее изображение это временный графический элемент, используемый в веб-дизайне и макете для зарезервирования пространства, где будет размещено окончательное изображение. Они помогают визуализировать структуру страницы до появления финального контента.',
14
+ 'Плейсхолдер или заполняющее изображение - это временный графический элемент, используемый в веб-дизайне и макете для зарезервирования пространства, где будет размещено окончательное изображение. Они помогают визуализировать структуру страницы до появления финального контента.',
15
15
  },
16
16
  {
17
17
  question: 'Могу ли я использовать любое разрешение в генераторе?',
@@ -16,7 +16,7 @@
16
16
  color: var(--pg-text);
17
17
  }
18
18
 
19
- :global(.theme-dark) .pg-root {
19
+ .theme-dark .pg-root {
20
20
  --pg-card-bg: #1e293b;
21
21
  --pg-bg: #0f172a;
22
22
  --pg-text: #f1f5f9;
@@ -123,7 +123,7 @@
123
123
  }
124
124
 
125
125
  .pg-preset-pill:hover,
126
- :global(.pg-preset-pill.active) {
126
+ .pg-preset-pill.active {
127
127
  background: var(--pg-primary);
128
128
  border-color: var(--pg-primary-dark);
129
129
  color: #fff;
@@ -9,6 +9,7 @@ interface Props {
9
9
 
10
10
  const { locale = 'es' } = Astro.props;
11
11
  const content = await placeholderGenerator.i18n[locale]?.();
12
+ if (!content) return null;
12
13
  ---
13
14
 
14
- {content && <SEORenderer content={{ locale, sections: content.seo }} />}
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -112,7 +112,7 @@ export const content: ToolLocaleContent<PromptLibraryUI> = {
112
112
  type: 'list',
113
113
  items: [
114
114
  '<strong>Sofortsuche:</strong> Finde jene spezifische Anweisung, die du vor Monaten verwendet hast, mit einer einfachen Textsuche.',
115
- '<strong>Tag-Klassifizierung:</strong> Verschlagworte deine Prompts mit Marketing", Programmierung" oder Copywriting", um schnell zu filtern.',
115
+ '<strong>Tag-Klassifizierung:</strong> Verschlagworte deine Prompts mit "Marketing", "Programmierung" oder "Copywriting", um schnell zu filtern.',
116
116
  '<strong>Ein-Klick-Kopieren:</strong> Den vollständigen Text mit einem einzigen Klick in die Zwischenablage kopieren.',
117
117
  '<strong>Vollständige Privatsphäre:</strong> Alle deine Daten werden lokal im Browser über localStorage gespeichert.',
118
118
  ],
@@ -20,7 +20,7 @@
20
20
  box-shadow: 0 4px 20px -5px rgba(0, 0, 0, 0.05);
21
21
  }
22
22
 
23
- :global(.theme-dark) .pl-topbar {
23
+ .theme-dark .pl-topbar {
24
24
  background: rgba(15, 23, 42, 0.4);
25
25
  border-color: rgba(255, 255, 255, 0.08);
26
26
  }
@@ -61,13 +61,13 @@
61
61
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.15);
62
62
  }
63
63
 
64
- :global(.theme-dark) .pl-search-input {
64
+ .theme-dark .pl-search-input {
65
65
  background: rgba(15, 23, 42, 0.6);
66
66
  border-color: rgba(255, 255, 255, 0.1);
67
67
  color: rgb(248, 250, 252);
68
68
  }
69
69
 
70
- :global(.theme-dark) .pl-search-input:focus {
70
+ .theme-dark .pl-search-input:focus {
71
71
  background: rgba(30, 41, 59, 0.8);
72
72
  }
73
73
 
@@ -121,11 +121,11 @@
121
121
  color: rgb(30, 41, 59);
122
122
  }
123
123
 
124
- :global(.theme-dark) .pl-btn-ghost {
124
+ .theme-dark .pl-btn-ghost {
125
125
  color: rgb(148, 163, 184);
126
126
  }
127
127
 
128
- :global(.theme-dark) .pl-btn-ghost:hover {
128
+ .theme-dark .pl-btn-ghost:hover {
129
129
  background: rgba(255, 255, 255, 0.05);
130
130
  color: rgb(248, 250, 252);
131
131
  }
@@ -164,11 +164,11 @@
164
164
  background: rgba(239, 68, 68, 0.1);
165
165
  }
166
166
 
167
- :global(.theme-dark) .pl-btn-icon {
167
+ .theme-dark .pl-btn-icon {
168
168
  color: rgb(148, 163, 184);
169
169
  }
170
170
 
171
- :global(.theme-dark) .pl-btn-icon:hover {
171
+ .theme-dark .pl-btn-icon:hover {
172
172
  background: rgba(255, 255, 255, 0.1);
173
173
  color: rgb(248, 250, 252);
174
174
  }
@@ -186,7 +186,7 @@
186
186
  margin-top: 2rem;
187
187
  }
188
188
 
189
- :global(.theme-dark) .pl-empty-state {
189
+ .theme-dark .pl-empty-state {
190
190
  border-color: rgba(255, 255, 255, 0.1);
191
191
  }
192
192
 
@@ -211,11 +211,11 @@
211
211
  line-height: 1.6;
212
212
  }
213
213
 
214
- :global(.theme-dark) .pl-empty-title {
214
+ .theme-dark .pl-empty-title {
215
215
  color: rgb(248, 250, 252);
216
216
  }
217
217
 
218
- :global(.theme-dark) .pl-empty-desc {
218
+ .theme-dark .pl-empty-desc {
219
219
  color: rgb(148, 163, 184);
220
220
  }
221
221
 
@@ -272,7 +272,7 @@
272
272
  opacity: 1;
273
273
  }
274
274
 
275
- :global(.theme-dark) .pl-card {
275
+ .theme-dark .pl-card {
276
276
  background: rgba(30, 41, 59, 0.5);
277
277
  border-color: rgba(255, 255, 255, 0.08);
278
278
  }
@@ -291,7 +291,7 @@
291
291
  line-height: 1.3;
292
292
  }
293
293
 
294
- :global(.theme-dark) .pl-card-title {
294
+ .theme-dark .pl-card-title {
295
295
  color: rgb(248, 250, 252);
296
296
  }
297
297
 
@@ -309,7 +309,7 @@
309
309
  border: 1px solid rgba(0, 0, 0, 0.03);
310
310
  }
311
311
 
312
- :global(.theme-dark) .pl-card-body {
312
+ .theme-dark .pl-card-body {
313
313
  background: rgba(15, 23, 42, 0.4);
314
314
  border-color: rgba(255, 255, 255, 0.05);
315
315
  }
@@ -327,7 +327,7 @@
327
327
  -webkit-box-orient: vertical;
328
328
  }
329
329
 
330
- :global(.theme-dark) .pl-card-text {
330
+ .theme-dark .pl-card-text {
331
331
  color: rgb(203, 213, 225);
332
332
  }
333
333
 
@@ -348,7 +348,7 @@
348
348
  text-transform: uppercase;
349
349
  }
350
350
 
351
- :global(.theme-dark) .pl-card-tag {
351
+ .theme-dark .pl-card-tag {
352
352
  background: rgba(139, 92, 246, 0.15);
353
353
  color: rgb(167, 139, 250);
354
354
  }
@@ -380,12 +380,12 @@
380
380
  color: rgb(5, 150, 105);
381
381
  }
382
382
 
383
- :global(.theme-dark) .pl-var-highlight {
383
+ .theme-dark .pl-var-highlight {
384
384
  background: rgba(139, 92, 246, 0.3);
385
385
  color: rgb(167, 139, 250);
386
386
  }
387
387
 
388
- :global(.theme-dark) .pl-var-highlight.pl-var-filled {
388
+ .theme-dark .pl-var-highlight.pl-var-filled {
389
389
  background: rgba(16, 185, 129, 0.3);
390
390
  color: rgb(52, 211, 153);
391
391
  }
@@ -421,7 +421,7 @@
421
421
  box-sizing: border-box;
422
422
  }
423
423
 
424
- :global(.theme-dark) .pl-var-input {
424
+ .theme-dark .pl-var-input {
425
425
  background: rgba(15, 23, 42, 0.5);
426
426
  border-color: rgba(255, 255, 255, 0.1);
427
427
  color: rgb(248, 250, 252);
@@ -460,7 +460,7 @@
460
460
  border: 1px solid rgba(0, 0, 0, 0.1);
461
461
  }
462
462
 
463
- :global(.theme-dark) .pl-modal-container {
463
+ .theme-dark .pl-modal-container {
464
464
  background: rgb(30, 41, 59);
465
465
  border-color: rgba(255, 255, 255, 0.1);
466
466
  }
@@ -505,7 +505,7 @@
505
505
  color: rgb(51, 65, 85);
506
506
  }
507
507
 
508
- :global(.theme-dark) .pl-label {
508
+ .theme-dark .pl-label {
509
509
  color: rgb(226, 232, 240);
510
510
  }
511
511
 
@@ -536,13 +536,13 @@
536
536
  line-height: 1.6;
537
537
  }
538
538
 
539
- :global(.theme-dark) .pl-input {
539
+ .theme-dark .pl-input {
540
540
  background: rgba(15, 23, 42, 0.6);
541
541
  border-color: rgba(255, 255, 255, 0.1);
542
542
  color: rgb(248, 250, 252);
543
543
  }
544
544
 
545
- :global(.theme-dark) .pl-textarea {
545
+ .theme-dark .pl-textarea {
546
546
  background: rgba(15, 23, 42, 0.6);
547
547
  border-color: rgba(255, 255, 255, 0.1);
548
548
  color: rgb(248, 250, 252);
@@ -562,11 +562,11 @@
562
562
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.15);
563
563
  }
564
564
 
565
- :global(.theme-dark) .pl-input:focus {
565
+ .theme-dark .pl-input:focus {
566
566
  background: rgba(15, 23, 42, 0.9);
567
567
  }
568
568
 
569
- :global(.theme-dark) .pl-textarea:focus {
569
+ .theme-dark .pl-textarea:focus {
570
570
  background: rgba(15, 23, 42, 0.9);
571
571
  }
572
572
 
@@ -576,7 +576,7 @@
576
576
  margin-top: 0.25rem;
577
577
  }
578
578
 
579
- :global(.theme-dark) .pl-hint {
579
+ .theme-dark .pl-hint {
580
580
  color: rgb(148, 163, 184);
581
581
  }
582
582
 
@@ -594,7 +594,7 @@
594
594
  cursor: text;
595
595
  }
596
596
 
597
- :global(.theme-dark) .pl-tags-input-wrapper {
597
+ .theme-dark .pl-tags-input-wrapper {
598
598
  background: rgba(15, 23, 42, 0.6);
599
599
  border-color: rgba(255, 255, 255, 0.1);
600
600
  }
@@ -605,7 +605,7 @@
605
605
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.15);
606
606
  }
607
607
 
608
- :global(.theme-dark) .pl-tags-input-wrapper:focus-within {
608
+ .theme-dark .pl-tags-input-wrapper:focus-within {
609
609
  background: rgba(15, 23, 42, 0.9);
610
610
  }
611
611
 
@@ -626,7 +626,7 @@
626
626
  outline: none;
627
627
  }
628
628
 
629
- :global(.theme-dark) .pl-tags-input-field {
629
+ .theme-dark .pl-tags-input-field {
630
630
  color: rgb(248, 250, 252);
631
631
  }
632
632
 
@@ -639,7 +639,7 @@
639
639
  border-top: 1px solid rgba(0, 0, 0, 0.05);
640
640
  }
641
641
 
642
- :global(.theme-dark) .pl-modal-footer {
642
+ .theme-dark .pl-modal-footer {
643
643
  border-top-color: rgba(255, 255, 255, 0.05);
644
644
  }
645
645
 
@@ -663,7 +663,7 @@
663
663
  margin-bottom: 0.5rem;
664
664
  }
665
665
 
666
- :global(.theme-dark) .pl-confirm-title {
666
+ .theme-dark .pl-confirm-title {
667
667
  color: rgb(248, 250, 252);
668
668
  }
669
669
 
@@ -9,6 +9,7 @@ interface Props {
9
9
 
10
10
  const { locale = 'es' } = Astro.props;
11
11
  const content = await promptLibrary.i18n[locale]?.();
12
+ if (!content) return null;
12
13
  ---
13
14
 
14
- {content && <SEORenderer content={{ locale, sections: content.seo }} />}
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -9,7 +9,7 @@ const description = 'Prüfen Sie den echten Kontrast Ihrer Designs mit APCA (WCA
9
9
  const faqData = [
10
10
  {
11
11
  question: 'Was ist APCA und warum unterscheidet es sich von WCAG 2.1?',
12
- answer: 'APCA ist der Advanced Perceptual Contrast Algorithm, der für WCAG 3.0 entwickelt wurde. Anders als das alte einfache Verhältnis verwendet APCA mathematische Modelle, die nachbilden, wie das menschliche Gehirn Kontrast wahrnimmt unter Berücksichtigung der Polarität (heller vs. dunkler Hintergrund) und der Schriftgröße bzw. des Schriftgewichts.',
12
+ answer: 'APCA ist der Advanced Perceptual Contrast Algorithm, der für WCAG 3.0 entwickelt wurde. Anders als das alte einfache Verhältnis verwendet APCA mathematische Modelle, die nachbilden, wie das menschliche Gehirn Kontrast wahrnimmt - unter Berücksichtigung der Polarität (heller vs. dunkler Hintergrund) und der Schriftgröße bzw. des Schriftgewichts.',
13
13
  },
14
14
  {
15
15
  question: 'Was bedeutet der Lc-Wert?',
@@ -108,7 +108,7 @@ export const content: ToolLocaleContent<ReadabilityCalculatorUI> = {
108
108
  { type: 'title', text: 'Visueller Lesbarkeitsrechner (WCAG vs APCA)', level: 2 },
109
109
  {
110
110
  type: 'paragraph',
111
- html: 'Verstehen Sie, wie Farben und Typografie die tatsächliche Lesbarkeit beeinflussen mit dem neuen wahrnehmungsbasierten Barrierefreiheitsstandard. WCAG 2.1 nutzt eine einfache Formel aus dem Jahr 2008. <strong>APCA</strong> ist das neue Modell für <strong>WCAG 3.0</strong>, das menschliche Wahrnehmung nachbildet.',
111
+ html: 'Verstehen Sie, wie Farben und Typografie die tatsächliche Lesbarkeit beeinflussen - mit dem neuen wahrnehmungsbasierten Barrierefreiheitsstandard. WCAG 2.1 nutzt eine einfache Formel aus dem Jahr 2008. <strong>APCA</strong> ist das neue Modell für <strong>WCAG 3.0</strong>, das menschliche Wahrnehmung nachbildet.',
112
112
  },
113
113
  { type: 'title', text: 'Kernpunkte von APCA', level: 3 },
114
114
  {
@@ -9,6 +9,7 @@ interface Props {
9
9
 
10
10
  const { locale = 'es' } = Astro.props;
11
11
  const content = await readabilityCalculator.i18n[locale]?.();
12
+ if (!content) return null;
12
13
  ---
13
14
 
14
- {content && <SEORenderer content={{ locale, sections: content.seo }} />}
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -1,14 +1,17 @@
1
1
  .rc-root {
2
2
  width: 100%;
3
+ min-width: 0;
3
4
  }
4
5
 
5
6
  .rc-container {
7
+ container-type: inline-size;
6
8
  display: grid;
7
9
  grid-template-columns: 1fr;
8
10
  gap: 2rem;
9
11
  max-width: 1200px;
10
12
  margin: 0 auto;
11
13
  padding: 1.5rem;
14
+ min-width: 0;
12
15
  }
13
16
 
14
17
  @media (min-width: 1024px) {
@@ -28,9 +31,10 @@
28
31
  flex-direction: column;
29
32
  gap: 2rem;
30
33
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 10px 15px -3px rgba(0, 0, 0, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.5);
34
+ min-width: 0;
31
35
  }
32
36
 
33
- :global(.theme-dark) .rc-card {
37
+ .theme-dark .rc-card {
34
38
  background: rgba(15, 23, 42, 0.6);
35
39
  border: 1px solid rgba(255, 255, 255, 0.08);
36
40
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2);
@@ -55,13 +59,13 @@
55
59
  margin-bottom: 0.75rem;
56
60
  }
57
61
 
58
- :global(.theme-dark) .rc-group-title {
62
+ .theme-dark .rc-group-title {
59
63
  color: rgb(148, 163, 184);
60
64
  }
61
65
 
62
66
  .rc-inputs-grid {
63
67
  display: grid;
64
- grid-template-columns: repeat(2, 1fr);
68
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
65
69
  gap: 1.5rem;
66
70
  }
67
71
 
@@ -77,7 +81,7 @@
77
81
  color: rgb(30, 41, 59);
78
82
  }
79
83
 
80
- :global(.theme-dark) .rc-label-mini {
84
+ .theme-dark .rc-label-mini {
81
85
  color: rgb(241, 245, 249);
82
86
  }
83
87
 
@@ -90,9 +94,10 @@
90
94
  padding: 0.5rem;
91
95
  border-radius: 0.75rem;
92
96
  transition: all 0.2s ease;
97
+ min-width: 0;
93
98
  }
94
99
 
95
- :global(.theme-dark) .rc-color-input-container {
100
+ .theme-dark .rc-color-input-container {
96
101
  background: rgba(30, 41, 59, 0.5);
97
102
  border-color: rgb(51, 65, 85);
98
103
  }
@@ -118,7 +123,7 @@
118
123
  border-radius: 0.4rem;
119
124
  }
120
125
 
121
- :global(.theme-dark) .rc-color-picker::-webkit-color-swatch {
126
+ .theme-dark .rc-color-picker::-webkit-color-swatch {
122
127
  border: 1px solid rgba(255, 255, 255, 0.2);
123
128
  }
124
129
 
@@ -127,9 +132,11 @@
127
132
  font-weight: 600;
128
133
  color: rgb(71, 85, 105);
129
134
  flex: 1;
135
+ min-width: 0;
136
+ overflow-wrap: anywhere;
130
137
  }
131
138
 
132
- :global(.theme-dark) .rc-hex-text {
139
+ .theme-dark .rc-hex-text {
133
140
  color: rgb(148, 163, 184);
134
141
  }
135
142
 
@@ -170,7 +177,7 @@
170
177
  outline: none;
171
178
  }
172
179
 
173
- :global(.theme-dark) .rc-range {
180
+ .theme-dark .rc-range {
174
181
  background: rgb(51, 65, 85);
175
182
  }
176
183
 
@@ -193,7 +200,7 @@
193
200
 
194
201
  .rc-comparison-grid {
195
202
  display: grid;
196
- grid-template-columns: repeat(2, 1fr);
203
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
197
204
  gap: 1rem;
198
205
  }
199
206
 
@@ -206,9 +213,10 @@
206
213
  gap: 0.5rem;
207
214
  background: rgba(255, 255, 255, 0.4);
208
215
  border: 1px solid rgba(0, 0, 0, 0.05);
216
+ min-width: 0;
209
217
  }
210
218
 
211
- :global(.theme-dark) .rc-score-card {
219
+ .theme-dark .rc-score-card {
212
220
  background: rgba(255, 255, 255, 0.03);
213
221
  border-color: rgba(255, 255, 255, 0.05);
214
222
  }
@@ -232,6 +240,8 @@
232
240
  padding: 0.2rem 0.6rem;
233
241
  border-radius: 0.5rem;
234
242
  text-transform: uppercase;
243
+ text-align: center;
244
+ overflow-wrap: anywhere;
235
245
  }
236
246
 
237
247
  .rc-status-pass {
@@ -244,12 +254,12 @@
244
254
  color: rgb(153, 27, 27);
245
255
  }
246
256
 
247
- :global(.theme-dark) .rc-status-pass {
257
+ .theme-dark .rc-status-pass {
248
258
  background: rgba(34, 197, 94, 0.15);
249
259
  color: rgb(134, 239, 172);
250
260
  }
251
261
 
252
- :global(.theme-dark) .rc-status-fail {
262
+ .theme-dark .rc-status-fail {
253
263
  background: rgba(239, 68, 68, 0.15);
254
264
  color: rgb(252, 165, 165);
255
265
  }
@@ -274,6 +284,7 @@
274
284
  .rc-preview-text {
275
285
  line-height: 1.5;
276
286
  margin: 0;
287
+ overflow-wrap: anywhere;
277
288
  }
278
289
 
279
290
  .rc-apca-breakdown {
@@ -292,6 +303,7 @@
292
303
  .rc-breakdown-item {
293
304
  display: flex;
294
305
  justify-content: space-between;
306
+ gap: 1rem;
295
307
  font-size: 0.875rem;
296
308
  }
297
309
 
@@ -300,7 +312,7 @@
300
312
  font-weight: 600;
301
313
  }
302
314
 
303
- :global(.theme-dark) .rc-item-label {
315
+ .theme-dark .rc-item-label {
304
316
  color: rgb(148, 163, 184);
305
317
  }
306
318
 
@@ -309,6 +321,8 @@
309
321
  display: flex;
310
322
  align-items: center;
311
323
  gap: 0.4rem;
324
+ text-align: right;
325
+ white-space: nowrap;
312
326
  }
313
327
 
314
328
  .rc-check-yes {
@@ -317,4 +331,74 @@
317
331
 
318
332
  .rc-check-no {
319
333
  color: rgb(239, 68, 68);
320
- }
334
+ }
335
+
336
+ @container (max-width: 520px) {
337
+ .rc-container {
338
+ gap: 1rem;
339
+ padding: 0;
340
+ }
341
+
342
+ .rc-card {
343
+ border-radius: 1rem;
344
+ gap: 1.25rem;
345
+ padding: 1rem;
346
+ }
347
+
348
+ .rc-control-section {
349
+ gap: 1.25rem;
350
+ }
351
+
352
+ .rc-group-title {
353
+ margin-bottom: 0.75rem;
354
+ }
355
+
356
+ .rc-inputs-grid,
357
+ .rc-comparison-grid {
358
+ grid-template-columns: 1fr;
359
+ gap: 1rem;
360
+ }
361
+
362
+ .rc-color-input-container {
363
+ align-items: stretch;
364
+ }
365
+
366
+ .rc-color-picker {
367
+ flex: 0 0 2.5rem;
368
+ }
369
+
370
+ .rc-score-card,
371
+ .rc-apca-breakdown {
372
+ padding: 1rem;
373
+ border-radius: 0.75rem;
374
+ }
375
+
376
+ .rc-main-preview-box {
377
+ min-height: 120px;
378
+ padding: 1.25rem;
379
+ border-radius: 0.875rem;
380
+ }
381
+
382
+ .rc-breakdown-item {
383
+ align-items: flex-start;
384
+ flex-direction: column;
385
+ gap: 0.35rem;
386
+ }
387
+
388
+ .rc-item-check {
389
+ text-align: left;
390
+ }
391
+ }
392
+
393
+ @media (max-width: 640px) {
394
+ .rc-container {
395
+ gap: 1rem;
396
+ padding: 0;
397
+ }
398
+
399
+ .rc-card {
400
+ border-radius: 1rem;
401
+ gap: 1.25rem;
402
+ padding: 1rem;
403
+ }
404
+ }
@@ -31,7 +31,7 @@ const faqData = [
31
31
 
32
32
  const howToData = [
33
33
  { name: 'SVG einfügen', text: 'Füge den SVG-Code aus Figma, Illustrator oder Inkscape in das Textfeld ein.' },
34
- { name: 'Optionen konfigurieren', text: 'Aktiviere oder deaktiviere die Optionen: IDs entfernen, width/height entfernen und minifizieren je nach Bedarf.' },
34
+ { name: 'Optionen konfigurieren', text: 'Aktiviere oder deaktiviere die Optionen: IDs entfernen, width/height entfernen und minifizieren - je nach Bedarf.' },
35
35
  { name: 'Bereinigen', text: 'Klicke auf SVG bereinigen, um den Code zu verarbeiten und das optimierte Ergebnis zu erhalten.' },
36
36
  { name: 'Kopieren oder herunterladen', text: 'Nutze die Schaltflächen Kopieren oder Herunterladen, um das bereinigte SVG für die Produktion zu sichern.' },
37
37
  ];
@@ -108,7 +108,7 @@ export const content: ToolLocaleContent<SvgSanitizerUI> = {
108
108
  { type: 'title', text: 'Warum sind exportierte SVGs so unordentlich?', level: 3 },
109
109
  {
110
110
  type: 'paragraph',
111
- html: 'Wenn du ein SVG aus Figma exportierst, erhältst du eine Datei voller Attribute, die nur innerhalb der App einen Sinn ergeben: <code>data-name</code>, <code>xml:space</code>, Verweise auf interne Ebenen und Design-Metadaten. Das Ergebnis ist ein SVG, das 4070 % größer als nötig sein kann.',
111
+ html: 'Wenn du ein SVG aus Figma exportierst, erhältst du eine Datei voller Attribute, die nur innerhalb der App einen Sinn ergeben: <code>data-name</code>, <code>xml:space</code>, Verweise auf interne Ebenen und Design-Metadaten. Das Ergebnis ist ein SVG, das 40-70 % größer als nötig sein kann.',
112
112
  },
113
113
  { type: 'title', text: 'Was der Bereiniger entfernt', level: 3 },
114
114
  {
@@ -108,7 +108,7 @@ export const content: ToolLocaleContent<SvgSanitizerUI> = {
108
108
  { type: 'title', text: 'Mengapa SVG yang diekspor begitu berantakan?', level: 3 },
109
109
  {
110
110
  type: 'paragraph',
111
- html: 'Saat kamu mengekspor SVG dari Figma, kamu mendapatkan file yang penuh dengan atribut yang hanya bermakna di dalam aplikasinya: <code>data-name</code>, <code>xml:space</code>, referensi ke layer internal, dan metadata desain. Hasilnya adalah SVG yang bisa 4070% lebih besar dari yang seharusnya.',
111
+ html: 'Saat kamu mengekspor SVG dari Figma, kamu mendapatkan file yang penuh dengan atribut yang hanya bermakna di dalam aplikasinya: <code>data-name</code>, <code>xml:space</code>, referensi ke layer internal, dan metadata desain. Hasilnya adalah SVG yang bisa 40-70% lebih besar dari yang seharusnya.',
112
112
  },
113
113
  { type: 'title', text: 'Apa yang dihapus oleh Pembersih', level: 3 },
114
114
  {
@@ -108,7 +108,7 @@ export const content: ToolLocaleContent<SvgSanitizerUI> = {
108
108
  { type: 'title', text: 'Dlaczego wyeksportowane pliki SVG są takie brudne?', level: 3 },
109
109
  {
110
110
  type: 'paragraph',
111
- html: 'Gdy eksportujesz SVG z Figmy, otrzymujesz plik wypełniony atrybutami, które mają sens tylko wewnątrz aplikacji: <code>data-name</code>, <code>xml:space</code>, odwołania do wewnętrznych warstw i metadane projektu. Efektem jest SVG, który może ważyć o 4070% więcej niż powinien.',
111
+ html: 'Gdy eksportujesz SVG z Figmy, otrzymujesz plik wypełniony atrybutami, które mają sens tylko wewnątrz aplikacji: <code>data-name</code>, <code>xml:space</code>, odwołania do wewnętrznych warstw i metadane projektu. Efektem jest SVG, który może ważyć o 40-70% więcej niż powinien.',
112
112
  },
113
113
  { type: 'title', text: 'Co usuwa oczyszczacz', level: 3 },
114
114
  {