diff --git a/src/lib/components/common/skincraft_viewer_modal_styles.ts b/src/lib/components/common/skincraft_viewer_modal_styles.ts index 53464a84..83194bda 100644 --- a/src/lib/components/common/skincraft_viewer_modal_styles.ts +++ b/src/lib/components/common/skincraft_viewer_modal_styles.ts @@ -7,8 +7,12 @@ 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. The 1920px ceiling is the stage's native resolution — + past it 4K+ displays only upscale. */ dialog { - width: min(1120px, calc(100vw - 48px)); + 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); @@ -429,8 +433,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 +469,25 @@ 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), 2240px); + width: min(90vw, calc(80dvh * 16 / 9 + 320px), 2240px); } 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. 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); } @@ -499,10 +511,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`