@jjlmoya/utils-games-development 1.65.0 → 1.67.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 (77) hide show
  1. package/package.json +67 -67
  2. package/scripts/postinstall.mjs +27 -27
  3. package/src/category/GamesCategorySEO.astro +19 -19
  4. package/src/category/i18n/de.ts +15 -15
  5. package/src/category/i18n/en.ts +15 -15
  6. package/src/category/i18n/es.ts +15 -15
  7. package/src/category/i18n/fr.ts +15 -15
  8. package/src/category/i18n/id.ts +10 -10
  9. package/src/category/i18n/it.ts +10 -10
  10. package/src/category/i18n/ja.ts +10 -10
  11. package/src/category/i18n/ko.ts +10 -10
  12. package/src/category/i18n/nl.ts +10 -10
  13. package/src/category/i18n/pl.ts +10 -10
  14. package/src/category/i18n/pt.ts +10 -10
  15. package/src/category/i18n/ru.ts +10 -10
  16. package/src/category/i18n/sv.ts +10 -10
  17. package/src/category/i18n/tr.ts +10 -10
  18. package/src/category/i18n/zh.ts +10 -10
  19. package/src/category/seo.astro +15 -15
  20. package/src/components/PreviewNavSidebar.astro +116 -116
  21. package/src/components/PreviewToolbar.astro +143 -143
  22. package/src/data.ts +11 -11
  23. package/src/env.d.ts +5 -5
  24. package/src/index.ts +20 -20
  25. package/src/layouts/PreviewLayout.astro +122 -122
  26. package/src/pages/[locale]/[slug].astro +165 -165
  27. package/src/pages/[locale].astro +250 -250
  28. package/src/pages/index.astro +4 -4
  29. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  30. package/src/tests/category_seo_quality.test.ts +74 -0
  31. package/src/tests/diacritics_density.test.ts +118 -118
  32. package/src/tests/faq_count.test.ts +19 -19
  33. package/src/tests/i18n_coverage.test.ts +36 -36
  34. package/src/tests/inverted_punctuation.test.ts +84 -84
  35. package/src/tests/mocks/astro_mock.js +2 -2
  36. package/src/tests/no_en_dash.test.ts +70 -70
  37. package/src/tests/no_h1_in_components.test.ts +48 -48
  38. package/src/tests/pagespeed_best_practices.test.ts +198 -198
  39. package/src/tests/qa-test-helpers.ts +32 -32
  40. package/src/tests/qa_bibliography_links.test.ts +41 -41
  41. package/src/tests/qa_claim_evidence.test.ts +69 -69
  42. package/src/tests/qa_logic_reference_coverage.test.ts +46 -46
  43. package/src/tests/qa_runtime_i18n.test.ts +100 -100
  44. package/src/tests/schemas_fulfillment.test.ts +23 -23
  45. package/src/tests/script_density.test.ts +94 -94
  46. package/src/tests/seo_length.test.ts +23 -23
  47. package/src/tests/seo_wellformed_export.test.ts +65 -0
  48. package/src/tests/slug_language_code_format.test.ts +23 -23
  49. package/src/tests/slug_uniqueness.test.ts +80 -80
  50. package/src/tests/title_quality.test.ts +56 -56
  51. package/src/tool/audioLoopPointFinder/audio-loop-point-finder.css +322 -322
  52. package/src/tool/audioLoopPointFinder/client.ts +262 -262
  53. package/src/tool/damageFormulaLab/bibliography.astro +3 -21
  54. package/src/tool/damageFormulaLab/seo.astro +7 -5
  55. package/src/tool/gameDeltaTimeFixedTimestepLab/bibliography.astro +3 -19
  56. package/src/tool/hitboxHurtboxAnimator/hitbox-hurtbox-animator.css +614 -614
  57. package/src/tool/hitboxHurtboxAnimator/seo.astro +7 -5
  58. package/src/tool/saveFileEditor/component.astro +351 -351
  59. package/src/tool/saveFileEditor/game-save-file-editor.css +250 -250
  60. package/src/tool/spriteSheetPacker/app-client.ts +248 -248
  61. package/src/tool/spriteSheetPacker/bibliography.ts +12 -12
  62. package/src/tool/spriteSheetPacker/component.astro +229 -229
  63. package/src/tool/spriteSheetPacker/dropzone-client.ts +55 -55
  64. package/src/tool/spriteSheetPacker/entry.ts +28 -28
  65. package/src/tool/spriteSheetPacker/exporter.ts +116 -116
  66. package/src/tool/spriteSheetPacker/extractor-client.ts +127 -127
  67. package/src/tool/spriteSheetPacker/flipbook-client.ts +60 -60
  68. package/src/tool/spriteSheetPacker/logic.test.ts +155 -155
  69. package/src/tool/spriteSheetPacker/logic.ts +32 -32
  70. package/src/tool/spriteSheetPacker/packer-core.ts +121 -121
  71. package/src/tool/spriteSheetPacker/packer-ui.ts +86 -86
  72. package/src/tool/spriteSheetPacker/sprite-sheet-packer.css +578 -578
  73. package/src/tool/spriteSheetPacker/types.ts +89 -89
  74. package/src/tool/spriteSheetPacker/ui.ts +42 -42
  75. package/src/tool/steamCapsuleGenerator/index.ts +9 -9
  76. package/src/tool/steamCapsuleGenerator/validation.ts +14 -14
  77. package/src/types.ts +72 -72
@@ -1,614 +1,614 @@
1
- :root {
2
- --n-hha-ink: #241b31;
3
- --n-hha-muted: #6f627c;
4
- --n-hha-paper: #fffaf0;
5
- --n-hha-panel: #fff;
6
- --n-hha-stage: #15111f;
7
- --n-hha-line: #d9cbd8;
8
- --n-hha-glow: #f7dfa1;
9
- --n-hha-coral: #ff4d6d;
10
- --n-hha-mint: #2dd4bf;
11
- --n-hha-violet: #8b5cf6;
12
- --n-hha-amber: #f59e0b;
13
- --n-hha-sky: #38bdf8;
14
- --n-hha-pink: #f472b6;
15
- --n-hha-white: #fff;
16
- --n-hha-danger: #a61b3b;
17
- --n-hha-focus: #6d28d9;
18
- --n-hha-action: #241b31;
19
- --n-hha-shadow: rgba(44, 27, 55, 0.16);
20
- --n-hha-grid: rgba(255, 255, 255, 0.07);
21
- }
22
-
23
- .theme-dark {
24
- --n-hha-ink: #f8ecff;
25
- --n-hha-muted: #c8b9d1;
26
- --n-hha-paper: #18121f;
27
- --n-hha-panel: #241b2d;
28
- --n-hha-stage: #0c0911;
29
- --n-hha-line: #51425d;
30
- --n-hha-glow: #7a6023;
31
- --n-hha-white: #fff;
32
- --n-hha-danger: #ff7693;
33
- --n-hha-focus: #c4a5ff;
34
- --n-hha-action: #5b21b6;
35
- --n-hha-shadow: rgba(0, 0, 0, 0.38);
36
- --n-hha-grid: rgba(255, 255, 255, 0.08);
37
- }
38
-
39
- .hha {
40
- color: var(--n-hha-ink);
41
- background: radial-gradient(circle at 50% 20%, var(--n-hha-panel), var(--n-hha-paper) 72%);
42
- border: 1px solid var(--n-hha-line);
43
- border-radius: 1.5rem;
44
- box-shadow: 0 1.5rem 4rem var(--n-hha-shadow);
45
- overflow: hidden;
46
- }
47
-
48
- .hha button,
49
- .hha input {
50
- font: inherit;
51
- }
52
-
53
- .hha button,
54
- .hha label {
55
- -webkit-tap-highlight-color: transparent;
56
- }
57
-
58
- .hha button:focus-visible,
59
- .hha input:focus-visible,
60
- .hha:focus-visible {
61
- outline: 3px solid var(--n-hha-focus);
62
- outline-offset: 3px;
63
- }
64
-
65
- .hha-intro {
66
- display: flex;
67
- align-items: center;
68
- justify-content: space-between;
69
- gap: 1rem;
70
- padding: 1rem 1.25rem;
71
- color: var(--n-hha-ink);
72
- background: linear-gradient(90deg, var(--n-hha-glow), var(--n-hha-paper));
73
- border-bottom: 1px solid var(--n-hha-line);
74
- }
75
-
76
- .hha-intro p,
77
- .hha-intro span,
78
- .hha-load p,
79
- .hha-export p,
80
- .hha-footer-line p {
81
- margin: 0;
82
- }
83
-
84
- .hha-intro p {
85
- max-width: 62ch;
86
- font-weight: 700;
87
- }
88
-
89
- .hha-intro span {
90
- font-size: 0.8rem;
91
- color: var(--n-hha-muted);
92
- }
93
-
94
- .hha-load {
95
- display: flex;
96
- align-items: center;
97
- justify-content: space-between;
98
- gap: 1rem;
99
- padding: 1.25rem;
100
- border-bottom: 1px solid var(--n-hha-line);
101
- }
102
-
103
- .hha-load strong,
104
- .hha-export strong {
105
- display: block;
106
- margin-bottom: 0.25rem;
107
- font-size: 1rem;
108
- }
109
-
110
- .hha-load p,
111
- .hha-export p,
112
- .hha-coordinate-note,
113
- .hha-no-selection {
114
- color: var(--n-hha-muted);
115
- font-size: 0.85rem;
116
- }
117
-
118
- .hha input[type="file"] {
119
- position: absolute;
120
- width: 1px;
121
- height: 1px;
122
- opacity: 0;
123
- pointer-events: none;
124
- }
125
-
126
- .hha-button,
127
- .hha-icon-button,
128
- .hha-mode-switch button,
129
- .hha-type-rack button,
130
- .hha-geometry button,
131
- .hha-inspector button {
132
- color: var(--n-hha-ink);
133
- background: var(--n-hha-panel);
134
- border: 1px solid var(--n-hha-line);
135
- border-radius: 0.65rem;
136
- cursor: pointer;
137
- font-weight: 700;
138
- }
139
-
140
- .hha-button {
141
- display: inline-flex;
142
- align-items: center;
143
- justify-content: center;
144
- min-height: 2.6rem;
145
- padding: 0.55rem 0.9rem;
146
- }
147
-
148
- .hha-button-primary,
149
- .hha-play,
150
- .hha-mode-switch button.is-active {
151
- color: var(--n-hha-white);
152
- background: var(--n-hha-action);
153
- border-color: var(--n-hha-action);
154
- }
155
-
156
- .hha-control-deck {
157
- display: grid;
158
- grid-template-columns: 1fr 1.5fr auto;
159
- gap: 1rem;
160
- padding: 1rem 1.25rem;
161
- border-bottom: 1px solid var(--n-hha-line);
162
- }
163
-
164
- .hha-control-deck fieldset,
165
- .hha-pivot {
166
- display: flex;
167
- align-items: flex-end;
168
- gap: 0.65rem;
169
- margin: 0;
170
- padding: 0;
171
- border: 0;
172
- }
173
-
174
- .hha-control-deck legend,
175
- .hha-pivot legend {
176
- width: 100%;
177
- margin-bottom: 0.45rem;
178
- font-size: 0.75rem;
179
- font-weight: 800;
180
- letter-spacing: 0.09em;
181
- text-transform: uppercase;
182
- }
183
-
184
- .hha-control-deck label,
185
- .hha-fields label,
186
- .hha-pivot label {
187
- display: grid;
188
- gap: 0.3rem;
189
- font-size: 0.75rem;
190
- font-weight: 700;
191
- }
192
-
193
- .hha input[type="number"],
194
- .hha input[type="text"] {
195
- box-sizing: border-box;
196
- width: 100%;
197
- min-width: 0;
198
- min-height: 2.6rem;
199
- padding: 0.55rem 0.65rem;
200
- color: var(--n-hha-ink);
201
- background: var(--n-hha-panel);
202
- border: 1px solid var(--n-hha-line);
203
- border-radius: 0.55rem;
204
- font-variant-numeric: tabular-nums;
205
- }
206
-
207
- .hha-control-deck input[type="number"] {
208
- width: 4.5rem;
209
- }
210
-
211
- .hha-transport,
212
- .hha-history {
213
- display: flex;
214
- align-items: center;
215
- gap: 0.4rem;
216
- }
217
-
218
- .hha-icon-button {
219
- display: grid;
220
- place-items: center;
221
- width: 2.6rem;
222
- height: 2.6rem;
223
- }
224
-
225
- .hha-icon-button span {
226
- width: 0.65rem;
227
- height: 0.65rem;
228
- border-top: 2px solid currentcolor;
229
- border-left: 2px solid currentcolor;
230
- transform: rotate(-45deg);
231
- }
232
-
233
- .hha-icon-button.is-next span {
234
- transform: rotate(135deg);
235
- }
236
-
237
- .hha-range {
238
- min-width: 7rem;
239
- }
240
-
241
- .hha-control-deck .hha-check {
242
- display: flex;
243
- align-items: center;
244
- min-height: 2.6rem;
245
- }
246
-
247
- .hha-workbench {
248
- display: grid;
249
- grid-template-columns: minmax(9rem, 0.7fr) minmax(20rem, 3fr) minmax(13rem, 1fr);
250
- min-height: 34rem;
251
- }
252
-
253
- .hha-layers,
254
- .hha-inspector {
255
- padding: 1rem;
256
- background: var(--n-hha-panel);
257
- }
258
-
259
- .hha-layers {
260
- border-right: 1px solid var(--n-hha-line);
261
- }
262
-
263
- .hha-inspector {
264
- min-width: 0;
265
- border-left: 1px solid var(--n-hha-line);
266
- }
267
-
268
- .hha h2 {
269
- margin: 0 0 0.85rem;
270
- font-size: 0.78rem;
271
- letter-spacing: 0.09em;
272
- text-transform: uppercase;
273
- }
274
-
275
- .hha-mode-switch {
276
- display: grid;
277
- grid-template-columns: 1fr 1fr;
278
- margin-bottom: 1rem;
279
- }
280
-
281
- .hha-mode-switch button {
282
- min-height: 2.5rem;
283
- border-radius: 0;
284
- }
285
-
286
- .hha-mode-switch button:first-child {
287
- border-radius: 0.6rem 0 0 0.6rem;
288
- }
289
-
290
- .hha-mode-switch button:last-child {
291
- border-radius: 0 0.6rem 0.6rem 0;
292
- }
293
-
294
- .hha-type-rack,
295
- .hha-geometry,
296
- .hha-copy-actions {
297
- display: grid;
298
- gap: 0.45rem;
299
- }
300
-
301
- .hha-type-rack button,
302
- .hha-geometry button,
303
- .hha-copy-actions button {
304
- display: flex;
305
- align-items: center;
306
- gap: 0.55rem;
307
- min-height: 2.55rem;
308
- padding: 0.5rem 0.65rem;
309
- text-align: left;
310
- }
311
-
312
- .hha-type-rack button i {
313
- width: 0.7rem;
314
- height: 0.7rem;
315
- background: var(--n-hha-coral);
316
- border-radius: 50%;
317
- box-shadow: 0 0 0 4px rgba(255, 77, 109, 0.14);
318
- }
319
-
320
- .hha-type-rack button:nth-child(2) i { background: var(--n-hha-mint); }
321
- .hha-type-rack button:nth-child(3) i { background: var(--n-hha-violet); }
322
- .hha-type-rack button:nth-child(4) i { background: var(--n-hha-amber); }
323
- .hha-type-rack button:nth-child(5) i { background: var(--n-hha-sky); }
324
- .hha-type-rack button:nth-child(6) i { background: var(--n-hha-pink); }
325
-
326
- .hha-type-rack button.is-active,
327
- .hha-geometry button.is-active {
328
- border-color: var(--n-hha-focus);
329
- box-shadow: inset 0 0 0 1px var(--n-hha-focus);
330
- }
331
-
332
- .hha-geometry {
333
- grid-template-columns: 1fr;
334
- margin-top: 1rem;
335
- }
336
-
337
- .hha-geometry button {
338
- justify-content: flex-start;
339
- width: 100%;
340
- font-size: 0.75rem;
341
- }
342
-
343
- .hha-geometry span {
344
- width: 0.85rem;
345
- height: 0.7rem;
346
- border: 2px solid var(--n-hha-ink);
347
- }
348
-
349
- .hha-geometry button:last-child span {
350
- border-radius: 50%;
351
- }
352
-
353
- .hha-stage-column {
354
- min-width: 0;
355
- padding: 1rem;
356
- background: linear-gradient(135deg, var(--n-hha-paper), var(--n-hha-panel));
357
- }
358
-
359
- .hha-stage-header,
360
- .hha-timeline-wrap > strong {
361
- display: flex;
362
- align-items: center;
363
- justify-content: space-between;
364
- margin-bottom: 0.6rem;
365
- font-size: 0.75rem;
366
- font-weight: 800;
367
- letter-spacing: 0.08em;
368
- text-transform: uppercase;
369
- }
370
-
371
- .hha-badges {
372
- display: flex;
373
- gap: 0.35rem;
374
- }
375
-
376
- .hha-badges b {
377
- padding: 0.3rem 0.5rem;
378
- color: var(--n-hha-muted);
379
- background: var(--n-hha-panel);
380
- border: 1px solid var(--n-hha-line);
381
- border-radius: 2rem;
382
- font-size: 0.75rem;
383
- }
384
-
385
- .hha-light-table {
386
- position: relative;
387
- display: grid;
388
- place-items: center;
389
- min-height: 26rem;
390
- overflow: auto;
391
- background-color: var(--n-hha-stage);
392
- background-image: linear-gradient(45deg, var(--n-hha-grid) 25%, transparent 25%), linear-gradient(-45deg, var(--n-hha-grid) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--n-hha-grid) 75%), linear-gradient(-45deg, transparent 75%, var(--n-hha-grid) 75%);
393
- background-position: 0 0, 0 8px, 8px -8px, -8px 0;
394
- background-size: 16px 16px;
395
- border: 0.5rem solid var(--n-hha-ink);
396
- border-radius: 0.75rem;
397
- box-shadow: inset 0 0 4rem rgba(0, 0, 0, 0.45), 0 0 0 1px var(--n-hha-line);
398
- }
399
-
400
- .hha-light-table::before,
401
- .hha-light-table::after {
402
- position: absolute;
403
- top: 50%;
404
- width: 0.9rem;
405
- height: 5rem;
406
- background: repeating-linear-gradient(180deg, var(--n-hha-glow) 0 0.65rem, transparent 0.65rem 1.3rem);
407
- content: "";
408
- transform: translateY(-50%);
409
- }
410
-
411
- .hha-light-table::before { left: 0.55rem; }
412
- .hha-light-table::after { right: 0.55rem; }
413
-
414
- .hha canvas {
415
- z-index: 1;
416
- display: block;
417
- max-width: calc(100% - 4rem);
418
- max-height: 31rem;
419
- cursor: crosshair;
420
- image-rendering: pixelated;
421
- box-shadow: 0 0 2rem rgba(247, 223, 161, 0.2);
422
- touch-action: none;
423
- }
424
-
425
- .hha-empty-stage {
426
- position: absolute;
427
- z-index: 2;
428
- display: grid;
429
- place-items: center;
430
- max-width: 24rem;
431
- padding: 1.5rem;
432
- color: var(--n-hha-white);
433
- text-align: center;
434
- pointer-events: none;
435
- }
436
-
437
- .hha-empty-stage span {
438
- width: 4rem;
439
- height: 4rem;
440
- border: 2px solid var(--n-hha-coral);
441
- border-radius: 0.6rem;
442
- box-shadow: 1rem 0.7rem 0 -0.15rem var(--n-hha-mint), -0.8rem 0.9rem 0 -0.15rem var(--n-hha-violet);
443
- transform: rotate(-4deg);
444
- }
445
-
446
- .hha.has-images .hha-empty-stage {
447
- display: none;
448
- }
449
-
450
- .hha-timeline-wrap {
451
- margin-top: 0.9rem;
452
- }
453
-
454
- .hha-timeline {
455
- display: flex;
456
- gap: 0.45rem;
457
- padding: 0.5rem 0.2rem;
458
- overflow-x: auto;
459
- }
460
-
461
- .hha-frame {
462
- position: relative;
463
- flex: 0 0 3.5rem;
464
- min-height: 3.6rem;
465
- color: var(--n-hha-ink);
466
- background: var(--n-hha-panel);
467
- border: 1px solid var(--n-hha-line);
468
- border-radius: 0.5rem;
469
- cursor: pointer;
470
- }
471
-
472
- .hha-frame.is-active {
473
- border-color: var(--n-hha-focus);
474
- box-shadow: 0 0 0 2px var(--n-hha-focus);
475
- transform: translateY(-2px);
476
- }
477
-
478
- .hha-frame span { font-weight: 900; }
479
-
480
- .hha-frame b {
481
- position: absolute;
482
- top: 0.25rem;
483
- right: 0.35rem;
484
- color: var(--n-hha-muted);
485
- font-size: 0.75rem;
486
- }
487
-
488
- .hha-frame em {
489
- position: absolute;
490
- right: 0.3rem;
491
- bottom: 0.3rem;
492
- left: 0.3rem;
493
- display: flex;
494
- gap: 2px;
495
- }
496
-
497
- .hha-frame i {
498
- height: 3px;
499
- flex: 1;
500
- background: var(--mark);
501
- border-radius: 1rem;
502
- }
503
-
504
- .hha-fields {
505
- display: grid;
506
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
507
- gap: 0.55rem;
508
- }
509
-
510
- .hha-wide {
511
- grid-column: 1 / -1;
512
- }
513
-
514
- .hha-inspector button {
515
- min-width: 0;
516
- min-height: 2.5rem;
517
- padding: 0.45rem;
518
- overflow-wrap: anywhere;
519
- white-space: normal;
520
- }
521
-
522
- .hha .hha-danger {
523
- color: var(--n-hha-danger);
524
- border-color: var(--n-hha-danger);
525
- }
526
-
527
- .hha-copy-actions {
528
- margin-top: 1rem;
529
- }
530
-
531
- .hha-pivot {
532
- display: grid;
533
- grid-template-columns: 1fr 1fr;
534
- margin-top: 1.2rem;
535
- padding-top: 1rem;
536
- border-top: 1px solid var(--n-hha-line);
537
- }
538
-
539
- .hha-pivot legend {
540
- grid-column: 1 / -1;
541
- }
542
-
543
- .hha-export {
544
- display: flex;
545
- align-items: center;
546
- justify-content: space-between;
547
- gap: 1rem;
548
- padding: 1.2rem 1.25rem;
549
- border-top: 1px solid var(--n-hha-line);
550
- }
551
-
552
- .hha-export > div:last-of-type {
553
- display: flex;
554
- flex-wrap: wrap;
555
- justify-content: flex-end;
556
- gap: 0.5rem;
557
- }
558
-
559
- .hha-footer-line {
560
- display: grid;
561
- grid-template-columns: 1fr 2fr;
562
- gap: 1rem;
563
- padding: 0.8rem 1.25rem;
564
- color: var(--n-hha-muted);
565
- background: var(--n-hha-paper);
566
- border-top: 1px solid var(--n-hha-line);
567
- font-size: 0.75rem;
568
- }
569
-
570
- .hha-footer-line [data-role="status"] {
571
- color: var(--n-hha-ink);
572
- font-weight: 800;
573
- }
574
-
575
- @media (max-width: 900px) {
576
- .hha-control-deck { grid-template-columns: 1fr; }
577
- .hha-workbench { grid-template-columns: 10rem minmax(18rem, 1fr); }
578
- .hha-inspector {
579
- grid-column: 1 / -1;
580
- border-top: 1px solid var(--n-hha-line);
581
- border-left: 0;
582
- }
583
- .hha-fields { grid-template-columns: repeat(5, 1fr); }
584
- .hha-wide { grid-column: auto; }
585
- }
586
-
587
- @media (max-width: 640px) {
588
- .hha-intro,
589
- .hha-load,
590
- .hha-export {
591
- align-items: stretch;
592
- flex-direction: column;
593
- }
594
- .hha-control-deck fieldset {
595
- align-items: stretch;
596
- flex-wrap: wrap;
597
- }
598
- .hha-workbench {
599
- display: flex;
600
- flex-direction: column;
601
- }
602
- .hha-layers {
603
- border-right: 0;
604
- border-bottom: 1px solid var(--n-hha-line);
605
- }
606
- .hha-type-rack { grid-template-columns: repeat(3, 1fr); }
607
- .hha-light-table { min-height: 19rem; }
608
- .hha-stage-column { padding: 0.75rem; }
609
- .hha-fields { grid-template-columns: 1fr 1fr; }
610
- .hha-wide { grid-column: 1 / -1; }
611
- .hha-export > div:last-of-type { justify-content: stretch; }
612
- .hha-export .hha-button { flex: 1 1 10rem; }
613
- .hha-footer-line { grid-template-columns: 1fr; }
614
- }
1
+ :root {
2
+ --n-hha-ink: #241b31;
3
+ --n-hha-muted: #6f627c;
4
+ --n-hha-paper: #fffaf0;
5
+ --n-hha-panel: #fff;
6
+ --n-hha-stage: #15111f;
7
+ --n-hha-line: #d9cbd8;
8
+ --n-hha-glow: #f7dfa1;
9
+ --n-hha-coral: #ff4d6d;
10
+ --n-hha-mint: #2dd4bf;
11
+ --n-hha-violet: #8b5cf6;
12
+ --n-hha-amber: #f59e0b;
13
+ --n-hha-sky: #38bdf8;
14
+ --n-hha-pink: #f472b6;
15
+ --n-hha-white: #fff;
16
+ --n-hha-danger: #a61b3b;
17
+ --n-hha-focus: #6d28d9;
18
+ --n-hha-action: #241b31;
19
+ --n-hha-shadow: rgba(44, 27, 55, 0.16);
20
+ --n-hha-grid: rgba(255, 255, 255, 0.07);
21
+ }
22
+
23
+ .theme-dark {
24
+ --n-hha-ink: #f8ecff;
25
+ --n-hha-muted: #c8b9d1;
26
+ --n-hha-paper: #18121f;
27
+ --n-hha-panel: #241b2d;
28
+ --n-hha-stage: #0c0911;
29
+ --n-hha-line: #51425d;
30
+ --n-hha-glow: #7a6023;
31
+ --n-hha-white: #fff;
32
+ --n-hha-danger: #ff7693;
33
+ --n-hha-focus: #c4a5ff;
34
+ --n-hha-action: #5b21b6;
35
+ --n-hha-shadow: rgba(0, 0, 0, 0.38);
36
+ --n-hha-grid: rgba(255, 255, 255, 0.08);
37
+ }
38
+
39
+ .hha {
40
+ color: var(--n-hha-ink);
41
+ background: radial-gradient(circle at 50% 20%, var(--n-hha-panel), var(--n-hha-paper) 72%);
42
+ border: 1px solid var(--n-hha-line);
43
+ border-radius: 1.5rem;
44
+ box-shadow: 0 1.5rem 4rem var(--n-hha-shadow);
45
+ overflow: hidden;
46
+ }
47
+
48
+ .hha button,
49
+ .hha input {
50
+ font: inherit;
51
+ }
52
+
53
+ .hha button,
54
+ .hha label {
55
+ -webkit-tap-highlight-color: transparent;
56
+ }
57
+
58
+ .hha button:focus-visible,
59
+ .hha input:focus-visible,
60
+ .hha:focus-visible {
61
+ outline: 3px solid var(--n-hha-focus);
62
+ outline-offset: 3px;
63
+ }
64
+
65
+ .hha-intro {
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: space-between;
69
+ gap: 1rem;
70
+ padding: 1rem 1.25rem;
71
+ color: var(--n-hha-ink);
72
+ background: linear-gradient(90deg, var(--n-hha-glow), var(--n-hha-paper));
73
+ border-bottom: 1px solid var(--n-hha-line);
74
+ }
75
+
76
+ .hha-intro p,
77
+ .hha-intro span,
78
+ .hha-load p,
79
+ .hha-export p,
80
+ .hha-footer-line p {
81
+ margin: 0;
82
+ }
83
+
84
+ .hha-intro p {
85
+ max-width: 62ch;
86
+ font-weight: 700;
87
+ }
88
+
89
+ .hha-intro span {
90
+ font-size: 0.8rem;
91
+ color: var(--n-hha-muted);
92
+ }
93
+
94
+ .hha-load {
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: space-between;
98
+ gap: 1rem;
99
+ padding: 1.25rem;
100
+ border-bottom: 1px solid var(--n-hha-line);
101
+ }
102
+
103
+ .hha-load strong,
104
+ .hha-export strong {
105
+ display: block;
106
+ margin-bottom: 0.25rem;
107
+ font-size: 1rem;
108
+ }
109
+
110
+ .hha-load p,
111
+ .hha-export p,
112
+ .hha-coordinate-note,
113
+ .hha-no-selection {
114
+ color: var(--n-hha-muted);
115
+ font-size: 0.85rem;
116
+ }
117
+
118
+ .hha input[type="file"] {
119
+ position: absolute;
120
+ width: 1px;
121
+ height: 1px;
122
+ opacity: 0;
123
+ pointer-events: none;
124
+ }
125
+
126
+ .hha-button,
127
+ .hha-icon-button,
128
+ .hha-mode-switch button,
129
+ .hha-type-rack button,
130
+ .hha-geometry button,
131
+ .hha-inspector button {
132
+ color: var(--n-hha-ink);
133
+ background: var(--n-hha-panel);
134
+ border: 1px solid var(--n-hha-line);
135
+ border-radius: 0.65rem;
136
+ cursor: pointer;
137
+ font-weight: 700;
138
+ }
139
+
140
+ .hha-button {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ min-height: 2.6rem;
145
+ padding: 0.55rem 0.9rem;
146
+ }
147
+
148
+ .hha-button-primary,
149
+ .hha-play,
150
+ .hha-mode-switch button.is-active {
151
+ color: var(--n-hha-white);
152
+ background: var(--n-hha-action);
153
+ border-color: var(--n-hha-action);
154
+ }
155
+
156
+ .hha-control-deck {
157
+ display: grid;
158
+ grid-template-columns: 1fr 1.5fr auto;
159
+ gap: 1rem;
160
+ padding: 1rem 1.25rem;
161
+ border-bottom: 1px solid var(--n-hha-line);
162
+ }
163
+
164
+ .hha-control-deck fieldset,
165
+ .hha-pivot {
166
+ display: flex;
167
+ align-items: flex-end;
168
+ gap: 0.65rem;
169
+ margin: 0;
170
+ padding: 0;
171
+ border: 0;
172
+ }
173
+
174
+ .hha-control-deck legend,
175
+ .hha-pivot legend {
176
+ width: 100%;
177
+ margin-bottom: 0.45rem;
178
+ font-size: 0.75rem;
179
+ font-weight: 800;
180
+ letter-spacing: 0.09em;
181
+ text-transform: uppercase;
182
+ }
183
+
184
+ .hha-control-deck label,
185
+ .hha-fields label,
186
+ .hha-pivot label {
187
+ display: grid;
188
+ gap: 0.3rem;
189
+ font-size: 0.75rem;
190
+ font-weight: 700;
191
+ }
192
+
193
+ .hha input[type="number"],
194
+ .hha input[type="text"] {
195
+ box-sizing: border-box;
196
+ width: 100%;
197
+ min-width: 0;
198
+ min-height: 2.6rem;
199
+ padding: 0.55rem 0.65rem;
200
+ color: var(--n-hha-ink);
201
+ background: var(--n-hha-panel);
202
+ border: 1px solid var(--n-hha-line);
203
+ border-radius: 0.55rem;
204
+ font-variant-numeric: tabular-nums;
205
+ }
206
+
207
+ .hha-control-deck input[type="number"] {
208
+ width: 4.5rem;
209
+ }
210
+
211
+ .hha-transport,
212
+ .hha-history {
213
+ display: flex;
214
+ align-items: center;
215
+ gap: 0.4rem;
216
+ }
217
+
218
+ .hha-icon-button {
219
+ display: grid;
220
+ place-items: center;
221
+ width: 2.6rem;
222
+ height: 2.6rem;
223
+ }
224
+
225
+ .hha-icon-button span {
226
+ width: 0.65rem;
227
+ height: 0.65rem;
228
+ border-top: 2px solid currentcolor;
229
+ border-left: 2px solid currentcolor;
230
+ transform: rotate(-45deg);
231
+ }
232
+
233
+ .hha-icon-button.is-next span {
234
+ transform: rotate(135deg);
235
+ }
236
+
237
+ .hha-range {
238
+ min-width: 7rem;
239
+ }
240
+
241
+ .hha-control-deck .hha-check {
242
+ display: flex;
243
+ align-items: center;
244
+ min-height: 2.6rem;
245
+ }
246
+
247
+ .hha-workbench {
248
+ display: grid;
249
+ grid-template-columns: minmax(9rem, 0.7fr) minmax(20rem, 3fr) minmax(13rem, 1fr);
250
+ min-height: 34rem;
251
+ }
252
+
253
+ .hha-layers,
254
+ .hha-inspector {
255
+ padding: 1rem;
256
+ background: var(--n-hha-panel);
257
+ }
258
+
259
+ .hha-layers {
260
+ border-right: 1px solid var(--n-hha-line);
261
+ }
262
+
263
+ .hha-inspector {
264
+ min-width: 0;
265
+ border-left: 1px solid var(--n-hha-line);
266
+ }
267
+
268
+ .hha h2 {
269
+ margin: 0 0 0.85rem;
270
+ font-size: 0.78rem;
271
+ letter-spacing: 0.09em;
272
+ text-transform: uppercase;
273
+ }
274
+
275
+ .hha-mode-switch {
276
+ display: grid;
277
+ grid-template-columns: 1fr 1fr;
278
+ margin-bottom: 1rem;
279
+ }
280
+
281
+ .hha-mode-switch button {
282
+ min-height: 2.5rem;
283
+ border-radius: 0;
284
+ }
285
+
286
+ .hha-mode-switch button:first-child {
287
+ border-radius: 0.6rem 0 0 0.6rem;
288
+ }
289
+
290
+ .hha-mode-switch button:last-child {
291
+ border-radius: 0 0.6rem 0.6rem 0;
292
+ }
293
+
294
+ .hha-type-rack,
295
+ .hha-geometry,
296
+ .hha-copy-actions {
297
+ display: grid;
298
+ gap: 0.45rem;
299
+ }
300
+
301
+ .hha-type-rack button,
302
+ .hha-geometry button,
303
+ .hha-copy-actions button {
304
+ display: flex;
305
+ align-items: center;
306
+ gap: 0.55rem;
307
+ min-height: 2.55rem;
308
+ padding: 0.5rem 0.65rem;
309
+ text-align: left;
310
+ }
311
+
312
+ .hha-type-rack button i {
313
+ width: 0.7rem;
314
+ height: 0.7rem;
315
+ background: var(--n-hha-coral);
316
+ border-radius: 50%;
317
+ box-shadow: 0 0 0 4px rgba(255, 77, 109, 0.14);
318
+ }
319
+
320
+ .hha-type-rack button:nth-child(2) i { background: var(--n-hha-mint); }
321
+ .hha-type-rack button:nth-child(3) i { background: var(--n-hha-violet); }
322
+ .hha-type-rack button:nth-child(4) i { background: var(--n-hha-amber); }
323
+ .hha-type-rack button:nth-child(5) i { background: var(--n-hha-sky); }
324
+ .hha-type-rack button:nth-child(6) i { background: var(--n-hha-pink); }
325
+
326
+ .hha-type-rack button.is-active,
327
+ .hha-geometry button.is-active {
328
+ border-color: var(--n-hha-focus);
329
+ box-shadow: inset 0 0 0 1px var(--n-hha-focus);
330
+ }
331
+
332
+ .hha-geometry {
333
+ grid-template-columns: 1fr;
334
+ margin-top: 1rem;
335
+ }
336
+
337
+ .hha-geometry button {
338
+ justify-content: flex-start;
339
+ width: 100%;
340
+ font-size: 0.75rem;
341
+ }
342
+
343
+ .hha-geometry span {
344
+ width: 0.85rem;
345
+ height: 0.7rem;
346
+ border: 2px solid var(--n-hha-ink);
347
+ }
348
+
349
+ .hha-geometry button:last-child span {
350
+ border-radius: 50%;
351
+ }
352
+
353
+ .hha-stage-column {
354
+ min-width: 0;
355
+ padding: 1rem;
356
+ background: linear-gradient(135deg, var(--n-hha-paper), var(--n-hha-panel));
357
+ }
358
+
359
+ .hha-stage-header,
360
+ .hha-timeline-wrap > strong {
361
+ display: flex;
362
+ align-items: center;
363
+ justify-content: space-between;
364
+ margin-bottom: 0.6rem;
365
+ font-size: 0.75rem;
366
+ font-weight: 800;
367
+ letter-spacing: 0.08em;
368
+ text-transform: uppercase;
369
+ }
370
+
371
+ .hha-badges {
372
+ display: flex;
373
+ gap: 0.35rem;
374
+ }
375
+
376
+ .hha-badges b {
377
+ padding: 0.3rem 0.5rem;
378
+ color: var(--n-hha-muted);
379
+ background: var(--n-hha-panel);
380
+ border: 1px solid var(--n-hha-line);
381
+ border-radius: 2rem;
382
+ font-size: 0.75rem;
383
+ }
384
+
385
+ .hha-light-table {
386
+ position: relative;
387
+ display: grid;
388
+ place-items: center;
389
+ min-height: 26rem;
390
+ overflow: auto;
391
+ background-color: var(--n-hha-stage);
392
+ background-image: linear-gradient(45deg, var(--n-hha-grid) 25%, transparent 25%), linear-gradient(-45deg, var(--n-hha-grid) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--n-hha-grid) 75%), linear-gradient(-45deg, transparent 75%, var(--n-hha-grid) 75%);
393
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0;
394
+ background-size: 16px 16px;
395
+ border: 0.5rem solid var(--n-hha-ink);
396
+ border-radius: 0.75rem;
397
+ box-shadow: inset 0 0 4rem rgba(0, 0, 0, 0.45), 0 0 0 1px var(--n-hha-line);
398
+ }
399
+
400
+ .hha-light-table::before,
401
+ .hha-light-table::after {
402
+ position: absolute;
403
+ top: 50%;
404
+ width: 0.9rem;
405
+ height: 5rem;
406
+ background: repeating-linear-gradient(180deg, var(--n-hha-glow) 0 0.65rem, transparent 0.65rem 1.3rem);
407
+ content: "";
408
+ transform: translateY(-50%);
409
+ }
410
+
411
+ .hha-light-table::before { left: 0.55rem; }
412
+ .hha-light-table::after { right: 0.55rem; }
413
+
414
+ .hha canvas {
415
+ z-index: 1;
416
+ display: block;
417
+ max-width: calc(100% - 4rem);
418
+ max-height: 31rem;
419
+ cursor: crosshair;
420
+ image-rendering: pixelated;
421
+ box-shadow: 0 0 2rem rgba(247, 223, 161, 0.2);
422
+ touch-action: none;
423
+ }
424
+
425
+ .hha-empty-stage {
426
+ position: absolute;
427
+ z-index: 2;
428
+ display: grid;
429
+ place-items: center;
430
+ max-width: 24rem;
431
+ padding: 1.5rem;
432
+ color: var(--n-hha-white);
433
+ text-align: center;
434
+ pointer-events: none;
435
+ }
436
+
437
+ .hha-empty-stage span {
438
+ width: 4rem;
439
+ height: 4rem;
440
+ border: 2px solid var(--n-hha-coral);
441
+ border-radius: 0.6rem;
442
+ box-shadow: 1rem 0.7rem 0 -0.15rem var(--n-hha-mint), -0.8rem 0.9rem 0 -0.15rem var(--n-hha-violet);
443
+ transform: rotate(-4deg);
444
+ }
445
+
446
+ .hha.has-images .hha-empty-stage {
447
+ display: none;
448
+ }
449
+
450
+ .hha-timeline-wrap {
451
+ margin-top: 0.9rem;
452
+ }
453
+
454
+ .hha-timeline {
455
+ display: flex;
456
+ gap: 0.45rem;
457
+ padding: 0.5rem 0.2rem;
458
+ overflow-x: auto;
459
+ }
460
+
461
+ .hha-frame {
462
+ position: relative;
463
+ flex: 0 0 3.5rem;
464
+ min-height: 3.6rem;
465
+ color: var(--n-hha-ink);
466
+ background: var(--n-hha-panel);
467
+ border: 1px solid var(--n-hha-line);
468
+ border-radius: 0.5rem;
469
+ cursor: pointer;
470
+ }
471
+
472
+ .hha-frame.is-active {
473
+ border-color: var(--n-hha-focus);
474
+ box-shadow: 0 0 0 2px var(--n-hha-focus);
475
+ transform: translateY(-2px);
476
+ }
477
+
478
+ .hha-frame span { font-weight: 900; }
479
+
480
+ .hha-frame b {
481
+ position: absolute;
482
+ top: 0.25rem;
483
+ right: 0.35rem;
484
+ color: var(--n-hha-muted);
485
+ font-size: 0.75rem;
486
+ }
487
+
488
+ .hha-frame em {
489
+ position: absolute;
490
+ right: 0.3rem;
491
+ bottom: 0.3rem;
492
+ left: 0.3rem;
493
+ display: flex;
494
+ gap: 2px;
495
+ }
496
+
497
+ .hha-frame i {
498
+ height: 3px;
499
+ flex: 1;
500
+ background: var(--mark);
501
+ border-radius: 1rem;
502
+ }
503
+
504
+ .hha-fields {
505
+ display: grid;
506
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
507
+ gap: 0.55rem;
508
+ }
509
+
510
+ .hha-wide {
511
+ grid-column: 1 / -1;
512
+ }
513
+
514
+ .hha-inspector button {
515
+ min-width: 0;
516
+ min-height: 2.5rem;
517
+ padding: 0.45rem;
518
+ overflow-wrap: anywhere;
519
+ white-space: normal;
520
+ }
521
+
522
+ .hha .hha-danger {
523
+ color: var(--n-hha-danger);
524
+ border-color: var(--n-hha-danger);
525
+ }
526
+
527
+ .hha-copy-actions {
528
+ margin-top: 1rem;
529
+ }
530
+
531
+ .hha-pivot {
532
+ display: grid;
533
+ grid-template-columns: 1fr 1fr;
534
+ margin-top: 1.2rem;
535
+ padding-top: 1rem;
536
+ border-top: 1px solid var(--n-hha-line);
537
+ }
538
+
539
+ .hha-pivot legend {
540
+ grid-column: 1 / -1;
541
+ }
542
+
543
+ .hha-export {
544
+ display: flex;
545
+ align-items: center;
546
+ justify-content: space-between;
547
+ gap: 1rem;
548
+ padding: 1.2rem 1.25rem;
549
+ border-top: 1px solid var(--n-hha-line);
550
+ }
551
+
552
+ .hha-export > div:last-of-type {
553
+ display: flex;
554
+ flex-wrap: wrap;
555
+ justify-content: flex-end;
556
+ gap: 0.5rem;
557
+ }
558
+
559
+ .hha-footer-line {
560
+ display: grid;
561
+ grid-template-columns: 1fr 2fr;
562
+ gap: 1rem;
563
+ padding: 0.8rem 1.25rem;
564
+ color: var(--n-hha-muted);
565
+ background: var(--n-hha-paper);
566
+ border-top: 1px solid var(--n-hha-line);
567
+ font-size: 0.75rem;
568
+ }
569
+
570
+ .hha-footer-line [data-role="status"] {
571
+ color: var(--n-hha-ink);
572
+ font-weight: 800;
573
+ }
574
+
575
+ @media (max-width: 900px) {
576
+ .hha-control-deck { grid-template-columns: 1fr; }
577
+ .hha-workbench { grid-template-columns: 10rem minmax(18rem, 1fr); }
578
+ .hha-inspector {
579
+ grid-column: 1 / -1;
580
+ border-top: 1px solid var(--n-hha-line);
581
+ border-left: 0;
582
+ }
583
+ .hha-fields { grid-template-columns: repeat(5, 1fr); }
584
+ .hha-wide { grid-column: auto; }
585
+ }
586
+
587
+ @media (max-width: 640px) {
588
+ .hha-intro,
589
+ .hha-load,
590
+ .hha-export {
591
+ align-items: stretch;
592
+ flex-direction: column;
593
+ }
594
+ .hha-control-deck fieldset {
595
+ align-items: stretch;
596
+ flex-wrap: wrap;
597
+ }
598
+ .hha-workbench {
599
+ display: flex;
600
+ flex-direction: column;
601
+ }
602
+ .hha-layers {
603
+ border-right: 0;
604
+ border-bottom: 1px solid var(--n-hha-line);
605
+ }
606
+ .hha-type-rack { grid-template-columns: repeat(3, 1fr); }
607
+ .hha-light-table { min-height: 19rem; }
608
+ .hha-stage-column { padding: 0.75rem; }
609
+ .hha-fields { grid-template-columns: 1fr 1fr; }
610
+ .hha-wide { grid-column: 1 / -1; }
611
+ .hha-export > div:last-of-type { justify-content: stretch; }
612
+ .hha-export .hha-button { flex: 1 1 10rem; }
613
+ .hha-footer-line { grid-template-columns: 1fr; }
614
+ }