@energy8platform/shell 0.2.1 → 0.2.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.d.ts CHANGED
@@ -471,7 +471,7 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
471
471
  tokens: ShellTokens;
472
472
  layout: ShellLayoutMode;
473
473
  soundOn: boolean;
474
- readonly engineVersion = "0.2.1";
474
+ readonly engineVersion = "0.2.3";
475
475
  readonly actions: ShellActions;
476
476
  private renderer;
477
477
  private i18n;
@@ -537,7 +537,7 @@ interface I18n {
537
537
  declare function createI18n(opts: I18nOptions): I18n;
538
538
 
539
539
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
540
- declare const PACKAGE_VERSION = "0.2.1";
540
+ declare const PACKAGE_VERSION = "0.2.3";
541
541
 
542
542
  /** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
543
543
  * an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
package/dist/index.esm.js CHANGED
@@ -1324,7 +1324,7 @@ class KeyboardController {
1324
1324
 
1325
1325
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1326
1326
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1327
- const PACKAGE_VERSION = '0.2.1';
1327
+ const PACKAGE_VERSION = '0.2.3';
1328
1328
 
1329
1329
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1330
1330
  function resolveConfig(config) {
package/dist/pixi.cjs.js CHANGED
@@ -1354,7 +1354,7 @@ class KeyboardController {
1354
1354
 
1355
1355
  // AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
1356
1356
  /** The @energy8platform/shell package version, stamped into the game-info footer. */
1357
- const PACKAGE_VERSION = '0.2.1';
1357
+ const PACKAGE_VERSION = '0.2.3';
1358
1358
 
1359
1359
  /** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
1360
1360
  function resolveConfig(config) {
@@ -4275,6 +4275,10 @@ function imageBox(url, w, h) {
4275
4275
  return c;
4276
4276
  }
4277
4277
 
4278
+ /** Below this frame height (px), a wide/landscape popout (e.g. Popout S 400×225) stacks its cards
4279
+ * vertically and scrolls — like mobile — so descriptions stay readable instead of shrinking to a
4280
+ * ~4px floor. Wide + taller frames (Popout L and up) keep the centred horizontal row. */
4281
+ const SHORT_STACK_H = 340;
4278
4282
  /** Buy-bonus overlay — art-forward cards (one per option), a live bet footer, and a confirm modal.
4279
4283
  * Returns null when there are no bonus options. */
4280
4284
  function openBuyBonus(host) {
@@ -4304,6 +4308,8 @@ class BuyBonusOverlay extends pixi_js.Container {
4304
4308
  cardEntries = [];
4305
4309
  /** Keyboard focus index into the affordable subset of cardEntries. -1 = none. */
4306
4310
  focusIndex = -1;
4311
+ /** true when cards are stacked vertically (mobile, or a short landscape popout). */
4312
+ stack = false;
4307
4313
  // Drag-scroll state. The drag is handled on the (unmasked) overlay, not the masked strip — a mask
4308
4314
  // prunes pointer events outside its band, stalling globalpointermove mid-drag so later cards never
4309
4315
  // scroll into reach. The overlay sees the whole screen, so the scroll runs the full range.
@@ -4413,7 +4419,10 @@ class BuyBonusOverlay extends pixi_js.Container {
4413
4419
  }
4414
4420
  buildCards() {
4415
4421
  this.strip.removeChildren().forEach((c) => c.destroy({ children: true }));
4416
- const mobile = this.host.layout === 'mobile';
4422
+ // Stack (readable vertical list + scroll) on mobile OR on a short landscape popout; a shrink-to-fit
4423
+ // horizontal row on wide + tall frames. See SHORT_STACK_H.
4424
+ const stack = this.host.layout === 'mobile' || this.h <= SHORT_STACK_H;
4425
+ this.stack = stack;
4417
4426
  const top = this.headerH + 6;
4418
4427
  const areaH = this.h - top - this.footerH - 6;
4419
4428
  const gap = 14;
@@ -4424,12 +4433,12 @@ class BuyBonusOverlay extends pixi_js.Container {
4424
4433
  // N cards (+ gaps + 24px side margins) fit the frame width. min() of the two = the binding fit.
4425
4434
  // Floor 4 is a last-resort so a 400×225 popout still shows the CTA (then X-drag scrolls the slack).
4426
4435
  const emH = 3.4 * (areaH / 100);
4427
- const emW = mobile
4436
+ const emW = stack
4428
4437
  ? (this.w - 48) / 18 // vertical stack: a single card spans the width
4429
4438
  : (this.w - 48 - (n - 1) * gap) / (18 * n); // row: N cards + gaps fit the frame width
4430
- const em = mobile ? Math.min(12, emW) : clamp(4, Math.min(emH, emW), 12);
4439
+ const em = stack ? Math.min(12, emW) : clamp(4, Math.min(emH, emW), 12);
4431
4440
  const cardW = Math.min(18 * em, this.w - 48);
4432
- const cards = this.bonuses.map((b) => this.buildCard(b, cardW, em, mobile, areaH));
4441
+ const cards = this.bonuses.map((b) => this.buildCard(b, cardW, em, stack, areaH));
4433
4442
  const cardH = Math.max(...cards.map((c) => c.height));
4434
4443
  for (const c of cards)
4435
4444
  c.setHeight(cardH);
@@ -4452,7 +4461,7 @@ class BuyBonusOverlay extends pixi_js.Container {
4452
4461
  this.focusIndex = -1;
4453
4462
  }
4454
4463
  this.stripMask.clear();
4455
- if (mobile) {
4464
+ if (stack) {
4456
4465
  // vertical stack — scroll vertically if it overflows (simple drag)
4457
4466
  let y = 0;
4458
4467
  const colX = (this.w - cardW) / 2;
@@ -4479,7 +4488,7 @@ class BuyBonusOverlay extends pixi_js.Container {
4479
4488
  }
4480
4489
  }
4481
4490
  // ── one card ──────────────────────────────────────────────────────────────
4482
- buildCard(bonus, cardW, em, mobile, areaH) {
4491
+ buildCard(bonus, cardW, em, stack, areaH) {
4483
4492
  const accent = effectiveAccent(bonus);
4484
4493
  const ink = contrastText(accent);
4485
4494
  const price = bonus.priceMultiplier * this.host.state.bet;
@@ -4681,7 +4690,8 @@ class BuyBonusOverlay extends pixi_js.Container {
4681
4690
  * Browse phase: arrows move focus; +/- step bet; Enter/Space opens confirm; Escape closes.
4682
4691
  * Confirm phase: Enter/Space buys/activates; Escape returns to browse. */
4683
4692
  onKey(e) {
4684
- const mobile = this.host.layout === 'mobile';
4693
+ // Vertical stack (mobile / short popout) → Up/Down navigate; horizontal row → Left/Right.
4694
+ const stack = this.stack;
4685
4695
  if (this.confirm && this.confirmBonus) {
4686
4696
  // ── Confirm phase ──
4687
4697
  switch (e.code) {
@@ -4715,8 +4725,8 @@ class BuyBonusOverlay extends pixi_js.Container {
4715
4725
  return true;
4716
4726
  }
4717
4727
  // Determine navigation direction from key code + layout
4718
- const fwdKey = e.code === 'ArrowRight' || (mobile && e.code === 'ArrowDown');
4719
- const bwdKey = e.code === 'ArrowLeft' || (mobile && e.code === 'ArrowUp');
4728
+ const fwdKey = e.code === 'ArrowRight' || (stack && e.code === 'ArrowDown');
4729
+ const bwdKey = e.code === 'ArrowLeft' || (stack && e.code === 'ArrowUp');
4720
4730
  if (fwdKey) {
4721
4731
  if (last < 0)
4722
4732
  return true;