diff --git a/B05_Profile/B05_Profile_UI_Profile_Drag.ts b/B05_Profile/B05_Profile_UI_Profile_Drag.ts index 8339c28d6..e3cbe853c 100644 --- a/B05_Profile/B05_Profile_UI_Profile_Drag.ts +++ b/B05_Profile/B05_Profile_UI_Profile_Drag.ts @@ -9,6 +9,7 @@ import { createPanelResizer } from "@ui/ui_template_resizer"; import { readStateRaw, stateKey, writeStateRaw } from "../A00_Common/b_page_state"; +import { profilePanelMaxHeight } from "./B05_Profile_UI_Profile_Heights"; import { MASSHAUL_MIN_HEIGHT } from "./B05_Profile_UI_Profile_MassHaul"; import { TABLE_OVERLAY_MIN_HEIGHT } from "./B05_Profile_UI_Profile_TableOverlay"; @@ -19,8 +20,6 @@ const MIN_CHART_HEIGHT = 100; const MASSHAUL_HANDLE_GUTTER_PX = 13; /** 패널을 끌어 줄일 수 있는 하한(px) — 이보다 낮으면 그래프도 테이블도 못 읽는다. */ const MIN_PANEL_HEIGHT = 180; -/** 상한은 위 칸(3D · 횡단 카드)이 완전히 가려지지 않도록 부모 높이의 90%까지만 허용한다. */ -const MAX_PANEL_HEIGHT_RATIO = 0.9; /** 접힘·높이는 화면 취향(①) — 두 보기가 **같은 키 하나**를 쓴다(계획서 24-2c). */ const HEIGHT_KEY = stateKey("profile-height") ?? ""; @@ -147,7 +146,8 @@ export function createProfileDrag(ctx: ProfileDragContext): ProfileDrag { chrome + MIN_CHART_HEIGHT + MASSHAUL_HANDLE_GUTTER_PX + massMin + tableMin, ); }, - max: () => (root.parentElement?.clientHeight ?? window.innerHeight) * MAX_PANEL_HEIGHT_RATIO, + // 상한 = 가운데 칸 높이의 90%(위 칸 3D · 횡단 카드가 다 가려지지 않게) — Heights 와 한 식 + max: () => profilePanelMaxHeight(root), storageKey: HEIGHT_KEY, }); diff --git a/B05_Profile/B05_Profile_UI_Profile_Heights.ts b/B05_Profile/B05_Profile_UI_Profile_Heights.ts index 170c37ed8..24561487d 100644 --- a/B05_Profile/B05_Profile_UI_Profile_Heights.ts +++ b/B05_Profile/B05_Profile_UI_Profile_Heights.ts @@ -19,6 +19,13 @@ const MASSHAUL_HANDLE_GUTTER_PX = 13; /** 패널 자동 확대 상한 — 메인 리사이저 max와 같은 식이어야 한다(부모 높이 비율). */ const MAX_PANEL_HEIGHT_RATIO = 0.9; +/** 패널 높이 상한(px) — 메인 리사이저 max 와 자동 확대가 같이 쓴다. 기준 = 한 페이지 가운데 칸 + * `.design-page__main`(바로 위 `.design-page__profile` 은 display: contents 라 높이 0). */ +export function profilePanelMaxHeight(root: HTMLElement): number { + const basis = root.closest(".design-page__main") ?? root.parentElement; + return (basis?.clientHeight || window.innerHeight) * MAX_PANEL_HEIGHT_RATIO; +} + export interface HeightCascadeDeps { /** 패널 루트 — 자리가 모자라면 이 높이를 키운다. */ root: HTMLElement; @@ -155,9 +162,7 @@ export function createHeightCascade(deps: HeightCascadeDeps): HeightCascade { // 상한은 메인 리사이저 max와 **같은 식**이어야 한다 — 예전 window 92% 상한은 // 리사이저 상한(부모 90%)보다 높아, 자동 확대 직후 손잡이를 잡는 순간 낮은 // 상한으로 clamp되며 패널이 뚝 떨어졌다(2026-08-06 분석). - const growCap = Math.round( - (deps.root.parentElement?.clientHeight ?? window.innerHeight) * MAX_PANEL_HEIGHT_RATIO, - ); + const growCap = Math.round(profilePanelMaxHeight(deps.root)); const grown = Math.min(deps.root.offsetHeight + deficit, growCap); if (grown > deps.root.offsetHeight + 1) { deps.root.style.setProperty("--b05-profile-height", `${grown}px`);