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