@jjlmoya/utils-science 1.38.0 → 1.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +5 -1
  4. package/src/index.ts +2 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/conway-life-rule-lab/bibliography.astro +14 -0
  8. package/src/tool/conway-life-rule-lab/bibliography.ts +16 -0
  9. package/src/tool/conway-life-rule-lab/component.astro +132 -0
  10. package/src/tool/conway-life-rule-lab/conway-life-rule-lab.css +603 -0
  11. package/src/tool/conway-life-rule-lab/entry.ts +26 -0
  12. package/src/tool/conway-life-rule-lab/i18n/de.ts +50 -0
  13. package/src/tool/conway-life-rule-lab/i18n/en.ts +174 -0
  14. package/src/tool/conway-life-rule-lab/i18n/es.ts +50 -0
  15. package/src/tool/conway-life-rule-lab/i18n/fr.ts +50 -0
  16. package/src/tool/conway-life-rule-lab/i18n/id.ts +50 -0
  17. package/src/tool/conway-life-rule-lab/i18n/it.ts +50 -0
  18. package/src/tool/conway-life-rule-lab/i18n/ja.ts +50 -0
  19. package/src/tool/conway-life-rule-lab/i18n/ko.ts +50 -0
  20. package/src/tool/conway-life-rule-lab/i18n/nl.ts +50 -0
  21. package/src/tool/conway-life-rule-lab/i18n/pl.ts +50 -0
  22. package/src/tool/conway-life-rule-lab/i18n/pt.ts +50 -0
  23. package/src/tool/conway-life-rule-lab/i18n/ru.ts +50 -0
  24. package/src/tool/conway-life-rule-lab/i18n/sv.ts +50 -0
  25. package/src/tool/conway-life-rule-lab/i18n/tr.ts +50 -0
  26. package/src/tool/conway-life-rule-lab/i18n/zh.ts +50 -0
  27. package/src/tool/conway-life-rule-lab/index.ts +11 -0
  28. package/src/tool/conway-life-rule-lab/logic/LifeAchievements.ts +85 -0
  29. package/src/tool/conway-life-rule-lab/logic/LifeCanvasRenderer.ts +104 -0
  30. package/src/tool/conway-life-rule-lab/logic/LifeLabDom.ts +55 -0
  31. package/src/tool/conway-life-rule-lab/logic/LifeLabRuntime.ts +253 -0
  32. package/src/tool/conway-life-rule-lab/logic/LifePatterns.ts +35 -0
  33. package/src/tool/conway-life-rule-lab/logic/LifeRules.ts +60 -0
  34. package/src/tool/conway-life-rule-lab/logic/LifeUniverse.ts +165 -0
  35. package/src/tool/conway-life-rule-lab/logic.ts +6 -0
  36. package/src/tool/conway-life-rule-lab/seo.astro +15 -0
  37. package/src/tool/crystal-lattice-structure-finder/bibliography.astro +14 -0
  38. package/src/tool/crystal-lattice-structure-finder/bibliography.ts +20 -0
  39. package/src/tool/crystal-lattice-structure-finder/component.astro +366 -0
  40. package/src/tool/crystal-lattice-structure-finder/crystal-lattice-structure-finder.css +387 -0
  41. package/src/tool/crystal-lattice-structure-finder/data.ts +220 -0
  42. package/src/tool/crystal-lattice-structure-finder/entry.ts +26 -0
  43. package/src/tool/crystal-lattice-structure-finder/i18n/de.ts +218 -0
  44. package/src/tool/crystal-lattice-structure-finder/i18n/en.ts +218 -0
  45. package/src/tool/crystal-lattice-structure-finder/i18n/es.ts +218 -0
  46. package/src/tool/crystal-lattice-structure-finder/i18n/fr.ts +218 -0
  47. package/src/tool/crystal-lattice-structure-finder/i18n/id.ts +218 -0
  48. package/src/tool/crystal-lattice-structure-finder/i18n/it.ts +218 -0
  49. package/src/tool/crystal-lattice-structure-finder/i18n/ja.ts +218 -0
  50. package/src/tool/crystal-lattice-structure-finder/i18n/ko.ts +218 -0
  51. package/src/tool/crystal-lattice-structure-finder/i18n/nl.ts +218 -0
  52. package/src/tool/crystal-lattice-structure-finder/i18n/pl.ts +218 -0
  53. package/src/tool/crystal-lattice-structure-finder/i18n/pt.ts +218 -0
  54. package/src/tool/crystal-lattice-structure-finder/i18n/ru.ts +218 -0
  55. package/src/tool/crystal-lattice-structure-finder/i18n/sv.ts +218 -0
  56. package/src/tool/crystal-lattice-structure-finder/i18n/tr.ts +218 -0
  57. package/src/tool/crystal-lattice-structure-finder/i18n/zh.ts +218 -0
  58. package/src/tool/crystal-lattice-structure-finder/index.ts +11 -0
  59. package/src/tool/crystal-lattice-structure-finder/logic.ts +39 -0
  60. package/src/tool/crystal-lattice-structure-finder/seo.astro +15 -0
  61. package/src/tools.ts +4 -0
@@ -0,0 +1,603 @@
1
+ :root {
2
+ --life-bg: #eef3ed;
3
+ --life-panel: rgba(255, 255, 255, 0.88);
4
+ --life-ink: #132019;
5
+ --life-muted: #657469;
6
+ --life-line: rgba(19, 32, 25, 0.13);
7
+ --life-board: #dfe7dd;
8
+ --life-board-canvas: #dfe7dd;
9
+ --life-grid-canvas: rgba(35, 55, 43, 0.08);
10
+ --life-cell: #0f5f45;
11
+ --life-cell-low: #1f684d;
12
+ --life-cell-high: #092f24;
13
+ --life-warm: #f0b35b;
14
+ --life-accent: #2aa876;
15
+ --life-danger: #d95757;
16
+ --life-shadow: rgba(8, 24, 16, 0.18);
17
+ --life-board-inset: 34px;
18
+ --life-glass: rgba(247, 251, 246, 0.56);
19
+ --life-glass-line: rgba(19, 32, 25, 0.12);
20
+ }
21
+
22
+ .theme-dark,
23
+ :root.theme-dark,
24
+ [data-theme="dark"] {
25
+ --life-bg: #080d0a;
26
+ --life-panel: rgba(15, 25, 19, 0.88);
27
+ --life-ink: #f0fff4;
28
+ --life-muted: #9db1a4;
29
+ --life-line: rgba(240, 255, 244, 0.12);
30
+ --life-board: #030704;
31
+ --life-board-canvas: #030704;
32
+ --life-grid-canvas: rgba(166, 255, 197, 0.07);
33
+ --life-cell: #a1ffbd;
34
+ --life-cell-low: #8af0ac;
35
+ --life-cell-high: #d8ffd8;
36
+ --life-warm: #ffc46b;
37
+ --life-accent: #50d89b;
38
+ --life-danger: #ff7474;
39
+ --life-shadow: rgba(0, 0, 0, 0.42);
40
+ --life-glass: rgba(3, 7, 4, 0.5);
41
+ --life-glass-line: rgba(161, 255, 189, 0.14);
42
+ }
43
+
44
+ .theme-dark .life-lab-root,
45
+ :root.theme-dark .life-lab-root,
46
+ [data-theme="dark"] .life-lab-root {
47
+ --life-bg: #080d0a;
48
+ --life-panel: rgba(15, 25, 19, 0.88);
49
+ --life-ink: #f0fff4;
50
+ --life-muted: #9db1a4;
51
+ --life-line: rgba(240, 255, 244, 0.12);
52
+ --life-board: #0b0f12;
53
+ --life-board-canvas: #0b0f12;
54
+ --life-grid-canvas: rgba(255, 255, 255, 0.03);
55
+ --life-cell-low: #50d89b;
56
+ --life-cell-high: #b7ffd0;
57
+ --life-accent: #50d89b;
58
+ --life-shadow: rgba(0, 0, 0, 0.42);
59
+ --life-glass: rgba(6, 10, 12, 0.58);
60
+ --life-glass-line: rgba(161, 255, 189, 0.14);
61
+ }
62
+
63
+ .life-lab-root {
64
+ display: grid;
65
+ gap: 1rem;
66
+ max-width: 1180px;
67
+ margin: 0 auto;
68
+ padding: 0.75rem;
69
+ color: var(--life-ink);
70
+ background:
71
+ linear-gradient(135deg, color-mix(in srgb, var(--life-accent) 13%, transparent), transparent 38%),
72
+ linear-gradient(315deg, color-mix(in srgb, var(--life-warm) 16%, transparent), transparent 40%),
73
+ var(--life-bg);
74
+ border: 1px solid var(--life-line);
75
+ border-radius: 8px;
76
+ }
77
+
78
+ .life-lab-board-shell {
79
+ position: relative;
80
+ min-height: 430px;
81
+ overflow: hidden;
82
+ background: var(--life-board);
83
+ border: 1px solid color-mix(in srgb, var(--life-accent) 22%, var(--life-line));
84
+ border-radius: 8px;
85
+ box-shadow: 0 28px 80px var(--life-shadow);
86
+ }
87
+
88
+ .life-lab-canvas {
89
+ display: block;
90
+ width: 100%;
91
+ height: 100%;
92
+ min-height: 430px;
93
+ cursor: crosshair;
94
+ touch-action: manipulation;
95
+ }
96
+
97
+ .life-lab-editing .life-lab-canvas {
98
+ cursor: cell;
99
+ }
100
+
101
+ .life-lab-board-toolbar,
102
+ .life-lab-signal {
103
+ position: absolute;
104
+ z-index: 2;
105
+ display: flex;
106
+ gap: 0.18rem;
107
+ align-items: center;
108
+ background: var(--life-glass);
109
+ border: 1px solid var(--life-glass-line);
110
+ border-radius: 999px;
111
+ backdrop-filter: blur(18px);
112
+ }
113
+
114
+ .life-lab-board-toolbar {
115
+ top: 0.8rem;
116
+ left: 50%;
117
+ padding: 0.22rem;
118
+ transform: translateX(-50%);
119
+ }
120
+
121
+ .life-lab-signal {
122
+ left: 50%;
123
+ bottom: 0.8rem;
124
+ justify-content: center;
125
+ padding: 0.45rem 0.75rem;
126
+ color: var(--life-ink);
127
+ transform: translateX(-50%);
128
+ }
129
+
130
+ .life-lab-signal span,
131
+ .life-lab-readout span,
132
+ .life-lab-control span {
133
+ font-size: 0.66rem;
134
+ font-weight: 800;
135
+ letter-spacing: 0.1em;
136
+ text-transform: uppercase;
137
+ }
138
+
139
+ .life-lab-signal span {
140
+ color: var(--life-muted);
141
+ }
142
+
143
+ .life-lab-signal strong {
144
+ font-size: clamp(1rem, 4.5vw, 1.45rem);
145
+ font-weight: 500;
146
+ letter-spacing: 0;
147
+ }
148
+
149
+ .life-lab-sr-only {
150
+ position: absolute;
151
+ width: 1px;
152
+ height: 1px;
153
+ padding: 0;
154
+ margin: -1px;
155
+ overflow: hidden;
156
+ clip-path: inset(50%);
157
+ white-space: nowrap;
158
+ border: 0;
159
+ }
160
+
161
+ .life-lab-icon-button {
162
+ position: relative;
163
+ display: grid;
164
+ place-items: center;
165
+ width: 38px;
166
+ height: 38px;
167
+ color: var(--life-ink);
168
+ background: transparent;
169
+ border: 0;
170
+ border-radius: 50%;
171
+ cursor: pointer;
172
+ opacity: 0.72;
173
+ transition:
174
+ background 160ms ease,
175
+ color 160ms ease,
176
+ opacity 160ms ease;
177
+ }
178
+
179
+ .life-lab-icon-button:hover,
180
+ .life-lab-icon-button:focus-visible,
181
+ .life-lab-icon-button.life-lab-running {
182
+ opacity: 1;
183
+ background: color-mix(in srgb, var(--life-accent) 14%, transparent);
184
+ }
185
+
186
+ .life-lab-icon {
187
+ position: relative;
188
+ display: block;
189
+ width: 18px;
190
+ height: 18px;
191
+ }
192
+
193
+ .life-lab-icon-play::before {
194
+ position: absolute;
195
+ top: 3px;
196
+ left: 5px;
197
+ width: 0;
198
+ height: 0;
199
+ content: "";
200
+ border-top: 6px solid transparent;
201
+ border-bottom: 6px solid transparent;
202
+ border-left: 9px solid currentcolor;
203
+ transition:
204
+ left 160ms ease,
205
+ width 160ms ease,
206
+ height 160ms ease,
207
+ border 160ms ease,
208
+ background 160ms ease;
209
+ }
210
+
211
+ .life-lab-paused-icon .life-lab-icon-play::before,
212
+ .life-lab-paused-icon .life-lab-icon-play::after {
213
+ position: absolute;
214
+ top: 3px;
215
+ width: 1.5px;
216
+ height: 12px;
217
+ content: "";
218
+ background: currentcolor;
219
+ border: 0;
220
+ transition:
221
+ left 160ms ease,
222
+ background 160ms ease,
223
+ opacity 160ms ease;
224
+ }
225
+
226
+ .life-lab-paused-icon .life-lab-icon-play::before {
227
+ left: 6px;
228
+ }
229
+
230
+ .life-lab-paused-icon .life-lab-icon-play::after {
231
+ left: 11px;
232
+ }
233
+
234
+ .life-lab-icon-step::before,
235
+ .life-lab-icon-step::after {
236
+ position: absolute;
237
+ content: "";
238
+ }
239
+
240
+ .life-lab-icon-step::before {
241
+ top: 5px;
242
+ left: 3px;
243
+ width: 8px;
244
+ height: 8px;
245
+ border-top: 1.5px solid currentcolor;
246
+ border-right: 1.5px solid currentcolor;
247
+ transform: rotate(45deg);
248
+ }
249
+
250
+ .life-lab-icon-step::after {
251
+ top: 3px;
252
+ right: 3px;
253
+ width: 1.5px;
254
+ height: 12px;
255
+ background: currentcolor;
256
+ }
257
+
258
+ .life-lab-icon-clear::before,
259
+ .life-lab-icon-clear::after {
260
+ position: absolute;
261
+ top: 8px;
262
+ left: 3px;
263
+ width: 12px;
264
+ height: 1.5px;
265
+ content: "";
266
+ background: currentcolor;
267
+ }
268
+
269
+ .life-lab-icon-clear::before {
270
+ transform: rotate(45deg);
271
+ }
272
+
273
+ .life-lab-icon-clear::after {
274
+ transform: rotate(-45deg);
275
+ }
276
+
277
+ .life-lab-console {
278
+ display: grid;
279
+ gap: 1.25rem;
280
+ padding: 1.15rem;
281
+ background: var(--life-panel);
282
+ border: 1px solid var(--life-line);
283
+ border-radius: 8px;
284
+ backdrop-filter: blur(14px);
285
+ }
286
+
287
+ .life-lab-readouts {
288
+ display: grid;
289
+ grid-template-columns: repeat(2, minmax(0, 1fr));
290
+ gap: 1rem 1.25rem;
291
+ padding-bottom: 0.25rem;
292
+ }
293
+
294
+ .life-lab-readout {
295
+ min-height: 64px;
296
+ padding: 0;
297
+ background: transparent;
298
+ border: 0;
299
+ border-radius: 0;
300
+ }
301
+
302
+ .life-lab-readout span,
303
+ .life-lab-control span {
304
+ color: var(--life-muted);
305
+ }
306
+
307
+ .life-lab-readout strong {
308
+ display: block;
309
+ margin-top: 0.25rem;
310
+ font-size: clamp(1.55rem, 7vw, 2.25rem);
311
+ font-weight: 430;
312
+ line-height: 1;
313
+ white-space: nowrap;
314
+ overflow-wrap: anywhere;
315
+ }
316
+
317
+ .life-lab-readout-main {
318
+ grid-column: 1 / -1;
319
+ min-height: 132px;
320
+ padding-bottom: 1rem;
321
+ border-bottom: 1px solid var(--life-line);
322
+ background: transparent;
323
+ }
324
+
325
+ .life-lab-readout-main strong {
326
+ margin-top: 0.2rem;
327
+ font-size: clamp(5rem, 30vw, 8.5rem);
328
+ font-weight: 360;
329
+ letter-spacing: -0.05em;
330
+ }
331
+
332
+ .life-lab-achievements {
333
+ display: grid;
334
+ gap: 0.65rem;
335
+ padding: 0.2rem 0 0.4rem;
336
+ border-bottom: 1px solid var(--life-line);
337
+ }
338
+
339
+ .life-lab-achievements-label {
340
+ color: var(--life-muted);
341
+ font-size: 0.66rem;
342
+ font-weight: 800;
343
+ letter-spacing: 0.1em;
344
+ text-transform: uppercase;
345
+ }
346
+
347
+ .life-lab-achievement {
348
+ display: grid;
349
+ grid-template-columns: minmax(74px, 0.35fr) minmax(0, 0.65fr);
350
+ gap: 0.65rem;
351
+ align-items: baseline;
352
+ color: var(--life-muted);
353
+ opacity: 0.46;
354
+ }
355
+
356
+ .life-lab-achievement strong {
357
+ color: inherit;
358
+ font-size: 1rem;
359
+ font-weight: 500;
360
+ white-space: nowrap;
361
+ }
362
+
363
+ .life-lab-achievement span {
364
+ font-size: 0.72rem;
365
+ line-height: 1.25;
366
+ }
367
+
368
+ .life-lab-achievement-active {
369
+ color: var(--life-ink);
370
+ opacity: 1;
371
+ }
372
+
373
+ .life-lab-achievement-active strong {
374
+ color: var(--life-accent);
375
+ }
376
+
377
+ .life-lab-rule-deck {
378
+ display: grid;
379
+ grid-template-columns: 1fr;
380
+ gap: 0.15rem;
381
+ padding: 0.15rem 0;
382
+ overflow: visible;
383
+ border: 0;
384
+ border-top: 1px solid var(--life-line);
385
+ border-bottom: 1px solid var(--life-line);
386
+ border-radius: 0;
387
+ }
388
+
389
+ .life-lab-rule-preset,
390
+ .life-lab-command {
391
+ min-height: 42px;
392
+ color: var(--life-ink);
393
+ background: transparent;
394
+ border: 0;
395
+ font-weight: 780;
396
+ cursor: pointer;
397
+ }
398
+
399
+ .life-lab-rule-preset {
400
+ min-height: 38px;
401
+ padding: 0.55rem 0.15rem;
402
+ color: var(--life-muted);
403
+ border-bottom: 0;
404
+ font-size: 0.72rem;
405
+ letter-spacing: 0.08em;
406
+ text-transform: uppercase;
407
+ }
408
+
409
+ .life-lab-rule-preset:hover,
410
+ .life-lab-rule-preset.active {
411
+ color: var(--life-ink);
412
+ background: transparent;
413
+ box-shadow: inset 0 -1px 0 var(--life-accent);
414
+ }
415
+
416
+ .life-lab-controls {
417
+ display: grid;
418
+ gap: 0.85rem;
419
+ }
420
+
421
+ .life-lab-control {
422
+ display: grid;
423
+ gap: 0.42rem;
424
+ }
425
+
426
+ .life-lab-control input,
427
+ .life-lab-control select {
428
+ width: 100%;
429
+ min-height: 42px;
430
+ color: var(--life-ink);
431
+ background: transparent;
432
+ border: 1px solid var(--life-line);
433
+ border-radius: 6px;
434
+ }
435
+
436
+ .life-lab-control input[type="text"],
437
+ .life-lab-control select {
438
+ padding: 0 0.75rem;
439
+ font-size: 1rem;
440
+ }
441
+
442
+ .life-lab-select-shell {
443
+ position: relative;
444
+ display: block;
445
+ }
446
+
447
+ .life-lab-select-shell::after {
448
+ position: absolute;
449
+ top: 50%;
450
+ right: 0.85rem;
451
+ width: 0.52rem;
452
+ height: 0.52rem;
453
+ content: "";
454
+ border-right: 1.5px solid var(--life-muted);
455
+ border-bottom: 1.5px solid var(--life-muted);
456
+ transform: translateY(-68%) rotate(45deg);
457
+ pointer-events: none;
458
+ }
459
+
460
+ .life-lab-control select {
461
+ -webkit-appearance: none;
462
+ -moz-appearance: none;
463
+ appearance: none;
464
+ padding-right: 2.15rem;
465
+ }
466
+
467
+ .life-lab-control select option {
468
+ color: #132019;
469
+ background: #f7fbf6;
470
+ }
471
+
472
+ .theme-dark .life-lab-control select option,
473
+ :root.theme-dark .life-lab-control select option,
474
+ [data-theme="dark"] .life-lab-control select option {
475
+ color: #f0fff4;
476
+ background: #0b0f12;
477
+ }
478
+
479
+ .life-lab-control input[type="range"] {
480
+ -webkit-appearance: none;
481
+ appearance: none;
482
+ border: 0;
483
+ cursor: pointer;
484
+ }
485
+
486
+ .life-lab-control input[type="range"]::-webkit-slider-runnable-track {
487
+ height: 2px;
488
+ background: color-mix(in srgb, var(--life-accent) 28%, var(--life-line));
489
+ border-radius: 999px;
490
+ }
491
+
492
+ .life-lab-control input[type="range"]::-moz-range-track {
493
+ height: 2px;
494
+ background: color-mix(in srgb, var(--life-accent) 28%, var(--life-line));
495
+ border-radius: 999px;
496
+ }
497
+
498
+ .life-lab-control input[type="range"]::-webkit-slider-thumb {
499
+ -webkit-appearance: none;
500
+ appearance: none;
501
+ width: 18px;
502
+ height: 18px;
503
+ margin-top: -8px;
504
+ background: var(--life-accent);
505
+ border: 2px solid var(--life-panel);
506
+ border-radius: 50%;
507
+ }
508
+
509
+ .life-lab-control input[type="range"]::-moz-range-thumb {
510
+ width: 18px;
511
+ height: 18px;
512
+ background: var(--life-accent);
513
+ border: 2px solid var(--life-panel);
514
+ border-radius: 50%;
515
+ }
516
+
517
+ .life-lab-control input[type="range"]:hover::-webkit-slider-thumb {
518
+ background: color-mix(in srgb, var(--life-accent) 82%, var(--life-ink));
519
+ }
520
+
521
+ .life-lab-control input[type="range"]:hover::-moz-range-thumb {
522
+ background: color-mix(in srgb, var(--life-accent) 82%, var(--life-ink));
523
+ }
524
+
525
+ .life-lab-invalid {
526
+ border-color: var(--life-danger);
527
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--life-danger) 18%, transparent);
528
+ }
529
+
530
+ .life-lab-command {
531
+ padding: 0 0.9rem;
532
+ color: var(--life-ink);
533
+ background: transparent;
534
+ border: 1px solid var(--life-line);
535
+ border-radius: 6px;
536
+ }
537
+
538
+ .life-lab-controls > .life-lab-command {
539
+ align-self: end;
540
+ }
541
+
542
+ .life-lab-command:hover {
543
+ background: color-mix(in srgb, var(--life-accent) 10%, transparent);
544
+ }
545
+
546
+ .life-lab-command-warm {
547
+ color: var(--life-ink);
548
+ background: transparent;
549
+ border-color: color-mix(in srgb, var(--life-warm) 44%, var(--life-line));
550
+ }
551
+
552
+ .life-lab-console .life-lab-command {
553
+ min-height: 42px;
554
+ color: var(--life-ink);
555
+ background: transparent;
556
+ border-color: var(--life-line);
557
+ }
558
+
559
+ .life-lab-console .life-lab-command:hover {
560
+ border-color: color-mix(in srgb, var(--life-accent) 52%, var(--life-line));
561
+ }
562
+
563
+ @media (min-width: 760px) {
564
+ .life-lab-root {
565
+ grid-template-columns: minmax(0, 1.35fr) minmax(340px, 0.65fr);
566
+ padding: 1rem;
567
+ }
568
+
569
+ .life-lab-board-shell,
570
+ .life-lab-canvas {
571
+ min-height: 690px;
572
+ }
573
+
574
+ .life-lab-board-toolbar {
575
+ right: auto;
576
+ }
577
+
578
+ .life-lab-signal {
579
+ right: auto;
580
+ min-width: 240px;
581
+ }
582
+
583
+ .life-lab-readouts {
584
+ grid-template-columns: repeat(3, minmax(0, 1fr));
585
+ }
586
+
587
+ .life-lab-readout-main {
588
+ grid-column: span 3;
589
+ }
590
+
591
+ .life-lab-rule-deck {
592
+ grid-template-columns: repeat(4, 1fr);
593
+ }
594
+
595
+ .life-lab-controls {
596
+ grid-template-columns: repeat(2, minmax(0, 1fr));
597
+ align-items: end;
598
+ }
599
+
600
+ .life-lab-control-wide {
601
+ grid-column: 1 / -1;
602
+ }
603
+ }
@@ -0,0 +1,26 @@
1
+ import type { ScienceToolEntry } from '../../types';
2
+
3
+ export const conwayLifeRuleLab: ScienceToolEntry = {
4
+ id: 'conway-life-rule-lab',
5
+ icons: {
6
+ bg: 'mdi:grid',
7
+ fg: 'mdi:gamepad-variant-outline',
8
+ },
9
+ i18n: {
10
+ de: () => import('./i18n/de').then((m) => m.content),
11
+ en: () => import('./i18n/en').then((m) => m.content),
12
+ es: () => import('./i18n/es').then((m) => m.content),
13
+ fr: () => import('./i18n/fr').then((m) => m.content),
14
+ id: () => import('./i18n/id').then((m) => m.content),
15
+ it: () => import('./i18n/it').then((m) => m.content),
16
+ ja: () => import('./i18n/ja').then((m) => m.content),
17
+ ko: () => import('./i18n/ko').then((m) => m.content),
18
+ nl: () => import('./i18n/nl').then((m) => m.content),
19
+ pl: () => import('./i18n/pl').then((m) => m.content),
20
+ pt: () => import('./i18n/pt').then((m) => m.content),
21
+ ru: () => import('./i18n/ru').then((m) => m.content),
22
+ sv: () => import('./i18n/sv').then((m) => m.content),
23
+ tr: () => import('./i18n/tr').then((m) => m.content),
24
+ zh: () => import('./i18n/zh').then((m) => m.content),
25
+ },
26
+ };
@@ -0,0 +1,50 @@
1
+ import { content as enContent } from './en';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+
4
+ export const content: ToolLocaleContent = {
5
+ ...enContent,
6
+ slug: 'conway-spiel-des-lebens-regellabor',
7
+ title: 'Conway Spiel des Lebens Regellabor',
8
+ description: 'Spiele, bearbeite und vergleiche Conway-artige zelluläre Automaten mit B/S-Regeln, Mustersaaten, Live-Metriken und responsivem Simulationsfeld.',
9
+ ui: {
10
+ boardLabel: 'Feld für Life-artige zelluläre Automaten',
11
+ play: 'Start',
12
+ pause: 'Pause',
13
+ step: 'Schritt',
14
+ clear: 'Leere Leinwand',
15
+ randomize: 'Zufall',
16
+ ruleLabel: 'Regelnotation',
17
+ ruleHelp: 'Geburt / Überleben',
18
+ speedLabel: 'Tempo',
19
+ densityLabel: 'Startdichte',
20
+ patternLabel: 'Muster',
21
+ placePattern: 'Muster setzen',
22
+ generation: 'Generation',
23
+ population: 'Population',
24
+ density: 'Dichte',
25
+ stability: 'Stabilität',
26
+ births: 'Geburten',
27
+ deaths: 'Tode',
28
+ achievementsLabel: 'Laborprotokoll',
29
+ achievementPulsar: 'Pulsar',
30
+ achievementPulsarDescription: 'Oszillation mit Periode 2 erkannt',
31
+ achievementImmortal: 'Unsterblich',
32
+ achievementImmortalDescription: 'Generation 500 mit vollständiger Stabilität erreicht',
33
+ achievementBigBang: 'Big Bang',
34
+ achievementBigBangDescription: 'Eine dünne Zufallssaat überschritt 1.000 lebende Zellen',
35
+ presetClassic: 'Conway Classic',
36
+ presetHighlife: 'HighLife',
37
+ presetSeeds: 'Seeds',
38
+ presetDayNight: 'Tag und Nacht',
39
+ patternGlider: 'Gleiter',
40
+ patternGosper: 'Gosper-Kanone',
41
+ patternPulsar: 'Pulsar',
42
+ patternRPentomino: 'R-Pentomino',
43
+ colonyStatus: 'Koloniesignal',
44
+ statusFrozen: 'stabil',
45
+ statusGrowing: 'wachsend',
46
+ statusFading: 'rückläufig',
47
+ statusChaotic: 'volatil',
48
+ invalidRule: 'Verwende B/S-Notation wie B3/S23.',
49
+ },
50
+ };