@gamepark/react-game 7.6.1 → 7.6.3

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 (46) hide show
  1. package/dist/components/GameProvider/GameErrorBoundary.js +108 -108
  2. package/dist/components/JournalTabs/History/SetupLogItem.js +19 -19
  3. package/dist/components/material/Dices/OctahedralDiceDescription.d.ts +48 -0
  4. package/dist/components/material/Dices/OctahedralDiceDescription.js +142 -0
  5. package/dist/components/material/Dices/OctahedralDiceDescription.js.map +1 -0
  6. package/dist/components/material/GameTable/DevToolEntry.d.ts +17 -0
  7. package/dist/components/material/GameTable/DevToolEntry.js +13 -0
  8. package/dist/components/material/GameTable/DevToolEntry.js.map +1 -0
  9. package/dist/components/material/GameTable/DevTools/DevToolsStyles.d.ts +58 -0
  10. package/dist/components/material/GameTable/DevTools/DevToolsStyles.js +706 -0
  11. package/dist/components/material/GameTable/DevTools/DevToolsStyles.js.map +1 -0
  12. package/dist/components/material/GameTable/DevToolsHub.d.ts +4 -21
  13. package/dist/components/material/GameTable/DevToolsHub.js +24 -830
  14. package/dist/components/material/GameTable/DevToolsHub.js.map +1 -1
  15. package/dist/components/material/GameTable/DevToolsStyles.d.ts +67 -0
  16. package/dist/components/material/GameTable/DevToolsStyles.js +752 -0
  17. package/dist/components/material/GameTable/DevToolsStyles.js.map +1 -0
  18. package/dist/components/material/GameTable/JsonHighlighter.d.ts +3 -0
  19. package/dist/components/material/GameTable/JsonHighlighter.js +37 -0
  20. package/dist/components/material/GameTable/JsonHighlighter.js.map +1 -0
  21. package/dist/components/menus/BugReport/BugReportButton.d.ts +1 -0
  22. package/dist/components/menus/BugReport/BugReportButton.js +13 -0
  23. package/dist/components/menus/BugReport/BugReportButton.js.map +1 -0
  24. package/dist/components/menus/BugReport/BugReportDialog.d.ts +6 -0
  25. package/dist/components/menus/BugReport/BugReportDialog.js +110 -0
  26. package/dist/components/menus/BugReport/BugReportDialog.js.map +1 -0
  27. package/dist/components/menus/BugReport/index.d.ts +2 -0
  28. package/dist/components/menus/BugReport/index.js +3 -0
  29. package/dist/components/menus/BugReport/index.js.map +1 -0
  30. package/dist/components/menus/Menu/Menu.js +2 -1
  31. package/dist/components/menus/Menu/Menu.js.map +1 -1
  32. package/dist/css/backgroundCss.js +3 -3
  33. package/dist/css/cursorCss.js +6 -6
  34. package/dist/css/fadeIn.js +6 -6
  35. package/dist/css/shineEffect.js +28 -28
  36. package/dist/css/transformCss.js +4 -4
  37. package/package.json +3 -3
  38. package/dist/components/material/Wheel/WheelContent.d.ts +0 -13
  39. package/dist/components/material/Wheel/WheelContent.js +0 -37
  40. package/dist/components/material/Wheel/WheelContent.js.map +0 -1
  41. package/dist/hooks/useFailures.d.ts +0 -1
  42. package/dist/hooks/useFailures.js +0 -11
  43. package/dist/hooks/useFailures.js.map +0 -1
  44. package/dist/hooks/useWebP.d.ts +0 -1
  45. package/dist/hooks/useWebP.js +0 -13
  46. package/dist/hooks/useWebP.js.map +0 -1
@@ -1,64 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
2
2
  /** @jsxImportSource @emotion/react */
3
- import { css, keyframes } from '@emotion/react';
4
3
  import { useCallback, useContext, useRef, useState } from 'react';
5
4
  import { createPortal } from 'react-dom';
6
5
  import { usePlayerId, usePlayerIds } from '../../../hooks/usePlayerId';
7
6
  import { gameContext } from '../../GameProvider/GameContext';
8
- const GP_PRIMARY = '#28B8CE';
9
- const GP_DARK = '#002448';
10
- const GP_SURFACE = '#0a1929';
11
- const GP_ACCENT = '#9fe2f7';
12
- // ═══════════════════════════════════════
13
- // JSON syntax highlighting (pure React)
14
- // ═══════════════════════════════════════
15
- const highlightJson = (json) => {
16
- const parts = [];
17
- // Regex to match JSON tokens
18
- const tokenRegex = /("(?:\\.|[^"\\])*"\s*:)|("(?:\\.|[^"\\])*")|(true|false|null)|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|([{}[\],])/g;
19
- let lastIndex = 0;
20
- let match;
21
- while ((match = tokenRegex.exec(json)) !== null) {
22
- // Add whitespace between tokens
23
- if (match.index > lastIndex) {
24
- parts.push(json.slice(lastIndex, match.index));
25
- }
26
- const [full, key, str, bool, num, punct] = match;
27
- if (key) {
28
- // key: "xxx":
29
- const colonIdx = key.lastIndexOf(':');
30
- parts.push(_jsx("span", { css: jsonKeyCss, children: key.slice(0, colonIdx) }, `k${match.index}`));
31
- parts.push(key.slice(colonIdx));
32
- }
33
- else if (str) {
34
- parts.push(_jsx("span", { css: jsonStringCss, children: full }, `s${match.index}`));
35
- }
36
- else if (bool) {
37
- parts.push(_jsx("span", { css: jsonBoolCss, children: full }, `b${match.index}`));
38
- }
39
- else if (num) {
40
- parts.push(_jsx("span", { css: jsonNumCss, children: full }, `n${match.index}`));
41
- }
42
- else if (punct) {
43
- parts.push(_jsx("span", { css: jsonPunctCss, children: full }, `p${match.index}`));
44
- }
45
- lastIndex = match.index + full.length;
46
- }
47
- if (lastIndex < json.length) {
48
- parts.push(json.slice(lastIndex));
49
- }
50
- return parts;
51
- };
52
- /**
53
- * A single entry in the DevToolsHub panel.
54
- * Use this instead of raw `<button>` when adding custom tools via `children`.
55
- *
56
- * @example
57
- * <DevToolsHub>
58
- * <DevToolEntry icon="✦" label="Card Viewer" desc="Browse agents" onClick={() => setShowCards(true)} />
59
- * </DevToolsHub>
60
- */
61
- export const DevToolEntry = ({ icon, label, desc, onClick }) => (_jsxs("button", { css: devToolBtnCss, onClick: onClick, children: [_jsx("span", { css: devToolIconCss, children: icon }), _jsx("span", { css: devToolLabelCss, children: label }), desc && _jsx("span", { css: devToolDescCss, children: desc })] }));
7
+ import { highlightJson } from './JsonHighlighter';
8
+ import { fabCss, logoCss, hubContainerCss, mainMenuCss, subPanelCss, subPanelHeaderCss, subPanelTitleCss, subPanelContentCss, panelHeaderCss, headerLogoCss, panelTitleCss, panelBadgeCss, menuListCss, menuItemCss, menuItemActiveCss, menuItemIconCss, menuItemLabelCss, menuChevronCss, devToolBtnCss, devToolIconCss, devToolLabelCss, devToolDescCss, toolBtnActiveCss, activeIndicatorCss, dividerCss, inlineRowCss, stepBtnCss, numberInputCss, textInputCss, goBtnCss, playerBtnCss, playerBtnActiveCss, savedListCss, savedEntryCss, savedLabelCss, savedActionsCss, smallBtnCss, smallBtnDangerCss, backdropCss, flashCss, modalBackdropCss, modalCss, modalHeaderCss, modalTitleCss, modalCloseBtnCss, modalBodyCss, modalTextareaCss, jsonPreviewCss, jsonPreviewLabelCss, jsonPreviewCodeCss, jsonErrorTextCss, pasteErrorCss, modalFooterCss, modalCancelBtnCss, modalLoadBtnCss, toggleRowCss, checkboxCss, toggleLabelCss } from './DevToolsStyles';
9
+ export { DevToolEntry } from './DevToolEntry';
10
+ export { devToolBtnCss, devToolIconCss, devToolLabelCss, devToolDescCss } from './DevToolsStyles';
62
11
  // ═══════════════════════════════════════
63
12
  // Save/Load helpers
64
13
  // ═══════════════════════════════════════
@@ -146,19 +95,15 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
146
95
  return;
147
96
  }
148
97
  try {
149
- const state = JSON.parse(raw);
150
- if (g) {
151
- g.new(state);
152
- doFlash(`Loaded: ${getSaveLabel(key, gameName)}`);
153
- }
154
- else {
155
- doFlash('game helper not available');
156
- }
98
+ JSON.parse(raw); // validate JSON
99
+ localStorage.setItem(gameName, raw);
100
+ doFlash(`Loaded: ${getSaveLabel(key, gameName)}`);
101
+ window.location.reload();
157
102
  }
158
103
  catch {
159
104
  doFlash('Invalid save data');
160
105
  }
161
- }, [g, gameName, doFlash]);
106
+ }, [gameName, doFlash]);
162
107
  const handleDownloadSave = useCallback((key) => {
163
108
  const raw = localStorage.getItem(key);
164
109
  if (!raw) {
@@ -187,14 +132,11 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
187
132
  const reader = new FileReader();
188
133
  reader.onload = () => {
189
134
  try {
190
- const state = JSON.parse(reader.result);
191
- if (g) {
192
- g.new(state);
193
- doFlash(`Imported: ${file.name}`);
194
- }
195
- else {
196
- doFlash('game helper not available');
197
- }
135
+ const raw = reader.result;
136
+ JSON.parse(raw); // validate JSON
137
+ localStorage.setItem(gameName, raw);
138
+ doFlash(`Imported: ${file.name}`);
139
+ window.location.reload();
198
140
  }
199
141
  catch {
200
142
  doFlash('Invalid JSON file');
@@ -202,33 +144,28 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
202
144
  };
203
145
  reader.readAsText(file);
204
146
  e.target.value = '';
205
- }, [g, doFlash]);
147
+ }, [gameName, doFlash]);
206
148
  const handleImportPaste = useCallback(() => {
207
149
  if (!importText.trim()) {
208
150
  setPasteError('Paste a JSON state first');
209
151
  return;
210
152
  }
211
153
  try {
212
- const state = JSON.parse(importText);
213
- if (g) {
214
- g.new(state);
215
- setImportText('');
216
- setPasteError(null);
217
- setShowPasteModal(false);
218
- doFlash('State imported!');
219
- }
220
- else {
221
- setPasteError('game helper not available');
222
- }
154
+ JSON.parse(importText); // validate JSON
155
+ localStorage.setItem(gameName, importText);
156
+ setImportText('');
157
+ setPasteError(null);
158
+ setShowPasteModal(false);
159
+ doFlash('State imported!');
160
+ window.location.reload();
223
161
  }
224
162
  catch {
225
163
  setPasteError('Invalid JSON — check syntax');
226
164
  }
227
- }, [g, importText, doFlash]);
165
+ }, [gameName, importText, doFlash]);
228
166
  const handlePasteChange = useCallback((value) => {
229
167
  setImportText(value);
230
168
  setPasteError(null);
231
- // Try to pretty-print if valid
232
169
  try {
233
170
  const parsed = JSON.parse(value);
234
171
  setImportText(JSON.stringify(parsed, null, 2));
@@ -276,7 +213,7 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
276
213
  handleSave(); }, css: textInputCss }), _jsx("button", { css: goBtnCss, onClick: handleSave, children: "Save" })] })] }), saveKeys.length > 0 && (_jsx("div", { css: savedListCss, children: saveKeys.map(key => (_jsxs("div", { css: savedEntryCss, children: [_jsx("span", { css: savedLabelCss, children: getSaveLabel(key, gameName) }), _jsxs("div", { css: savedActionsCss, children: [_jsx("button", { css: smallBtnCss, onClick: () => handleLoad(key), title: "Load", children: '\u25B6' }), _jsx("button", { css: smallBtnCss, onClick: () => handleDownloadSave(key), title: "Download", children: '\u2913' }), _jsx("button", { css: [smallBtnCss, smallBtnDangerCss], onClick: () => handleDelete(key), title: "Delete", children: '\u2715' })] })] }, key))) })), _jsx("div", { css: dividerCss }), _jsxs("button", { css: devToolBtnCss, onClick: () => fileInputRef.current?.click(), children: [_jsx("span", { css: devToolIconCss, children: '\u2912' }), _jsx("span", { css: devToolLabelCss, children: "Import File" }), _jsx("span", { css: devToolDescCss, children: "Load state from JSON file" })] }), _jsx("input", { ref: fileInputRef, type: "file", accept: ".json,application/json", onChange: handleImportFile, style: { display: 'none' } }), _jsxs("button", { css: devToolBtnCss, onClick: () => { setShowPasteModal(true); setPasteError(null); }, children: [_jsx("span", { css: devToolIconCss, children: '\u2398' }), _jsx("span", { css: devToolLabelCss, children: "Paste State" }), _jsx("span", { css: devToolDescCss, children: "Open editor to paste JSON" })] })] })), activeMenu === 'export' && (_jsxs(_Fragment, { children: [_jsxs("button", { css: devToolBtnCss, onClick: handleDownloadState, children: [_jsx("span", { css: devToolIconCss, children: '\u2913' }), _jsx("span", { css: devToolLabelCss, children: "Download State" }), _jsx("span", { css: devToolDescCss, children: "Save state as .json file" })] }), _jsxs("button", { css: devToolBtnCss, onClick: () => {
277
214
  const raw = localStorage.getItem(gameName);
278
215
  if (raw) {
279
- copyToClipboard(raw, `${gameName} state`);
216
+ void copyToClipboard(raw, `${gameName} state`);
280
217
  }
281
218
  else {
282
219
  doFlash(`No "${gameName}" key in localStorage`);
@@ -290,747 +227,4 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
290
227
  }
291
228
  })() })] })), pasteError && _jsx("div", { css: pasteErrorCss, children: pasteError })] }), _jsxs("div", { css: modalFooterCss, children: [_jsx("button", { css: modalCancelBtnCss, onClick: () => { setShowPasteModal(false); setPasteError(null); }, children: "Cancel" }), _jsx("button", { css: modalLoadBtnCss, onClick: handleImportPaste, children: "Load State" })] })] })] }))] }), root);
292
229
  };
293
- // ═══════════════════════════════════════
294
- // Styles — GamePark branded
295
- // ═══════════════════════════════════════
296
- const fabPulse = keyframes `
297
- 0%, 100% { box-shadow: 0 0 0 0 rgba(40, 184, 206, 0.25); }
298
- 50% { box-shadow: 0 0 0 5px rgba(40, 184, 206, 0); }
299
- `;
300
- const fabCss = css `
301
- position: fixed;
302
- bottom: 16px;
303
- left: 16px;
304
- z-index: 900;
305
- width: 40px;
306
- height: 40px;
307
- border-radius: 10px;
308
- border: 1px solid rgba(40, 184, 206, 0.4);
309
- background: linear-gradient(145deg, ${GP_SURFACE}, ${GP_DARK});
310
- cursor: pointer;
311
- display: flex;
312
- align-items: center;
313
- justify-content: center;
314
- padding: 0;
315
- animation: ${fabPulse} 3s ease-in-out infinite;
316
- transition: all 0.2s;
317
-
318
- &:hover {
319
- border-color: rgba(40, 184, 206, 0.7);
320
- animation: none;
321
- }
322
-
323
- &[data-open="true"] {
324
- animation: none;
325
- background: ${GP_PRIMARY};
326
- border-color: ${GP_PRIMARY};
327
- }
328
- `;
329
- const logoCss = css `
330
- width: 22px;
331
- height: 22px;
332
- fill: ${GP_PRIMARY};
333
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
334
-
335
- &[data-open="true"] {
336
- fill: ${GP_DARK};
337
- transform: rotate(90deg);
338
- }
339
- `;
340
- const slideUp = keyframes `
341
- from { opacity: 0; transform: translateY(8px) scale(0.97); }
342
- to { opacity: 1; transform: translateY(0) scale(1); }
343
- `;
344
- const slideRight = keyframes `
345
- from { opacity: 0; transform: translateX(-8px) scale(0.97); }
346
- to { opacity: 1; transform: translateX(0) scale(1); }
347
- `;
348
- const hubContainerCss = css `
349
- position: fixed;
350
- bottom: 64px;
351
- left: 16px;
352
- z-index: 900;
353
- display: flex;
354
- align-items: flex-end;
355
- gap: 6px;
356
- `;
357
- const mainMenuCss = css `
358
- position: relative;
359
- width: 200px;
360
- background: linear-gradient(170deg, #0f2035 0%, ${GP_SURFACE} 100%);
361
- border: 1px solid rgba(40, 184, 206, 0.25);
362
- border-radius: 12px;
363
- box-shadow:
364
- 0 12px 40px rgba(0, 0, 0, 0.5),
365
- 0 0 0 1px rgba(0, 0, 0, 0.3),
366
- inset 0 1px 0 rgba(159, 226, 247, 0.05);
367
- animation: ${slideUp} 0.2s ease-out;
368
- font-family: 'Mulish', sans-serif;
369
- overflow: hidden;
370
- `;
371
- const subPanelCss = css `
372
- width: 320px;
373
- max-height: calc(100vh - 80px);
374
- display: flex;
375
- flex-direction: column;
376
- background: linear-gradient(170deg, #0f2035 0%, ${GP_SURFACE} 100%);
377
- border: 1px solid rgba(40, 184, 206, 0.25);
378
- border-radius: 12px;
379
- box-shadow:
380
- 0 12px 40px rgba(0, 0, 0, 0.5),
381
- 0 0 0 1px rgba(0, 0, 0, 0.3),
382
- inset 0 1px 0 rgba(159, 226, 247, 0.05);
383
- animation: ${slideRight} 0.15s ease-out;
384
- font-family: 'Mulish', sans-serif;
385
- overflow: hidden;
386
- `;
387
- const subPanelHeaderCss = css `
388
- padding: 10px 16px;
389
- border-bottom: 1px solid rgba(40, 184, 206, 0.15);
390
- background: rgba(40, 184, 206, 0.04);
391
- flex-shrink: 0;
392
- `;
393
- const subPanelTitleCss = css `
394
- font-size: 12px;
395
- font-weight: 800;
396
- color: #5a8a98;
397
- text-transform: uppercase;
398
- letter-spacing: 0.1em;
399
- `;
400
- const subPanelContentCss = css `
401
- display: flex;
402
- flex-direction: column;
403
- padding: 6px;
404
- gap: 2px;
405
- overflow-y: auto;
406
- flex: 1;
407
- min-height: 0;
408
- `;
409
- const panelHeaderCss = css `
410
- display: flex;
411
- align-items: center;
412
- gap: 8px;
413
- padding: 12px 16px;
414
- border-bottom: 1px solid rgba(40, 184, 206, 0.15);
415
- background: rgba(40, 184, 206, 0.04);
416
- `;
417
- const headerLogoCss = css `
418
- width: 18px;
419
- height: 18px;
420
- fill: ${GP_ACCENT};
421
- flex-shrink: 0;
422
- `;
423
- const panelTitleCss = css `
424
- font-size: 14px;
425
- font-weight: 800;
426
- color: #e0f0f4;
427
- text-transform: uppercase;
428
- letter-spacing: 0.08em;
429
- flex: 1;
430
- `;
431
- const panelBadgeCss = css `
432
- font-size: 9px;
433
- font-weight: 800;
434
- padding: 2px 6px;
435
- border-radius: 4px;
436
- background: rgba(40, 184, 206, 0.15);
437
- color: ${GP_PRIMARY};
438
- letter-spacing: 0.1em;
439
- `;
440
- const menuListCss = css `
441
- display: flex;
442
- flex-direction: column;
443
- padding: 6px;
444
- gap: 2px;
445
- `;
446
- const menuItemCss = css `
447
- position: relative;
448
- display: flex;
449
- align-items: center;
450
- gap: 10px;
451
- padding: 10px 12px;
452
- border: none;
453
- border-radius: 8px;
454
- background: transparent;
455
- cursor: pointer;
456
- text-align: left;
457
- transition: background 0.15s;
458
- font-family: inherit;
459
-
460
- &:hover {
461
- background: rgba(40, 184, 206, 0.08);
462
- }
463
- `;
464
- const menuItemActiveCss = css `
465
- background: rgba(40, 184, 206, 0.12);
466
-
467
- &::before {
468
- content: '';
469
- position: absolute;
470
- left: 0;
471
- top: 50%;
472
- transform: translateY(-50%);
473
- width: 3px;
474
- height: 18px;
475
- border-radius: 0 3px 3px 0;
476
- background: ${GP_PRIMARY};
477
- }
478
- `;
479
- const menuItemIconCss = css `
480
- font-size: 15px;
481
- color: ${GP_PRIMARY};
482
- display: flex;
483
- align-items: center;
484
- justify-content: center;
485
- width: 28px;
486
- height: 28px;
487
- border-radius: 6px;
488
- background: rgba(40, 184, 206, 0.08);
489
- flex-shrink: 0;
490
- `;
491
- const menuItemLabelCss = css `
492
- font-size: 13px;
493
- font-weight: 700;
494
- color: #e0f0f4;
495
- flex: 1;
496
- `;
497
- const menuChevronCss = css `
498
- font-size: 10px;
499
- color: #3a6070;
500
- `;
501
- const toolReveal = keyframes `
502
- from { opacity: 0; transform: translateX(-6px); }
503
- to { opacity: 1; transform: translateX(0); }
504
- `;
505
- export const devToolBtnCss = css `
506
- position: relative;
507
- display: grid;
508
- grid-template-columns: 28px 1fr;
509
- grid-template-rows: auto auto;
510
- align-items: center;
511
- gap: 0 10px;
512
- padding: 10px 12px;
513
- border: none;
514
- border-radius: 8px;
515
- background: transparent;
516
- cursor: pointer;
517
- text-align: left;
518
- transition: background 0.15s;
519
- animation: ${toolReveal} 0.25s ease-out backwards;
520
- font-family: inherit;
521
-
522
- &:hover {
523
- background: rgba(40, 184, 206, 0.08);
524
- }
525
- &:active {
526
- background: rgba(40, 184, 206, 0.14);
527
- }
528
- `;
529
- const toolBtnActiveCss = css `
530
- background: rgba(40, 184, 206, 0.1);
531
- &::after {
532
- content: '';
533
- position: absolute;
534
- left: 0;
535
- top: 8px;
536
- bottom: 8px;
537
- width: 3px;
538
- border-radius: 0 3px 3px 0;
539
- background: ${GP_PRIMARY};
540
- }
541
- `;
542
- export const devToolIconCss = css `
543
- grid-row: 1 / -1;
544
- font-size: 15px;
545
- color: ${GP_PRIMARY};
546
- display: flex;
547
- align-items: center;
548
- justify-content: center;
549
- width: 28px;
550
- height: 28px;
551
- border-radius: 6px;
552
- background: rgba(40, 184, 206, 0.08);
553
- `;
554
- export const devToolLabelCss = css `
555
- font-size: 14px;
556
- font-weight: 700;
557
- color: #e0f0f4;
558
- line-height: 1.2;
559
- `;
560
- export const devToolDescCss = css `
561
- font-size: 12px;
562
- color: #5a8a98;
563
- line-height: 1.2;
564
- `;
565
- const activeIndicatorCss = css `
566
- position: absolute;
567
- top: 10px;
568
- right: 12px;
569
- width: 7px;
570
- height: 7px;
571
- border-radius: 50%;
572
- background: ${GP_PRIMARY};
573
- box-shadow: 0 0 6px rgba(40, 184, 206, 0.5);
574
- `;
575
- const dividerCss = css `
576
- height: 1px;
577
- margin: 4px 12px;
578
- background: rgba(40, 184, 206, 0.1);
579
- `;
580
- // ── Inline controls ──
581
- const inlineRowCss = css `
582
- grid-column: 1 / -1;
583
- display: flex;
584
- align-items: center;
585
- gap: 4px;
586
- margin-top: 6px;
587
- `;
588
- const stepBtnCss = css `
589
- width: 26px;
590
- height: 26px;
591
- border-radius: 5px;
592
- border: 1px solid rgba(40, 184, 206, 0.25);
593
- background: rgba(40, 184, 206, 0.06);
594
- color: ${GP_PRIMARY};
595
- font-size: 14px;
596
- font-weight: 700;
597
- cursor: pointer;
598
- display: flex;
599
- align-items: center;
600
- justify-content: center;
601
- font-family: inherit;
602
- transition: all 0.15s;
603
-
604
- &:hover {
605
- background: rgba(40, 184, 206, 0.14);
606
- border-color: rgba(40, 184, 206, 0.4);
607
- }
608
- `;
609
- const numberInputCss = css `
610
- width: 48px;
611
- height: 26px;
612
- border-radius: 5px;
613
- border: 1px solid rgba(40, 184, 206, 0.25);
614
- background: rgba(0, 0, 0, 0.3);
615
- color: #e0f0f4;
616
- font-size: 13px;
617
- font-weight: 700;
618
- text-align: center;
619
- font-family: inherit;
620
- font-variant-numeric: tabular-nums;
621
-
622
- &:focus {
623
- outline: none;
624
- border-color: ${GP_PRIMARY};
625
- box-shadow: 0 0 0 2px rgba(40, 184, 206, 0.15);
626
- }
627
-
628
- &::-webkit-inner-spin-button,
629
- &::-webkit-outer-spin-button {
630
- -webkit-appearance: none;
631
- margin: 0;
632
- }
633
- `;
634
- const textInputCss = css `
635
- flex: 1;
636
- height: 26px;
637
- border-radius: 5px;
638
- border: 1px solid rgba(40, 184, 206, 0.25);
639
- background: rgba(0, 0, 0, 0.3);
640
- color: #e0f0f4;
641
- font-size: 12px;
642
- font-weight: 600;
643
- padding: 0 8px;
644
- font-family: inherit;
645
-
646
- &::placeholder {
647
- color: #3a6070;
648
- }
649
-
650
- &:focus {
651
- outline: none;
652
- border-color: ${GP_PRIMARY};
653
- box-shadow: 0 0 0 2px rgba(40, 184, 206, 0.15);
654
- }
655
- `;
656
- const goBtnCss = css `
657
- height: 26px;
658
- padding: 0 12px;
659
- border-radius: 5px;
660
- border: 1px solid rgba(40, 184, 206, 0.35);
661
- background: rgba(40, 184, 206, 0.15);
662
- color: ${GP_PRIMARY};
663
- font-size: 12px;
664
- font-weight: 800;
665
- text-transform: uppercase;
666
- letter-spacing: 0.05em;
667
- cursor: pointer;
668
- margin-left: auto;
669
- font-family: inherit;
670
- transition: all 0.15s;
671
- flex-shrink: 0;
672
-
673
- &:hover {
674
- background: rgba(40, 184, 206, 0.25);
675
- border-color: rgba(40, 184, 206, 0.5);
676
- }
677
- `;
678
- const playerBtnCss = css `
679
- height: 26px;
680
- padding: 0 10px;
681
- border-radius: 5px;
682
- border: 1px solid rgba(40, 184, 206, 0.25);
683
- background: rgba(40, 184, 206, 0.06);
684
- color: #5a8a98;
685
- font-size: 12px;
686
- font-weight: 700;
687
- cursor: pointer;
688
- font-family: inherit;
689
- transition: all 0.15s;
690
-
691
- &:hover {
692
- background: rgba(40, 184, 206, 0.14);
693
- border-color: rgba(40, 184, 206, 0.4);
694
- color: #e0f0f4;
695
- }
696
- `;
697
- const playerBtnActiveCss = css `
698
- background: rgba(40, 184, 206, 0.2);
699
- border-color: ${GP_PRIMARY};
700
- color: ${GP_PRIMARY};
701
- `;
702
- // ── Save/Load styles ──
703
- const savedListCss = css `
704
- display: flex;
705
- flex-direction: column;
706
- gap: 2px;
707
- padding: 0 8px;
708
- `;
709
- const savedEntryCss = css `
710
- display: flex;
711
- align-items: center;
712
- justify-content: space-between;
713
- padding: 5px 8px;
714
- border-radius: 5px;
715
- background: rgba(40, 184, 206, 0.04);
716
- border: 1px solid rgba(40, 184, 206, 0.08);
717
- `;
718
- const savedLabelCss = css `
719
- font-size: 12px;
720
- font-weight: 600;
721
- color: #8ab8c8;
722
- overflow: hidden;
723
- text-overflow: ellipsis;
724
- white-space: nowrap;
725
- flex: 1;
726
- margin-right: 8px;
727
- `;
728
- const savedActionsCss = css `
729
- display: flex;
730
- gap: 4px;
731
- flex-shrink: 0;
732
- `;
733
- const smallBtnCss = css `
734
- width: 22px;
735
- height: 22px;
736
- border-radius: 4px;
737
- border: 1px solid rgba(40, 184, 206, 0.25);
738
- background: rgba(40, 184, 206, 0.08);
739
- color: ${GP_PRIMARY};
740
- font-size: 10px;
741
- cursor: pointer;
742
- display: flex;
743
- align-items: center;
744
- justify-content: center;
745
- font-family: inherit;
746
- transition: all 0.15s;
747
-
748
- &:hover {
749
- background: rgba(40, 184, 206, 0.2);
750
- border-color: rgba(40, 184, 206, 0.4);
751
- }
752
- `;
753
- const smallBtnDangerCss = css `
754
- &:hover {
755
- background: rgba(220, 60, 60, 0.2);
756
- border-color: rgba(220, 60, 60, 0.4);
757
- color: #dc3c3c;
758
- }
759
- `;
760
- // ── Backdrop (click-outside to close) ──
761
- const backdropCss = css `
762
- position: fixed;
763
- inset: 0;
764
- z-index: 899;
765
- `;
766
- // ── Paste Modal ──
767
- const modalBackdropCss = css `
768
- position: fixed;
769
- inset: 0;
770
- z-index: 1000;
771
- background: rgba(0, 0, 0, 0.6);
772
- backdrop-filter: blur(2px);
773
- `;
774
- const modalFadeIn = keyframes `
775
- from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
776
- to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
777
- `;
778
- const modalCss = css `
779
- position: fixed;
780
- top: 50%;
781
- left: 50%;
782
- transform: translate(-50%, -50%);
783
- z-index: 1001;
784
- width: min(700px, 90vw);
785
- max-height: 80vh;
786
- display: flex;
787
- flex-direction: column;
788
- background: linear-gradient(170deg, #0f2035 0%, ${GP_SURFACE} 100%);
789
- border: 1px solid rgba(40, 184, 206, 0.3);
790
- border-radius: 12px;
791
- box-shadow: 0 24px 60px rgba(0, 0, 0, 0.7);
792
- font-family: 'Mulish', sans-serif;
793
- animation: ${modalFadeIn} 0.2s ease-out;
794
- `;
795
- const modalHeaderCss = css `
796
- display: flex;
797
- align-items: center;
798
- justify-content: space-between;
799
- padding: 14px 20px;
800
- border-bottom: 1px solid rgba(40, 184, 206, 0.15);
801
- background: rgba(40, 184, 206, 0.04);
802
- border-radius: 12px 12px 0 0;
803
- `;
804
- const modalTitleCss = css `
805
- font-size: 14px;
806
- font-weight: 800;
807
- color: #e0f0f4;
808
- text-transform: uppercase;
809
- letter-spacing: 0.08em;
810
- `;
811
- const modalCloseBtnCss = css `
812
- width: 28px;
813
- height: 28px;
814
- border: none;
815
- border-radius: 6px;
816
- background: rgba(40, 184, 206, 0.08);
817
- color: #5a8a98;
818
- font-size: 12px;
819
- cursor: pointer;
820
- display: flex;
821
- align-items: center;
822
- justify-content: center;
823
- transition: all 0.15s;
824
-
825
- &:hover {
826
- background: rgba(220, 60, 60, 0.2);
827
- color: #dc3c3c;
828
- }
829
- `;
830
- const modalBodyCss = css `
831
- flex: 1;
832
- overflow-y: auto;
833
- padding: 16px 20px;
834
- display: flex;
835
- flex-direction: column;
836
- gap: 12px;
837
- min-height: 0;
838
- `;
839
- const modalTextareaCss = css `
840
- width: 100%;
841
- min-height: 100px;
842
- border-radius: 8px;
843
- border: 1px solid rgba(40, 184, 206, 0.25);
844
- background: rgba(0, 0, 0, 0.4);
845
- color: #e0f0f4;
846
- font-size: 13px;
847
- font-weight: 500;
848
- padding: 12px;
849
- font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
850
- resize: vertical;
851
- line-height: 1.5;
852
-
853
- &::placeholder {
854
- color: #3a6070;
855
- }
856
-
857
- &:focus {
858
- outline: none;
859
- border-color: ${GP_PRIMARY};
860
- box-shadow: 0 0 0 2px rgba(40, 184, 206, 0.15);
861
- }
862
- `;
863
- const jsonPreviewCss = css `
864
- border-radius: 8px;
865
- border: 1px solid rgba(40, 184, 206, 0.15);
866
- background: rgba(0, 0, 0, 0.3);
867
- overflow: hidden;
868
- `;
869
- const jsonPreviewLabelCss = css `
870
- font-size: 10px;
871
- font-weight: 800;
872
- color: #3a6070;
873
- text-transform: uppercase;
874
- letter-spacing: 0.1em;
875
- padding: 6px 12px;
876
- border-bottom: 1px solid rgba(40, 184, 206, 0.08);
877
- `;
878
- const jsonPreviewCodeCss = css `
879
- padding: 12px;
880
- margin: 0;
881
- font-size: 12px;
882
- font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
883
- line-height: 1.6;
884
- color: #8ab8c8;
885
- max-height: 300px;
886
- overflow-y: auto;
887
- white-space: pre;
888
- tab-size: 2;
889
- `;
890
- const pasteErrorCss = css `
891
- font-size: 12px;
892
- font-weight: 700;
893
- color: #dc3c3c;
894
- padding: 6px 10px;
895
- border-radius: 6px;
896
- background: rgba(220, 60, 60, 0.1);
897
- border: 1px solid rgba(220, 60, 60, 0.2);
898
- `;
899
- const modalFooterCss = css `
900
- display: flex;
901
- justify-content: flex-end;
902
- gap: 8px;
903
- padding: 12px 20px;
904
- border-top: 1px solid rgba(40, 184, 206, 0.15);
905
- `;
906
- const modalCancelBtnCss = css `
907
- height: 32px;
908
- padding: 0 16px;
909
- border-radius: 6px;
910
- border: 1px solid rgba(40, 184, 206, 0.25);
911
- background: transparent;
912
- color: #5a8a98;
913
- font-size: 13px;
914
- font-weight: 700;
915
- cursor: pointer;
916
- font-family: inherit;
917
- transition: all 0.15s;
918
-
919
- &:hover {
920
- background: rgba(40, 184, 206, 0.08);
921
- color: #e0f0f4;
922
- }
923
- `;
924
- const modalLoadBtnCss = css `
925
- height: 32px;
926
- padding: 0 20px;
927
- border-radius: 6px;
928
- border: 1px solid rgba(40, 184, 206, 0.4);
929
- background: rgba(40, 184, 206, 0.2);
930
- color: ${GP_PRIMARY};
931
- font-size: 13px;
932
- font-weight: 800;
933
- text-transform: uppercase;
934
- letter-spacing: 0.05em;
935
- cursor: pointer;
936
- font-family: inherit;
937
- transition: all 0.15s;
938
-
939
- &:hover {
940
- background: rgba(40, 184, 206, 0.35);
941
- border-color: ${GP_PRIMARY};
942
- }
943
- `;
944
- // ── JSON syntax colors ──
945
- const jsonKeyCss = css `
946
- color: ${GP_ACCENT};
947
- `;
948
- const jsonStringCss = css `
949
- color: #8bbb6a;
950
- `;
951
- const jsonBoolCss = css `
952
- color: #d4872a;
953
- `;
954
- const jsonNumCss = css `
955
- color: #c4a0e8;
956
- `;
957
- const jsonPunctCss = css `
958
- color: #5a6a78;
959
- `;
960
- const jsonErrorTextCss = css `
961
- color: #dc3c3c;
962
- `;
963
- // ── Flash ──
964
- const flashFade = keyframes `
965
- 0% { opacity: 0; transform: translateY(6px); }
966
- 15% { opacity: 1; transform: translateY(0); }
967
- 85% { opacity: 1; transform: translateY(0); }
968
- 100% { opacity: 0; transform: translateY(-6px); }
969
- `;
970
- const flashCss = css `
971
- position: absolute;
972
- bottom: 100%;
973
- left: 0;
974
- right: 0;
975
- margin-bottom: 8px;
976
- padding: 6px 14px;
977
- font-size: 12px;
978
- font-weight: 700;
979
- color: ${GP_PRIMARY};
980
- text-align: center;
981
- background: linear-gradient(145deg, ${GP_SURFACE}, ${GP_DARK});
982
- border: 1px solid rgba(40, 184, 206, 0.3);
983
- border-radius: 8px;
984
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
985
- white-space: nowrap;
986
- pointer-events: none;
987
- animation: ${flashFade} 1.5s ease-out forwards;
988
- `;
989
- // ── Game Options toggles ──
990
- const toggleRowCss = css `
991
- grid-column: 1 / -1;
992
- display: flex;
993
- align-items: center;
994
- gap: 8px;
995
- margin-top: 4px;
996
- padding: 4px 0;
997
- cursor: pointer;
998
- `;
999
- const checkboxCss = css `
1000
- appearance: none;
1001
- width: 16px;
1002
- height: 16px;
1003
- border-radius: 4px;
1004
- border: 1px solid rgba(40, 184, 206, 0.35);
1005
- background: rgba(0, 0, 0, 0.3);
1006
- cursor: pointer;
1007
- flex-shrink: 0;
1008
- position: relative;
1009
- transition: all 0.15s;
1010
-
1011
- &:checked {
1012
- background: rgba(40, 184, 206, 0.2);
1013
- border-color: ${GP_PRIMARY};
1014
- }
1015
-
1016
- &:checked::after {
1017
- content: '\u2713';
1018
- position: absolute;
1019
- top: 50%;
1020
- left: 50%;
1021
- transform: translate(-50%, -50%);
1022
- font-size: 11px;
1023
- color: ${GP_PRIMARY};
1024
- font-weight: 700;
1025
- }
1026
-
1027
- &:hover {
1028
- border-color: rgba(40, 184, 206, 0.5);
1029
- }
1030
- `;
1031
- const toggleLabelCss = css `
1032
- font-size: 12px;
1033
- font-weight: 600;
1034
- color: #5a8a98;
1035
- `;
1036
230
  //# sourceMappingURL=DevToolsHub.js.map