From 6ae8448c63da92a7cd2e8b3bcfb4fda1c5ae46c6 Mon Sep 17 00:00:00 2001 From: Syed Zaidi Date: Mon, 3 Aug 2026 20:02:21 -0400 Subject: [PATCH 1/2] fix(inventory): scale 3D modal with viewport, unify market action row --- .../common/skincraft_viewer_modal_styles.ts | 24 ++++++++++++------- .../inventory/selected_item_info.ts | 18 +++++++------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/lib/components/common/skincraft_viewer_modal_styles.ts b/src/lib/components/common/skincraft_viewer_modal_styles.ts index 53464a84..ab57f082 100644 --- a/src/lib/components/common/skincraft_viewer_modal_styles.ts +++ b/src/lib/components/common/skincraft_viewer_modal_styles.ts @@ -7,8 +7,11 @@ export const skinCraftViewerModalStyles = ` font-family: Arial, Helvetica, sans-serif; } + /* Width follows the viewport; the height-derived term caps the 16:9 stage at 80vh so the + composition scales with the screen, mirroring the market site's screenshot dialog. */ dialog { - width: min(1120px, calc(100vw - 48px)); + width: min(90vw, calc(80vh * 16 / 9)); + width: min(90vw, calc(80dvh * 16 / 9)); max-width: none; padding: 0; border: 1px solid rgba(193, 206, 255, 0.12); @@ -429,8 +432,10 @@ export const skinCraftViewerModalStyles = ` } @media (min-width: 1168px) and (max-width: 1519px) and (min-height: 840px) { + /* The 122px item strip sits above the stage, so it joins the height budget. */ dialog.has-items { - width: 1120px; + width: max(1120px, min(90vw, calc((80vh - 122px) * 16 / 9))); + width: max(1120px, min(90vw, calc((80dvh - 122px) * 16 / 9))); } dialog.has-items .modal-body { @@ -463,19 +468,24 @@ export const skinCraftViewerModalStyles = ` } @media (min-width: 1520px) { + /* The 320px item panel sits beside the stage, so it joins the width budget instead. */ dialog.has-items { - width: min(1440px, calc(100vw - 48px)); + width: min(90vw, calc(80vh * 16 / 9 + 320px)); + width: min(90vw, calc(80dvh * 16 / 9 + 320px)); } dialog.has-items .modal-body { display: grid; - grid-template-columns: minmax(280px, 320px) 1120px; + grid-template-columns: 320px minmax(0, 1fr); } dialog.has-items .item-panel { display: flex; flex-direction: column; - height: min(630px, calc(100vh - 104px)); + /* The stage's height (its column width at 16:9), restated because the panel's own + content must not be what sizes the shared grid row. */ + height: min(calc((90vw - 320px) * 9 / 16), 80vh); + height: min(calc((90vw - 320px) * 9 / 16), 80dvh); border-right: 1px solid rgba(193, 206, 255, 0.1); } @@ -499,10 +509,6 @@ export const skinCraftViewerModalStyles = ` dialog.has-items .item-card { height: 92px; } - - dialog.has-items .viewer-stage { - width: 1120px; - } } @media (max-width: 640px) { diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index 6c169cb4..4f795186 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -60,10 +60,10 @@ export class SelectedItemInfo extends FloatElement { flex-wrap: wrap; align-items: center; gap: 10px; + margin: 14px 0 10px; } .market-btn-container { - margin: 10px 0 10px 0; padding: 5px; width: fit-content; border: solid 1px rgb(56 64 77); @@ -219,19 +219,19 @@ export class SelectedItemInfo extends FloatElement { ); } - if (this.canListOnCSFloat || this.show3dButton) { - // The modal lives outside the flex row: as a flex item its host would add a gap and - // nudge the 3D button whenever it mounts. + if (this.canListOnCSFloat || this.show3dButton || this.stallListing) { + // One flex row for every action: the market action (list button or active listing — + // mutually exclusive) keeps the left slot in both states, and nothing wraps while + // there's room. The modal lives outside the row: as a flex item its host would add a + // gap and nudge the 3D button whenever it mounts. containerChildren.push( - html`
${this.renderListOnCSFloat()} ${this.renderViewIn3D()}
+ html`
+ ${this.renderListOnCSFloat()} ${this.renderFloatMarketListing()} ${this.renderViewIn3D()} +
${this.renderListModal()}` ); } - if (isSellableOnCSFloat(this.asset.description)) { - containerChildren.push(this.renderFloatMarketListing()); - } - if (containerChildren.length === 0) { return html``; } From 65e35c4e1b80e91a569b4bee3a87b6b4e0a93e89 Mon Sep 17 00:00:00 2001 From: Syed Zaidi Date: Tue, 4 Aug 2026 23:58:56 -0400 Subject: [PATCH 2/2] fix(inventory): cap 3D modal width on very large displays --- .../common/skincraft_viewer_modal_styles.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/lib/components/common/skincraft_viewer_modal_styles.ts b/src/lib/components/common/skincraft_viewer_modal_styles.ts index ab57f082..83194bda 100644 --- a/src/lib/components/common/skincraft_viewer_modal_styles.ts +++ b/src/lib/components/common/skincraft_viewer_modal_styles.ts @@ -8,10 +8,11 @@ export const skinCraftViewerModalStyles = ` } /* Width follows the viewport; the height-derived term caps the 16:9 stage at 80vh so the - composition scales with the screen, mirroring the market site's screenshot dialog. */ + composition scales with the screen. The 1920px ceiling is the stage's native resolution — + past it 4K+ displays only upscale. */ dialog { - width: min(90vw, calc(80vh * 16 / 9)); - width: min(90vw, calc(80dvh * 16 / 9)); + width: min(90vw, calc(80vh * 16 / 9), 1920px); + width: min(90vw, calc(80dvh * 16 / 9), 1920px); max-width: none; padding: 0; border: 1px solid rgba(193, 206, 255, 0.12); @@ -470,8 +471,8 @@ export const skinCraftViewerModalStyles = ` @media (min-width: 1520px) { /* The 320px item panel sits beside the stage, so it joins the width budget instead. */ dialog.has-items { - width: min(90vw, calc(80vh * 16 / 9 + 320px)); - width: min(90vw, calc(80dvh * 16 / 9 + 320px)); + width: min(90vw, calc(80vh * 16 / 9 + 320px), 2240px); + width: min(90vw, calc(80dvh * 16 / 9 + 320px), 2240px); } dialog.has-items .modal-body { @@ -483,9 +484,10 @@ export const skinCraftViewerModalStyles = ` display: flex; flex-direction: column; /* The stage's height (its column width at 16:9), restated because the panel's own - content must not be what sizes the shared grid row. */ - height: min(calc((90vw - 320px) * 9 / 16), 80vh); - height: min(calc((90vw - 320px) * 9 / 16), 80dvh); + content must not be what sizes the shared grid row. Tracks the same 2240px ceiling + as the dialog, or it would outgrow the stage it sits beside. */ + height: min(calc((min(90vw, 2240px) - 320px) * 9 / 16), 80vh); + height: min(calc((min(90vw, 2240px) - 320px) * 9 / 16), 80dvh); border-right: 1px solid rgba(193, 206, 255, 0.1); }