@jjlmoya/utils-motor 1.2.0 → 1.4.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 (95) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +4 -1
  3. package/src/entries.ts +10 -1
  4. package/src/index.ts +15 -0
  5. package/src/tests/locale_completeness.test.ts +1 -1
  6. package/src/tests/seo_translation_completeness.test.ts +69 -0
  7. package/src/tests/tool_validation.test.ts +1 -1
  8. package/src/tool/carMotorcycleGearRatioCalculator/bibliography.astro +6 -0
  9. package/src/tool/carMotorcycleGearRatioCalculator/bibliography.ts +12 -0
  10. package/src/tool/carMotorcycleGearRatioCalculator/car-motorcycle-gear-ratio-rpm-speed-calculator.css +668 -0
  11. package/src/tool/carMotorcycleGearRatioCalculator/component.astro +137 -0
  12. package/src/tool/carMotorcycleGearRatioCalculator/controller.ts +209 -0
  13. package/src/tool/carMotorcycleGearRatioCalculator/dom-views.ts +121 -0
  14. package/src/tool/carMotorcycleGearRatioCalculator/entry.ts +30 -0
  15. package/src/tool/carMotorcycleGearRatioCalculator/evaluator.ts +28 -0
  16. package/src/tool/carMotorcycleGearRatioCalculator/i18n/de.ts +162 -0
  17. package/src/tool/carMotorcycleGearRatioCalculator/i18n/en.ts +162 -0
  18. package/src/tool/carMotorcycleGearRatioCalculator/i18n/es.ts +162 -0
  19. package/src/tool/carMotorcycleGearRatioCalculator/i18n/fr.ts +162 -0
  20. package/src/tool/carMotorcycleGearRatioCalculator/i18n/id.ts +162 -0
  21. package/src/tool/carMotorcycleGearRatioCalculator/i18n/it.ts +162 -0
  22. package/src/tool/carMotorcycleGearRatioCalculator/i18n/ja.ts +162 -0
  23. package/src/tool/carMotorcycleGearRatioCalculator/i18n/ko.ts +162 -0
  24. package/src/tool/carMotorcycleGearRatioCalculator/i18n/nl.ts +162 -0
  25. package/src/tool/carMotorcycleGearRatioCalculator/i18n/pl.ts +162 -0
  26. package/src/tool/carMotorcycleGearRatioCalculator/i18n/pt.ts +162 -0
  27. package/src/tool/carMotorcycleGearRatioCalculator/i18n/ru.ts +162 -0
  28. package/src/tool/carMotorcycleGearRatioCalculator/i18n/sv.ts +162 -0
  29. package/src/tool/carMotorcycleGearRatioCalculator/i18n/tr.ts +162 -0
  30. package/src/tool/carMotorcycleGearRatioCalculator/i18n/zh.ts +162 -0
  31. package/src/tool/carMotorcycleGearRatioCalculator/index.ts +10 -0
  32. package/src/tool/carMotorcycleGearRatioCalculator/logic.test.ts +51 -0
  33. package/src/tool/carMotorcycleGearRatioCalculator/logic.ts +91 -0
  34. package/src/tool/carMotorcycleGearRatioCalculator/seo.astro +15 -0
  35. package/src/tool/carMotorcycleGearRatioCalculator/storage.ts +46 -0
  36. package/src/tool/carMotorcycleGearRatioCalculator/ui.ts +50 -0
  37. package/src/tool/motorcycleSkidMarkSpeedEstimator/bibliography.astro +6 -0
  38. package/src/tool/motorcycleSkidMarkSpeedEstimator/bibliography.ts +12 -0
  39. package/src/tool/motorcycleSkidMarkSpeedEstimator/component.astro +166 -0
  40. package/src/tool/motorcycleSkidMarkSpeedEstimator/controller.ts +207 -0
  41. package/src/tool/motorcycleSkidMarkSpeedEstimator/dom-views.ts +101 -0
  42. package/src/tool/motorcycleSkidMarkSpeedEstimator/entry.ts +30 -0
  43. package/src/tool/motorcycleSkidMarkSpeedEstimator/evaluator.ts +7 -0
  44. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/de.ts +185 -0
  45. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/en.ts +185 -0
  46. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/es.ts +185 -0
  47. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/fr.ts +185 -0
  48. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/id.ts +185 -0
  49. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/it.ts +185 -0
  50. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/ja.ts +201 -0
  51. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/ko.ts +201 -0
  52. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/nl.ts +185 -0
  53. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/pl.ts +185 -0
  54. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/pt.ts +185 -0
  55. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/ru.ts +185 -0
  56. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/sv.ts +185 -0
  57. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/tr.ts +185 -0
  58. package/src/tool/motorcycleSkidMarkSpeedEstimator/i18n/zh.ts +201 -0
  59. package/src/tool/motorcycleSkidMarkSpeedEstimator/index.ts +10 -0
  60. package/src/tool/motorcycleSkidMarkSpeedEstimator/logic.test.ts +229 -0
  61. package/src/tool/motorcycleSkidMarkSpeedEstimator/logic.ts +179 -0
  62. package/src/tool/motorcycleSkidMarkSpeedEstimator/motorcycle-skid-mark-speed-estimator.css +523 -0
  63. package/src/tool/motorcycleSkidMarkSpeedEstimator/seo.astro +15 -0
  64. package/src/tool/motorcycleSkidMarkSpeedEstimator/storage.ts +49 -0
  65. package/src/tool/motorcycleSkidMarkSpeedEstimator/ui.ts +46 -0
  66. package/src/tool/tirePressureConverter/bibliography.astro +6 -0
  67. package/src/tool/tirePressureConverter/bibliography.ts +12 -0
  68. package/src/tool/tirePressureConverter/component.astro +82 -0
  69. package/src/tool/tirePressureConverter/controller.ts +120 -0
  70. package/src/tool/tirePressureConverter/dom-views.ts +31 -0
  71. package/src/tool/tirePressureConverter/entry.ts +30 -0
  72. package/src/tool/tirePressureConverter/evaluator.ts +8 -0
  73. package/src/tool/tirePressureConverter/i18n/de.ts +96 -0
  74. package/src/tool/tirePressureConverter/i18n/en.ts +96 -0
  75. package/src/tool/tirePressureConverter/i18n/es.ts +96 -0
  76. package/src/tool/tirePressureConverter/i18n/fr.ts +96 -0
  77. package/src/tool/tirePressureConverter/i18n/id.ts +95 -0
  78. package/src/tool/tirePressureConverter/i18n/it.ts +95 -0
  79. package/src/tool/tirePressureConverter/i18n/ja.ts +95 -0
  80. package/src/tool/tirePressureConverter/i18n/ko.ts +95 -0
  81. package/src/tool/tirePressureConverter/i18n/nl.ts +95 -0
  82. package/src/tool/tirePressureConverter/i18n/pl.ts +95 -0
  83. package/src/tool/tirePressureConverter/i18n/pt.ts +95 -0
  84. package/src/tool/tirePressureConverter/i18n/ru.ts +95 -0
  85. package/src/tool/tirePressureConverter/i18n/sv.ts +95 -0
  86. package/src/tool/tirePressureConverter/i18n/tr.ts +95 -0
  87. package/src/tool/tirePressureConverter/i18n/zh.ts +95 -0
  88. package/src/tool/tirePressureConverter/index.ts +10 -0
  89. package/src/tool/tirePressureConverter/logic.test.ts +37 -0
  90. package/src/tool/tirePressureConverter/logic.ts +47 -0
  91. package/src/tool/tirePressureConverter/seo.astro +15 -0
  92. package/src/tool/tirePressureConverter/storage.ts +27 -0
  93. package/src/tool/tirePressureConverter/tire-pressure-converter-psi-bar-kpa-kgf-cm2.css +293 -0
  94. package/src/tool/tirePressureConverter/ui.ts +20 -0
  95. package/src/tools.ts +4 -1
@@ -0,0 +1,668 @@
1
+ .gear-tool {
2
+ --n-paper: #f4f1ed;
3
+ --n-surface: #fffdf9;
4
+ --n-surface-soft: #f1e8e0;
5
+ --n-ink: #2c2520;
6
+ --n-muted: #746b64;
7
+ --n-line: #d9ccc0;
8
+ --n-accent: #a85437;
9
+ --n-accent-soft: #f0d8cc;
10
+ --n-accent-strong: #7e3b29;
11
+ --n-on-accent: #fff;
12
+ --n-warm: #d78d4e;
13
+ --n-warm-soft: #f5e0c6;
14
+ --n-danger: #b1433e;
15
+ --n-danger-soft: #f3d8d4;
16
+ --n-shadow: rgba(44, 37, 32, 0.12);
17
+
18
+ background: var(--n-paper);
19
+ border: 1px solid var(--n-line);
20
+ border-radius: 1.35rem;
21
+ box-shadow: 0 1rem 2.5rem var(--n-shadow);
22
+ color: var(--n-ink);
23
+ display: grid;
24
+ gap: 1.25rem;
25
+ padding: clamp(1rem, 2.5vw, 1.75rem);
26
+ }
27
+
28
+ .theme-dark .gear-tool {
29
+ --n-paper: #111315;
30
+ --n-surface: #191b1e;
31
+ --n-surface-soft: #242629;
32
+ --n-ink: #f4efe9;
33
+ --n-muted: #b8afa7;
34
+ --n-line: #45413e;
35
+ --n-accent: #df8b61;
36
+ --n-accent-soft: #503126;
37
+ --n-accent-strong: #ffc0a0;
38
+ --n-on-accent: #fff;
39
+ --n-warm: #e4af65;
40
+ --n-warm-soft: #4a3826;
41
+ --n-danger: #ff9385;
42
+ --n-danger-soft: #542d2b;
43
+ --n-shadow: rgba(0, 0, 0, 0.35);
44
+ }
45
+
46
+ .gear-tool-intro {
47
+ display: grid;
48
+ gap: 0.3rem;
49
+ max-width: 50rem;
50
+ }
51
+
52
+ .tool-kicker,
53
+ .eyebrow,
54
+ .scene-label {
55
+ color: var(--n-accent);
56
+ font-size: 0.68rem;
57
+ font-weight: 900;
58
+ letter-spacing: 0.14em;
59
+ text-transform: uppercase;
60
+ }
61
+
62
+ .gear-tool-intro p,
63
+ .educational-notice {
64
+ color: var(--n-muted);
65
+ font-size: 0.9rem;
66
+ line-height: 1.5;
67
+ margin: 0;
68
+ }
69
+
70
+ .gear-layout {
71
+ align-items: start;
72
+ display: grid;
73
+ gap: 1rem;
74
+ grid-template-columns: minmax(17rem, 0.78fr) minmax(25rem, 1.22fr);
75
+ }
76
+
77
+ .gear-controls,
78
+ .gear-visual {
79
+ background: var(--n-surface);
80
+ border: 1px solid var(--n-line);
81
+ border-radius: 1.05rem;
82
+ min-width: 0;
83
+ }
84
+
85
+ .gear-controls {
86
+ align-self: start;
87
+ display: grid;
88
+ gap: 0.9rem;
89
+ padding: 0.9rem;
90
+ }
91
+
92
+ .control-block {
93
+ display: grid;
94
+ gap: 0.6rem;
95
+ }
96
+
97
+ .control-block + .control-block {
98
+ border-top: 1px solid var(--n-line);
99
+ padding-top: 0.85rem;
100
+ }
101
+
102
+ .control-heading {
103
+ align-items: center;
104
+ display: flex;
105
+ font-size: 0.78rem;
106
+ font-weight: 850;
107
+ gap: 0.7rem;
108
+ justify-content: space-between;
109
+ }
110
+
111
+ .control-note {
112
+ color: var(--n-muted);
113
+ font-size: 0.68rem;
114
+ font-weight: 650;
115
+ text-align: right;
116
+ }
117
+
118
+ .profile-chips,
119
+ .unit-switch {
120
+ display: flex;
121
+ gap: 0.4rem;
122
+ }
123
+
124
+ .profile-chip,
125
+ .unit-button,
126
+ .reset-button {
127
+ appearance: none;
128
+ border: 1px solid var(--n-line);
129
+ color: var(--n-ink);
130
+ cursor: pointer;
131
+ font: inherit;
132
+ }
133
+
134
+ .profile-chip {
135
+ align-items: center;
136
+ background: var(--n-surface-soft);
137
+ border-radius: 0.65rem;
138
+ display: flex;
139
+ flex: 1;
140
+ font-size: 0.78rem;
141
+ gap: 0.45rem;
142
+ justify-content: center;
143
+ min-height: 2.45rem;
144
+ padding: 0.45rem;
145
+ }
146
+
147
+ .profile-chip.is-active {
148
+ background: var(--n-accent);
149
+ border-color: var(--n-accent);
150
+ color: var(--n-on-accent);
151
+ }
152
+
153
+ .profile-chip-mark {
154
+ align-items: center;
155
+ background: var(--n-paper);
156
+ border-radius: 0.3rem;
157
+ color: var(--n-accent-strong);
158
+ display: inline-flex;
159
+ font-size: 0.65rem;
160
+ font-weight: 900;
161
+ height: 1.25rem;
162
+ justify-content: center;
163
+ width: 1.25rem;
164
+ }
165
+
166
+ .unit-switch {
167
+ background: var(--n-surface-soft);
168
+ border: 1px solid var(--n-line);
169
+ border-radius: 0.5rem;
170
+ padding: 0.16rem;
171
+ }
172
+
173
+ .unit-button {
174
+ background: transparent;
175
+ border-color: transparent;
176
+ border-radius: 0.32rem;
177
+ color: var(--n-ink);
178
+ font-size: 0.68rem;
179
+ font-weight: 850;
180
+ min-width: 4.1rem;
181
+ padding: 0.36rem 0.5rem;
182
+ }
183
+
184
+ .unit-button.is-active {
185
+ background: var(--n-accent);
186
+ border-color: var(--n-accent);
187
+ color: var(--n-on-accent);
188
+ }
189
+
190
+ .control-grid {
191
+ display: grid;
192
+ gap: 0.65rem;
193
+ grid-template-columns: repeat(2, minmax(0, 1fr));
194
+ }
195
+
196
+ .input-field,
197
+ .gear-input {
198
+ color: var(--n-muted);
199
+ display: grid;
200
+ font-size: 0.67rem;
201
+ font-weight: 750;
202
+ gap: 0.28rem;
203
+ }
204
+
205
+ .input-with-unit {
206
+ align-items: center;
207
+ background: var(--n-surface-soft);
208
+ border: 1px solid var(--n-line);
209
+ border-radius: 0.55rem;
210
+ display: flex;
211
+ min-height: 2.45rem;
212
+ overflow: hidden;
213
+ }
214
+
215
+ .input-with-unit input,
216
+ .gear-input input {
217
+ background: transparent;
218
+ border: 0;
219
+ color: var(--n-ink);
220
+ font: inherit;
221
+ min-width: 0;
222
+ outline: 0;
223
+ padding: 0.55rem;
224
+ width: 100%;
225
+ }
226
+
227
+ .input-with-unit:focus-within,
228
+ .gear-input:focus-within {
229
+ border-color: var(--n-accent);
230
+ box-shadow: 0 0 0 3px var(--n-accent-soft);
231
+ }
232
+
233
+ .input-with-unit b {
234
+ color: var(--n-accent-strong);
235
+ font-size: 0.62rem;
236
+ padding-right: 0.5rem;
237
+ white-space: nowrap;
238
+ }
239
+
240
+ .gear-input-grid {
241
+ display: grid;
242
+ gap: 0.45rem;
243
+ grid-template-columns: repeat(3, minmax(0, 1fr));
244
+ }
245
+
246
+ .gear-input {
247
+ background: var(--n-surface-soft);
248
+ border: 1px solid var(--n-line);
249
+ border-radius: 0.55rem;
250
+ gap: 0;
251
+ overflow: hidden;
252
+ }
253
+
254
+ .gear-input span {
255
+ border-bottom: 1px solid var(--n-line);
256
+ color: var(--n-accent-strong);
257
+ font-size: 0.6rem;
258
+ padding: 0.3rem 0.45rem;
259
+ }
260
+
261
+ .reset-button {
262
+ background: transparent;
263
+ border-radius: 0.55rem;
264
+ color: var(--n-muted);
265
+ font-size: 0.68rem;
266
+ justify-self: start;
267
+ padding: 0.45rem 0.6rem;
268
+ }
269
+
270
+ .gear-visual {
271
+ display: grid;
272
+ gap: 0.85rem;
273
+ padding: 0.9rem;
274
+ }
275
+
276
+ .gear-results {
277
+ border-top: 1px solid var(--n-line);
278
+ display: grid;
279
+ gap: 0.85rem;
280
+ padding-top: 1rem;
281
+ }
282
+
283
+ .transmission-scene {
284
+ background: var(--n-surface-soft);
285
+ border: 1px solid var(--n-line);
286
+ border-radius: 0.85rem;
287
+ overflow: hidden;
288
+ }
289
+
290
+ .scene-svg {
291
+ display: block;
292
+ height: auto;
293
+ width: 100%;
294
+ }
295
+
296
+ .scene-svg text {
297
+ fill: var(--n-muted);
298
+ font-size: 13px;
299
+ font-weight: 800;
300
+ letter-spacing: 0.08em;
301
+ text-transform: uppercase;
302
+ }
303
+
304
+ .scene-road {
305
+ fill: none;
306
+ stroke: var(--n-line);
307
+ stroke-width: 8;
308
+ }
309
+
310
+ .scene-shaft,
311
+ .scene-final-drive {
312
+ fill: none;
313
+ stroke: var(--n-accent);
314
+ stroke-linecap: round;
315
+ stroke-width: 13;
316
+ }
317
+
318
+ .scene-shaft {
319
+ animation: shaft-flow var(--engine-duration, 3s) linear infinite;
320
+ stroke-dasharray: 2 22;
321
+ }
322
+
323
+ .scene-engine {
324
+ fill: var(--n-warm-soft);
325
+ stroke: var(--n-warm);
326
+ stroke-width: 8;
327
+ }
328
+
329
+ .scene-engine-core,
330
+ .scene-gear {
331
+ fill: var(--n-accent-soft);
332
+ stroke: var(--n-accent);
333
+ stroke-width: 7;
334
+ }
335
+
336
+ .scene-gear {
337
+ stroke-dasharray: 2 15;
338
+ transform-box: fill-box;
339
+ transform-origin: center;
340
+ }
341
+
342
+ .scene-gear-large {
343
+ animation: gear-turn var(--engine-duration, 3s) linear infinite;
344
+ }
345
+
346
+ .scene-gear-mid {
347
+ animation: gear-turn-reverse var(--engine-duration, 3s) linear infinite;
348
+ }
349
+
350
+ .scene-gear-small {
351
+ animation: gear-turn var(--engine-duration, 3s) linear infinite;
352
+ }
353
+
354
+ .scene-wheel {
355
+ animation: wheel-turn var(--wheel-duration, 2.8s) linear infinite;
356
+ fill: var(--n-surface);
357
+ stroke: var(--n-warm);
358
+ stroke-width: 12;
359
+ transform-box: fill-box;
360
+ transform-origin: center;
361
+ }
362
+
363
+ .scene-wheel-inner,
364
+ .scene-spoke {
365
+ fill: none;
366
+ stroke: var(--n-warm);
367
+ stroke-width: 4;
368
+ }
369
+
370
+ .scene-readout {
371
+ border-top: 1px solid var(--n-line);
372
+ padding: 0.7rem 0.9rem 0.8rem;
373
+ }
374
+
375
+ .scene-readout-row {
376
+ display: grid;
377
+ gap: 0.6rem;
378
+ grid-template-columns: repeat(3, 1fr);
379
+ margin-top: 0.35rem;
380
+ }
381
+
382
+ .scene-readout-row span {
383
+ color: var(--n-muted);
384
+ display: grid;
385
+ font-size: 0.63rem;
386
+ gap: 0.15rem;
387
+ }
388
+
389
+ .scene-readout-row b {
390
+ color: var(--n-ink);
391
+ font-size: 0.82rem;
392
+ }
393
+
394
+ .motion-hint {
395
+ border-top: 1px solid var(--n-line);
396
+ color: var(--n-muted);
397
+ display: flex;
398
+ font-size: 0.65rem;
399
+ gap: 0.5rem;
400
+ line-height: 1.4;
401
+ padding: 0.6rem 0.9rem 0.7rem;
402
+ }
403
+
404
+ .motion-hint strong {
405
+ color: var(--n-accent-strong);
406
+ white-space: nowrap;
407
+ }
408
+
409
+ .results-head {
410
+ align-items: end;
411
+ display: flex;
412
+ gap: 0.75rem;
413
+ justify-content: space-between;
414
+ }
415
+
416
+ .results-head strong {
417
+ display: block;
418
+ font-size: clamp(2.2rem, 5vw, 3.7rem);
419
+ letter-spacing: -0.06em;
420
+ line-height: 0.98;
421
+ margin-top: 0.25rem;
422
+ }
423
+
424
+ .results-context {
425
+ color: var(--n-muted);
426
+ display: block;
427
+ font-size: 0.72rem;
428
+ margin-top: 0.35rem;
429
+ }
430
+
431
+ .status-badge {
432
+ border-radius: 999px;
433
+ font-size: 0.65rem;
434
+ font-weight: 850;
435
+ padding: 0.4rem 0.6rem;
436
+ white-space: nowrap;
437
+ }
438
+
439
+ .status-normal {
440
+ background: var(--n-accent-soft);
441
+ color: var(--n-accent-strong);
442
+ }
443
+
444
+ .status-warning {
445
+ background: var(--n-warm-soft);
446
+ color: var(--n-warm);
447
+ }
448
+
449
+ .status-critical {
450
+ background: var(--n-danger-soft);
451
+ color: var(--n-danger);
452
+ }
453
+
454
+ .answer-card {
455
+ background: var(--n-accent-soft);
456
+ border-left: 4px solid var(--n-accent);
457
+ border-radius: 0.75rem;
458
+ display: grid;
459
+ gap: 0.6rem;
460
+ padding: 0.8rem 0.9rem;
461
+ }
462
+
463
+ .answer-grid {
464
+ display: grid;
465
+ gap: 0.7rem;
466
+ grid-template-columns: repeat(2, minmax(0, 1fr));
467
+ }
468
+
469
+ .answer-primary,
470
+ .answer-secondary {
471
+ display: grid;
472
+ gap: 0.15rem;
473
+ }
474
+
475
+ .answer-primary span,
476
+ .answer-secondary span {
477
+ color: var(--n-muted);
478
+ font-size: 0.65rem;
479
+ }
480
+
481
+ .answer-primary strong,
482
+ .answer-secondary strong {
483
+ color: var(--n-ink);
484
+ font-size: 1.35rem;
485
+ letter-spacing: -0.03em;
486
+ }
487
+
488
+ .answer-primary strong small,
489
+ .answer-secondary strong small {
490
+ font-size: 0.7rem;
491
+ letter-spacing: 0;
492
+ }
493
+
494
+ .answer-primary b,
495
+ .answer-secondary b {
496
+ color: var(--n-accent-strong);
497
+ font-size: 0.68rem;
498
+ }
499
+
500
+ .answer-card p {
501
+ border-top: 1px solid var(--n-line);
502
+ color: var(--n-muted);
503
+ font-size: 0.68rem;
504
+ line-height: 1.4;
505
+ margin: 0;
506
+ padding-top: 0.55rem;
507
+ }
508
+
509
+ .ladder-heading {
510
+ align-items: baseline;
511
+ display: flex;
512
+ gap: 0.6rem;
513
+ justify-content: space-between;
514
+ }
515
+
516
+ .ladder-heading > span {
517
+ color: var(--n-ink);
518
+ font-size: 0.75rem;
519
+ font-weight: 850;
520
+ }
521
+
522
+ .ladder-heading small {
523
+ color: var(--n-muted);
524
+ font-size: 0.63rem;
525
+ text-align: right;
526
+ }
527
+
528
+ .gear-result-list {
529
+ display: grid;
530
+ gap: 0.35rem;
531
+ }
532
+
533
+ .gear-row {
534
+ align-items: center;
535
+ background: var(--n-surface-soft);
536
+ border: 1px solid transparent;
537
+ border-radius: 0.55rem;
538
+ color: var(--n-muted);
539
+ display: grid;
540
+ font-size: 0.68rem;
541
+ gap: 0.6rem;
542
+ grid-template-columns: 4.3rem 1fr auto auto;
543
+ padding: 0.55rem 0.65rem;
544
+ }
545
+
546
+ .gear-row-active {
547
+ border-color: var(--n-accent);
548
+ box-shadow: inset 3px 0 0 var(--n-accent);
549
+ }
550
+
551
+ .gear-number {
552
+ color: var(--n-accent-strong);
553
+ font-weight: 850;
554
+ }
555
+
556
+ .gear-speed,
557
+ .gear-rpm {
558
+ text-align: right;
559
+ white-space: nowrap;
560
+ }
561
+
562
+ .gear-row b {
563
+ color: var(--n-ink);
564
+ }
565
+
566
+ .educational-notice {
567
+ border-top: 1px solid var(--n-line);
568
+ font-size: 0.72rem;
569
+ padding-top: 0.75rem;
570
+ }
571
+
572
+ @keyframes wheel-turn {
573
+ from { transform: rotate(0deg); }
574
+ to { transform: rotate(360deg); }
575
+ }
576
+
577
+ @keyframes gear-turn {
578
+ from { transform: rotate(0deg); }
579
+ to { transform: rotate(360deg); }
580
+ }
581
+
582
+ @keyframes gear-turn-reverse {
583
+ from { transform: rotate(360deg); }
584
+ to { transform: rotate(0deg); }
585
+ }
586
+
587
+ @keyframes shaft-flow {
588
+ from { stroke-dashoffset: 0; }
589
+ to { stroke-dashoffset: -48; }
590
+ }
591
+
592
+ @media (max-width: 860px) {
593
+ .gear-layout {
594
+ grid-template-columns: 1fr;
595
+ }
596
+
597
+ .gear-controls,
598
+ .gear-visual {
599
+ padding: 0.8rem;
600
+ }
601
+ }
602
+
603
+ @media (max-width: 520px) {
604
+ .gear-tool {
605
+ border-radius: 1rem;
606
+ padding: 0.75rem;
607
+ }
608
+
609
+ .gear-layout,
610
+ .gear-results {
611
+ gap: 0.75rem;
612
+ }
613
+
614
+ .gear-results {
615
+ padding-top: 0.85rem;
616
+ }
617
+
618
+ .control-grid {
619
+ grid-template-columns: 1fr;
620
+ }
621
+
622
+ .gear-input-grid {
623
+ grid-template-columns: repeat(2, minmax(0, 1fr));
624
+ }
625
+
626
+ .results-head {
627
+ align-items: start;
628
+ display: grid;
629
+ gap: 0.4rem;
630
+ }
631
+
632
+ .status-badge {
633
+ justify-self: start;
634
+ }
635
+
636
+ .results-head strong {
637
+ font-size: 2.45rem;
638
+ }
639
+
640
+ .answer-grid {
641
+ grid-template-columns: 1fr;
642
+ }
643
+
644
+ .ladder-heading {
645
+ align-items: start;
646
+ flex-direction: column;
647
+ gap: 0.2rem;
648
+ }
649
+
650
+ .ladder-heading small {
651
+ text-align: left;
652
+ }
653
+
654
+ .gear-row {
655
+ gap: 0.35rem;
656
+ grid-template-columns: 3.7rem minmax(0, 1fr) auto;
657
+ }
658
+
659
+ .gear-rpm {
660
+ grid-column: 3;
661
+ grid-row: 1;
662
+ }
663
+
664
+ .motion-hint {
665
+ display: grid;
666
+ gap: 0.2rem;
667
+ }
668
+ }