@jjlmoya/utils-audiovisual 1.19.0 → 1.21.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 (80) hide show
  1. package/package.json +4 -2
  2. package/src/category/i18n/de.ts +1 -1
  3. package/src/category/i18n/fr.ts +1 -1
  4. package/src/category/i18n/ru.ts +1 -1
  5. package/src/layouts/PreviewLayout.astro +7 -2
  6. package/src/tests/diacritics_density.test.ts +118 -0
  7. package/src/tests/inverted_punctuation.test.ts +84 -0
  8. package/src/tests/no_en_dash.test.ts +70 -0
  9. package/src/tests/pagespeed_best_practices.test.ts +198 -0
  10. package/src/tests/script_density.test.ts +94 -0
  11. package/src/tool/chromaticLens/component.astro +2 -2
  12. package/src/tool/chromaticLens/i18n/de.ts +6 -6
  13. package/src/tool/chromaticLens/i18n/fr.ts +3 -3
  14. package/src/tool/chromaticLens/i18n/pl.ts +1 -1
  15. package/src/tool/chromaticLens/i18n/ru.ts +10 -10
  16. package/src/tool/chromaticLens/i18n/zh.ts +2 -2
  17. package/src/tool/collageMaker/component.astro +3 -3
  18. package/src/tool/collageMaker/i18n/de.ts +6 -6
  19. package/src/tool/collageMaker/i18n/fr.ts +4 -4
  20. package/src/tool/collageMaker/i18n/pl.ts +5 -5
  21. package/src/tool/collageMaker/i18n/ru.ts +12 -12
  22. package/src/tool/collageMaker/i18n/sv.ts +3 -3
  23. package/src/tool/collageMaker/i18n/zh.ts +1 -1
  24. package/src/tool/depthOfFieldCalculator/component.astro +1 -1
  25. package/src/tool/depthOfFieldCalculator/i18n/de.ts +3 -3
  26. package/src/tool/depthOfFieldCalculator/i18n/en.ts +7 -7
  27. package/src/tool/depthOfFieldCalculator/i18n/es.ts +2 -2
  28. package/src/tool/depthOfFieldCalculator/i18n/fr.ts +6 -6
  29. package/src/tool/depthOfFieldCalculator/i18n/id.ts +2 -2
  30. package/src/tool/depthOfFieldCalculator/i18n/it.ts +2 -2
  31. package/src/tool/depthOfFieldCalculator/i18n/ja.ts +1 -1
  32. package/src/tool/depthOfFieldCalculator/i18n/ko.ts +1 -1
  33. package/src/tool/depthOfFieldCalculator/i18n/nl.ts +2 -2
  34. package/src/tool/depthOfFieldCalculator/i18n/pl.ts +2 -2
  35. package/src/tool/depthOfFieldCalculator/i18n/pt.ts +2 -2
  36. package/src/tool/depthOfFieldCalculator/i18n/ru.ts +6 -6
  37. package/src/tool/depthOfFieldCalculator/i18n/sv.ts +2 -2
  38. package/src/tool/depthOfFieldCalculator/i18n/tr.ts +1 -1
  39. package/src/tool/depthOfFieldCalculator/i18n/zh.ts +3 -3
  40. package/src/tool/exifCleaner/component.astro +1 -1
  41. package/src/tool/exifCleaner/i18n/de.ts +8 -8
  42. package/src/tool/exifCleaner/i18n/fr.ts +11 -11
  43. package/src/tool/exifCleaner/i18n/pl.ts +6 -6
  44. package/src/tool/exifCleaner/i18n/ru.ts +14 -14
  45. package/src/tool/exifCleaner/i18n/zh.ts +3 -3
  46. package/src/tool/imageCompressor/component.astro +6 -4
  47. package/src/tool/imageCompressor/i18n/de.ts +16 -16
  48. package/src/tool/imageCompressor/i18n/fr.ts +8 -8
  49. package/src/tool/imageCompressor/i18n/pl.ts +1 -1
  50. package/src/tool/imageCompressor/i18n/ru.ts +9 -9
  51. package/src/tool/imageCompressor/i18n/zh.ts +1 -1
  52. package/src/tool/printQualityCalculator/component.astro +118 -110
  53. package/src/tool/printQualityCalculator/i18n/de.ts +5 -5
  54. package/src/tool/printQualityCalculator/i18n/fr.ts +11 -11
  55. package/src/tool/printQualityCalculator/i18n/pl.ts +4 -4
  56. package/src/tool/printQualityCalculator/i18n/ru.ts +11 -11
  57. package/src/tool/printQualityCalculator/i18n/zh.ts +4 -4
  58. package/src/tool/printQualityCalculator/print-quality-calculator-pixels-to-cm-dpi.css +193 -40
  59. package/src/tool/privacyBlur/component.astro +2 -2
  60. package/src/tool/privacyBlur/i18n/de.ts +5 -5
  61. package/src/tool/privacyBlur/i18n/fr.ts +9 -9
  62. package/src/tool/privacyBlur/i18n/ru.ts +6 -6
  63. package/src/tool/subtitleSync/component.astro +2 -2
  64. package/src/tool/subtitleSync/i18n/de.ts +1 -1
  65. package/src/tool/subtitleSync/i18n/fr.ts +9 -9
  66. package/src/tool/subtitleSync/i18n/ru.ts +6 -6
  67. package/src/tool/subtitleSync/i18n/sv.ts +4 -4
  68. package/src/tool/timelapseCalculator/i18n/fr.ts +6 -6
  69. package/src/tool/timelapseCalculator/i18n/ru.ts +3 -3
  70. package/src/tool/timelapseCalculator/i18n/zh.ts +4 -4
  71. package/src/tool/tvDistance/component.astro +1 -1
  72. package/src/tool/tvDistance/i18n/fr.ts +2 -2
  73. package/src/tool/tvDistance/i18n/ru.ts +9 -9
  74. package/src/tool/tvDistance/i18n/zh.ts +4 -4
  75. package/src/tool/videoFrameExtractor/component.astro +3 -3
  76. package/src/tool/videoFrameExtractor/i18n/fr.ts +8 -8
  77. package/src/tool/videoFrameExtractor/i18n/ru.ts +2 -2
  78. package/src/tool/videoMerger/component.astro +3 -3
  79. package/src/tool/videoMerger/i18n/de.ts +1 -1
  80. package/src/tool/videoMerger/i18n/fr.ts +6 -6
@@ -57,9 +57,9 @@ const seo: ChromaticLensLocaleContent['seo'] = [
57
57
  title: 'Intelligente Extraktion von Farbpaletten',
58
58
  items: [
59
59
  'Professioneller Median-Cut-Algorithmus zur Farbanalyse',
60
- 'Extraktion von 312 dominanten Farben aus jedem Bild',
60
+ 'Extraktion von 3-12 dominanten Farben aus jedem Bild',
61
61
  'HEX-Codes direkt in die Zwischenablage kopierbar',
62
- '100% lokale Verarbeitung ideal für Kreative'
62
+ '100% lokale Verarbeitung - ideal für Kreative'
63
63
  ]
64
64
  },
65
65
  { type: 'title', text: 'Farbetraktion: Wissenschaft und Design', level: 2 },
@@ -138,15 +138,15 @@ const seo: ChromaticLensLocaleContent['seo'] = [
138
138
 
139
139
  { type: 'proscons', items: [
140
140
  {
141
- pro: 'Mathematische Präzision bei der Extraktion keine ungefähre visuelle Auswahl',
141
+ pro: 'Mathematische Präzision bei der Extraktion - keine ungefähre visuelle Auswahl',
142
142
  con: 'Kaum sichtbare Farben können enthalten sein, wenn sie viele Pixel haben'
143
143
  },
144
144
  {
145
- pro: 'Sofortiges Kopieren in die Zwischenablage perfekte Integration in den Workflow',
145
+ pro: 'Sofortiges Kopieren in die Zwischenablage - perfekte Integration in den Workflow',
146
146
  con: 'Benötigt einen modernen Browser, der mit der Canvas-API kompatibel ist'
147
147
  },
148
148
  {
149
- pro: 'Vollständige Privatsphäre 100% lokale Analyse ohne Datenübermittlung',
149
+ pro: 'Vollständige Privatsphäre - 100% lokale Analyse ohne Datenübermittlung',
150
150
  con: 'Kein Verlauf früherer Analysen gespeichert'
151
151
  },
152
152
  {
@@ -164,7 +164,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
164
164
  },
165
165
  {
166
166
  term: 'RGB-Farbraum',
167
- definition: 'Farbmodell basierend auf Rot, Grün und Blau. Jede Farbe wird als Kombination dieser drei Werte (0255) dargestellt. Standard für Bildschirme und Web.'
167
+ definition: 'Farbmodell basierend auf Rot, Grün und Blau. Jede Farbe wird als Kombination dieser drei Werte (0-255) dargestellt. Standard für Bildschirme und Web.'
168
168
  },
169
169
  {
170
170
  term: 'HEX-Code',
@@ -62,7 +62,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
62
62
  'Traitement 100 % local - idéal pour les créatifs'
63
63
  ]
64
64
  },
65
- { type: 'title', text: 'Extraction de Palettes de Couleurs : Science et Design', level: 2 },
65
+ { type: 'title', text: 'Extraction de Palettes de Couleurs: Science et Design', level: 2 },
66
66
  { type: 'paragraph', html: 'Vous êtes-vous déjà demandé pourquoi une photographie de film semble si harmonieuse ? Ce n\'est pas un hasard ; c\'est la théorie des couleurs en action. Lentille Chromatique vous permet d\'extraire cette harmonie directement du pixel, en la transformant en codes HEX utilisables dans vos projets de design.' },
67
67
 
68
68
  { type: 'stats', items: [
@@ -180,10 +180,10 @@ const seo: ChromaticLensLocaleContent['seo'] = [
180
180
  }
181
181
  ] },
182
182
 
183
- { type: 'message', title: 'Analyse Chromatique Professionnelle', ariaLabel: 'Informations techniques sur l\'analyse des couleurs', html: 'Lentille Chromatique transforme l\'analyse visuelle manuelle en précision algorithmique. Elle ne se contente pas d\'extraire des couleurs : elle capture l\'essence émotionnelle et visuelle de toute image, la plaçant directement dans votre presse-papiers sous forme de codes HEX prêts à l\'emploi. Confidentialité totale, analyses illimitées.' },
183
+ { type: 'message', title: 'Analyse Chromatique Professionnelle', ariaLabel: 'Informations techniques sur l\'analyse des couleurs', html: 'Lentille Chromatique transforme l\'analyse visuelle manuelle en précision algorithmique. Elle ne se contente pas d\'extraire des couleurs: elle capture l\'essence émotionnelle et visuelle de toute image, la plaçant directement dans votre presse-papiers sous forme de codes HEX prêts à l\'emploi. Confidentialité totale, analyses illimitées.' },
184
184
 
185
185
  { type: 'title', text: 'Concevez Depuis l\'Inspiration Visuelle', level: 3 },
186
- { type: 'paragraph', html: 'La meilleure palette de couleurs est celle qui capture l\'intention visuelle de votre référence. Lentille Chromatique automatise ce qui était auparavant un processus manuel : observer, analyser, noter. Désormais, faites simplement glisser une image et obtenez des codes HEX professionnels en quelques secondes.' }
186
+ { type: 'paragraph', html: 'La meilleure palette de couleurs est celle qui capture l\'intention visuelle de votre référence. Lentille Chromatique automatise ce qui était auparavant un processus manuel: observer, analyser, noter. Désormais, faites simplement glisser une image et obtenez des codes HEX professionnels en quelques secondes.' }
187
187
  ];
188
188
 
189
189
  const faqSchema: WithContext<FAQPage> = {
@@ -74,7 +74,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
74
74
  { type: 'title', text: 'Wyjaśnienie Algorytmu Median Cut', level: 3 },
75
75
  { type: 'paragraph', html: 'Inteligentna ekstrakcja palety nie jest prostym losowym próbkowaniem pikseli. Wykorzystuje algorytm Median Cut, technikę rekurencyjnego partycjonowania, która zapewnia wierne odwzorowanie:' },
76
76
  { type: 'list', items: [
77
- '<strong>Podział Rekurencyjny:</strong> Kostka kolorów RGB obrazu jest rekurencyjnie dzielona na mniejsze pudełka.',
77
+ '<strong>Podział Rekurencyjny:</strong> \"Kostka kolorów\" RGB obrazu jest rekurencyjnie dzielona na mniejsze pudełka.',
78
78
  '<strong>Równowaga Objętości:</strong> Każda partycja dąży do pogrupowania pikseli z tej samej przestrzeni barw o podobnych objętościach.',
79
79
  '<strong>Średnia Ważona:</strong> Wynikowy kolor każdego pudełka jest średnią wszystkich pikseli, które zawiera.',
80
80
  '<strong>Wierne Odwzorowanie:</strong> Dominujące kolory odzwierciedlają rzeczywistą atmosferę wizualną obrazu, a nie prostą próbkę.'
@@ -20,7 +20,7 @@ const ui: ChromaticLensUI = {
20
20
  const faq: ChromaticLensLocaleContent['faq'] = [
21
21
  {
22
22
  question: "Как работает извлечение цвета?",
23
- answer: "Мы используем алгоритм «Median Cut», который группирует пиксели изображения в соответствии с их близостью в цветовом пространстве RGB для поиска наиболее репрезентативных тонов.",
23
+ answer: "Мы используем алгоритм \"Median Cut\", который группирует пиксели изображения в соответствии с их близостью в цветовом пространстве RGB для поиска наиболее репрезентативных тонов.",
24
24
  },
25
25
  {
26
26
  question: "Могу ли я копировать цвета в свой дизайнерский редактор?",
@@ -57,9 +57,9 @@ const seo: ChromaticLensLocaleContent['seo'] = [
57
57
  title: 'Интеллектуальное извлечение цветовой палитры',
58
58
  items: [
59
59
  'Профессиональный алгоритм Median Cut для анализа цвета',
60
- 'Извлечение 312 доминирующих цветов из любого изображения',
60
+ 'Извлечение 3-12 доминирующих цветов из любого изображения',
61
61
  'HEX-коды копируются непосредственно в буфер обмена',
62
- '100% локальная обработка идеально для креативщиков'
62
+ '100% локальная обработка - идеально для креативщиков'
63
63
  ]
64
64
  },
65
65
  { type: 'title', text: 'Извлечение цветовой палитры: наука и дизайн', level: 2 },
@@ -72,9 +72,9 @@ const seo: ChromaticLensLocaleContent['seo'] = [
72
72
  ], columns: 3 },
73
73
 
74
74
  { type: 'title', text: 'Объяснение алгоритма Median Cut', level: 3 },
75
- { type: 'paragraph', html: 'Интеллектуальное извлечение палитры это не простая случайная выборка пикселей. Оно использует алгоритм Median Cut, метод рекурсивного разделения, который обеспечивает верное представление:' },
75
+ { type: 'paragraph', html: 'Интеллектуальное извлечение палитры - это не простая случайная выборка пикселей. Оно использует алгоритм Median Cut, метод рекурсивного разделения, который обеспечивает верное представление:' },
76
76
  { type: 'list', items: [
77
- '<strong>Рекурсивное деление:</strong> «Цветовой куб» RGB изображения рекурсивно делится на более мелкие блоки.',
77
+ '<strong>Рекурсивное деление:</strong> \"Цветовой куб\" RGB изображения рекурсивно делится на более мелкие блоки.',
78
78
  '<strong>Баланс объема:</strong> Каждый раздел стремится сгруппировать пиксели одного цветового пространства с похожими объемами.',
79
79
  '<strong>Средневзвешенное значение:</strong> Результирующий цвет каждого блока является средним значением всех содержащихся в нем пикселей.',
80
80
  '<strong>Точное представление:</strong> Доминирующие цвета отражают реальную визуальную атмосферу изображения, а не просто случайную пробу.'
@@ -138,15 +138,15 @@ const seo: ChromaticLensLocaleContent['seo'] = [
138
138
 
139
139
  { type: 'proscons', items: [
140
140
  {
141
- pro: 'Математическая точность при извлечении не приблизительный визуальный выбор',
141
+ pro: 'Математическая точность при извлечении - не приблизительный визуальный выбор',
142
142
  con: 'Могут быть включены едва видимые цвета, если в них много пикселей'
143
143
  },
144
144
  {
145
- pro: 'Мгновенное копирование в буфер обмена идеальная интеграция с рабочим процессом',
145
+ pro: 'Мгновенное копирование в буфер обмена - идеальная интеграция с рабочим процессом',
146
146
  con: 'Требуется современный браузер, совместимый с Canvas API'
147
147
  },
148
148
  {
149
- pro: 'Полная конфиденциальность 100% локальный анализ без отправки данных',
149
+ pro: 'Полная конфиденциальность - 100% локальный анализ без отправки данных',
150
150
  con: 'История предыдущих анализов не сохраняется'
151
151
  },
152
152
  {
@@ -164,7 +164,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
164
164
  },
165
165
  {
166
166
  term: 'Цветовое пространство RGB',
167
- definition: 'Цветовая модель, основанная на красном, зеленом и синем цветах. Каждый цвет представлен как комбинация этих трех значений (0255). Стандарт для цифровых экранов и веб-интерфейсов.'
167
+ definition: 'Цветовая модель, основанная на красном, зеленом и синем цветах. Каждый цвет представлен как комбинация этих трех значений (0-255). Стандарт для цифровых экранов и веб-интерфейсов.'
168
168
  },
169
169
  {
170
170
  term: 'HEX-код',
@@ -183,7 +183,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
183
183
  { type: 'message', title: 'Профессиональный хроматический анализ', ariaLabel: 'Техническая информация об анализе цвета', html: 'Chromatic Lens превращает ручной визуальный анализ в алгоритмическую точность. Он не просто извлекает цвета: он улавливает эмоциональную и визуальную суть любого изображения, помещая её прямо в ваш буфер обмена в виде готовых к использованию HEX-кодов. Полная конфиденциальность, без ограничений по объему анализа.' },
184
184
 
185
185
  { type: 'title', text: 'Дизайн на основе визуального вдохновения', level: 3 },
186
- { type: 'paragraph', html: 'Лучшая цветовая палитра та, которая улавливает визуальный замысел вашего референса. Chromatic Lens автоматизирует то, что раньше было ручным процессом: наблюдение, анализ, запись. Теперь просто перетащите изображение и получите профессиональные HEX-коды за считанные секунды.' }
186
+ { type: 'paragraph', html: 'Лучшая цветовая палитра - та, которая улавливает визуальный замысел вашего референса. Chromatic Lens автоматизирует то, что раньше было ручным процессом: наблюдение, анализ, запись. Теперь просто перетащите изображение и получите профессиональные HEX-коды за считанные секунды.' }
187
187
  ];
188
188
 
189
189
  const faqSchema: WithContext<FAQPage> = {
@@ -20,7 +20,7 @@ const ui: ChromaticLensUI = {
20
20
  const faq: ChromaticLensLocaleContent['faq'] = [
21
21
  {
22
22
  question: "色彩提取是如何工作的?",
23
- answer: "我们使用“中位切分”(Median Cut)算法。该算法根据图像像素在 RGB 色彩空间中的接近程度进行分组,从而找到最具代表性的色调。",
23
+ answer: "我们使用\"中位切分\"(Median Cut)算法。该算法根据图像像素在 RGB 色彩空间中的接近程度进行分组,从而找到最具代表性的色调。",
24
24
  },
25
25
  {
26
26
  question: "我可以将颜色复制到我的设计编辑器吗?",
@@ -74,7 +74,7 @@ const seo: ChromaticLensLocaleContent['seo'] = [
74
74
  { type: 'title', text: '中位切分算法详解', level: 3 },
75
75
  { type: 'paragraph', html: '智能调色盘提取并非简单的随机采样。它使用中位切分(Median Cut)算法,这是一种确保忠实呈现的递归切分技术:' },
76
76
  { type: 'list', items: [
77
- '<strong>递归细分:</strong> 图像的 RGB “色彩立方体”被递归地细分为更小的方块。',
77
+ '<strong>递归细分:</strong> 图像的 RGB \"色彩立方体\"被递归地细分为更小的方块。',
78
78
  '<strong>体积平衡:</strong> 每个分区都力求将色彩空间中体积相似的像素归为一类。',
79
79
  '<strong>加权平均:</strong> 每个方块最终产生的颜色是其包含的所有像素的平均值。',
80
80
  '<strong>忠实呈现:</strong> 主导色彩反映了图像真实的视觉氛围,而不仅仅是简单的样本。'
@@ -16,7 +16,7 @@ const dropSub = (ui.dropSub ?? '').replace('{link}', `<span class="cm-drop-link"
16
16
  <div class="cm-left-col">
17
17
 
18
18
  <div id="cm-drop-zone" class="cm-drop-zone">
19
- <input type="file" id="cm-file-input" accept="image/*" multiple />
19
+ <input type="file" id="cm-file-input" accept="image/*" multiple aria-label={ui.dropTitle} />
20
20
  <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
21
21
  <rect x="3" y="3" width="18" height="18" rx="2"/>
22
22
  <circle cx="8.5" cy="8.5" r="1.5"/>
@@ -64,14 +64,14 @@ const dropSub = (ui.dropSub ?? '').replace('{link}', `<span class="cm-drop-link"
64
64
  <input type="range" id="cm-border-width" min="0" max="30" value="0" class="cm-slider" />
65
65
  </div>
66
66
  <div class="cm-setting">
67
- <label class="cm-setting-label">{ui.borderColorLabel}</label>
67
+ <label class="cm-setting-label" for="cm-border-color">{ui.borderColorLabel}</label>
68
68
  <div class="cm-color-row">
69
69
  <input type="color" id="cm-border-color" value="#ffffff" class="cm-color-swatch" />
70
70
  <span id="cm-bc-val" class="cm-color-code">#FFFFFF</span>
71
71
  </div>
72
72
  </div>
73
73
  <div class="cm-setting">
74
- <label class="cm-setting-label">{ui.bgColorLabel}</label>
74
+ <label class="cm-setting-label" for="cm-bg-color">{ui.bgColorLabel}</label>
75
75
  <div class="cm-color-row">
76
76
  <input type="color" id="cm-bg-color" value="#1a1a1a" class="cm-color-swatch" />
77
77
  <span id="cm-bg-val" class="cm-color-code">#1A1A1A</span>
@@ -8,7 +8,7 @@ const description = 'Erstellen Sie in Sekundenschnelle kostenlos Fotocollagen. W
8
8
 
9
9
  const ui: CollageMakerUI = {
10
10
  dropTitle: "Bilder hierher ziehen",
11
- dropSub: "oder {link} min. 2, max. 9",
11
+ dropSub: "oder {link} - min. 2, max. 9",
12
12
  dropLink: "Dateien auswählen",
13
13
  imgsLoaded: "Geladene Bilder",
14
14
  layoutLabel: "Layout",
@@ -80,7 +80,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
80
80
  '<strong>Gleichgewicht:</strong> Visuelle Verteilung des Gewichts (helle vs. dunkle Bilder, große vs. kleine).',
81
81
  '<strong>Visueller Fluss:</strong> Das Auge sollte die Komposition natürlich durchqueren, ohne tote Winkel.',
82
82
  '<strong>Kontrast:</strong> Variationen in Farbe, Größe und Form, die Aufmerksamkeit erregen.',
83
- '<strong>Einheit:</strong> Thematische Kohärenz Bilder müssen gemeinsam dieselbe Geschichte erzählen.'
83
+ '<strong>Einheit:</strong> Thematische Kohärenz - Bilder müssen gemeinsam dieselbe Geschichte erzählen.'
84
84
  ], icon: 'mdi:check' },
85
85
 
86
86
  { type: 'card', title: 'Intelligente und adaptive Designs', html: 'Unser System berechnet automatisch die optimale Platzverteilung basierend auf der Anzahl der Fotos. 2 Bilder = symmetrisches Raster; 5 Bilder = ausgewogene asymmetrische Verteilung. Jedes Raster ist darauf ausgelegt, die visuelle Wirkung zu maximieren.' },
@@ -88,7 +88,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
88
88
  { type: 'comparative', items: [
89
89
  {
90
90
  title: 'Für soziale Netzwerke',
91
- description: 'Instagram, TikTok, Facebook quadratische Formate',
91
+ description: 'Instagram, TikTok, Facebook - quadratische Formate',
92
92
  icon: 'mdi:share-all',
93
93
  points: [
94
94
  '1200px ist perfekt für den Instagram-Feed',
@@ -129,7 +129,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
129
129
 
130
130
  { type: 'proscons', items: [
131
131
  {
132
- pro: 'Professionelle vordefinierte Designs keine Kenntnisse in Komposition erforderlich',
132
+ pro: 'Professionelle vordefinierte Designs - keine Kenntnisse in Komposition erforderlich',
133
133
  con: 'Optionen auf vordefinierte Raster beschränkt'
134
134
  },
135
135
  {
@@ -137,7 +137,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
137
137
  con: 'Nicht so anpassbar wie Photoshop'
138
138
  },
139
139
  {
140
- pro: '100% lokale Verarbeitung Privatsphäre, Schnelligkeit, keine Limits',
140
+ pro: '100% lokale Verarbeitung - Privatsphäre, Schnelligkeit, keine Limits',
141
141
  con: 'Erfordert einen modernen Browser'
142
142
  },
143
143
  {
@@ -171,7 +171,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
171
171
  }
172
172
  ] },
173
173
 
174
- { type: 'message', title: 'Sofortige visuelle Erzählung', ariaLabel: 'Informationen über Komposition und Collagen', html: 'Jede Collage erzählt eine Geschichte. Unser automatischer Designer sorgt dafür, dass Ihre visuellen Geschichten ausgewogen und professionell wirken und bereit für die Welt sind ohne auf einen Grafiker warten zu müssen.' },
174
+ { type: 'message', title: 'Sofortige visuelle Erzählung', ariaLabel: 'Informationen über Komposition und Collagen', html: 'Jede Collage erzählt eine Geschichte. Unser automatischer Designer sorgt dafür, dass Ihre visuellen Geschichten ausgewogen und professionell wirken und bereit für die Welt sind - ohne auf einen Grafiker warten zu müssen.' },
175
175
 
176
176
  { type: 'title', text: 'Erstellen, teilen, inspirieren', level: 3 },
177
177
  { type: 'paragraph', html: 'Eine gut gemachte Collage macht den Unterschied zwischen einem vergesslichen Post und einem, an den sich Ihre Follower erinnern und den sie teilen. Nutzen Sie intelligente Komposition für Ihre visuellen Geschichten, um Wirkung zu erzielen.' }
@@ -65,7 +65,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
65
65
  'Traitement instantané sans limites d\'utilisation'
66
66
  ]
67
67
  },
68
- { type: 'title', text: 'Conception de Collages : Des Compositions qui Racontent des Histoires', level: 2 },
68
+ { type: 'title', text: 'Conception de Collages: Des Compositions qui Racontent des Histoires', level: 2 },
69
69
  { type: 'paragraph', html: 'Un collage est plus qu\'un mélange de photos ; c\'est un récit visuel qui communique une émotion et un contexte. Notre outil permet de créer des compositions géométriques professionnelles pour Instagram, Facebook, Pinterest ou des projets personnels sans avoir besoin de Photoshop ou de logiciels coûteux.' },
70
70
 
71
71
  { type: 'stats', items: [
@@ -74,7 +74,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
74
74
  { value: 'Instantané', label: 'Génération', icon: 'mdi:lightning-bolt' }
75
75
  ], columns: 3 },
76
76
 
77
- { type: 'title', text: 'Composition Visuelle : Principes de Design', level: 3 },
77
+ { type: 'title', text: 'Composition Visuelle: Principes de Design', level: 3 },
78
78
  { type: 'paragraph', html: 'La composition est l\'art d\'organiser les éléments visuels de manière à guider l\'œil du spectateur et à communiquer une intention. Un bon collage équilibre :' },
79
79
  { type: 'list', items: [
80
80
  '<strong>Équilibre :</strong> Distribution visuelle du poids (images claires vs sombres, grandes vs petites).',
@@ -119,7 +119,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
119
119
  }
120
120
  ], columns: 3 },
121
121
 
122
- { type: 'title', text: 'Personnalisation : Bordures et Couleurs', level: 3 },
122
+ { type: 'title', text: 'Personnalisation: Bordures et Couleurs', level: 3 },
123
123
  { type: 'table', headers: ['Élément', 'Effet Visuel', 'Recommandation'], rows: [
124
124
  ['Bordure Blanche', 'Propre, minimaliste, moderne', 'Réseaux sociaux, portfolios numériques'],
125
125
  ['Bordure Noire', 'Dramatique, professionnel, artistique', 'Photographie d\'art, mode, luxe'],
@@ -155,7 +155,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
155
155
  },
156
156
  {
157
157
  term: 'Règle des Tiers',
158
- definition: 'Principe de composition : divise l\'image en 9 zones égales (3x3). Positionnez les sujets sur les lignes d\'intersection pour un impact maximal.'
158
+ definition: 'Principe de composition: divise l\'image en 9 zones égales (3x3). Positionnez les sujets sur les lignes d\'intersection pour un impact maximal.'
159
159
  },
160
160
  {
161
161
  term: 'Grille Symétrique',
@@ -80,7 +80,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
80
80
  '<strong>Równowagę:</strong> Wizualne rozłożenie ciężaru (jasne vs ciemne obrazy, duże vs małe).',
81
81
  '<strong>Przepływ Wizualny:</strong> Wzrok powinien naturalnie poruszać się po kompozycji, bez martwych punktów.',
82
82
  '<strong>Kontrast:</strong> Zmiany koloru, rozmiaru i kształtu, które przyciągają uwagę.',
83
- '<strong>Jedność:</strong> Spójność tematyczna obrazy muszą mówić razem o tej samej historii.'
83
+ '<strong>Jedność:</strong> Spójność tematyczna - obrazy muszą \"mówić razem\" o tej samej historii.'
84
84
  ], icon: 'mdi:check' },
85
85
 
86
86
  { type: 'card', title: 'Inteligentne i adaptacyjne projekty', html: 'Nasz system automatycznie oblicza optymalny rozkład przestrzeni na podstawie liczby zdjęć. 2 zdjęcia = siatka symetryczna; 5 zdjęć = zrównoważony rozkład asymetryczny. Każda siatka jest zaprojektowana tak, aby zmaksymalizować wpływ wizualny.' },
@@ -88,7 +88,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
88
88
  { type: 'comparative', items: [
89
89
  {
90
90
  title: 'Dla mediów społecznościowych',
91
- description: 'Instagram, TikTok, Facebook formaty kwadratowe',
91
+ description: 'Instagram, TikTok, Facebook - formaty kwadratowe',
92
92
  icon: 'mdi:share-all',
93
93
  points: [
94
94
  '1200px to idealna rozdzielczość dla feedu na Instagramie',
@@ -129,7 +129,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
129
129
 
130
130
  { type: 'proscons', items: [
131
131
  {
132
- pro: 'Profesjonalne predefiniowane projekty nie wymaga wiedzy o kompozycji',
132
+ pro: 'Profesjonalne predefiniowane projekty - nie wymaga wiedzy o kompozycji',
133
133
  con: 'Opcje ograniczone do ustalonych siatek'
134
134
  },
135
135
  {
@@ -137,7 +137,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
137
137
  con: 'Mniejsza swoboda niż w Photoshopie'
138
138
  },
139
139
  {
140
- pro: '100% lokalne przetwarzanie prywatność, szybkość, brak limitów',
140
+ pro: '100% lokalne przetwarzanie - prywatność, szybkość, brak limitów',
141
141
  con: 'Wymaga nowoczesnej przeglądarki'
142
142
  },
143
143
  {
@@ -171,7 +171,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
171
171
  }
172
172
  ] },
173
173
 
174
- { type: 'message', title: 'Natychmiastowa Narracja Wizualna', ariaLabel: 'Informacje o kompozycji i kolażach', html: 'Każdy kolaż opowiada historię. Nasz automatyczny projektant dba o to, aby Twoje wizualne historie były zrównoważone, profesjonalne i gotowe na świat bez konieczności czekania na pracę grafika.' },
174
+ { type: 'message', title: 'Natychmiastowa Narracja Wizualna', ariaLabel: 'Informacje o kompozycji i kolażach', html: 'Każdy kolaż opowiada historię. Nasz automatyczny projektant dba o to, aby Twoje wizualne historie były zrównoważone, profesjonalne i gotowe na świat - bez konieczności czekania na pracę grafika.' },
175
175
 
176
176
  { type: 'title', text: 'Twórz, Udostępniaj, Inspiruj', level: 3 },
177
177
  { type: 'paragraph', html: 'Dobrze zrobiony kolaż to różnica między postem, o którym szybko się zapomina, a takim, który obserwujący zapamiętają i udostępnią. Wykorzystaj inteligentną kompozycję w swoich wizualnych historiach, aby wywrzeć wrażenie.' }
@@ -8,7 +8,7 @@ const description = 'Создавайте фотоколлажи бесплат
8
8
 
9
9
  const ui: CollageMakerUI = {
10
10
  dropTitle: "Перетащите изображения сюда",
11
- dropSub: "или {link} мин. 2, макс. 9",
11
+ dropSub: "или {link} - мин. 2, макс. 9",
12
12
  dropLink: "выберите файлы",
13
13
  imgsLoaded: "Загруженные изображения",
14
14
  layoutLabel: "Макет",
@@ -66,7 +66,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
66
66
  ]
67
67
  },
68
68
  { type: 'title', text: 'Дизайн коллажа: композиции, которые рассказывают истории', level: 2 },
69
- { type: 'paragraph', html: 'Коллаж это больше, чем просто набор фотографий; это визуальное повествование, передающее эмоции и контекст. Наш инструмент позволяет создавать профессиональные геометрические композиции для Instagram, Facebook, Pinterest или личных проектов без использования Photoshop или дорогого ПО.' },
69
+ { type: 'paragraph', html: 'Коллаж - это больше, чем просто набор фотографий; это визуальное повествование, передающее эмоции и контекст. Наш инструмент позволяет создавать профессиональные геометрические композиции для Instagram, Facebook, Pinterest или личных проектов без использования Photoshop или дорогого ПО.' },
70
70
 
71
71
  { type: 'stats', items: [
72
72
  { value: '2-9', label: 'Фото в коллаже', icon: 'mdi:image-multiple' },
@@ -75,12 +75,12 @@ const seo: CollageMakerLocaleContent['seo'] = [
75
75
  ], columns: 3 },
76
76
 
77
77
  { type: 'title', text: 'Визуальная композиция: принципы дизайна', level: 3 },
78
- { type: 'paragraph', html: 'Композиция это искусство организации визуальных элементов так, чтобы направлять взгляд зрителя и передавать идею. Хороший коллаж соблюдает баланс:' },
78
+ { type: 'paragraph', html: 'Композиция - это искусство организации визуальных элементов так, чтобы направлять взгляд зрителя и передавать идею. Хороший коллаж соблюдает баланс:' },
79
79
  { type: 'list', items: [
80
80
  '<strong>Баланс:</strong> визуальное распределение веса (светлые и темные фото, крупные и мелкие детали).',
81
- '<strong>Визуальный поток:</strong> взгляд должен плавно перемещаться по композиции без «мертвых зон».',
81
+ '<strong>Визуальный поток:</strong> взгляд должен плавно перемещаться по композиции без \"мертвых зон\".',
82
82
  '<strong>Контраст:</strong> различия в цвете, размере и форме, привлекающие внимание.',
83
- '<strong>Единство:</strong> тематическая связность изображения должны «говорить вместе» об одной истории.'
83
+ '<strong>Единство:</strong> тематическая связность - изображения должны \"говорить вместе\" об одной истории.'
84
84
  ], icon: 'mdi:check' },
85
85
 
86
86
  { type: 'card', title: 'Умные и адаптивные макеты', html: 'Наша система автоматически рассчитывает оптимальное распределение пространства в зависимости от количества фотографий. 2 фото = симметричная сетка; 5 фото = сбалансированное асимметричное распределение. Каждая сетка разработана для максимального визуального эффекта.' },
@@ -88,10 +88,10 @@ const seo: CollageMakerLocaleContent['seo'] = [
88
88
  { type: 'comparative', items: [
89
89
  {
90
90
  title: 'Для социальных сетей',
91
- description: 'Instagram, TikTok, Facebook квадратные форматы',
91
+ description: 'Instagram, TikTok, Facebook - квадратные форматы',
92
92
  icon: 'mdi:share-all',
93
93
  points: [
94
- '1200px идеальное разрешение для ленты Instagram',
94
+ '1200px - идеальное разрешение для ленты Instagram',
95
95
  'Квадратный формат исключает обрезку при публикации',
96
96
  'Настраиваемые рамки для личного брендинга'
97
97
  ],
@@ -129,7 +129,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
129
129
 
130
130
  { type: 'proscons', items: [
131
131
  {
132
- pro: 'Профессиональные макеты знания композиции не требуются',
132
+ pro: 'Профессиональные макеты - знания композиции не требуются',
133
133
  con: 'Ограниченный выбор готовых сеток'
134
134
  },
135
135
  {
@@ -137,7 +137,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
137
137
  con: 'Меньше гибкости, чем в Photoshop'
138
138
  },
139
139
  {
140
- pro: '100% локальная обработка конфиденциальность, скорость, без лимитов',
140
+ pro: '100% локальная обработка - конфиденциальность, скорость, без лимитов',
141
141
  con: 'Требуется современный браузер'
142
142
  },
143
143
  {
@@ -146,7 +146,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
146
146
  }
147
147
  ], proTitle: 'Преимущества', conTitle: 'Ограничения' },
148
148
 
149
- { type: 'diagnostic', variant: 'success', title: 'Готов для соцсетей', icon: 'mdi:check-circle-outline', badge: 'Оптимизирован', html: '1200x1200px идеальное разрешение для Instagram. Оно поддерживает любые пропорции, но квадратный формат максимизирует эффект в ленте, исключает обрезку и отлично смотрится на десктопе, планшете и смартфоне.' },
149
+ { type: 'diagnostic', variant: 'success', title: 'Готов для соцсетей', icon: 'mdi:check-circle-outline', badge: 'Оптимизирован', html: '1200x1200px - идеальное разрешение для Instagram. Оно поддерживает любые пропорции, но квадратный формат максимизирует эффект в ленте, исключает обрезку и отлично смотрится на десктопе, планшете и смартфоне.' },
150
150
 
151
151
  { type: 'glossary', items: [
152
152
  {
@@ -171,10 +171,10 @@ const seo: CollageMakerLocaleContent['seo'] = [
171
171
  }
172
172
  ] },
173
173
 
174
- { type: 'message', title: 'Мгновенная визуальная история', ariaLabel: 'Информация о композиции и коллажах', html: 'Каждый коллаж это история. Наш автоматический дизайнер позаботится о том, чтобы она была сбалансированной и профессиональной. Вам не нужно ждать работы графического дизайнера.' },
174
+ { type: 'message', title: 'Мгновенная визуальная история', ariaLabel: 'Информация о композиции и коллажах', html: 'Каждый коллаж - это история. Наш автоматический дизайнер позаботится о том, чтобы она была сбалансированной и профессиональной. Вам не нужно ждать работы графического дизайнера.' },
175
175
 
176
176
  { type: 'title', text: 'Создавайте, делитесь, вдохновляйте', level: 3 },
177
- { type: 'paragraph', html: 'Качественный коллаж это разница между обычным постом и тем, который запомнят и репостнут. Используйте умную композицию, чтобы ваши истории производили эффект.' }
177
+ { type: 'paragraph', html: 'Качественный коллаж - это разница между обычным постом и тем, который запомнят и репостнут. Используйте умную композицию, чтобы ваши истории производили эффект.' }
178
178
  ];
179
179
 
180
180
  const faqSchema: WithContext<FAQPage> = {
@@ -80,7 +80,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
80
80
  '<strong>Balans:</strong> Visuell fördelning av vikt (ljusa vs mörka bilder, stora vs små).',
81
81
  '<strong>Visuellt flöde:</strong> Ögat bör röra sig naturligt genom kompositionen utan döda punkter.',
82
82
  '<strong>Kontrast:</strong> Variationer i färg, storlek och form som fångar uppmärksamheten.',
83
- '<strong>Enhet:</strong> Tematisk koherens bilderna måste \"tala tillsammans\" om samma berättelse.'
83
+ '<strong>Enhet:</strong> Tematisk koherens - bilderna måste \"tala tillsammans\" om samma berättelse.'
84
84
  ], icon: 'mdi:check' },
85
85
 
86
86
  { type: 'card', title: 'Smarta och adaptiva designer', html: 'Vårt system beräknar automatiskt den optimala rumsfördelningen baserat på antalet foton. 2 bilder = symmetriskt rutnät; 5 bilder = balanserad asymmetrisk fördelning. Varje rutnät är utformat för att maximera den visuella effekten.' },
@@ -129,7 +129,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
129
129
 
130
130
  { type: 'proscons', items: [
131
131
  {
132
- pro: 'Professionella fördefinierade designer inga förkunskaper i komposition krävs',
132
+ pro: 'Professionella fördefinierade designer - inga förkunskaper i komposition krävs',
133
133
  con: 'Alternativen är begränsade till förutbestämda rutnät'
134
134
  },
135
135
  {
@@ -137,7 +137,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
137
137
  con: 'Inte lika anpassningsbart som Photoshop'
138
138
  },
139
139
  {
140
- pro: '100% lokal bearbetning integritet, snabbhet, inga gränser',
140
+ pro: '100% lokal bearbetning - integritet, snabbhet, inga gränser',
141
141
  con: 'Kräver en modern webbläsare'
142
142
  },
143
143
  {
@@ -80,7 +80,7 @@ const seo: CollageMakerLocaleContent['seo'] = [
80
80
  '<strong>平衡:</strong> 视觉重量的分布(明亮与阴暗图像、大图与小图)。',
81
81
  '<strong>视觉流:</strong> 视线应自然地穿过构图,没有死角。',
82
82
  '<strong>对比:</strong> 颜色、大小和形状的变化,以吸引注意力。',
83
- '<strong>统一:</strong> 主题连贯性——图像必须“共同讲述”同一个故事。'
83
+ '<strong>统一:</strong> 主题连贯性,图像必须\"共同讲述\"同一个故事。'
84
84
  ], icon: 'mdi:check' },
85
85
 
86
86
  { type: 'card', title: '智能自适应设计', html: '我们的系统根据照片数量自动计算最佳空间分布。2 张图像 = 对称网格;5 张图像 = 平衡的非对称分布。每个网格都旨在最大化视觉冲击力。' },
@@ -37,7 +37,7 @@ const moreSensors = SENSOR_PRESETS.filter(s => !QUICK_SENSOR_KEYS.includes(s.ke
37
37
  </div>
38
38
  <div class="dof-sensor-row">
39
39
  <div class="dof-select-wrapper">
40
- <select id="dof-sensor-more" class="dof-select">
40
+ <select id="dof-sensor-more" class="dof-select" aria-label={ui.sensorLabel}>
41
41
  <option value="">{ui.moreLabel}</option>
42
42
  {moreSensors.map(s => (
43
43
  <option value={s.key} data-coc={s.coc}>{s.label}</option>
@@ -10,7 +10,7 @@ const ui: DepthOfFieldUI = {
10
10
  title: 'Schärfentiefe Rechner',
11
11
  paramsTitle: 'Parameter',
12
12
  sensorLabel: 'Kamerasensor',
13
- moreLabel: 'Weitere Sensoren',
13
+ moreLabel: 'Weitere Sensoren...',
14
14
  apertureLabel: 'Blende',
15
15
  focalLabel: 'Brennweite',
16
16
  distanceLabel: 'Motivabstand',
@@ -80,7 +80,7 @@ const seo: DepthOfFieldLocaleContent['seo'] = [
80
80
 
81
81
  { type: 'title', text: 'Die hyperfokale Distanz: Maximale Schärfe', level: 3 },
82
82
  { type: 'paragraph', html: 'Wenn Sie auf die <strong>hyperfokale Distanz</strong> fokussieren, erscheint alles von der halben Distanz bis Unendlich scharf. Ideal für die Landschaftsfotografie.' },
83
- { type: 'tip', title: 'Praxistipp', html: 'Stellen Sie in der Straßenfotografie den Fokus auf die Hyperfokaldistanz ein. Mit einem 35mm-Objektiv an APS-C bei f/8 liegt diese bei ca. <strong>4 Metern</strong> alles von 2m bis Unendlich wird scharf.' },
83
+ { type: 'tip', title: 'Praxistipp', html: 'Stellen Sie in der Straßenfotografie den Fokus auf die Hyperfokaldistanz ein. Mit einem 35mm-Objektiv an APS-C bei f/8 liegt diese bei ca. <strong>4 Metern</strong> - alles von 2m bis Unendlich wird scharf.' },
84
84
 
85
85
  { type: 'title', text: 'Sensorgröße und Zerstreuungskreis', level: 3 },
86
86
  { type: 'paragraph', html: 'Der <strong>Zerstreuungskreis (CoC)</strong> definiert die akzeptable Schärfe. Ein Vollformatsensor hat einen CoC von 0,030 mm; ein Smartphonesensor ca. 0,006 mm. Kleinere CoC-Werte bedeuten strengere Schärfekriterien.' },
@@ -92,7 +92,7 @@ const seo: DepthOfFieldLocaleContent['seo'] = [
92
92
 
93
93
  { type: 'title', text: 'DoF im Kino: Brennweite vs. Sensor', level: 3 },
94
94
  { type: 'paragraph', html: 'Cinematographen, die auf Super 35 drehen, nutzen oft längere Brennweiten für den typischen "Cinematic Look". Die Kombination aus lichtstarkem Objektiv und 85mm+ Brennweite ist der Klassiker.' },
95
- { type: 'diagnostic', variant: 'success', title: 'Die Fokus Verteilungsregel', icon: 'mdi:lightbulb-outline', badge: 'Profi Technik', html: 'Bei einem Motiv in 3m Entfernung mit 50mm bei f/2.8: Der Bereich hinter dem Motiv ist immer größer als der davor etwa im <strong>Verhältnis 2:1</strong>.' },
95
+ { type: 'diagnostic', variant: 'success', title: 'Die Fokus Verteilungsregel', icon: 'mdi:lightbulb-outline', badge: 'Profi Technik', html: 'Bei einem Motiv in 3m Entfernung mit 50mm bei f/2.8: Der Bereich hinter dem Motiv ist immer größer als der davor - etwa im <strong>Verhältnis 2:1</strong>.' },
96
96
  ];
97
97
 
98
98
  const faqSchema: WithContext<FAQPage> = {
@@ -10,7 +10,7 @@ const ui: DepthOfFieldUI = {
10
10
  title: 'Depth of Field Calculator',
11
11
  paramsTitle: 'Parameters',
12
12
  sensorLabel: 'Camera Sensor',
13
- moreLabel: 'More sensors',
13
+ moreLabel: 'More sensors...',
14
14
  apertureLabel: 'Aperture',
15
15
  focalLabel: 'Focal Length',
16
16
  distanceLabel: 'Subject Distance',
@@ -40,7 +40,7 @@ const faq: DepthOfFieldLocaleContent['faq'] = [
40
40
  },
41
41
  {
42
42
  question: 'Why does a larger aperture (smaller f-number) reduce DoF?',
43
- answer: 'A wider aperture collects light over a larger area of the lens, which increases the size of the circle of confusion for out-of-focus points. This narrows the zone of acceptable sharpness the depth of field.',
43
+ answer: 'A wider aperture collects light over a larger area of the lens, which increases the size of the circle of confusion for out-of-focus points. This narrows the zone of acceptable sharpness - the depth of field.',
44
44
  },
45
45
  {
46
46
  question: 'How does sensor size affect depth of field?',
@@ -55,11 +55,11 @@ const howTo: DepthOfFieldLocaleContent['howTo'] = [
55
55
  },
56
56
  {
57
57
  name: 'Set aperture and focal length',
58
- text: 'Drag the aperture slider to choose an f-stop in 1/3-stop increments. Drag the focal length slider it uses a logarithmic scale so wide-angle changes are more granular.',
58
+ text: 'Drag the aperture slider to choose an f-stop in 1/3-stop increments. Drag the focal length slider - it uses a logarithmic scale so wide-angle changes are more granular.',
59
59
  },
60
60
  {
61
61
  name: 'Set the subject distance',
62
- text: 'Drag the subject distance slider to the distance between your camera and the main subject. Toggle between metres and feet as needed your last choice is remembered.',
62
+ text: 'Drag the subject distance slider to the distance between your camera and the main subject. Toggle between metres and feet as needed - your last choice is remembered.',
63
63
  },
64
64
  {
65
65
  name: 'Read the results',
@@ -80,7 +80,7 @@ const seo: DepthOfFieldLocaleContent['seo'] = [
80
80
 
81
81
  { type: 'title', text: 'The Hyperfocal Distance: Maximum Sharpness', level: 3 },
82
82
  { type: 'paragraph', html: 'When you focus at the <strong>hyperfocal distance</strong>, everything from half that distance to infinity appears acceptably sharp. Landscape photographers use this technique to ensure both a foreground rock and distant mountains are in focus simultaneously.' },
83
- { type: 'tip', title: 'Practical tip', html: 'For street photography, set your focus to the hyperfocal distance and shoot without looking through the viewfinder. With a 35mm lens on APS-C at f/8, the hyperfocal distance is roughly <strong>4 metres</strong> everything from 2m to infinity will be sharp.' },
83
+ { type: 'tip', title: 'Practical tip', html: 'For street photography, set your focus to the hyperfocal distance and shoot without looking through the viewfinder. With a 35mm lens on APS-C at f/8, the hyperfocal distance is roughly <strong>4 metres</strong> - everything from 2m to infinity will be sharp.' },
84
84
 
85
85
  { type: 'title', text: 'Sensor Size and the Circle of Confusion', level: 3 },
86
86
  { type: 'paragraph', html: 'The <strong>circle of confusion (CoC)</strong> is the threshold that defines "acceptable sharpness" for a given sensor format. A Full Frame sensor has a CoC of 0.030mm; a smartphone sensor uses ~0.006mm. Smaller CoC values mean stricter sharpness criteria and, consequently, shallower perceived depth of field.' },
@@ -91,8 +91,8 @@ const seo: DepthOfFieldLocaleContent['seo'] = [
91
91
  ]},
92
92
 
93
93
  { type: 'title', text: 'DoF in Cinema: Focal Length vs. Sensor', level: 3 },
94
- { type: 'paragraph', html: 'Cinematographers shooting on Super 35 (close to APS-C) frequently use longer focal lengths to compress perspective, which also narrows DoF and creates the characteristic "cinematic look". The combination of a fast prime (f/1.4f/2.8) and a 85mm+ focal length at portrait distances is the classic recipe.' },
95
- { type: 'diagnostic', variant: 'success', title: 'The Focus Distribution Rule', icon: 'mdi:lightbulb-outline', badge: 'Pro Technique', html: 'For a subject at 3 metres with a 50mm lens at f/2.8 on Full Frame: near limit ≈ 2.73m, far limit ≈ 3.33m, total DoF ≈ 60cm. The back zone is always larger than the front zone roughly <strong>2:1 ratio</strong> for most real-world distances.' },
94
+ { type: 'paragraph', html: 'Cinematographers shooting on Super 35 (close to APS-C) frequently use longer focal lengths to compress perspective, which also narrows DoF and creates the characteristic "cinematic look". The combination of a fast prime (f/1.4-f/2.8) and a 85mm+ focal length at portrait distances is the classic recipe.' },
95
+ { type: 'diagnostic', variant: 'success', title: 'The Focus Distribution Rule', icon: 'mdi:lightbulb-outline', badge: 'Pro Technique', html: 'For a subject at 3 metres with a 50mm lens at f/2.8 on Full Frame: near limit ≈ 2.73m, far limit ≈ 3.33m, total DoF ≈ 60cm. The back zone is always larger than the front zone - roughly <strong>2:1 ratio</strong> for most real-world distances.' },
96
96
  ];
97
97
 
98
98
  const faqSchema: WithContext<FAQPage> = {
@@ -10,7 +10,7 @@ const ui: DepthOfFieldUI = {
10
10
  title: 'Profundidad de Campo',
11
11
  paramsTitle: 'Parámetros',
12
12
  sensorLabel: 'Sensor de la Cámara',
13
- moreLabel: 'Más sensores',
13
+ moreLabel: 'Más sensores...',
14
14
  apertureLabel: 'Apertura',
15
15
  focalLabel: 'Distancia Focal',
16
16
  distanceLabel: 'Distancia al Sujeto',
@@ -91,7 +91,7 @@ const seo: DepthOfFieldLocaleContent['seo'] = [
91
91
  ]},
92
92
 
93
93
  { type: 'title', text: 'La Profundidad de Campo en el Cine: Focal vs. Sensor', level: 3 },
94
- { type: 'paragraph', html: 'Los cineastas que ruedan en Super 35 (cercano al APS-C) suelen usar distancias focales más largas para comprimir la perspectiva, lo que también reduce la profundidad de campo y crea el característico "look cinematográfico". La combinación de un objetivo luminoso (f/1.4f/2.8) y una focal de más de 85mm a distancias de retrato es la receta clásica.' },
94
+ { type: 'paragraph', html: 'Los cineastas que ruedan en Super 35 (cercano al APS-C) suelen usar distancias focales más largas para comprimir la perspectiva, lo que también reduce la profundidad de campo y crea el característico "look cinematográfico". La combinación de un objetivo luminoso (f/1.4-f/2.8) y una focal de más de 85mm a distancias de retrato es la receta clásica.' },
95
95
  { type: 'diagnostic', variant: 'success', title: 'La Regla de Distribución del Enfoque', icon: 'mdi:lightbulb-outline', badge: 'Técnica Pro', html: 'Para un sujeto a 3 metros con un 50mm a f/2.8 en Full Frame: límite cercano ≈ 2,73m, límite lejano ≈ 3,33m, DoF total ≈ 60cm. La zona trasera siempre es mayor que la delantera, aproximadamente en una <strong>proporción 2:1</strong> para la mayoría de distancias reales.' },
96
96
  ];
97
97