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