@jjlmoya/utils-tabletop 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 (123) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +11 -1
  3. package/src/index.ts +1 -0
  4. package/src/tests/locale_completeness.test.ts +1 -1
  5. package/src/tests/tool_validation.test.ts +1 -1
  6. package/src/tool/decision-wheel/audio.ts +78 -0
  7. package/src/tool/decision-wheel/bibliography.astro +16 -0
  8. package/src/tool/decision-wheel/bibliography.ts +8 -0
  9. package/src/tool/decision-wheel/client.ts +226 -0
  10. package/src/tool/decision-wheel/component.astro +48 -0
  11. package/src/tool/decision-wheel/components/SegmentEditor.astro +22 -0
  12. package/src/tool/decision-wheel/components/SpinHistory.astro +17 -0
  13. package/src/tool/decision-wheel/components/SpinResult.astro +13 -0
  14. package/src/tool/decision-wheel/components/WheelCanvas.astro +23 -0
  15. package/src/tool/decision-wheel/decision-wheel.css +632 -0
  16. package/src/tool/decision-wheel/drawing.ts +144 -0
  17. package/src/tool/decision-wheel/entry.ts +48 -0
  18. package/src/tool/decision-wheel/i18n/de.ts +97 -0
  19. package/src/tool/decision-wheel/i18n/en.ts +251 -0
  20. package/src/tool/decision-wheel/i18n/es.ts +93 -0
  21. package/src/tool/decision-wheel/i18n/fr.ts +93 -0
  22. package/src/tool/decision-wheel/i18n/id.ts +93 -0
  23. package/src/tool/decision-wheel/i18n/it.ts +93 -0
  24. package/src/tool/decision-wheel/i18n/ja.ts +93 -0
  25. package/src/tool/decision-wheel/i18n/ko.ts +93 -0
  26. package/src/tool/decision-wheel/i18n/nl.ts +93 -0
  27. package/src/tool/decision-wheel/i18n/pl.ts +93 -0
  28. package/src/tool/decision-wheel/i18n/pt.ts +93 -0
  29. package/src/tool/decision-wheel/i18n/ru.ts +75 -0
  30. package/src/tool/decision-wheel/i18n/sv.ts +93 -0
  31. package/src/tool/decision-wheel/i18n/tr.ts +93 -0
  32. package/src/tool/decision-wheel/i18n/zh.ts +93 -0
  33. package/src/tool/decision-wheel/index.ts +9 -0
  34. package/src/tool/decision-wheel/logic.test.ts +163 -0
  35. package/src/tool/decision-wheel/logic.ts +145 -0
  36. package/src/tool/decision-wheel/seo.astro +16 -0
  37. package/src/tool/decision-wheel/types.ts +14 -0
  38. package/src/tool/decision-wheel/ui.ts +121 -0
  39. package/src/tool/fantasy-runes-translator/bibliography.astro +16 -0
  40. package/src/tool/fantasy-runes-translator/bibliography.ts +16 -0
  41. package/src/tool/fantasy-runes-translator/client.ts +205 -0
  42. package/src/tool/fantasy-runes-translator/component.astro +95 -0
  43. package/src/tool/fantasy-runes-translator/entry.ts +56 -0
  44. package/src/tool/fantasy-runes-translator/fantasy-runes-translator.css +712 -0
  45. package/src/tool/fantasy-runes-translator/i18n/de.ts +139 -0
  46. package/src/tool/fantasy-runes-translator/i18n/en.ts +139 -0
  47. package/src/tool/fantasy-runes-translator/i18n/es.ts +139 -0
  48. package/src/tool/fantasy-runes-translator/i18n/fr.ts +139 -0
  49. package/src/tool/fantasy-runes-translator/i18n/id.ts +139 -0
  50. package/src/tool/fantasy-runes-translator/i18n/it.ts +139 -0
  51. package/src/tool/fantasy-runes-translator/i18n/ja.ts +139 -0
  52. package/src/tool/fantasy-runes-translator/i18n/ko.ts +139 -0
  53. package/src/tool/fantasy-runes-translator/i18n/nl.ts +139 -0
  54. package/src/tool/fantasy-runes-translator/i18n/pl.ts +139 -0
  55. package/src/tool/fantasy-runes-translator/i18n/pt.ts +139 -0
  56. package/src/tool/fantasy-runes-translator/i18n/ru.ts +139 -0
  57. package/src/tool/fantasy-runes-translator/i18n/sv.ts +139 -0
  58. package/src/tool/fantasy-runes-translator/i18n/tr.ts +139 -0
  59. package/src/tool/fantasy-runes-translator/i18n/zh.ts +139 -0
  60. package/src/tool/fantasy-runes-translator/index.ts +9 -0
  61. package/src/tool/fantasy-runes-translator/logic.ts +174 -0
  62. package/src/tool/fantasy-runes-translator/seo.astro +16 -0
  63. package/src/tool/fantasy-runes-translator/types.ts +26 -0
  64. package/src/tool/rpg-initiative-tracker/bibliography.astro +16 -0
  65. package/src/tool/rpg-initiative-tracker/bibliography.ts +12 -0
  66. package/src/tool/rpg-initiative-tracker/client.ts +201 -0
  67. package/src/tool/rpg-initiative-tracker/component.astro +23 -0
  68. package/src/tool/rpg-initiative-tracker/components/AddForm.astro +49 -0
  69. package/src/tool/rpg-initiative-tracker/components/CombatantList.astro +16 -0
  70. package/src/tool/rpg-initiative-tracker/components/TurnControls.astro +28 -0
  71. package/src/tool/rpg-initiative-tracker/entry.ts +50 -0
  72. package/src/tool/rpg-initiative-tracker/i18n/de.ts +266 -0
  73. package/src/tool/rpg-initiative-tracker/i18n/en.ts +263 -0
  74. package/src/tool/rpg-initiative-tracker/i18n/es.ts +264 -0
  75. package/src/tool/rpg-initiative-tracker/i18n/fr.ts +263 -0
  76. package/src/tool/rpg-initiative-tracker/i18n/id.ts +263 -0
  77. package/src/tool/rpg-initiative-tracker/i18n/it.ts +263 -0
  78. package/src/tool/rpg-initiative-tracker/i18n/ja.ts +263 -0
  79. package/src/tool/rpg-initiative-tracker/i18n/ko.ts +263 -0
  80. package/src/tool/rpg-initiative-tracker/i18n/nl.ts +263 -0
  81. package/src/tool/rpg-initiative-tracker/i18n/pl.ts +264 -0
  82. package/src/tool/rpg-initiative-tracker/i18n/pt.ts +263 -0
  83. package/src/tool/rpg-initiative-tracker/i18n/ru.ts +264 -0
  84. package/src/tool/rpg-initiative-tracker/i18n/sv.ts +263 -0
  85. package/src/tool/rpg-initiative-tracker/i18n/tr.ts +263 -0
  86. package/src/tool/rpg-initiative-tracker/i18n/zh.ts +263 -0
  87. package/src/tool/rpg-initiative-tracker/index.ts +9 -0
  88. package/src/tool/rpg-initiative-tracker/logic.test.ts +121 -0
  89. package/src/tool/rpg-initiative-tracker/logic.ts +122 -0
  90. package/src/tool/rpg-initiative-tracker/rpg-initiative-tracker.css +617 -0
  91. package/src/tool/rpg-initiative-tracker/seo.astro +16 -0
  92. package/src/tool/rpg-initiative-tracker/types.ts +15 -0
  93. package/src/tool/score-tracker/bibliography.astro +16 -0
  94. package/src/tool/score-tracker/bibliography.ts +12 -0
  95. package/src/tool/score-tracker/client.ts +248 -0
  96. package/src/tool/score-tracker/component.astro +34 -0
  97. package/src/tool/score-tracker/components/Leaderboard.astro +19 -0
  98. package/src/tool/score-tracker/components/PlayerSetup.astro +32 -0
  99. package/src/tool/score-tracker/components/RoundScoring.astro +22 -0
  100. package/src/tool/score-tracker/components/ScoreHistory.astro +25 -0
  101. package/src/tool/score-tracker/entry.ts +57 -0
  102. package/src/tool/score-tracker/i18n/de.ts +278 -0
  103. package/src/tool/score-tracker/i18n/en.ts +278 -0
  104. package/src/tool/score-tracker/i18n/es.ts +251 -0
  105. package/src/tool/score-tracker/i18n/fr.ts +278 -0
  106. package/src/tool/score-tracker/i18n/id.ts +278 -0
  107. package/src/tool/score-tracker/i18n/it.ts +278 -0
  108. package/src/tool/score-tracker/i18n/ja.ts +278 -0
  109. package/src/tool/score-tracker/i18n/ko.ts +278 -0
  110. package/src/tool/score-tracker/i18n/nl.ts +278 -0
  111. package/src/tool/score-tracker/i18n/pl.ts +278 -0
  112. package/src/tool/score-tracker/i18n/pt.ts +278 -0
  113. package/src/tool/score-tracker/i18n/ru.ts +278 -0
  114. package/src/tool/score-tracker/i18n/sv.ts +278 -0
  115. package/src/tool/score-tracker/i18n/tr.ts +278 -0
  116. package/src/tool/score-tracker/i18n/zh.ts +278 -0
  117. package/src/tool/score-tracker/index.ts +9 -0
  118. package/src/tool/score-tracker/logic.test.ts +83 -0
  119. package/src/tool/score-tracker/logic.ts +122 -0
  120. package/src/tool/score-tracker/score-tracker.css +1029 -0
  121. package/src/tool/score-tracker/seo.astro +16 -0
  122. package/src/tool/score-tracker/types.ts +17 -0
  123. package/src/tools.ts +8 -0
@@ -0,0 +1,1029 @@
1
+ :root {
2
+ --score-gold: #f59e0b;
3
+ --score-silver: #94a3b8;
4
+ --score-bronze: #d97706;
5
+ --score-first: #22c55e;
6
+ --score-last: #ef4444;
7
+ --crown-glow: #fbbf24;
8
+ --magic-score: #a78bfa;
9
+ }
10
+
11
+ .score-main-wrapper {
12
+ background: var(--bg-surface);
13
+ border: 1px solid var(--border-color);
14
+ border-radius: 1.25rem;
15
+ padding: 1.5rem;
16
+ color: var(--text-base);
17
+ display: flex;
18
+ flex-direction: column;
19
+ gap: 1.5rem;
20
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
21
+ animation: wrapper-appear 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
22
+ }
23
+
24
+ @keyframes wrapper-appear {
25
+ 0% {
26
+ opacity: 0;
27
+ transform: scale(0.96) translateY(10px);
28
+ }
29
+ 100% {
30
+ opacity: 1;
31
+ transform: scale(1) translateY(0);
32
+ }
33
+ }
34
+
35
+ .player-setup-panel {
36
+ background: var(--bg-page);
37
+ border: 1px solid var(--border-color);
38
+ border-radius: 1rem;
39
+ padding: 1.25rem;
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: 1rem;
43
+ animation: panel-glide 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
44
+ }
45
+
46
+ @keyframes panel-glide {
47
+ 0% {
48
+ opacity: 0;
49
+ transform: translateY(-8px);
50
+ }
51
+ 100% {
52
+ opacity: 1;
53
+ transform: translateY(0);
54
+ }
55
+ }
56
+
57
+ .panel-title {
58
+ font-size: 1rem;
59
+ font-weight: 900;
60
+ text-transform: uppercase;
61
+ letter-spacing: 0.05em;
62
+ color: var(--text-muted);
63
+ margin: 0;
64
+ }
65
+
66
+ .add-player-row {
67
+ display: flex;
68
+ gap: 0.5rem;
69
+ }
70
+
71
+ .add-player-input {
72
+ flex: 1;
73
+ background: var(--bg-surface);
74
+ border: 1px solid var(--border-color);
75
+ border-radius: 0.5rem;
76
+ padding: 0.6rem 0.75rem;
77
+ color: var(--text-base);
78
+ font-weight: 700;
79
+ font-size: 0.95rem;
80
+ outline: none;
81
+ transition: all 0.2s ease;
82
+ }
83
+
84
+ .add-player-input:focus {
85
+ border-color: var(--accent);
86
+ box-shadow: 0 0 0 3px rgba(244, 63, 94, 0.1);
87
+ }
88
+
89
+ .player-list {
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: 0.5rem;
93
+ }
94
+
95
+ .player-card {
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: space-between;
99
+ gap: 0.5rem;
100
+ background: var(--bg-surface);
101
+ border: 1px solid var(--border-color);
102
+ border-radius: 0.75rem;
103
+ padding: 0.6rem 0.75rem;
104
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
105
+ animation: player-slide-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
106
+ }
107
+
108
+ @keyframes player-slide-in {
109
+ 0% {
110
+ opacity: 0;
111
+ transform: translateX(-12px) scale(0.95);
112
+ }
113
+ 100% {
114
+ opacity: 1;
115
+ transform: translateX(0) scale(1);
116
+ }
117
+ }
118
+
119
+ .player-card:hover {
120
+ border-color: var(--accent);
121
+ transform: translateY(-2px) scale(1.02);
122
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
123
+ }
124
+
125
+ .player-card:active {
126
+ transform: scale(0.98);
127
+ }
128
+
129
+ .player-card-name {
130
+ display: flex;
131
+ align-items: center;
132
+ gap: 0.5rem;
133
+ font-weight: 800;
134
+ font-size: 0.95rem;
135
+ color: var(--text-base);
136
+ position: relative;
137
+ }
138
+
139
+ .player-rank-badge {
140
+ width: 1.5rem;
141
+ height: 1.5rem;
142
+ border-radius: 50%;
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ font-size: 0.7rem;
147
+ font-weight: 900;
148
+ color: var(--color-white);
149
+ background: var(--text-muted);
150
+ flex-shrink: 0;
151
+ transition: all 0.3s ease;
152
+ }
153
+
154
+ .player-rank-badge.rank-1 {
155
+ background: var(--score-gold);
156
+ box-shadow: 0 0 6px rgba(245, 158, 11, 0.4);
157
+ animation: badge-champion 2s infinite ease-in-out;
158
+ }
159
+
160
+ @keyframes badge-champion {
161
+ 0%, 100% {
162
+ box-shadow: 0 0 6px rgba(245, 158, 11, 0.4);
163
+ transform: scale(1);
164
+ }
165
+ 50% {
166
+ box-shadow: 0 0 14px rgba(245, 158, 11, 0.7);
167
+ transform: scale(1.1);
168
+ }
169
+ }
170
+
171
+ .player-rank-badge.rank-2 {
172
+ background: var(--score-silver);
173
+ }
174
+
175
+ .player-rank-badge.rank-3 {
176
+ background: var(--score-bronze);
177
+ }
178
+
179
+ .player-card-actions {
180
+ display: flex;
181
+ gap: 0.35rem;
182
+ }
183
+
184
+ .btn-icon-sm {
185
+ width: 2rem;
186
+ height: 2rem;
187
+ border-radius: 0.375rem;
188
+ border: 1px solid var(--border-color);
189
+ background: var(--bg-page);
190
+ color: var(--text-muted);
191
+ cursor: pointer;
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ font-size: 0.85rem;
196
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
197
+ }
198
+
199
+ .btn-icon-sm:hover {
200
+ border-color: var(--accent);
201
+ color: var(--accent);
202
+ transform: scale(1.15) rotate(-5deg);
203
+ }
204
+
205
+ .btn-icon-sm:active {
206
+ transform: scale(0.9);
207
+ }
208
+
209
+ .btn-icon-sm.remove:hover {
210
+ border-color: var(--score-last);
211
+ color: var(--score-last);
212
+ }
213
+
214
+ .btn-score-action {
215
+ border: 1px solid var(--border-color);
216
+ background: var(--bg-page);
217
+ color: var(--text-base);
218
+ font-weight: 800;
219
+ font-size: 0.8rem;
220
+ padding: 0.5rem 1rem;
221
+ border-radius: 0.5rem;
222
+ cursor: pointer;
223
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
224
+ text-transform: uppercase;
225
+ letter-spacing: 0.03em;
226
+ position: relative;
227
+ overflow: hidden;
228
+ }
229
+
230
+ .btn-score-action:hover {
231
+ border-color: var(--accent);
232
+ color: var(--accent);
233
+ transform: translateY(-2px) scale(1.03);
234
+ }
235
+
236
+ .btn-score-action:active {
237
+ transform: translateY(0) scale(0.97);
238
+ }
239
+
240
+ .btn-score-action.primary {
241
+ background: var(--accent);
242
+ color: var(--color-white);
243
+ border-color: var(--accent);
244
+ }
245
+
246
+ .btn-score-action.primary::before {
247
+ content: '';
248
+ position: absolute;
249
+ top: 0;
250
+ left: -150%;
251
+ width: 50%;
252
+ height: 100%;
253
+ background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) 100%);
254
+ transform: skewX(-25deg);
255
+ }
256
+
257
+ .btn-score-action.primary:hover::before {
258
+ animation: shine-sweep-score 1.2s infinite ease-in-out;
259
+ }
260
+
261
+ @keyframes shine-sweep-score {
262
+ 0% { left: -150%; }
263
+ 100% { left: 150%; }
264
+ }
265
+
266
+ .btn-score-action.primary:hover {
267
+ box-shadow: 0 4px 16px rgba(244, 63, 94, 0.35);
268
+ transform: translateY(-2px) scale(1.04);
269
+ }
270
+
271
+ .btn-score-action.danger {
272
+ border-color: var(--score-last);
273
+ color: var(--score-last);
274
+ }
275
+
276
+ .btn-score-action.danger:hover {
277
+ border-color: var(--score-last);
278
+ opacity: 0.85;
279
+ }
280
+
281
+ .score-layout {
282
+ display: grid;
283
+ grid-template-columns: 1.3fr 1fr;
284
+ gap: 1.5rem;
285
+ }
286
+
287
+ @media (max-width: 820px) {
288
+ .score-layout { grid-template-columns: 1fr; }
289
+ }
290
+
291
+ .round-scoring-panel {
292
+ background: var(--bg-page);
293
+ border: 1px solid var(--border-color);
294
+ border-radius: 1rem;
295
+ padding: 1.25rem;
296
+ display: flex;
297
+ flex-direction: column;
298
+ gap: 1rem;
299
+ transition: all 0.4s ease;
300
+ animation: panel-glide 0.3s ease;
301
+ }
302
+
303
+ .round-scoring-panel.has-scores {
304
+ border-color: var(--accent);
305
+ box-shadow: 0 0 20px rgba(244, 63, 94, 0.08), inset 0 0 20px rgba(244, 63, 94, 0.03);
306
+ animation: portal-pulse-score 4s infinite ease-in-out alternate;
307
+ }
308
+
309
+ @keyframes portal-pulse-score {
310
+ 0% { box-shadow: 0 0 20px rgba(244, 63, 94, 0.08), inset 0 0 20px rgba(244, 63, 94, 0.03); }
311
+ 100% { box-shadow: 0 0 30px rgba(167, 139, 250, 0.12), inset 0 0 25px rgba(167, 139, 250, 0.05); }
312
+ }
313
+
314
+ .round-header {
315
+ display: flex;
316
+ justify-content: space-between;
317
+ align-items: center;
318
+ }
319
+
320
+ .round-label {
321
+ font-weight: 900;
322
+ font-size: 1.1rem;
323
+ color: var(--accent);
324
+ animation: round-glow 2s infinite ease-in-out;
325
+ }
326
+
327
+ @keyframes round-glow {
328
+ 0%, 100% { text-shadow: 0 0 4px rgba(244, 63, 94, 0.1); }
329
+ 50% { text-shadow: 0 0 12px rgba(244, 63, 94, 0.3); }
330
+ }
331
+
332
+ .round-score-rows {
333
+ display: flex;
334
+ flex-direction: column;
335
+ gap: 0.5rem;
336
+ }
337
+
338
+ .score-row {
339
+ display: flex;
340
+ align-items: center;
341
+ gap: 0.5rem;
342
+ background: var(--bg-surface);
343
+ border: 1px solid var(--border-color);
344
+ border-radius: 0.75rem;
345
+ padding: 0.5rem 0.75rem;
346
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
347
+ animation: score-row-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
348
+ }
349
+
350
+ @keyframes score-row-in {
351
+ 0% {
352
+ opacity: 0;
353
+ transform: translateX(-10px);
354
+ }
355
+ 100% {
356
+ opacity: 1;
357
+ transform: translateX(0);
358
+ }
359
+ }
360
+
361
+ .score-row:hover {
362
+ border-color: var(--accent);
363
+ background: linear-gradient(135deg, var(--bg-surface), rgba(244, 63, 94, 0.03));
364
+ transform: translateX(3px);
365
+ }
366
+
367
+ .score-row:active {
368
+ transform: scale(0.99);
369
+ }
370
+
371
+ .score-row-name {
372
+ flex: 1;
373
+ font-weight: 800;
374
+ font-size: 0.9rem;
375
+ color: var(--text-base);
376
+ }
377
+
378
+ .score-row-controls {
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 0.35rem;
382
+ }
383
+
384
+ .btn-score-adjust {
385
+ width: 2.25rem;
386
+ height: 2.25rem;
387
+ border-radius: 0.375rem;
388
+ border: 1px solid var(--border-color);
389
+ background: var(--bg-page);
390
+ color: var(--text-base);
391
+ font-size: 1.1rem;
392
+ font-weight: 800;
393
+ cursor: pointer;
394
+ display: flex;
395
+ align-items: center;
396
+ justify-content: center;
397
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
398
+ position: relative;
399
+ overflow: hidden;
400
+ }
401
+
402
+ .btn-score-adjust:hover {
403
+ color: var(--color-white);
404
+ border-color: transparent;
405
+ }
406
+
407
+ .btn-score-adjust.inc:hover {
408
+ background: var(--score-first);
409
+ transform: scale(1.2);
410
+ box-shadow: 0 0 12px rgba(34, 197, 94, 0.4);
411
+ }
412
+
413
+ .btn-score-adjust.dec:hover {
414
+ background: var(--score-last);
415
+ transform: scale(1.2);
416
+ box-shadow: 0 0 12px rgba(239, 68, 68, 0.4);
417
+ }
418
+
419
+ .btn-score-adjust:active {
420
+ transform: scale(0.9);
421
+ }
422
+
423
+ .score-row-value {
424
+ min-width: 2.5rem;
425
+ text-align: center;
426
+ font-weight: 900;
427
+ font-size: 1.15rem;
428
+ color: var(--accent);
429
+ transition: all 0.2s ease;
430
+ }
431
+
432
+ .score-row-value.pulse-score {
433
+ animation: score-pop 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.275);
434
+ }
435
+
436
+ @keyframes score-pop {
437
+ 0% { transform: scale(1); }
438
+ 40% {
439
+ transform: scale(1.45);
440
+ color: var(--score-gold);
441
+ text-shadow: 0 0 15px rgba(245, 158, 11, 0.5);
442
+ }
443
+ 100% { transform: scale(1); }
444
+ }
445
+
446
+ .no-round-message {
447
+ display: flex;
448
+ flex-direction: column;
449
+ align-items: center;
450
+ justify-content: center;
451
+ padding: 3rem 1rem;
452
+ color: var(--text-muted);
453
+ text-align: center;
454
+ gap: 0.75rem;
455
+ animation: float-empty 3s infinite ease-in-out;
456
+ }
457
+
458
+ @keyframes float-empty {
459
+ 0%, 100% { transform: translateY(0); }
460
+ 50% { transform: translateY(-6px); }
461
+ }
462
+
463
+ .no-round-message svg {
464
+ width: 3rem;
465
+ height: 3rem;
466
+ opacity: 0.3;
467
+ animation: spin-slow 8s infinite linear;
468
+ }
469
+
470
+ @keyframes spin-slow {
471
+ 0% { transform: rotate(0deg); }
472
+ 100% { transform: rotate(360deg); }
473
+ }
474
+
475
+ .leaderboard-panel {
476
+ background: var(--bg-page);
477
+ border: 1px solid var(--border-color);
478
+ border-radius: 1rem;
479
+ padding: 1.25rem;
480
+ display: flex;
481
+ flex-direction: column;
482
+ gap: 0.75rem;
483
+ animation: panel-glide 0.4s ease;
484
+ }
485
+
486
+ .leaderboard-list {
487
+ display: flex;
488
+ flex-direction: column;
489
+ gap: 0.4rem;
490
+ }
491
+
492
+ .leaderboard-item {
493
+ display: flex;
494
+ align-items: center;
495
+ gap: 0.75rem;
496
+ background: var(--bg-surface);
497
+ border: 1px solid var(--border-color);
498
+ border-radius: 0.75rem;
499
+ padding: 0.6rem 0.75rem;
500
+ transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
501
+ animation: lb-slide-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
502
+ position: relative;
503
+ overflow: hidden;
504
+ isolation: isolate;
505
+ }
506
+
507
+ @keyframes lb-slide-in {
508
+ 0% {
509
+ opacity: 0;
510
+ transform: translateY(10px) scale(0.96);
511
+ }
512
+ 100% {
513
+ opacity: 1;
514
+ transform: translateY(0) scale(1);
515
+ }
516
+ }
517
+
518
+ .leaderboard-item::before {
519
+ content: '';
520
+ position: absolute;
521
+ left: 0;
522
+ top: 0;
523
+ bottom: 0;
524
+ width: 3px;
525
+ background: transparent;
526
+ transition: background 0.3s ease;
527
+ }
528
+
529
+ .leaderboard-item:hover {
530
+ transform: translateY(-2px) scale(1.02);
531
+ border-color: var(--accent);
532
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
533
+ }
534
+
535
+ .leaderboard-item:active {
536
+ transform: scale(0.98);
537
+ }
538
+
539
+ .leaderboard-item.first {
540
+ border-color: var(--score-gold);
541
+ background: linear-gradient(135deg, var(--bg-surface), rgba(245, 158, 11, 0.06));
542
+ animation: champion-glow-pulse 2s infinite ease-in-out, lb-slide-in 0.3s ease;
543
+ }
544
+
545
+ .leaderboard-item.first::after {
546
+ content: '';
547
+ position: absolute;
548
+ right: 1rem;
549
+ top: 50%;
550
+ transform: translateY(-50%);
551
+ width: 1.25rem;
552
+ height: 1.25rem;
553
+ background: var(--score-gold);
554
+ clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
555
+ opacity: 0.25;
556
+ pointer-events: none;
557
+ }
558
+
559
+ @keyframes champion-glow-pulse {
560
+ 0%, 100% { box-shadow: 0 0 8px rgba(245, 158, 11, 0.1), inset 0 0 8px rgba(245, 158, 11, 0.02); }
561
+ 50% { box-shadow: 0 0 20px rgba(245, 158, 11, 0.25), inset 0 0 15px rgba(245, 158, 11, 0.05); }
562
+ }
563
+
564
+ .leaderboard-item.first::before {
565
+ background: var(--score-gold);
566
+ box-shadow: 0 0 8px rgba(245, 158, 11, 0.5);
567
+ }
568
+
569
+ .leaderboard-rank {
570
+ width: 1.75rem;
571
+ height: 1.75rem;
572
+ border-radius: 50%;
573
+ display: flex;
574
+ align-items: center;
575
+ justify-content: center;
576
+ font-size: 0.75rem;
577
+ font-weight: 900;
578
+ color: var(--color-white);
579
+ background: var(--text-muted);
580
+ flex-shrink: 0;
581
+ transition: all 0.3s ease;
582
+ }
583
+
584
+ .leaderboard-rank.rank-1 {
585
+ background: linear-gradient(135deg, var(--score-gold), #fbbf24);
586
+ box-shadow: 0 0 12px rgba(245, 158, 11, 0.5);
587
+ animation: crown-pulse 2s infinite ease-in-out;
588
+ }
589
+
590
+ @keyframes crown-pulse {
591
+ 0%, 100% {
592
+ box-shadow: 0 0 8px rgba(245, 158, 11, 0.4);
593
+ transform: scale(1);
594
+ }
595
+ 50% {
596
+ box-shadow: 0 0 18px rgba(245, 158, 11, 0.7);
597
+ transform: scale(1.08);
598
+ }
599
+ }
600
+
601
+ .leaderboard-rank.rank-2 {
602
+ background: linear-gradient(135deg, var(--score-silver), #cbd5e1);
603
+ box-shadow: 0 0 6px rgba(148, 163, 184, 0.3);
604
+ }
605
+
606
+ .leaderboard-rank.rank-3 {
607
+ background: linear-gradient(135deg, var(--score-bronze), #f59e0b);
608
+ box-shadow: 0 0 6px rgba(217, 119, 6, 0.3);
609
+ }
610
+
611
+ .leaderboard-name {
612
+ flex: 1;
613
+ font-weight: 800;
614
+ font-size: 0.9rem;
615
+ color: var(--text-base);
616
+ }
617
+
618
+ .leaderboard-total {
619
+ font-weight: 900;
620
+ font-size: 1.15rem;
621
+ color: var(--accent);
622
+ transition: all 0.3s ease;
623
+ }
624
+
625
+ .leaderboard-item.first .leaderboard-total {
626
+ color: var(--score-gold);
627
+ text-shadow: 0 0 8px rgba(245, 158, 11, 0.2);
628
+ }
629
+
630
+ .score-history-panel {
631
+ background: var(--bg-page);
632
+ border: 1px solid var(--border-color);
633
+ border-radius: 1rem;
634
+ padding: 1.25rem;
635
+ margin-top: 1rem;
636
+ animation: panel-glide 0.5s ease;
637
+ }
638
+
639
+ .tabs-nav-score {
640
+ display: flex;
641
+ gap: 0.5rem;
642
+ border-bottom: 2px solid var(--border-color);
643
+ margin-bottom: 1rem;
644
+ padding-bottom: 0.5rem;
645
+ }
646
+
647
+ .tab-score-btn {
648
+ background: none;
649
+ color: var(--text-muted);
650
+ font-weight: 800;
651
+ font-size: 0.85rem;
652
+ padding: 0.4rem 1rem;
653
+ cursor: pointer;
654
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
655
+ text-transform: uppercase;
656
+ border-radius: 99px;
657
+ border: 1px solid transparent;
658
+ }
659
+
660
+ .tab-score-btn:hover {
661
+ color: var(--text-base);
662
+ transform: translateY(-1px) scale(1.03);
663
+ }
664
+
665
+ .tab-score-btn:active {
666
+ transform: scale(0.97);
667
+ }
668
+
669
+ .tab-score-btn.active {
670
+ background: var(--accent);
671
+ color: var(--color-white);
672
+ border-color: var(--accent);
673
+ box-shadow: 0 4px 12px rgba(244, 63, 94, 0.2);
674
+ }
675
+
676
+ .tab-score-pane {
677
+ display: none;
678
+ }
679
+
680
+ .tab-score-pane.active {
681
+ display: block;
682
+ animation: pane-fade 0.25s ease;
683
+ }
684
+
685
+ @keyframes pane-fade {
686
+ 0% {
687
+ opacity: 0;
688
+ transform: translateY(6px);
689
+ }
690
+ 100% {
691
+ opacity: 1;
692
+ transform: translateY(0);
693
+ }
694
+ }
695
+
696
+ .history-round-card {
697
+ background: var(--bg-surface);
698
+ border: 1px solid var(--border-color);
699
+ border-radius: 0.75rem;
700
+ padding: 0;
701
+ margin-bottom: 0.6rem;
702
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
703
+ animation: history-card-in 0.3s ease;
704
+ overflow: hidden;
705
+ }
706
+
707
+ @keyframes history-card-in {
708
+ 0% {
709
+ opacity: 0;
710
+ transform: translateY(8px) scale(0.98);
711
+ }
712
+ 100% {
713
+ opacity: 1;
714
+ transform: translateY(0) scale(1);
715
+ }
716
+ }
717
+
718
+ .history-round-card:hover {
719
+ border-color: var(--accent);
720
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
721
+ transform: translateY(-2px);
722
+ }
723
+
724
+ .history-round-header {
725
+ display: flex;
726
+ justify-content: space-between;
727
+ align-items: center;
728
+ padding: 0.6rem 1rem;
729
+ background: var(--bg-page);
730
+ border-bottom: 1px solid var(--border-color);
731
+ }
732
+
733
+ .history-round-title {
734
+ font-weight: 900;
735
+ font-size: 0.85rem;
736
+ color: var(--accent);
737
+ text-transform: uppercase;
738
+ letter-spacing: 0.04em;
739
+ }
740
+
741
+ .history-round-total {
742
+ font-weight: 900;
743
+ font-size: 0.85rem;
744
+ color: var(--text-muted);
745
+ }
746
+
747
+ .history-scores-body {
748
+ padding: 0.5rem 1rem;
749
+ }
750
+
751
+ .history-score-line {
752
+ display: flex;
753
+ justify-content: space-between;
754
+ align-items: center;
755
+ font-size: 0.85rem;
756
+ padding: 0.35rem 0;
757
+ border-bottom: 1px solid var(--border-color);
758
+ }
759
+
760
+ .history-score-line:last-child {
761
+ border-bottom: none;
762
+ }
763
+
764
+ .history-score-line:hover {
765
+ background: rgba(244, 63, 94, 0.02);
766
+ margin: 0 -1rem;
767
+ padding: 0.35rem 1rem;
768
+ }
769
+
770
+ .history-player-name {
771
+ font-weight: 700;
772
+ color: var(--text-base);
773
+ display: flex;
774
+ align-items: center;
775
+ gap: 0.4rem;
776
+ }
777
+
778
+ .history-player-score {
779
+ font-weight: 900;
780
+ font-size: 0.95rem;
781
+ padding: 0.1rem 0.5rem;
782
+ border-radius: 0.375rem;
783
+ }
784
+
785
+ .history-player-score.positive {
786
+ color: var(--score-first);
787
+ background: rgba(34, 197, 94, 0.08);
788
+ }
789
+
790
+ .history-player-score.negative {
791
+ color: var(--score-last);
792
+ background: rgba(239, 68, 68, 0.08);
793
+ }
794
+
795
+ .history-player-score.zero {
796
+ color: var(--text-muted);
797
+ background: transparent;
798
+ }
799
+
800
+ .rename-popup {
801
+ position: fixed;
802
+ inset: 0;
803
+ background: rgba(0, 0, 0, 0.5);
804
+ display: flex;
805
+ align-items: center;
806
+ justify-content: center;
807
+ z-index: 100;
808
+ animation: overlay-in 0.2s ease;
809
+ backdrop-filter: blur(4px);
810
+ }
811
+
812
+ @keyframes overlay-in {
813
+ 0% { opacity: 0; }
814
+ 100% { opacity: 1; }
815
+ }
816
+
817
+ .rename-popup-content {
818
+ background: var(--bg-surface);
819
+ border: 1px solid var(--border-color);
820
+ border-radius: 1rem;
821
+ padding: 1.5rem;
822
+ min-width: 300px;
823
+ display: flex;
824
+ flex-direction: column;
825
+ gap: 1rem;
826
+ box-shadow: 0 24px 80px rgba(0, 0, 0, 0.3);
827
+ animation: modal-pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
828
+ }
829
+
830
+ @keyframes modal-pop {
831
+ 0% {
832
+ transform: scale(0.85);
833
+ opacity: 0;
834
+ }
835
+ 100% {
836
+ transform: scale(1);
837
+ opacity: 1;
838
+ }
839
+ }
840
+
841
+ .rename-popup-content h3 {
842
+ margin: 0;
843
+ font-size: 1rem;
844
+ font-weight: 900;
845
+ text-transform: uppercase;
846
+ color: var(--accent);
847
+ }
848
+
849
+ .rename-popup-content input {
850
+ background: var(--bg-page);
851
+ border: 1px solid var(--border-color);
852
+ border-radius: 0.5rem;
853
+ padding: 0.6rem 0.75rem;
854
+ color: var(--text-base);
855
+ font-weight: 700;
856
+ font-size: 0.95rem;
857
+ outline: none;
858
+ transition: border-color 0.2s ease;
859
+ }
860
+
861
+ .rename-popup-content input:focus {
862
+ border-color: var(--accent);
863
+ box-shadow: 0 0 0 3px rgba(244, 63, 94, 0.1);
864
+ }
865
+
866
+ .rename-popup-actions {
867
+ display: flex;
868
+ gap: 0.5rem;
869
+ justify-content: flex-end;
870
+ }
871
+
872
+ .btn-rename-confirm {
873
+ background: var(--accent);
874
+ color: var(--color-white);
875
+ border: none;
876
+ font-weight: 800;
877
+ padding: 0.5rem 1.25rem;
878
+ border-radius: 0.5rem;
879
+ cursor: pointer;
880
+ transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
881
+ }
882
+
883
+ .btn-rename-confirm:hover {
884
+ opacity: 0.9;
885
+ transform: translateY(-1px) scale(1.03);
886
+ box-shadow: 0 4px 12px rgba(244, 63, 94, 0.3);
887
+ }
888
+
889
+ .btn-rename-confirm:active {
890
+ transform: scale(0.97);
891
+ }
892
+
893
+ .btn-rename-cancel {
894
+ background: var(--bg-page);
895
+ color: var(--text-muted);
896
+ border: 1px solid var(--border-color);
897
+ font-weight: 800;
898
+ padding: 0.5rem 1.25rem;
899
+ border-radius: 0.5rem;
900
+ cursor: pointer;
901
+ transition: all 0.2s ease;
902
+ }
903
+
904
+ .btn-rename-cancel:hover {
905
+ color: var(--text-base);
906
+ border-color: var(--accent);
907
+ }
908
+
909
+ .floating-score-particle {
910
+ position: absolute;
911
+ color: var(--color-white);
912
+ font-weight: 900;
913
+ font-size: 1.5rem;
914
+ pointer-events: none;
915
+ z-index: 50;
916
+ animation: particle-float-up 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
917
+ }
918
+
919
+ .floating-score-particle.particle-positive {
920
+ text-shadow: 0 0 10px var(--score-first), 0 0 20px var(--score-first), 0 0 30px rgba(34, 197, 94, 0.3);
921
+ color: var(--score-first);
922
+ }
923
+
924
+ .floating-score-particle.particle-negative {
925
+ text-shadow: 0 0 10px var(--score-last), 0 0 20px var(--score-last), 0 0 30px rgba(239, 68, 68, 0.3);
926
+ color: var(--score-last);
927
+ }
928
+
929
+ @keyframes particle-float-up {
930
+ 0% {
931
+ transform: translateY(0) scale(0.4) rotate(-10deg);
932
+ opacity: 0;
933
+ }
934
+ 20% {
935
+ opacity: 1;
936
+ transform: translateY(-12px) scale(1.4) rotate(5deg);
937
+ }
938
+ 100% {
939
+ transform: translateY(-70px) scale(1.8) rotate(-15deg);
940
+ opacity: 0;
941
+ }
942
+ }
943
+
944
+ .floating-big-particle {
945
+ position: fixed;
946
+ pointer-events: none;
947
+ z-index: 200;
948
+ font-weight: 900;
949
+ font-size: 3rem;
950
+ animation: big-particle-float 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
951
+ }
952
+
953
+ .floating-big-particle.big-positive {
954
+ text-shadow: 0 0 20px var(--score-first), 0 0 40px var(--score-first), 0 0 60px rgba(34, 197, 94, 0.2);
955
+ color: var(--score-first);
956
+ }
957
+
958
+ .floating-big-particle.big-negative {
959
+ text-shadow: 0 0 20px var(--score-last), 0 0 40px var(--score-last), 0 0 60px rgba(239, 68, 68, 0.2);
960
+ color: var(--score-last);
961
+ }
962
+
963
+ @keyframes big-particle-float {
964
+ 0% {
965
+ transform: translate(-50%, -50%) scale(0.3) rotate(-20deg);
966
+ opacity: 0;
967
+ }
968
+ 25% {
969
+ opacity: 1;
970
+ transform: translate(-50%, -60%) scale(1.3) rotate(10deg);
971
+ }
972
+ 100% {
973
+ transform: translate(-50%, -120%) scale(1) rotate(-5deg);
974
+ opacity: 0;
975
+ }
976
+ }
977
+
978
+
979
+
980
+ .no-history-msg {
981
+ text-align: center;
982
+ color: var(--text-muted);
983
+ font-weight: 700;
984
+ padding: 2rem 1rem;
985
+ }
986
+
987
+ .score-header-actions {
988
+ display: flex;
989
+ gap: 0.5rem;
990
+ flex-wrap: wrap;
991
+ }
992
+
993
+ .score-round-actions {
994
+ display: flex;
995
+ gap: 0.5rem;
996
+ }
997
+
998
+ .score-footer-actions {
999
+ display: flex;
1000
+ gap: 0.75rem;
1001
+ justify-content: flex-end;
1002
+ border-top: 1px solid var(--border-color);
1003
+ padding-top: 1rem;
1004
+ }
1005
+
1006
+ .btn-score-action.lp-active {
1007
+ position: relative;
1008
+ overflow: hidden;
1009
+ }
1010
+
1011
+ .btn-score-action.lp-active::before {
1012
+ content: '';
1013
+ position: absolute;
1014
+ inset: 0;
1015
+ background: var(--accent);
1016
+ opacity: 0.55;
1017
+ animation: lp-fill var(--lp-dur) linear forwards;
1018
+ transform-origin: left center;
1019
+ }
1020
+
1021
+ .btn-score-action.danger.lp-active::before {
1022
+ background: var(--score-last);
1023
+ opacity: 0.6;
1024
+ }
1025
+
1026
+ @keyframes lp-fill {
1027
+ from { transform: scaleX(0); }
1028
+ to { transform: scaleX(1); }
1029
+ }