@jjlmoya/utils-chrono 1.4.0 → 1.5.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 (114) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -0
  3. package/src/entries.ts +4 -1
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +1 -1
  6. package/src/tests/no_en_dash.test.ts +41 -0
  7. package/src/tests/tool_validation.test.ts +1 -1
  8. package/src/tool/beat-rate-converter/i18n/en.ts +1 -1
  9. package/src/tool/demagnetizing-timer/components/TimerPanel.astro +45 -17
  10. package/src/tool/demagnetizing-timer/i18n/de.ts +2 -2
  11. package/src/tool/demagnetizing-timer/i18n/en.ts +1 -1
  12. package/src/tool/demagnetizing-timer/i18n/es.ts +1 -1
  13. package/src/tool/demagnetizing-timer/i18n/id.ts +1 -1
  14. package/src/tool/demagnetizing-timer/i18n/it.ts +1 -1
  15. package/src/tool/demagnetizing-timer/i18n/nl.ts +1 -1
  16. package/src/tool/demagnetizing-timer/i18n/pl.ts +1 -1
  17. package/src/tool/demagnetizing-timer/i18n/pt.ts +1 -1
  18. package/src/tool/demagnetizing-timer/i18n/ru.ts +3 -3
  19. package/src/tool/demagnetizing-timer/i18n/sv.ts +1 -1
  20. package/src/tool/demagnetizing-timer/i18n/tr.ts +1 -1
  21. package/src/tool/lume-color-simulator/i18n/de.ts +13 -13
  22. package/src/tool/lume-color-simulator/i18n/en.ts +8 -8
  23. package/src/tool/lume-color-simulator/i18n/es.ts +7 -7
  24. package/src/tool/lume-color-simulator/i18n/fr.ts +4 -4
  25. package/src/tool/lume-color-simulator/i18n/id.ts +7 -7
  26. package/src/tool/lume-color-simulator/i18n/it.ts +7 -7
  27. package/src/tool/lume-color-simulator/i18n/ko.ts +3 -3
  28. package/src/tool/lume-color-simulator/i18n/nl.ts +8 -8
  29. package/src/tool/lume-color-simulator/i18n/pl.ts +13 -13
  30. package/src/tool/lume-color-simulator/i18n/pt.ts +4 -4
  31. package/src/tool/lume-color-simulator/i18n/ru.ts +8 -8
  32. package/src/tool/lume-color-simulator/i18n/sv.ts +16 -16
  33. package/src/tool/lume-color-simulator/i18n/tr.ts +8 -8
  34. package/src/tool/lume-color-simulator/i18n/zh.ts +7 -7
  35. package/src/tool/moon-phase-visualizer/i18n/de.ts +10 -10
  36. package/src/tool/moon-phase-visualizer/i18n/en.ts +6 -6
  37. package/src/tool/moon-phase-visualizer/i18n/es.ts +4 -4
  38. package/src/tool/moon-phase-visualizer/i18n/fr.ts +4 -4
  39. package/src/tool/moon-phase-visualizer/i18n/id.ts +4 -4
  40. package/src/tool/moon-phase-visualizer/i18n/it.ts +4 -4
  41. package/src/tool/moon-phase-visualizer/i18n/ko.ts +2 -2
  42. package/src/tool/moon-phase-visualizer/i18n/nl.ts +6 -6
  43. package/src/tool/moon-phase-visualizer/i18n/pl.ts +9 -9
  44. package/src/tool/moon-phase-visualizer/i18n/pt.ts +4 -4
  45. package/src/tool/moon-phase-visualizer/i18n/ru.ts +4 -4
  46. package/src/tool/moon-phase-visualizer/i18n/sv.ts +10 -10
  47. package/src/tool/moon-phase-visualizer/i18n/tr.ts +6 -6
  48. package/src/tool/moon-phase-visualizer/i18n/zh.ts +4 -4
  49. package/src/tool/power-reserve-estimator/i18n/de.ts +2 -2
  50. package/src/tool/power-reserve-estimator/i18n/es.ts +2 -2
  51. package/src/tool/power-reserve-estimator/i18n/fr.ts +2 -2
  52. package/src/tool/power-reserve-estimator/i18n/id.ts +2 -2
  53. package/src/tool/power-reserve-estimator/i18n/it.ts +2 -2
  54. package/src/tool/power-reserve-estimator/i18n/nl.ts +2 -2
  55. package/src/tool/power-reserve-estimator/i18n/pt.ts +2 -2
  56. package/src/tool/strap-taper-calculator/i18n/ru.ts +1 -1
  57. package/src/tool/tachymeter-calculator/bibliography.astro +16 -0
  58. package/src/tool/tachymeter-calculator/bibliography.ts +16 -0
  59. package/src/tool/tachymeter-calculator/client.ts +180 -0
  60. package/src/tool/tachymeter-calculator/component.astro +15 -0
  61. package/src/tool/tachymeter-calculator/components/CalculatorPanel.astro +121 -0
  62. package/src/tool/tachymeter-calculator/entry.ts +43 -0
  63. package/src/tool/tachymeter-calculator/i18n/de.ts +172 -0
  64. package/src/tool/tachymeter-calculator/i18n/en.ts +172 -0
  65. package/src/tool/tachymeter-calculator/i18n/es.ts +172 -0
  66. package/src/tool/tachymeter-calculator/i18n/fr.ts +172 -0
  67. package/src/tool/tachymeter-calculator/i18n/id.ts +172 -0
  68. package/src/tool/tachymeter-calculator/i18n/it.ts +172 -0
  69. package/src/tool/tachymeter-calculator/i18n/ja.ts +172 -0
  70. package/src/tool/tachymeter-calculator/i18n/ko.ts +172 -0
  71. package/src/tool/tachymeter-calculator/i18n/nl.ts +172 -0
  72. package/src/tool/tachymeter-calculator/i18n/pl.ts +172 -0
  73. package/src/tool/tachymeter-calculator/i18n/pt.ts +172 -0
  74. package/src/tool/tachymeter-calculator/i18n/ru.ts +172 -0
  75. package/src/tool/tachymeter-calculator/i18n/sv.ts +172 -0
  76. package/src/tool/tachymeter-calculator/i18n/tr.ts +172 -0
  77. package/src/tool/tachymeter-calculator/i18n/zh.ts +172 -0
  78. package/src/tool/tachymeter-calculator/index.ts +11 -0
  79. package/src/tool/tachymeter-calculator/seo.astro +16 -0
  80. package/src/tool/tachymeter-calculator/tachymeter-calculator.css +492 -0
  81. package/src/tool/tachymeter-calculator/utils.ts +10 -0
  82. package/src/tool/watch-accuracy-tracker/i18n/pl.ts +1 -1
  83. package/src/tool/watch-accuracy-tracker/i18n/ru.ts +4 -4
  84. package/src/tool/watch-savings-planner/i18n/en.ts +3 -3
  85. package/src/tool/watch-size-comparator/i18n/de.ts +30 -30
  86. package/src/tool/watch-size-comparator/i18n/en.ts +20 -20
  87. package/src/tool/watch-size-comparator/i18n/es.ts +16 -16
  88. package/src/tool/watch-size-comparator/i18n/fr.ts +18 -18
  89. package/src/tool/watch-size-comparator/i18n/id.ts +18 -18
  90. package/src/tool/watch-size-comparator/i18n/it.ts +18 -18
  91. package/src/tool/watch-size-comparator/i18n/ko.ts +11 -11
  92. package/src/tool/watch-size-comparator/i18n/nl.ts +20 -20
  93. package/src/tool/watch-size-comparator/i18n/pl.ts +27 -27
  94. package/src/tool/watch-size-comparator/i18n/pt.ts +17 -17
  95. package/src/tool/watch-size-comparator/i18n/ru.ts +18 -18
  96. package/src/tool/watch-size-comparator/i18n/sv.ts +29 -29
  97. package/src/tool/watch-size-comparator/i18n/tr.ts +20 -20
  98. package/src/tool/watch-size-comparator/i18n/zh.ts +17 -17
  99. package/src/tool/water-resistance-converter/i18n/de.ts +1 -1
  100. package/src/tool/water-resistance-converter/i18n/en.ts +1 -1
  101. package/src/tool/water-resistance-converter/i18n/es.ts +1 -1
  102. package/src/tool/water-resistance-converter/i18n/id.ts +1 -1
  103. package/src/tool/water-resistance-converter/i18n/ja.ts +1 -1
  104. package/src/tool/water-resistance-converter/i18n/ko.ts +1 -1
  105. package/src/tool/water-resistance-converter/i18n/nl.ts +1 -1
  106. package/src/tool/water-resistance-converter/i18n/pl.ts +1 -1
  107. package/src/tool/water-resistance-converter/i18n/pt.ts +1 -1
  108. package/src/tool/water-resistance-converter/i18n/ru.ts +1 -1
  109. package/src/tool/water-resistance-converter/i18n/sv.ts +1 -1
  110. package/src/tool/water-resistance-converter/i18n/tr.ts +1 -1
  111. package/src/tool/water-resistance-converter/i18n/zh.ts +1 -1
  112. package/src/tool/wrist-presence-calculator/i18n/de.ts +1 -1
  113. package/src/tool/wrist-presence-calculator/i18n/ru.ts +18 -18
  114. package/src/tools.ts +2 -0
@@ -0,0 +1,492 @@
1
+ .tool-main-card {
2
+ background: var(--bg-surface);
3
+ border: 1px solid var(--border-color);
4
+ border-radius: 1.25rem;
5
+ max-width: 440px;
6
+ margin: 0 auto;
7
+ padding: 1.75rem;
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: 1.25rem;
11
+ box-shadow: var(--shadow-base);
12
+ position: relative;
13
+ overflow: hidden;
14
+ }
15
+
16
+ .tach-panel {
17
+ display: flex;
18
+ flex-direction: column;
19
+ gap: 1rem;
20
+ position: relative;
21
+ z-index: 1;
22
+ }
23
+
24
+ .panel-section {
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: 0.5rem;
28
+ }
29
+
30
+ .section-label {
31
+ font-size: 0.75rem;
32
+ font-weight: 600;
33
+ color: var(--text-base);
34
+ opacity: 0.7;
35
+ text-transform: uppercase;
36
+ letter-spacing: 0.06em;
37
+ }
38
+
39
+ .preset-select {
40
+ width: 100%;
41
+ padding: 0.65rem 0.75rem;
42
+ background: var(--bg-page);
43
+ border: 1px solid var(--border-base);
44
+ border-radius: 0.75rem;
45
+ color: var(--text-base);
46
+ font-size: 0.875rem;
47
+ cursor: pointer;
48
+ transition: border-color 0.2s;
49
+ appearance: none;
50
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
51
+ background-repeat: no-repeat;
52
+ background-position: right 0.75rem center;
53
+ padding-right: 2rem;
54
+ }
55
+
56
+ .preset-select:focus {
57
+ outline: none;
58
+ border-color: var(--accent);
59
+ }
60
+
61
+ .stepper-wrap {
62
+ display: flex;
63
+ align-items: center;
64
+ background: var(--bg-page);
65
+ border: 1px solid var(--border-base);
66
+ border-radius: 0.75rem;
67
+ overflow: hidden;
68
+ transition: border-color 0.2s;
69
+ }
70
+
71
+ .stepper-wrap:focus-within {
72
+ border-color: var(--accent);
73
+ }
74
+
75
+ .stepper-input {
76
+ width: 100%;
77
+ padding: 0.6rem 0.25rem;
78
+ border: none;
79
+ background: transparent;
80
+ color: var(--text-base);
81
+ font-size: 0.875rem;
82
+ text-align: center;
83
+ font-variant-numeric: tabular-nums;
84
+ box-sizing: border-box;
85
+ -moz-appearance: textfield;
86
+ }
87
+
88
+ .stepper-input::-webkit-inner-spin-button,
89
+ .stepper-input::-webkit-outer-spin-button {
90
+ -webkit-appearance: none;
91
+ margin: 0;
92
+ }
93
+
94
+ .stepper-input:focus {
95
+ outline: none;
96
+ }
97
+
98
+ .stepper-btn {
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ min-width: 3rem;
103
+ padding: 0.5rem;
104
+ border: none;
105
+ background: transparent;
106
+ color: var(--text-base);
107
+ opacity: 0.5;
108
+ font-size: 0.75rem;
109
+ font-weight: 700;
110
+ cursor: pointer;
111
+ transition: all 0.15s ease;
112
+ user-select: none;
113
+ }
114
+
115
+ .stepper-btn:hover {
116
+ background: var(--bg-page);
117
+ color: var(--accent);
118
+ opacity: 1;
119
+ }
120
+
121
+ .stepper-btn:active {
122
+ background: var(--border-base);
123
+ transform: scale(0.95);
124
+ }
125
+
126
+ .tach-visual {
127
+ position: relative;
128
+ width: 240px;
129
+ height: 240px;
130
+ margin: 0 auto;
131
+ }
132
+
133
+ .tach-svg {
134
+ width: 100%;
135
+ height: 100%;
136
+ overflow: visible;
137
+ }
138
+
139
+ .tach-bezel-bg {
140
+ fill: url("#bezel-grad");
141
+ stroke: var(--border-base);
142
+ stroke-width: 1;
143
+ }
144
+
145
+ .tach-bezel-outer {
146
+ fill: none;
147
+ stroke: var(--border-color);
148
+ stroke-width: 2;
149
+ }
150
+
151
+ .tach-bezel-inner {
152
+ fill: none;
153
+ stroke: var(--border-base);
154
+ stroke-width: 1;
155
+ }
156
+
157
+ .tach-dial {
158
+ fill: url("#dial-grad");
159
+ stroke: var(--border-color);
160
+ stroke-width: 1;
161
+ }
162
+
163
+ .tick-major {
164
+ stroke: var(--text-base);
165
+ stroke-width: 2;
166
+ stroke-linecap: round;
167
+ opacity: 0.65;
168
+ }
169
+
170
+ .tick-minor {
171
+ stroke: var(--text-base);
172
+ stroke-width: 1;
173
+ stroke-linecap: round;
174
+ opacity: 0.3;
175
+ }
176
+
177
+ .tick-label-line {
178
+ opacity: 0.85;
179
+ }
180
+
181
+ .tick-label {
182
+ font-size: 6px;
183
+ font-weight: 700;
184
+ fill: var(--text-base);
185
+ opacity: 0.75;
186
+ }
187
+
188
+ .tach-hand-group {
189
+ transform-origin: 110px 110px;
190
+ transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
191
+ }
192
+
193
+ .tach-hand {
194
+ stroke: var(--accent);
195
+ stroke-width: 2.5;
196
+ stroke-linecap: round;
197
+ }
198
+
199
+ .tach-hand-tail {
200
+ stroke: var(--accent);
201
+ stroke-width: 1.5;
202
+ stroke-linecap: round;
203
+ opacity: 0.3;
204
+ }
205
+
206
+ .tach-pip {
207
+ fill: var(--accent);
208
+ }
209
+
210
+ .tach-pip-ring {
211
+ fill: none;
212
+ stroke: var(--accent);
213
+ stroke-width: 1.5;
214
+ opacity: 0.4;
215
+ }
216
+
217
+ .tach-sweep {
218
+ fill: none;
219
+ stroke: var(--accent);
220
+ stroke-width: 3;
221
+ stroke-linecap: round;
222
+ opacity: 0.35;
223
+ filter: url("#glow");
224
+ }
225
+
226
+ .tach-time-label {
227
+ font-size: 11px;
228
+ font-weight: 800;
229
+ fill: var(--text-base);
230
+ letter-spacing: 0.02em;
231
+ font-variant-numeric: tabular-nums;
232
+ opacity: 0.85;
233
+ }
234
+
235
+ .tach-speed-label {
236
+ font-size: 20px;
237
+ font-weight: 900;
238
+ fill: var(--accent);
239
+ letter-spacing: -0.02em;
240
+ font-variant-numeric: tabular-nums;
241
+ transition: fill 0.4s ease;
242
+ }
243
+
244
+ .tach-unit-label {
245
+ font-size: 7px;
246
+ font-weight: 600;
247
+ fill: var(--text-base);
248
+ opacity: 0.5;
249
+ letter-spacing: 0.08em;
250
+ }
251
+
252
+ .tach-glow {
253
+ fill: var(--accent);
254
+ opacity: 0.5;
255
+ animation: pulse-glow 1.5s ease-in-out infinite;
256
+ transform-origin: center;
257
+ }
258
+
259
+ .tach-glow-ring {
260
+ fill: none;
261
+ stroke: var(--accent);
262
+ stroke-width: 2;
263
+ opacity: 0.5;
264
+ animation: pulse-ring 1.5s ease-in-out infinite;
265
+ transform-origin: center;
266
+ }
267
+
268
+ @keyframes pulse-glow {
269
+ 0%, 100% { opacity: 0.25; }
270
+ 50% { opacity: 0.6; }
271
+ }
272
+
273
+ @keyframes pulse-ring {
274
+ 0%, 100% { opacity: 0.3; }
275
+ 50% { opacity: 0.6; }
276
+ }
277
+
278
+ .tach-readout {
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ gap: 1.5rem;
283
+ padding: 0.875rem 1rem;
284
+ background: var(--bg-page);
285
+ border: 1px solid var(--border-base);
286
+ border-radius: 1rem;
287
+ }
288
+
289
+ .readout-block {
290
+ display: flex;
291
+ flex-direction: column;
292
+ align-items: center;
293
+ gap: 0.15rem;
294
+ }
295
+
296
+ .readout-value {
297
+ font-size: 2rem;
298
+ font-weight: 800;
299
+ color: var(--accent);
300
+ letter-spacing: -0.03em;
301
+ line-height: 1;
302
+ font-variant-numeric: tabular-nums;
303
+ transition: color 0.4s ease;
304
+ }
305
+
306
+ .readout-unit {
307
+ font-size: 0.65rem;
308
+ font-weight: 600;
309
+ color: var(--text-base);
310
+ opacity: 0.5;
311
+ text-transform: uppercase;
312
+ letter-spacing: 0.04em;
313
+ }
314
+
315
+ .readout-label {
316
+ font-size: 0.65rem;
317
+ font-weight: 600;
318
+ color: var(--text-base);
319
+ opacity: 0.5;
320
+ text-transform: uppercase;
321
+ letter-spacing: 0.04em;
322
+ }
323
+
324
+ .readout-bezel {
325
+ font-size: 1.25rem;
326
+ font-weight: 700;
327
+ color: var(--text-base);
328
+ font-variant-numeric: tabular-nums;
329
+ }
330
+
331
+ .readout-divider {
332
+ width: 1px;
333
+ height: 2.5rem;
334
+ background: var(--border-base);
335
+ flex-shrink: 0;
336
+ }
337
+
338
+ .speed-fast .tach-hand,
339
+ .speed-fast .tach-hand-tail {
340
+ stroke: var(--color-red, #ef4444);
341
+ }
342
+
343
+ .speed-fast .tach-pip-ring {
344
+ stroke: var(--color-red, #ef4444);
345
+ }
346
+
347
+ .speed-fast .tach-sweep,
348
+ .speed-fast .tach-glow,
349
+ .speed-fast .tach-glow-ring {
350
+ stroke: var(--color-red, #ef4444);
351
+ }
352
+
353
+ .speed-fast .tach-glow {
354
+ fill: var(--color-red, #ef4444);
355
+ }
356
+
357
+ .speed-fast .tach-speed-label {
358
+ fill: var(--color-red, #ef4444);
359
+ }
360
+
361
+ .speed-fast .readout-value {
362
+ color: var(--color-red, #ef4444);
363
+ }
364
+
365
+ .speed-mid .tach-hand,
366
+ .speed-mid .tach-hand-tail {
367
+ stroke: var(--color-amber, #f59e0b);
368
+ }
369
+
370
+ .speed-mid .tach-pip-ring {
371
+ stroke: var(--color-amber, #f59e0b);
372
+ }
373
+
374
+ .speed-mid .tach-sweep,
375
+ .speed-mid .tach-glow,
376
+ .speed-mid .tach-glow-ring {
377
+ stroke: var(--color-amber, #f59e0b);
378
+ }
379
+
380
+ .speed-mid .tach-glow {
381
+ fill: var(--color-amber, #f59e0b);
382
+ }
383
+
384
+ .speed-mid .tach-speed-label {
385
+ fill: var(--color-amber, #f59e0b);
386
+ }
387
+
388
+ .speed-mid .readout-value {
389
+ color: var(--color-amber, #f59e0b);
390
+ }
391
+
392
+ .speed-slow .tach-hand,
393
+ .speed-slow .tach-hand-tail {
394
+ stroke: var(--color-green, #22c55e);
395
+ }
396
+
397
+ .speed-slow .tach-pip-ring {
398
+ stroke: var(--color-green, #22c55e);
399
+ }
400
+
401
+ .speed-slow .tach-sweep,
402
+ .speed-slow .tach-glow,
403
+ .speed-slow .tach-glow-ring {
404
+ stroke: var(--color-green, #22c55e);
405
+ }
406
+
407
+ .speed-slow .tach-glow {
408
+ fill: var(--color-green, #22c55e);
409
+ }
410
+
411
+ .speed-slow .tach-speed-label {
412
+ fill: var(--color-green, #22c55e);
413
+ }
414
+
415
+ .speed-slow .readout-value {
416
+ color: var(--color-green, #22c55e);
417
+ }
418
+
419
+ .steps-section {
420
+ display: flex;
421
+ flex-direction: column;
422
+ gap: 0.625rem;
423
+ padding: 1rem 1.125rem;
424
+ background: var(--bg-page);
425
+ border-radius: 0.875rem;
426
+ border: 1px solid var(--border-base);
427
+ }
428
+
429
+ .step-row {
430
+ display: flex;
431
+ align-items: center;
432
+ gap: 0.75rem;
433
+ }
434
+
435
+ .step-marker {
436
+ width: 1.375rem;
437
+ height: 1.375rem;
438
+ border-radius: 50%;
439
+ background: var(--accent);
440
+ color: var(--text-on-primary, #fff);
441
+ font-size: 0.6875rem;
442
+ font-weight: 700;
443
+ display: flex;
444
+ align-items: center;
445
+ justify-content: center;
446
+ flex-shrink: 0;
447
+ }
448
+
449
+ .step-text {
450
+ font-size: 0.8125rem;
451
+ color: var(--text-base);
452
+ opacity: 0.85;
453
+ line-height: 1.4;
454
+ }
455
+
456
+ .tip-row {
457
+ display: flex;
458
+ gap: 0.5rem;
459
+ padding: 0.75rem 1rem;
460
+ background: var(--bg-page);
461
+ border-radius: 0.75rem;
462
+ border: 1px solid var(--border-base);
463
+ }
464
+
465
+ .tip-icon {
466
+ flex-shrink: 0;
467
+ margin-top: 0.1rem;
468
+ color: var(--accent);
469
+ }
470
+
471
+ .tip-text {
472
+ font-size: 0.8rem;
473
+ color: var(--text-base);
474
+ opacity: 0.85;
475
+ line-height: 1.5;
476
+ }
477
+
478
+ @media (max-width: 520px) {
479
+ .tool-main-card {
480
+ padding: 1rem;
481
+ gap: 1rem;
482
+ }
483
+
484
+ .tach-visual {
485
+ width: 200px;
486
+ height: 200px;
487
+ }
488
+
489
+ .readout-value {
490
+ font-size: 1.5rem;
491
+ }
492
+ }
@@ -0,0 +1,10 @@
1
+ export function speedFromTime(seconds: number): number {
2
+ return 3600 / seconds;
3
+ }
4
+
5
+ export function formatTime(seconds: number): string {
6
+ if (seconds < 60) return `${seconds.toFixed(1)}s`;
7
+ const m = Math.floor(seconds / 60);
8
+ const s = seconds % 60;
9
+ return s > 0 ? `${m}m ${s.toFixed(0)}s` : `${m}m`;
10
+ }
@@ -77,7 +77,7 @@ export const content: ToolLocaleContent = {
77
77
  { type: 'title', text: 'Kompleksowy przewodnik po dokładności i regulacji zegarków mechanicznych', level: 2 },
78
78
  { type: 'paragraph', html: 'Zegarki mechaniczne to małe dzieła sztuki inżynieryjnej, jednak w przeciwieństwie do modeli kwarcowych są podatne na działanie czynników fizycznych i środowiskowych. Systematyczne monitorowanie dobowej odchyłki chodu pozwala ocenić stan mechanizmu i określić, kiedy zegarek wymaga profesjonalnego serwisu zegarmistrzowskiego.' },
79
79
  { type: 'title', text: 'Dlaczego zegarki mechaniczne spieszą lub spóźniają: Kluczowe czynniki', level: 2 },
80
- { type: 'paragraph', html: 'Wiele czynników wpływa na dobową dokładność zegarka. Grawitacja oddziałuje na koło balansowe i włos balansu w różny sposób, zależnie od pozycji spoczynkowej zegarka. Zmiany temperatur powodują kurczenie lub rozszerzanie się włosa, co zmienia częstotliwość drgań. Istotny jest również stopień naciągu sprężyny (rezerwa chodu) w pełni nakręcony zegarek pracuje stabilniej niż ten pod koniec rezerwy.' },
80
+ { type: 'paragraph', html: 'Wiele czynników wpływa na dobową dokładność zegarka. Grawitacja oddziałuje na koło balansowe i włos balansu w różny sposób, zależnie od pozycji spoczynkowej zegarka. Zmiany temperatur powodują kurczenie lub rozszerzanie się włosa, co zmienia częstotliwość drgań. Istotny jest również stopień naciągu sprężyny (rezerwa chodu) - w pełni nakręcony zegarek pracuje stabilniej niż ten pod koniec rezerwy.' },
81
81
  { type: 'title', text: 'Skumulowana odchyłka chodu: Jak sekundy zmieniają się w minuty', level: 2 },
82
82
  { type: 'paragraph', html: 'Dobowy błąd na poziomie zaledwie +5 sekund wydaje się mało znaczący, jednak czas płynie nieprzerwanie. W tydzień odchyłka ta urośnie do 35 sekund, w miesiąc do 2,5 minuty, a po roku zegarek będzie spieszył o ponad 30 minut. Ta skumulowana wartość pokazuje, jak ważne jest regularne mierzenie precyzji chodu.' },
83
83
  { type: 'title', text: 'Jak ręcznie mierzyć i obliczać dokładność zegarka', level: 2 },
@@ -88,7 +88,7 @@ export const content: ToolLocaleContent = {
88
88
  faq: [
89
89
  {
90
90
  question: 'Какая суточная погрешность считается нормой для механических часов?',
91
- answer: 'Обычные механические часы обычно отклоняются на +/- 1020 секунд в сутки. Часы с официальным сертификатом хронометра COSC отрегулированы в пределах от -4 до +6 секунд в сутки, в то время как высокоточные кварцевые механизмы могут обеспечивать погрешность менее +/- 0.5 секунды в день.',
91
+ answer: 'Обычные механические часы обычно отклоняются на +/- 10-20 секунд в сутки. Часы с официальным сертификатом хронометра COSC отрегулированы в пределах от -4 до +6 секунд в сутки, в то время как высокоточные кварцевые механизмы могут обеспечивать погрешность менее +/- 0.5 секунды в день.',
92
92
  },
93
93
  {
94
94
  question: 'Почему точность хода моих часов меняется в зависимости от положения?',
@@ -103,7 +103,7 @@ export const content: ToolLocaleContent = {
103
103
  },
104
104
  {
105
105
  name: 'Носить и ожидать',
106
- text: 'Носите часы как обычно или оставьте их в неподвижном положении минимум на 1224 часа.',
106
+ text: 'Носите часы как обычно или оставьте их в неподвижном положении минимум на 12-24 часа.',
107
107
  },
108
108
  {
109
109
  name: 'Записать конечное состояние',
@@ -128,7 +128,7 @@ export const content: ToolLocaleContent = {
128
128
  'name': 'Какая суточная погрешность считается нормой для механических часов?',
129
129
  'acceptedAnswer': {
130
130
  '@type': 'Answer',
131
- 'text': 'Обычные механические часы обычно отклоняются на +/- 1020 секунд в сутки. Часы с официальным сертификатом хронометра COSC отрегулированы в пределах от -4 до +6 секунд в сутки, в то время как высокоточные кварцевые механизмы могут обеспечивать погрешность менее +/- 0.5 секунды в день.'
131
+ 'text': 'Обычные механические часы обычно отклоняются на +/- 10-20 секунд в сутки. Часы с официальным сертификатом хронометра COSC отрегулированы в пределах от -4 до +6 секунд в сутки, в то время как высокоточные кварцевые механизмы могут обеспечивать погрешность менее +/- 0.5 секунды в день.'
132
132
  }
133
133
  },
134
134
  {
@@ -154,7 +154,7 @@ export const content: ToolLocaleContent = {
154
154
  {
155
155
  '@type': 'HowToStep',
156
156
  'name': 'Носить и ожидать',
157
- 'text': 'Носите часы как обычно или оставьте их в неподвижном положении минимум на 1224 часа.'
157
+ 'text': 'Носите часы как обычно или оставьте их в неподвижном положении минимум на 12-24 часа.'
158
158
  },
159
159
  {
160
160
  '@type': 'HowToStep',
@@ -48,14 +48,14 @@ export const content: ToolLocaleContent<WatchSavingsPlannerUI> = {
48
48
  { type: 'title', text: 'Why a Savings Plan Matters for Watch Collectors', level: 3 },
49
49
  { type: 'paragraph', html: 'Watch collecting is a patient game. Prices for sought-after models climb steadily, and impulse purchases often lead to regret. A structured savings approach keeps you disciplined, prevents financial strain, and makes the final purchase feel earned. Plus, tracking your progress day by day builds anticipation and makes the unboxing even sweeter.' },
50
50
  { type: 'title', text: 'How to Set Realistic Watch Savings Goals', level: 3 },
51
- { type: 'paragraph', html: 'Start with the total price including taxes and shipping. Then divide by how much you can comfortably set aside each month. A good rule of thumb is to dedicate no more than <strong>1015% of disposable income</strong> to watch savings. If the timeline feels too long, consider breaking it into smaller milestones-or exploring more affordable alternatives in the same style family.' },
51
+ { type: 'paragraph', html: 'Start with the total price including taxes and shipping. Then divide by how much you can comfortably set aside each month. A good rule of thumb is to dedicate no more than <strong>10-15% of disposable income</strong> to watch savings. If the timeline feels too long, consider breaking it into smaller milestones-or exploring more affordable alternatives in the same style family.' },
52
52
  { type: 'title', text: 'The Psychology of Goal Tracking', level: 3 },
53
53
  { type: 'paragraph', html: 'Visual progress tracking triggers dopamine release, the same neurochemical that makes collecting so rewarding. Each time you log a new contribution and watch the progress ring fill, you reinforce the habit. This is why small, regular savings often work better than sporadic large deposits-the ritual itself becomes part of the collecting experience.' },
54
54
  ],
55
55
  faq: [
56
56
  {
57
57
  question: 'How much should I save each month for a watch?',
58
- answer: 'Aim for 1015% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year. Adjust the amount based on your timeline: shorter goals need larger monthly contributions.',
58
+ answer: 'Aim for 10-15% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year. Adjust the amount based on your timeline: shorter goals need larger monthly contributions.',
59
59
  },
60
60
  {
61
61
  question: 'Should I save for one watch at a time or multiple?',
@@ -95,7 +95,7 @@ export const content: ToolLocaleContent<WatchSavingsPlannerUI> = {
95
95
  'name': 'How much should I save each month for a watch?',
96
96
  'acceptedAnswer': {
97
97
  '@type': 'Answer',
98
- 'text': 'Aim for 1015% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year.',
98
+ 'text': 'Aim for 10-15% of your disposable monthly income. The key is consistency-even $100 a month adds up to $1,200 a year.',
99
99
  },
100
100
  },
101
101
  {