@energy8platform/platform-core 0.25.1 → 0.25.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.
- package/dist/index.cjs.js +81 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +81 -16
- package/dist/index.esm.js.map +1 -1
- package/dist/shell.cjs.js +81 -16
- package/dist/shell.cjs.js.map +1 -1
- package/dist/shell.d.ts +3 -0
- package/dist/shell.esm.js +81 -16
- package/dist/shell.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/shell/GameShell.ts +40 -9
- package/src/shell/components/ReplayModal.ts +1 -1
- package/src/shell/i18n.ts +1 -0
- package/src/shell/shell.css.ts +36 -3
- package/src/shell/version.ts +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1327,15 +1327,30 @@ const SHELL_CSS = SHELL_FONT_CSS + `
|
|
|
1327
1327
|
/* the buy-bonus scroll area is a SIZE CONTAINER, so the cards' cqh units measure the overlay
|
|
1328
1328
|
(the popout frame) and not the browser window — cards fit without any vertical scroll. */
|
|
1329
1329
|
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-scroll { container-type:size; }
|
|
1330
|
+
/* Popout / landscape: the horizontal card strip must be the ONLY scroll axis. The cqh-sized cards
|
|
1331
|
+
are meant to fit the overlay height (no vertical scroll), but the old 7px font floor stopped them
|
|
1332
|
+
shrinking on the tiniest popouts — so they spilled past the frame and the overlay grew a SECOND,
|
|
1333
|
+
vertical scrollbar (scrollable in both directions). Two changes keep it single-axis:
|
|
1334
|
+
1. the card font floor drops (below) so cards actually fit the frame height; and
|
|
1335
|
+
2. vertical scrolling is locked off as a belt-and-braces guard, with the strip centred (the body
|
|
1336
|
+
fills the frame and centres the grid) so any sub-pixel slack splits evenly instead of clipping
|
|
1337
|
+
the price/CTA off the bottom.
|
|
1338
|
+
This mirrors the pixi shell, which masks the cards and drag-scrolls on the X axis alone. (Centring
|
|
1339
|
+
lives on the body, not the scroll box, so the grid keeps its width and its own X-scroll.) */
|
|
1340
|
+
#${SHELL_ROOT_ID}:not(.ge-mobile) [data-ge="buybonus-overlay"] .ge-ov-scroll { overflow-y:hidden; }
|
|
1341
|
+
#${SHELL_ROOT_ID}:not(.ge-mobile) [data-ge="buybonus-overlay"] .ge-ov-body {
|
|
1342
|
+
min-height:100%; box-sizing:border-box; display:flex; flex-direction:column; justify-content:center; }
|
|
1330
1343
|
/* buy-bonus uses the FULL overlay width (no 800px centre cap) so the card row isn't cropped at
|
|
1331
1344
|
the sides; small horizontal padding keeps the cards off the screen edges. */
|
|
1332
|
-
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-body { max-width:none; padding:clamp(
|
|
1345
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-body { max-width:none; padding:clamp(6px,2.5cqh,16px) clamp(12px,3vw,28px); }
|
|
1333
1346
|
#${SHELL_ROOT_ID} .ge-bb-grid { display:flex; gap:14px; justify-content:safe center; overflow-x:auto; overflow-y:hidden; padding-bottom:6px;
|
|
1334
1347
|
scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; }
|
|
1335
1348
|
/* the one knob that scales the whole card — cqh measures the overlay (popout frame), not the
|
|
1336
|
-
browser window, so cards shrink to fit the real container height.
|
|
1349
|
+
browser window, so cards shrink to fit the real container height. The floor is deliberately tiny:
|
|
1350
|
+
on a 400×225 popout the whole card (incl. the CTA) only fits below ~5px, and a fully visible,
|
|
1351
|
+
single-axis-scrolling card beats a bigger one whose button is clipped or needs a 2nd scrollbar. */
|
|
1337
1352
|
#${SHELL_ROOT_ID} .ge-bb-grid .ge-bonus-card { flex:0 0 18em; scroll-snap-align:start;
|
|
1338
|
-
font-size:clamp(
|
|
1353
|
+
font-size:clamp(4px, 3.4cqh, 12px); }
|
|
1339
1354
|
/* mobile: vertical stack at a fixed, readable size — scroll the list, don't shrink the cards */
|
|
1340
1355
|
#${SHELL_ROOT_ID}.ge-mobile .ge-bb-grid { display:flex; flex-direction:column; gap:14px; overflow:visible; }
|
|
1341
1356
|
#${SHELL_ROOT_ID}.ge-mobile .ge-bb-grid .ge-bonus-card { flex:0 0 auto; font-size:12px; }
|
|
@@ -1388,6 +1403,24 @@ const SHELL_CSS = SHELL_FONT_CSS + `
|
|
|
1388
1403
|
#${SHELL_ROOT_ID} .ge-bb-betval span { display:block; font-size:7px; font-weight:600; letter-spacing:.14em; text-transform:uppercase;
|
|
1389
1404
|
color:var(--shell-plaque-label); }
|
|
1390
1405
|
#${SHELL_ROOT_ID} .ge-bb-betval b { font-size:14px; font-weight:800; font-variant-numeric:tabular-nums; color:#fff; }
|
|
1406
|
+
/* Popout S (short landscape): the header (title + ✕) and the bet footer are fixed-px and dwarf the
|
|
1407
|
+
shrunk cards. Scale the buy-bonus chrome down with the FRAME height. Units are cqh (the overlay is a
|
|
1408
|
+
size container below), NOT vh — vh tracks the browser window, which only equals the frame inside the
|
|
1409
|
+
Stake iframe, so it wouldn't shrink in the demo's device-frame view. Coefficients hit the normal cap
|
|
1410
|
+
by ~450px tall (Popout L) and shrink below that, to a readable floor at Popout S (225px). */
|
|
1411
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] { container:ge-bb-frame / size; }
|
|
1412
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-head { padding:clamp(3px,1.33cqh,6px) 10px; }
|
|
1413
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-title { font-size:clamp(11px,3.5cqh,16px); }
|
|
1414
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-spacer { width:clamp(24px,7cqh,32px); }
|
|
1415
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-ov-nav { width:clamp(24px,7cqh,32px); height:clamp(24px,7cqh,32px);
|
|
1416
|
+
font-size:clamp(14px,4cqh,18px); border-radius:clamp(7px,2cqh,9px); }
|
|
1417
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betbar { padding:clamp(2px,.9cqh,4px); }
|
|
1418
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betpill { padding:clamp(2px,.67cqh,3px) clamp(4px,1.1cqh,5px); }
|
|
1419
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betstep { width:clamp(24px,7cqh,32px); height:clamp(24px,7cqh,32px);
|
|
1420
|
+
font-size:clamp(15px,4.4cqh,20px); }
|
|
1421
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betval { min-width:clamp(62px,17.5cqh,80px); }
|
|
1422
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betval b { font-size:clamp(11px,3.1cqh,14px); }
|
|
1423
|
+
#${SHELL_ROOT_ID} [data-ge="buybonus-overlay"] .ge-bb-betval span { font-size:clamp(6px,1.55cqh,7px); }
|
|
1391
1424
|
|
|
1392
1425
|
/* ═══ base/wide plaque bar — grouped dark + glass panels (reference-style) ═══ */
|
|
1393
1426
|
#${SHELL_ROOT_ID} .ge-zone-plaques { gap:0; } /* panels connect; buttons overlap */
|
|
@@ -1961,7 +1994,7 @@ function openSettingsModal(shell) {
|
|
|
1961
1994
|
|
|
1962
1995
|
// AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
|
|
1963
1996
|
/** The @energy8platform/platform-core package version, stamped at build time. */
|
|
1964
|
-
const PACKAGE_VERSION = '0.25.
|
|
1997
|
+
const PACKAGE_VERSION = '0.25.3';
|
|
1965
1998
|
|
|
1966
1999
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
1967
2000
|
function openGameInfoModal(shell) {
|
|
@@ -2616,7 +2649,7 @@ function buildReplayModal(shell, opts) {
|
|
|
2616
2649
|
row('Base bet', fmt(bet));
|
|
2617
2650
|
row('Cost multiplier', `${costMultiplier}×`);
|
|
2618
2651
|
row('Total cost', fmt(bet * costMultiplier));
|
|
2619
|
-
row('
|
|
2652
|
+
row('Win multiplier', `${payoutMultiplier}×`);
|
|
2620
2653
|
row('Total win', fmtWin(payoutMultiplier * bet), true);
|
|
2621
2654
|
ui.body.appendChild(rows);
|
|
2622
2655
|
const actions = document.createElement('div');
|
|
@@ -2701,6 +2734,7 @@ const RULES = [
|
|
|
2701
2734
|
['pay out', 'win / won'],
|
|
2702
2735
|
['paid out', 'won'],
|
|
2703
2736
|
['pays out', 'win'],
|
|
2737
|
+
['payout', 'win'], // single word; "pay out" (spaced) is handled above
|
|
2704
2738
|
['paytable', 'win table'],
|
|
2705
2739
|
['paylines', 'winlines'],
|
|
2706
2740
|
['payline', 'winline'],
|
|
@@ -2839,6 +2873,11 @@ class GameShell extends EventEmitter {
|
|
|
2839
2873
|
host.classList.remove('ge-fit');
|
|
2840
2874
|
host.style.transform = '';
|
|
2841
2875
|
host.style.transformOrigin = '';
|
|
2876
|
+
// clear any per-zone height-scale from a prior pass
|
|
2877
|
+
for (const el of host.querySelectorAll('.ge-zone, .ge-winpill')) {
|
|
2878
|
+
el.style.transform = '';
|
|
2879
|
+
el.style.transformOrigin = '';
|
|
2880
|
+
}
|
|
2842
2881
|
if (this.layout === 'mobile') {
|
|
2843
2882
|
// Shrink the whole stack to fit narrow phones (mobile-s, or big balance/win/total-win
|
|
2844
2883
|
// numbers in a row). The rows use space-between, so on overflow their content is
|
|
@@ -2855,20 +2894,43 @@ class GameShell extends EventEmitter {
|
|
|
2855
2894
|
}
|
|
2856
2895
|
return;
|
|
2857
2896
|
}
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
//
|
|
2861
|
-
|
|
2897
|
+
const availW = this.root.clientWidth - 12;
|
|
2898
|
+
const availH = this.root.clientHeight * GameShell.BAR_MAX_FRACTION;
|
|
2899
|
+
// 1) If the inline row overflows the width, lift the WIN pill onto its own line above the bar
|
|
2900
|
+
// (keeps the controls as large as possible — base's wide row + a big WIN pill hit this).
|
|
2901
|
+
if (pill && bar.scrollWidth > bar.clientWidth + 1) {
|
|
2862
2902
|
host.insertBefore(pill, bar);
|
|
2863
2903
|
pill.classList.add('ge-up');
|
|
2864
2904
|
}
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2905
|
+
// 2) Still too WIDE (the control row itself doesn't fit) → shrink-to-content + uniform scale,
|
|
2906
|
+
// centred. Only base's wide row reaches here.
|
|
2907
|
+
if (bar.scrollWidth > bar.clientWidth + 1) {
|
|
2908
|
+
host.classList.add('ge-fit');
|
|
2909
|
+
const naturalW = host.offsetWidth, naturalH = host.offsetHeight;
|
|
2910
|
+
const s = Math.min(1, naturalW > 0 ? availW / naturalW : 1, naturalH > 0 ? availH / naturalH : 1);
|
|
2911
|
+
if (s < 0.999)
|
|
2912
|
+
host.style.transform = `translateX(-50%) scale(${s.toFixed(4)})`;
|
|
2913
|
+
else
|
|
2914
|
+
host.classList.remove('ge-fit');
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2917
|
+
// 3) Fits the WIDTH but the stack (control row + any lifted WIN pill) is too TALL for a short
|
|
2918
|
+
// frame — replay/free-spins on Popout S. Shrink each piece toward its OWN edge so the bar
|
|
2919
|
+
// keeps its full-width space-between layout (menu hard-left, controls hard-right), just
|
|
2920
|
+
// lower — NOT packed into a centred cluster. Scale by frame HEIGHT only.
|
|
2921
|
+
const naturalH = host.offsetHeight;
|
|
2922
|
+
if (naturalH > availH && naturalH > 0) {
|
|
2923
|
+
const s = (availH / naturalH).toFixed(4);
|
|
2924
|
+
const scaleEdge = (el, origin) => {
|
|
2925
|
+
if (!el)
|
|
2926
|
+
return;
|
|
2927
|
+
el.style.transformOrigin = origin;
|
|
2928
|
+
el.style.transform = `scale(${s})`;
|
|
2929
|
+
};
|
|
2930
|
+
scaleEdge(bar.querySelector('.ge-zone-left'), 'left bottom');
|
|
2931
|
+
scaleEdge(bar.querySelector('.ge-zone-right'), 'right bottom');
|
|
2932
|
+
scaleEdge(host.querySelector('.ge-winpill'), 'center bottom');
|
|
2933
|
+
}
|
|
2872
2934
|
}
|
|
2873
2935
|
/** Spacebar starts a spin — same path as the spin disc. Ignored when `features.spacebar` is
|
|
2874
2936
|
* false, while a spin is running, while autoplay is active, outside base mode, when an
|
|
@@ -2981,6 +3043,9 @@ class GameShell extends EventEmitter {
|
|
|
2981
3043
|
/** Fraction of the frame a card modal may occupy; the rest is breathing-room margin. Keeps
|
|
2982
3044
|
* modals from filling a small popout edge-to-edge (so even short pickers scale down there). */
|
|
2983
3045
|
static MODAL_FIT = 0.86;
|
|
3046
|
+
/** Max fraction of the frame HEIGHT the bottom bar may occupy before it fit-scales down. Keeps the
|
|
3047
|
+
* bar a consistent, small slice on short popouts in EVERY mode (base ≈ this already via width). */
|
|
3048
|
+
static BAR_MAX_FRACTION = 0.27;
|
|
2984
3049
|
fitSheet(root) {
|
|
2985
3050
|
const card = root.querySelector('.ge-modal-card');
|
|
2986
3051
|
if (!card)
|