@progamestore/games 0.2.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.
- package/LICENSE +21 -0
- package/dist/GameAuth.d.ts +10 -0
- package/dist/GameAuth.d.ts.map +1 -0
- package/dist/GameAuth.js +108 -0
- package/dist/GameAuth.js.map +1 -0
- package/dist/GameButton.d.ts +21 -0
- package/dist/GameButton.d.ts.map +1 -0
- package/dist/GameButton.js +72 -0
- package/dist/GameButton.js.map +1 -0
- package/dist/GameShell.d.ts +26 -0
- package/dist/GameShell.d.ts.map +1 -0
- package/dist/GameShell.js +61 -0
- package/dist/GameShell.js.map +1 -0
- package/dist/GameTopbar.d.ts +62 -0
- package/dist/GameTopbar.d.ts.map +1 -0
- package/dist/GameTopbar.js +184 -0
- package/dist/GameTopbar.js.map +1 -0
- package/dist/Leaderboard.d.ts +8 -0
- package/dist/Leaderboard.d.ts.map +1 -0
- package/dist/Leaderboard.js +14 -0
- package/dist/Leaderboard.js.map +1 -0
- package/dist/SoundContext.d.ts +16 -0
- package/dist/SoundContext.d.ts.map +1 -0
- package/dist/SoundContext.js +16 -0
- package/dist/SoundContext.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/useAuth.d.ts +12 -0
- package/dist/useAuth.d.ts.map +1 -0
- package/dist/useAuth.js +46 -0
- package/dist/useAuth.js.map +1 -0
- package/dist/useGameSounds.d.ts +16 -0
- package/dist/useGameSounds.d.ts.map +1 -0
- package/dist/useGameSounds.js +93 -0
- package/dist/useGameSounds.js.map +1 -0
- package/dist/useLeaderboard.d.ts +18 -0
- package/dist/useLeaderboard.d.ts.map +1 -0
- package/dist/useLeaderboard.js +49 -0
- package/dist/useLeaderboard.js.map +1 -0
- package/dist/useRooms.d.ts +78 -0
- package/dist/useRooms.d.ts.map +1 -0
- package/dist/useRooms.js +104 -0
- package/dist/useRooms.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Serge Ivo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Sign-in / avatar widget for the GameTopbar `actions` slot.
|
|
4
|
+
*
|
|
5
|
+
* When not signed in: shows a small "Sign in" text button.
|
|
6
|
+
* When signed in: shows the user's avatar + first name, with a
|
|
7
|
+
* dropdown containing "Sign out".
|
|
8
|
+
*/
|
|
9
|
+
export declare function GameAuth(): React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=GameAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameAuth.d.ts","sourceRoot":"","sources":["../src/GameAuth.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC;;;;;;GAMG;AACH,wBAAgB,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CA2I5C"}
|
package/dist/GameAuth.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useAuth } from './useAuth.js';
|
|
4
|
+
/**
|
|
5
|
+
* Sign-in / avatar widget for the GameTopbar `actions` slot.
|
|
6
|
+
*
|
|
7
|
+
* When not signed in: shows a small "Sign in" text button.
|
|
8
|
+
* When signed in: shows the user's avatar + first name, with a
|
|
9
|
+
* dropdown containing "Sign out".
|
|
10
|
+
*/
|
|
11
|
+
export function GameAuth() {
|
|
12
|
+
const { user, loading, signIn, signOut } = useAuth();
|
|
13
|
+
const [open, setOpen] = useState(false);
|
|
14
|
+
const ref = useRef(null);
|
|
15
|
+
// Close dropdown when clicking outside
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!open)
|
|
18
|
+
return;
|
|
19
|
+
const handler = (e) => {
|
|
20
|
+
if (ref.current && !ref.current.contains(e.target)) {
|
|
21
|
+
setOpen(false);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
document.addEventListener('pointerdown', handler, true);
|
|
25
|
+
return () => document.removeEventListener('pointerdown', handler, true);
|
|
26
|
+
}, [open]);
|
|
27
|
+
if (loading)
|
|
28
|
+
return _jsx("div", {});
|
|
29
|
+
if (user === null) {
|
|
30
|
+
return (_jsx("button", { onClick: signIn, style: {
|
|
31
|
+
background: 'none',
|
|
32
|
+
border: 'none',
|
|
33
|
+
cursor: 'pointer',
|
|
34
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
35
|
+
fontSize: '0.7rem',
|
|
36
|
+
fontWeight: 600,
|
|
37
|
+
color: 'var(--muted, #6b7280)',
|
|
38
|
+
padding: 0,
|
|
39
|
+
margin: 0,
|
|
40
|
+
// 44px minimum touch target
|
|
41
|
+
minWidth: '44px',
|
|
42
|
+
minHeight: '44px',
|
|
43
|
+
display: 'inline-flex',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
justifyContent: 'center',
|
|
46
|
+
WebkitTapHighlightColor: 'transparent',
|
|
47
|
+
touchAction: 'manipulation',
|
|
48
|
+
}, children: "Sign in" }));
|
|
49
|
+
}
|
|
50
|
+
const firstName = user.name.split(' ')[0] ?? user.name;
|
|
51
|
+
return (_jsxs("div", { ref: ref, style: { position: 'relative' }, children: [_jsxs("button", { onClick: () => setOpen((v) => !v), style: {
|
|
52
|
+
background: 'none',
|
|
53
|
+
border: 'none',
|
|
54
|
+
cursor: 'pointer',
|
|
55
|
+
display: 'inline-flex',
|
|
56
|
+
alignItems: 'center',
|
|
57
|
+
gap: '0.35rem',
|
|
58
|
+
padding: 0,
|
|
59
|
+
margin: 0,
|
|
60
|
+
minWidth: '44px',
|
|
61
|
+
minHeight: '44px',
|
|
62
|
+
justifyContent: 'center',
|
|
63
|
+
WebkitTapHighlightColor: 'transparent',
|
|
64
|
+
touchAction: 'manipulation',
|
|
65
|
+
}, children: [_jsx("img", { src: user.avatar, alt: "", width: 24, height: 24, style: {
|
|
66
|
+
width: '24px',
|
|
67
|
+
height: '24px',
|
|
68
|
+
borderRadius: '50%',
|
|
69
|
+
objectFit: 'cover',
|
|
70
|
+
flexShrink: 0,
|
|
71
|
+
} }), _jsx("span", { style: {
|
|
72
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
73
|
+
fontSize: '0.7rem',
|
|
74
|
+
fontWeight: 600,
|
|
75
|
+
color: 'var(--ink, #1a1a1a)',
|
|
76
|
+
whiteSpace: 'nowrap',
|
|
77
|
+
}, children: firstName })] }), open && (_jsx("div", { style: {
|
|
78
|
+
position: 'absolute',
|
|
79
|
+
top: '100%',
|
|
80
|
+
right: 0,
|
|
81
|
+
marginTop: '0.25rem',
|
|
82
|
+
background: 'var(--panel, #fff)',
|
|
83
|
+
border: '1px solid var(--line, #e5e5e5)',
|
|
84
|
+
borderRadius: '0.5rem',
|
|
85
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
|
|
86
|
+
zIndex: 100,
|
|
87
|
+
minWidth: '7rem',
|
|
88
|
+
}, children: _jsx("button", { onClick: () => {
|
|
89
|
+
setOpen(false);
|
|
90
|
+
signOut();
|
|
91
|
+
}, style: {
|
|
92
|
+
display: 'flex',
|
|
93
|
+
alignItems: 'center',
|
|
94
|
+
width: '100%',
|
|
95
|
+
background: 'none',
|
|
96
|
+
border: 'none',
|
|
97
|
+
cursor: 'pointer',
|
|
98
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
99
|
+
fontSize: '0.7rem',
|
|
100
|
+
fontWeight: 600,
|
|
101
|
+
color: 'var(--ink, #1a1a1a)',
|
|
102
|
+
padding: '0.5rem 0.75rem',
|
|
103
|
+
minHeight: '44px',
|
|
104
|
+
WebkitTapHighlightColor: 'transparent',
|
|
105
|
+
touchAction: 'manipulation',
|
|
106
|
+
}, children: "Sign out" }) }))] }));
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=GameAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameAuth.js","sourceRoot":"","sources":["../src/GameAuth.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export type GameButtonVariant = 'primary' | 'secondary' | 'ghost';
|
|
4
|
+
export type GameButtonSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
export interface GameButtonProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
/** Visual style. Default: 'primary'. */
|
|
8
|
+
variant?: GameButtonVariant;
|
|
9
|
+
/** Touch-target size. Default: 'md'. All sizes meet the 44px minimum. */
|
|
10
|
+
size?: GameButtonSize;
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Full width. */
|
|
14
|
+
block?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Prescribed game button. Touch-friendly (min 44px target), brand-consistent
|
|
18
|
+
* styling. Three variants, three sizes — all opinionated, nothing custom.
|
|
19
|
+
*/
|
|
20
|
+
export declare function GameButton({ children, variant, size, onClick, disabled, block, }: GameButtonProps): React.JSX.Element;
|
|
21
|
+
//# sourceMappingURL=GameButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameButton.d.ts","sourceRoot":"","sources":["../src/GameButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,wCAAwC;IACxC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,yEAAyE;IACzE,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA0BD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,OAAmB,EACnB,IAAW,EACX,OAAO,EACP,QAAgB,EAChB,KAAa,GACd,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA0DrC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const SIZE = {
|
|
3
|
+
sm: {
|
|
4
|
+
minHeight: '2.75rem',
|
|
5
|
+
padding: '0.5rem 1rem',
|
|
6
|
+
fontSize: '0.85rem',
|
|
7
|
+
borderRadius: '0.625rem',
|
|
8
|
+
},
|
|
9
|
+
md: {
|
|
10
|
+
minHeight: '3rem',
|
|
11
|
+
padding: '0.625rem 1.25rem',
|
|
12
|
+
fontSize: '0.9rem',
|
|
13
|
+
borderRadius: '0.75rem',
|
|
14
|
+
},
|
|
15
|
+
lg: {
|
|
16
|
+
minHeight: '3.5rem',
|
|
17
|
+
padding: '0.75rem 1.75rem',
|
|
18
|
+
fontSize: '1rem',
|
|
19
|
+
borderRadius: '0.875rem',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Prescribed game button. Touch-friendly (min 44px target), brand-consistent
|
|
24
|
+
* styling. Three variants, three sizes — all opinionated, nothing custom.
|
|
25
|
+
*/
|
|
26
|
+
export function GameButton({ children, variant = 'primary', size = 'md', onClick, disabled = false, block = false, }) {
|
|
27
|
+
const s = SIZE[size];
|
|
28
|
+
const base = {
|
|
29
|
+
display: block ? 'flex' : 'inline-flex',
|
|
30
|
+
width: block ? '100%' : undefined,
|
|
31
|
+
alignItems: 'center',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
gap: '0.5rem',
|
|
34
|
+
minHeight: s.minHeight,
|
|
35
|
+
padding: s.padding,
|
|
36
|
+
fontSize: s.fontSize,
|
|
37
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
38
|
+
fontWeight: 700,
|
|
39
|
+
lineHeight: 1,
|
|
40
|
+
borderRadius: s.borderRadius,
|
|
41
|
+
border: 'none',
|
|
42
|
+
cursor: disabled ? 'default' : 'pointer',
|
|
43
|
+
opacity: disabled ? 0.4 : 1,
|
|
44
|
+
transition: 'transform 120ms ease, opacity 120ms ease',
|
|
45
|
+
WebkitTapHighlightColor: 'transparent',
|
|
46
|
+
touchAction: 'manipulation',
|
|
47
|
+
};
|
|
48
|
+
const variantStyles = {
|
|
49
|
+
primary: {
|
|
50
|
+
background: 'var(--accent, #10b981)',
|
|
51
|
+
color: '#fff',
|
|
52
|
+
},
|
|
53
|
+
secondary: {
|
|
54
|
+
background: 'var(--panel, #f5f3f0)',
|
|
55
|
+
color: 'var(--ink, #1a1a1a)',
|
|
56
|
+
boxShadow: 'inset 0 0 0 1px var(--line, #e5e5e5)',
|
|
57
|
+
},
|
|
58
|
+
ghost: {
|
|
59
|
+
background: 'transparent',
|
|
60
|
+
color: 'var(--muted, #6b7280)',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
return (_jsx("button", { style: { ...base, ...variantStyles[variant] }, onClick: disabled ? undefined : onClick, disabled: disabled, onPointerDown: (e) => {
|
|
64
|
+
if (!disabled)
|
|
65
|
+
e.currentTarget.style.transform = 'scale(0.96)';
|
|
66
|
+
}, onPointerUp: (e) => {
|
|
67
|
+
e.currentTarget.style.transform = '';
|
|
68
|
+
}, onPointerLeave: (e) => {
|
|
69
|
+
e.currentTarget.style.transform = '';
|
|
70
|
+
}, children: children }));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=GameButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameButton.js","sourceRoot":"","sources":["../src/GameButton.tsx"],"names":[],"mappings":";AAkBA,MAAM,IAAI,GAGN;IACF,EAAE,EAAE;QACF,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,SAAS;QACnB,YAAY,EAAE,UAAU;KACzB;IACD,EAAE,EAAE;QACF,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,kBAAkB;QAC3B,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,SAAS;KACxB;IACD,EAAE,EAAE;QACF,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,iBAAiB;QAC1B,QAAQ,EAAE,MAAM;QAChB,YAAY,EAAE,UAAU;KACzB;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,KAAK,GACG;IAChB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAErB,MAAM,IAAI,GAAwB;QAChC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa;QACvC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QACjC,UAAU,EAAE,QAAQ;QACpB,cAAc,EAAE,QAAQ;QACxB,GAAG,EAAE,QAAQ;QACb,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,UAAU,EAAE,kCAAkC;QAC9C,UAAU,EAAE,GAAG;QACf,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QACxC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3B,UAAU,EAAE,0CAA0C;QACtD,uBAAuB,EAAE,aAAa;QACtC,WAAW,EAAE,cAAc;KAC5B,CAAC;IAEF,MAAM,aAAa,GAAmD;QACpE,OAAO,EAAE;YACP,UAAU,EAAE,wBAAwB;YACpC,KAAK,EAAE,MAAM;SACd;QACD,SAAS,EAAE;YACT,UAAU,EAAE,uBAAuB;YACnC,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EAAE,sCAAsC;SAClD;QACD,KAAK,EAAE;YACL,UAAU,EAAE,aAAa;YACzB,KAAK,EAAE,uBAAuB;SAC/B;KACF,CAAC;IAEF,OAAO,CACL,iBACE,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,EAC7C,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EACvC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;YACnB,IAAI,CAAC,QAAQ;gBAAG,CAAC,CAAC,aAA6B,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC;QAClF,CAAC,EACD,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE;YAChB,CAAC,CAAC,aAA6B,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;QACxD,CAAC,EACD,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;YACnB,CAAC,CAAC,aAA6B,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;QACxD,CAAC,YAEA,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export interface GameShellProps {
|
|
4
|
+
/**
|
|
5
|
+
* Optional top bar — typically `<GameTopbar score={…} />`. Renders
|
|
6
|
+
* above the play area in a fixed-height row.
|
|
7
|
+
*/
|
|
8
|
+
topbar?: ReactNode;
|
|
9
|
+
/** The game itself. Sized to fill the remaining viewport. */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Brand-consistent layout for a game.
|
|
14
|
+
*
|
|
15
|
+
* Hard guarantees:
|
|
16
|
+
* - Outer wrapper is exactly 100svh tall, full-width — no body scroll.
|
|
17
|
+
* - The play area fills whatever's left after the topbar — never larger.
|
|
18
|
+
* - `overflow: hidden` on the wrapper means a game's internal overflow
|
|
19
|
+
* can't bleed out and create document-level scroll.
|
|
20
|
+
*
|
|
21
|
+
* Why 100svh (small viewport units) and not 100vh: on iOS Safari, 100vh
|
|
22
|
+
* includes the URL bar's hidden area, which lets content overflow when
|
|
23
|
+
* the bar reveals. 100svh stays equal to the *visible* viewport.
|
|
24
|
+
*/
|
|
25
|
+
export declare function GameShell({ topbar, children }: GameShellProps): React.JSX.Element;
|
|
26
|
+
//# sourceMappingURL=GameShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameShell.d.ts","sourceRoot":"","sources":["../src/GameShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA+EjF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SoundProvider } from './SoundContext.js';
|
|
3
|
+
/**
|
|
4
|
+
* Brand-consistent layout for a game.
|
|
5
|
+
*
|
|
6
|
+
* Hard guarantees:
|
|
7
|
+
* - Outer wrapper is exactly 100svh tall, full-width — no body scroll.
|
|
8
|
+
* - The play area fills whatever's left after the topbar — never larger.
|
|
9
|
+
* - `overflow: hidden` on the wrapper means a game's internal overflow
|
|
10
|
+
* can't bleed out and create document-level scroll.
|
|
11
|
+
*
|
|
12
|
+
* Why 100svh (small viewport units) and not 100vh: on iOS Safari, 100vh
|
|
13
|
+
* includes the URL bar's hidden area, which lets content overflow when
|
|
14
|
+
* the bar reveals. 100svh stays equal to the *visible* viewport.
|
|
15
|
+
*/
|
|
16
|
+
export function GameShell({ topbar, children }) {
|
|
17
|
+
return (_jsx(SoundProvider, { children: _jsxs("div", { style: {
|
|
18
|
+
position: 'fixed',
|
|
19
|
+
inset: 0,
|
|
20
|
+
display: 'flex',
|
|
21
|
+
flexDirection: 'column',
|
|
22
|
+
background: 'var(--paper)',
|
|
23
|
+
color: 'var(--ink)',
|
|
24
|
+
overflow: 'hidden',
|
|
25
|
+
// 100svh handles iOS URL-bar height changes correctly.
|
|
26
|
+
height: '100svh',
|
|
27
|
+
width: '100vw',
|
|
28
|
+
// Games are touch-first — prevent text selection, long-press menus,
|
|
29
|
+
// and the 300ms tap delay that makes games feel sluggish.
|
|
30
|
+
WebkitUserSelect: 'none',
|
|
31
|
+
userSelect: 'none',
|
|
32
|
+
WebkitTouchCallout: 'none',
|
|
33
|
+
touchAction: 'manipulation',
|
|
34
|
+
}, children: [topbar !== undefined && (_jsx("div", { style: {
|
|
35
|
+
flexShrink: 0,
|
|
36
|
+
borderBottom: '1px solid var(--line, #e5e5e5)',
|
|
37
|
+
background: 'var(--panel, var(--paper))',
|
|
38
|
+
}, children: topbar })), _jsx("div", { style: {
|
|
39
|
+
flex: 1,
|
|
40
|
+
minHeight: 0,
|
|
41
|
+
minWidth: 0,
|
|
42
|
+
position: 'relative',
|
|
43
|
+
overflow: 'hidden',
|
|
44
|
+
}, children: children }), _jsx("div", { style: {
|
|
45
|
+
flexShrink: 0,
|
|
46
|
+
paddingBottom: 'env(safe-area-inset-bottom, 0px)',
|
|
47
|
+
background: 'var(--panel, var(--paper))',
|
|
48
|
+
borderTop: '1px solid var(--line, #e5e5e5)',
|
|
49
|
+
textAlign: 'center',
|
|
50
|
+
}, children: _jsx("a", { href: "https://progamestore.online", target: "_blank", rel: "noopener noreferrer", style: {
|
|
51
|
+
display: 'block',
|
|
52
|
+
padding: '0.15rem 0',
|
|
53
|
+
fontSize: '0.55rem',
|
|
54
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
55
|
+
fontWeight: 600,
|
|
56
|
+
color: 'var(--muted, #999)',
|
|
57
|
+
textDecoration: 'none',
|
|
58
|
+
letterSpacing: '0.03em',
|
|
59
|
+
}, children: "progamestore.online" }) })] }) }));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=GameShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameShell.js","sourceRoot":"","sources":["../src/GameShell.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAYlD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAkB;IAC5D,OAAO,CACL,KAAC,aAAa,cACZ,eACE,KAAK,EAAE;gBACL,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,MAAM;gBACf,aAAa,EAAE,QAAQ;gBACvB,UAAU,EAAE,cAAc;gBAC1B,KAAK,EAAE,YAAY;gBACnB,QAAQ,EAAE,QAAQ;gBAClB,uDAAuD;gBACvD,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,OAAO;gBACd,oEAAoE;gBACpE,0DAA0D;gBAC1D,gBAAgB,EAAE,MAAM;gBACxB,UAAU,EAAE,MAAM;gBAClB,kBAAkB,EAAE,MAAM;gBAC1B,WAAW,EAAE,cAAc;aAC5B,aAEA,MAAM,KAAK,SAAS,IAAI,CACvB,cACE,KAAK,EAAE;wBACL,UAAU,EAAE,CAAC;wBACb,YAAY,EAAE,gCAAgC;wBAC9C,UAAU,EAAE,4BAA4B;qBACzC,YAEA,MAAM,GACH,CACP,EACD,cACE,KAAK,EAAE;wBACL,IAAI,EAAE,CAAC;wBACP,SAAS,EAAE,CAAC;wBACZ,QAAQ,EAAE,CAAC;wBACX,QAAQ,EAAE,UAAU;wBACpB,QAAQ,EAAE,QAAQ;qBACnB,YAEA,QAAQ,GACL,EAKN,cACE,KAAK,EAAE;wBACL,UAAU,EAAE,CAAC;wBACb,aAAa,EAAE,kCAAkC;wBACjD,UAAU,EAAE,4BAA4B;wBACxC,SAAS,EAAE,gCAAgC;wBAC3C,SAAS,EAAE,QAAQ;qBACpB,YAED,YACE,IAAI,EAAC,6BAA6B,EAClC,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,KAAK,EAAE;4BACL,OAAO,EAAE,OAAO;4BAChB,OAAO,EAAE,WAAW;4BACpB,QAAQ,EAAE,SAAS;4BACnB,UAAU,EAAE,kCAAkC;4BAC9C,UAAU,EAAE,GAAG;4BACf,KAAK,EAAE,oBAAoB;4BAC3B,cAAc,EAAE,MAAM;4BACtB,aAAa,EAAE,QAAQ;yBACxB,oCAGC,GACA,IACF,GACQ,CACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export interface GameTopbarStat {
|
|
4
|
+
/** Short uppercase label, e.g. "Score", "Lives", "Level". */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Display value — string or number. Shown big. */
|
|
7
|
+
value: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Optional accent — flips the value's color to the platform accent
|
|
10
|
+
* (typically used for the primary score).
|
|
11
|
+
*/
|
|
12
|
+
accent?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface GameTopbarProps {
|
|
15
|
+
/** The game's display name. Shows on the left in Manrope. */
|
|
16
|
+
title?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Convenience: the most-common case. If present, renders as a single
|
|
19
|
+
* "Score" stat. Equivalent to passing `stats: [{ label: 'Score',
|
|
20
|
+
* value: score, accent: true }]`.
|
|
21
|
+
*/
|
|
22
|
+
score?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Custom stat lineup. Use for games that need more than just a score
|
|
25
|
+
* (lives, level, time, etc.). Replaces the score-only convenience.
|
|
26
|
+
*/
|
|
27
|
+
stats?: GameTopbarStat[];
|
|
28
|
+
/**
|
|
29
|
+
* Optional right-side action slot for game-specific controls.
|
|
30
|
+
* Keep to ≤2 buttons — the topbar is brand surface, not a settings menu.
|
|
31
|
+
*/
|
|
32
|
+
actions?: ReactNode;
|
|
33
|
+
/**
|
|
34
|
+
* Game rules/instructions. When provided, an ℹ info icon appears in the
|
|
35
|
+
* topbar. Tapping it opens a fullscreen overlay with the rules content.
|
|
36
|
+
*/
|
|
37
|
+
rules?: ReactNode;
|
|
38
|
+
/**
|
|
39
|
+
* For interactive/real-time games (Tetris, Snake, etc.). When provided,
|
|
40
|
+
* the SDK renders standard play/pause + restart icon buttons in the topbar.
|
|
41
|
+
* `paused` controls the icon state (play vs pause).
|
|
42
|
+
*/
|
|
43
|
+
onPlayPause?: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the game is currently paused. Controls the play/pause icon.
|
|
46
|
+
* Only used when `onPlayPause` is provided.
|
|
47
|
+
*/
|
|
48
|
+
paused?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Restart/stop callback. When provided, renders a restart icon button.
|
|
51
|
+
*/
|
|
52
|
+
onRestart?: () => void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The single allowed topbar shape for ProGameStore games. Brand
|
|
56
|
+
* consistency: same font, same paddings, same color tokens, same stat
|
|
57
|
+
* layout across every game on the storefront.
|
|
58
|
+
*
|
|
59
|
+
* Use inside <GameShell topbar={<GameTopbar … />}>.
|
|
60
|
+
*/
|
|
61
|
+
export declare function GameTopbar({ title, score, stats, actions, rules, onPlayPause, paused, onRestart, }: GameTopbarProps): React.JSX.Element;
|
|
62
|
+
//# sourceMappingURL=GameTopbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameTopbar.d.ts","sourceRoot":"","sources":["../src/GameTopbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,KAAK,EACL,WAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA8QrC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useSound } from './SoundContext.js';
|
|
4
|
+
/**
|
|
5
|
+
* The single allowed topbar shape for ProGameStore games. Brand
|
|
6
|
+
* consistency: same font, same paddings, same color tokens, same stat
|
|
7
|
+
* layout across every game on the storefront.
|
|
8
|
+
*
|
|
9
|
+
* Use inside <GameShell topbar={<GameTopbar … />}>.
|
|
10
|
+
*/
|
|
11
|
+
export function GameTopbar({ title, score, stats, actions, rules, onPlayPause, paused, onRestart, }) {
|
|
12
|
+
const [showRules, setShowRules] = useState(false);
|
|
13
|
+
const sound = useSound();
|
|
14
|
+
const resolvedStats = stats && stats.length > 0
|
|
15
|
+
? stats
|
|
16
|
+
: score !== undefined
|
|
17
|
+
? [{ label: 'Score', value: score, accent: true }]
|
|
18
|
+
: [];
|
|
19
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: TOPBAR_BUTTON_CSS }), _jsxs("div", { style: {
|
|
20
|
+
display: 'flex',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
justifyContent: 'space-between',
|
|
23
|
+
gap: '0.75rem',
|
|
24
|
+
padding: '0.25rem 0.75rem',
|
|
25
|
+
height: '2rem',
|
|
26
|
+
}, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.25rem', minWidth: 0 }, children: [_jsx("a", { "data-fgs-tb-btn": true, href: "https://progamestore.online", target: "_blank", rel: "noopener noreferrer", style: {
|
|
27
|
+
background: 'none',
|
|
28
|
+
border: 'none',
|
|
29
|
+
cursor: 'pointer',
|
|
30
|
+
padding: 0,
|
|
31
|
+
minWidth: '2.75rem',
|
|
32
|
+
minHeight: '2.75rem',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
color: 'var(--muted, #999)',
|
|
37
|
+
WebkitTapHighlightColor: 'transparent',
|
|
38
|
+
textDecoration: 'none',
|
|
39
|
+
}, "aria-label": "Browse all games", children: _jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { x: "2", y: "2", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "9", y: "2", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "2", y: "9", width: "5", height: "5", rx: "1" }), _jsx("rect", { x: "9", y: "9", width: "5", height: "5", rx: "1" })] }) }), rules !== undefined && (_jsx("button", { "data-fgs-tb-btn": true, onClick: () => setShowRules(true), style: {
|
|
40
|
+
background: 'none',
|
|
41
|
+
border: 'none',
|
|
42
|
+
cursor: 'pointer',
|
|
43
|
+
padding: 0,
|
|
44
|
+
minWidth: '2.75rem',
|
|
45
|
+
minHeight: '2.75rem',
|
|
46
|
+
display: 'flex',
|
|
47
|
+
alignItems: 'center',
|
|
48
|
+
justifyContent: 'center',
|
|
49
|
+
color: 'var(--muted, #999)',
|
|
50
|
+
lineHeight: 1,
|
|
51
|
+
WebkitTapHighlightColor: 'transparent',
|
|
52
|
+
}, "aria-label": "Game rules", children: _jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "8", cy: "8", r: "6.5" }), _jsx("path", { d: "M8 11.5v0M8 5v4" })] }) })), title !== undefined && (_jsx("span", { style: {
|
|
53
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
54
|
+
fontWeight: 600,
|
|
55
|
+
fontSize: '0.8rem',
|
|
56
|
+
letterSpacing: '-0.01em',
|
|
57
|
+
whiteSpace: 'nowrap',
|
|
58
|
+
overflow: 'hidden',
|
|
59
|
+
textOverflow: 'ellipsis',
|
|
60
|
+
}, children: title }))] }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.75rem' }, children: [resolvedStats.map((s) => (_jsx(Stat, { stat: s }, s.label))), onPlayPause !== undefined && (_jsx("button", { "data-fgs-tb-btn": true, onClick: onPlayPause, style: {
|
|
61
|
+
background: 'none',
|
|
62
|
+
border: 'none',
|
|
63
|
+
cursor: 'pointer',
|
|
64
|
+
padding: 0,
|
|
65
|
+
minWidth: '2.75rem',
|
|
66
|
+
minHeight: '2.75rem',
|
|
67
|
+
display: 'flex',
|
|
68
|
+
alignItems: 'center',
|
|
69
|
+
justifyContent: 'center',
|
|
70
|
+
color: 'var(--ink, #f0f0f0)',
|
|
71
|
+
WebkitTapHighlightColor: 'transparent',
|
|
72
|
+
}, "aria-label": "Pause", "aria-pressed": paused === true, children: paused ? (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M4 2l10 6-10 6V2z" }) })) : (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: [_jsx("rect", { x: "2", y: "2", width: "4", height: "12", rx: "1" }), _jsx("rect", { x: "10", y: "2", width: "4", height: "12", rx: "1" })] })) })), onRestart !== undefined && (_jsx("button", { "data-fgs-tb-btn": true, onClick: onRestart, style: {
|
|
73
|
+
background: 'none',
|
|
74
|
+
border: 'none',
|
|
75
|
+
cursor: 'pointer',
|
|
76
|
+
padding: 0,
|
|
77
|
+
minWidth: '2.75rem',
|
|
78
|
+
minHeight: '2.75rem',
|
|
79
|
+
display: 'flex',
|
|
80
|
+
alignItems: 'center',
|
|
81
|
+
justifyContent: 'center',
|
|
82
|
+
color: 'var(--muted, #999)',
|
|
83
|
+
WebkitTapHighlightColor: 'transparent',
|
|
84
|
+
}, "aria-label": "Restart", children: _jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M2 8a6 6 0 0111.5-2.5" }), _jsx("path", { d: "M14 8a6 6 0 01-11.5 2.5" }), _jsx("path", { d: "M14 2v3.5h-3.5" }), _jsx("path", { d: "M2 14v-3.5h3.5" })] }) })), _jsx("button", { "data-fgs-tb-btn": true, onClick: sound.toggle, style: {
|
|
85
|
+
background: 'none',
|
|
86
|
+
border: 'none',
|
|
87
|
+
cursor: 'pointer',
|
|
88
|
+
padding: 0,
|
|
89
|
+
minWidth: '2.75rem',
|
|
90
|
+
minHeight: '2.75rem',
|
|
91
|
+
display: 'flex',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
justifyContent: 'center',
|
|
94
|
+
color: sound.muted ? 'var(--muted, #999)' : 'var(--accent, #10b981)',
|
|
95
|
+
WebkitTapHighlightColor: 'transparent',
|
|
96
|
+
}, "aria-label": "Mute", "aria-pressed": sound.muted, children: sound.muted ? (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M8 2L4 5.5H1.5v5H4L8 14V2z" }), _jsx("path", { d: "M12 5.5l4 5M16 5.5l-4 5" })] })) : (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M8 2L4 5.5H1.5v5H4L8 14V2z" }), _jsx("path", { d: "M11.5 5a4.5 4.5 0 010 6" }), _jsx("path", { d: "M13.5 3a7.5 7.5 0 010 10" })] })) }), actions !== undefined && (_jsx("div", { style: { display: 'flex', gap: '0.4rem', alignItems: 'center' }, children: actions }))] })] }), showRules && rules !== undefined && (_jsx(RulesOverlay, { onClose: () => setShowRules(false), children: rules }))] }));
|
|
97
|
+
}
|
|
98
|
+
function RulesOverlay({ children, onClose, }) {
|
|
99
|
+
return (_jsxs("div", { style: {
|
|
100
|
+
position: 'fixed',
|
|
101
|
+
inset: 0,
|
|
102
|
+
zIndex: 9999,
|
|
103
|
+
background: 'var(--paper, #0f0f0f)',
|
|
104
|
+
color: 'var(--ink, #f0f0f0)',
|
|
105
|
+
display: 'flex',
|
|
106
|
+
flexDirection: 'column',
|
|
107
|
+
overflow: 'hidden',
|
|
108
|
+
}, children: [_jsxs("div", { style: {
|
|
109
|
+
display: 'flex',
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
justifyContent: 'space-between',
|
|
112
|
+
padding: '0.5rem 0.75rem',
|
|
113
|
+
borderBottom: '1px solid var(--line, #2a2a2a)',
|
|
114
|
+
flexShrink: 0,
|
|
115
|
+
}, children: [_jsx("span", { style: {
|
|
116
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
117
|
+
fontWeight: 700,
|
|
118
|
+
fontSize: '0.9rem',
|
|
119
|
+
}, children: "How to Play" }), _jsx("button", { "data-fgs-tb-btn": true, onClick: onClose, style: {
|
|
120
|
+
background: 'none',
|
|
121
|
+
border: 'none',
|
|
122
|
+
cursor: 'pointer',
|
|
123
|
+
color: 'var(--muted, #999)',
|
|
124
|
+
fontSize: '1.2rem',
|
|
125
|
+
minWidth: '2.75rem',
|
|
126
|
+
minHeight: '2.75rem',
|
|
127
|
+
display: 'flex',
|
|
128
|
+
alignItems: 'center',
|
|
129
|
+
justifyContent: 'center',
|
|
130
|
+
WebkitTapHighlightColor: 'transparent',
|
|
131
|
+
}, "aria-label": "Close rules", children: "\u00D7" })] }), _jsx("div", { style: {
|
|
132
|
+
flex: 1,
|
|
133
|
+
overflowY: 'auto',
|
|
134
|
+
padding: '1rem',
|
|
135
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
136
|
+
fontSize: '0.9rem',
|
|
137
|
+
lineHeight: 1.6,
|
|
138
|
+
}, children: children })] }));
|
|
139
|
+
}
|
|
140
|
+
function Stat({ stat }) {
|
|
141
|
+
return (_jsxs("div", { style: { textAlign: 'right', lineHeight: 1.05 }, children: [_jsx("div", { style: {
|
|
142
|
+
fontFamily: '"Manrope", system-ui, sans-serif',
|
|
143
|
+
fontWeight: 800,
|
|
144
|
+
fontSize: '0.85rem',
|
|
145
|
+
color: stat.accent === true ? 'var(--accent)' : 'var(--ink)',
|
|
146
|
+
fontVariantNumeric: 'tabular-nums',
|
|
147
|
+
lineHeight: 1,
|
|
148
|
+
}, children: stat.value }), _jsx("div", { style: {
|
|
149
|
+
// Was 0.5rem (~8px) — too small to read in sunlight or for
|
|
150
|
+
// anyone with even mild low vision. 0.65rem (~10.4px) keeps
|
|
151
|
+
// the visual hierarchy (value still dominates at 0.85rem)
|
|
152
|
+
// while staying legible.
|
|
153
|
+
fontSize: '0.65rem',
|
|
154
|
+
fontWeight: 700,
|
|
155
|
+
textTransform: 'uppercase',
|
|
156
|
+
letterSpacing: '0.06em',
|
|
157
|
+
color: 'var(--muted)',
|
|
158
|
+
lineHeight: 1,
|
|
159
|
+
}, children: stat.label })] }));
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Pseudo-state styling for every topbar button + link. Tagged via
|
|
163
|
+
* `data-fgs-tb-btn`. Keep this small and predictable — the topbar is
|
|
164
|
+
* brand surface, not a creative palette.
|
|
165
|
+
*
|
|
166
|
+
* :active — opacity dip so taps feel anchored on touch devices that
|
|
167
|
+
* otherwise give no feedback (we already disable the
|
|
168
|
+
* default tap-highlight via WebkitTapHighlightColor).
|
|
169
|
+
*
|
|
170
|
+
* :focus-visible — accent outline so keyboard users see where focus
|
|
171
|
+
* is. -2px outline-offset draws inside the button's
|
|
172
|
+
* 2.75rem touch target so the ring doesn't bleed
|
|
173
|
+
* into adjacent controls.
|
|
174
|
+
*/
|
|
175
|
+
const TOPBAR_BUTTON_CSS = `
|
|
176
|
+
[data-fgs-tb-btn] { transition: opacity 80ms ease; }
|
|
177
|
+
[data-fgs-tb-btn]:active { opacity: 0.55; }
|
|
178
|
+
[data-fgs-tb-btn]:focus-visible {
|
|
179
|
+
outline: 2px solid var(--accent, #10b981);
|
|
180
|
+
outline-offset: -2px;
|
|
181
|
+
border-radius: 0.4rem;
|
|
182
|
+
}
|
|
183
|
+
`;
|
|
184
|
+
//# sourceMappingURL=GameTopbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameTopbar.js","sourceRoot":"","sources":["../src/GameTopbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LeaderboardEntry } from './useLeaderboard.js';
|
|
2
|
+
export interface LeaderboardProps {
|
|
3
|
+
topScores: LeaderboardEntry[];
|
|
4
|
+
recentScores: LeaderboardEntry[];
|
|
5
|
+
loading: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function Leaderboard({ topScores, recentScores, loading, }: LeaderboardProps): React.JSX.Element;
|
|
8
|
+
//# sourceMappingURL=Leaderboard.d.ts.map
|