@gamepark/react-game 7.6.4 → 7.6.6
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.
- package/dist/components/GameProvider/GameErrorBoundary.js +108 -108
- package/dist/components/JournalTabs/History/SetupLogItem.js +19 -19
- package/dist/components/material/GameTable/DevTools/DevToolEntry.js +9 -10
- package/dist/components/material/GameTable/DevTools/DevToolEntry.js.map +1 -1
- package/dist/components/material/GameTable/DevTools/DevToolsHub.js +47 -46
- package/dist/components/material/GameTable/DevTools/DevToolsHub.js.map +1 -1
- package/dist/components/material/GameTable/DevTools/ExportPanel.js +9 -10
- package/dist/components/material/GameTable/DevTools/ExportPanel.js.map +1 -1
- package/dist/components/material/GameTable/DevTools/GamePanel.js +41 -44
- package/dist/components/material/GameTable/DevTools/GamePanel.js.map +1 -1
- package/dist/components/material/GameTable/DevTools/SaveLoadPanel.js +65 -66
- package/dist/components/material/GameTable/DevTools/SaveLoadPanel.js.map +1 -1
- package/dist/components/material/GameTable/DevToolsHub.d.ts +21 -4
- package/dist/components/material/GameTable/DevToolsHub.js +830 -24
- package/dist/components/material/GameTable/DevToolsHub.js.map +1 -1
- package/dist/components/material/Wheel/WheelContent.d.ts +13 -0
- package/dist/components/material/Wheel/WheelContent.js +37 -0
- package/dist/components/material/Wheel/WheelContent.js.map +1 -0
- package/dist/components/menus/BugReport/BugReportDialog.js +38 -38
- package/dist/css/backgroundCss.js +3 -3
- package/dist/css/cursorCss.js +6 -6
- package/dist/css/fadeIn.js +6 -6
- package/dist/css/shineEffect.js +28 -28
- package/dist/css/transformCss.js +4 -4
- package/dist/hooks/useFailures.d.ts +1 -0
- package/dist/hooks/useFailures.js +11 -0
- package/dist/hooks/useFailures.js.map +1 -0
- package/dist/hooks/useWebP.d.ts +1 -0
- package/dist/hooks/useWebP.js +13 -0
- package/dist/hooks/useWebP.js.map +1 -0
- package/package.json +3 -3
- package/dist/components/material/Dices/OctahedralDiceDescription.d.ts +0 -48
- package/dist/components/material/Dices/OctahedralDiceDescription.js +0 -142
- package/dist/components/material/Dices/OctahedralDiceDescription.js.map +0 -1
- package/dist/components/material/GameTable/DevToolEntry.d.ts +0 -17
- package/dist/components/material/GameTable/DevToolEntry.js +0 -13
- package/dist/components/material/GameTable/DevToolEntry.js.map +0 -1
- package/dist/components/material/GameTable/DevTools/DevToolsStyles.d.ts +0 -58
- package/dist/components/material/GameTable/DevTools/DevToolsStyles.js +0 -706
- package/dist/components/material/GameTable/DevTools/DevToolsStyles.js.map +0 -1
- package/dist/components/material/GameTable/DevToolsStyles.d.ts +0 -67
- package/dist/components/material/GameTable/DevToolsStyles.js +0 -752
- package/dist/components/material/GameTable/DevToolsStyles.js.map +0 -1
- package/dist/components/material/GameTable/JsonHighlighter.d.ts +0 -3
- package/dist/components/material/GameTable/JsonHighlighter.js +0 -37
- package/dist/components/material/GameTable/JsonHighlighter.js.map +0 -1
|
@@ -1,13 +1,64 @@
|
|
|
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';
|
|
3
4
|
import { useCallback, useContext, useRef, useState } from 'react';
|
|
4
5
|
import { createPortal } from 'react-dom';
|
|
5
6
|
import { usePlayerId, usePlayerIds } from '../../../hooks/usePlayerId';
|
|
6
7
|
import { gameContext } from '../../GameProvider/GameContext';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 })] }));
|
|
11
62
|
// ═══════════════════════════════════════
|
|
12
63
|
// Save/Load helpers
|
|
13
64
|
// ═══════════════════════════════════════
|
|
@@ -95,15 +146,19 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
|
|
|
95
146
|
return;
|
|
96
147
|
}
|
|
97
148
|
try {
|
|
98
|
-
JSON.parse(raw);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
+
}
|
|
102
157
|
}
|
|
103
158
|
catch {
|
|
104
159
|
doFlash('Invalid save data');
|
|
105
160
|
}
|
|
106
|
-
}, [gameName, doFlash]);
|
|
161
|
+
}, [g, gameName, doFlash]);
|
|
107
162
|
const handleDownloadSave = useCallback((key) => {
|
|
108
163
|
const raw = localStorage.getItem(key);
|
|
109
164
|
if (!raw) {
|
|
@@ -132,11 +187,14 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
|
|
|
132
187
|
const reader = new FileReader();
|
|
133
188
|
reader.onload = () => {
|
|
134
189
|
try {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
+
}
|
|
140
198
|
}
|
|
141
199
|
catch {
|
|
142
200
|
doFlash('Invalid JSON file');
|
|
@@ -144,28 +202,33 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
|
|
|
144
202
|
};
|
|
145
203
|
reader.readAsText(file);
|
|
146
204
|
e.target.value = '';
|
|
147
|
-
}, [
|
|
205
|
+
}, [g, doFlash]);
|
|
148
206
|
const handleImportPaste = useCallback(() => {
|
|
149
207
|
if (!importText.trim()) {
|
|
150
208
|
setPasteError('Paste a JSON state first');
|
|
151
209
|
return;
|
|
152
210
|
}
|
|
153
211
|
try {
|
|
154
|
-
JSON.parse(importText);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
+
}
|
|
161
223
|
}
|
|
162
224
|
catch {
|
|
163
225
|
setPasteError('Invalid JSON — check syntax');
|
|
164
226
|
}
|
|
165
|
-
}, [
|
|
227
|
+
}, [g, importText, doFlash]);
|
|
166
228
|
const handlePasteChange = useCallback((value) => {
|
|
167
229
|
setImportText(value);
|
|
168
230
|
setPasteError(null);
|
|
231
|
+
// Try to pretty-print if valid
|
|
169
232
|
try {
|
|
170
233
|
const parsed = JSON.parse(value);
|
|
171
234
|
setImportText(JSON.stringify(parsed, null, 2));
|
|
@@ -213,7 +276,7 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
|
|
|
213
276
|
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: () => {
|
|
214
277
|
const raw = localStorage.getItem(gameName);
|
|
215
278
|
if (raw) {
|
|
216
|
-
|
|
279
|
+
copyToClipboard(raw, `${gameName} state`);
|
|
217
280
|
}
|
|
218
281
|
else {
|
|
219
282
|
doFlash(`No "${gameName}" key in localStorage`);
|
|
@@ -227,4 +290,747 @@ export const DevToolsHub = ({ children, fabBottom, gameOptions }) => {
|
|
|
227
290
|
}
|
|
228
291
|
})() })] })), 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);
|
|
229
292
|
};
|
|
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
|
+
`;
|
|
230
1036
|
//# sourceMappingURL=DevToolsHub.js.map
|