.b05-route-layout { height: calc(100vh - var(--spacing-64)); height: calc(100dvh - var(--spacing-64)); min-height: 0; overflow: hidden; } .b05-route-layout .ui-workflow-layout__body, .b05-route-layout .ui-workflow-layout__main { height: 100%; min-height: 0; } .b05-route-layout .ui-workflow-layout__main { overflow: hidden; } .b05-route__main { position: relative; display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; overflow: hidden; } .b05-route__viewport { position: relative; width: 100%; flex: 1 1 auto; height: auto; min-height: 0; overflow: hidden; background: var(--color-surface); } /* 하단 종단 패널: 그래프 + 12행 도면 테이블을 담기 위해 화면 높이의 60%를 차지한다. 3D 뷰포트를 밀어내지 않고 그 위를 덮는 오버레이로 띄운다 — 패널을 여닫아도 3D 뷰 크기가 변하지 않아 카메라 시점과 렌더 비용이 그대로 유지된다. 접기 핸들로 언제든 내릴 수 있어 3D 뷰를 전체 영역으로 볼 수 있다. */ .b05-route-profile { position: absolute; z-index: 3; right: 0; bottom: 0; left: 0; display: flex; height: 60vh; /* 기본은 화면의 60%. 위쪽 경계를 끌면 --b05-profile-height(px)가 대신 들어온다. */ height: var(--b05-profile-height, 60dvh); flex-direction: column; min-height: 0; overflow: visible; border-top: 1px solid var(--color-border); background: var(--color-surface-raised); transition: height var(--transition-fast); } /* 끄는 동안에는 transition을 끈다 — 켜 두면 손보다 패널이 늦게 따라온다. */ .b05-route-profile.is-resizing, .b05-drainage.is-resizing { transition: none; } /* 접힌 패널에는 끌 것이 없다 — 손잡이를 숨겨 잘못 잡히지 않게 한다. */ .b05-route-profile.is-collapsed > .ui-resizer, .b05-drainage.is-collapsed > .ui-resizer { display: none; } .b05-route-profile.is-collapsed { height: 0; min-height: 0; } /* 종단면 본문 + 우측 배수유역 패널의 2단 가로 배치. */ .b05-route-profile__content { display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; } /* 그래프 본문 + 로딩 서클을 겹치기 위한 칸. body는 그릴 때마다 자식이 교체된다. */ .b05-route-profile__body-wrap { position: relative; display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; } .b05-route-profile__body { box-sizing: border-box; flex: 1 1 auto; min-width: 0; min-height: 0; overflow-x: scroll; overflow-y: hidden; /* 좌측 여백을 0으로 둔다. 여백이 있으면 sticky 이름표 열이 그 여백까지 못 덮어, 가로 스크롤 시 셀 값이 이름표 왼쪽 틈으로 새어 보인다. 우측만 숨 돌릴 여백을 준다. */ padding-left: 0; padding-right: 15px; } /* 가로 스크롤바는 전역 pill 스크롤바(테마 `*::-webkit-scrollbar`, 8px)를 그대로 쓴다 — 좌측 사이드바와 동일한 형태로 통일. (예전엔 이 패널만 12px 두꺼운 막대로 덮어썼다.) */ /* 그래프와 테이블을 같은 폭으로 쌓아 X축이 저절로 맞물리게 한다. */ .b05-profile__canvas { position: relative; /* 유토곡선 경계 드래그 바(absolute)의 기준 */ display: flex; flex-direction: column; } .b05-profile__chart { position: relative; flex: 0 0 auto; min-height: 0; } /* 가로 스크롤 고정 Y축(.b05-profile__yaxis*)의 정의처는 B05_Profile_UI_Style_MassHaul.css다 — buildStickyYAxis를 쓰는 B05·B06이 함께 얻는다. */ .b05-route-profile.is-collapsed .b05-route-profile__body-wrap, .b05-route-profile.is-collapsed .b05-route-profile__body, .b05-route-profile.is-collapsed .b05-route-profile__balance { display: none; } .b05-route-profile__empty { margin: 0; padding: var(--spacing-24); color: var(--color-text-muted); font-size: var(--text-body-sm); } .b05-route-profile .b06-section__chart-wrap { height: 100%; } /* X·Y축 제목은 아래 도면 테이블이 그대로 담고 있어 중복이라 숨긴다. */ .b05-route-profile .b06-chart__axis-label { display: none; } /* 측점 이름(세로선 항목)은 그래프에서도 보여야 어느 측점의 선인지 바로 읽힌다. 다만 하단 편집 버튼(is-down: bottom 2px, 높이 15px)과 겹치지 않도록 라벨을 살짝 위로 올려 하단 여백 위쪽에 앉힌다(하단 버튼 밴드와 분리). */ .b05-route-profile .b06-chart__station-label { transform: translateY(-9px); } /* 비정규 측점(구조물)은 그래프에서도 파선 세로선으로 구분해 규칙 측점과 헷갈리지 않게 한다. */ .b05-route-profile .b06-chart__station-line--irregular { stroke: var(--color-royal-amethyst, rgb(139 92 246)); stroke-width: 1.4; stroke-dasharray: 5 3; } .b05-route__viewport canvas { display: block; width: 100%; height: 100%; } /* 3D 뷰포트 안내 문구 — 우상단 텍스트만(배경·테두리 없음, 회색). 2026-08-01 사용자 지시. 우측 세로 진행단계 오버레이와 겹치지 않도록 그 폭만큼 안쪽으로 들여 놓는다. */ .b05-route__viewer-status { position: absolute; z-index: 2; top: var(--spacing-16); right: calc(var(--wf-left-panel-width) / 2 + var(--spacing-48)); left: auto; max-width: 420px; color: var(--color-text-muted); font-size: var(--text-caption); text-align: right; pointer-events: none; } /* 뷰셋·표시 토글 버튼 묶음 — 좌상단(2026-08-01 사용자 지시). 안내 문구가 우상단으로 옮겨져 좌상단이 비었다. */ .b05-route__view-controls { position: absolute; z-index: 2; top: var(--spacing-16); left: var(--spacing-16); display: flex; align-items: center; gap: var(--spacing-8); } /* 방위 나침반을 놓을 자리 — ISO 버튼 바로 아래(2026-09-03 사용자 지시). 버튼 줄 높이 34px + 위 여백 16px 아래에 붙인다. 위젯 모양·색은 공용 (`ui_template/ui_template_compass.css`)이고 여기서는 위치만 준다. */ .b05-route__compass { top: calc(var(--spacing-16) + 34px + var(--spacing-8)); left: var(--spacing-16); } .b05-route__view-group { display: flex; gap: var(--spacing-4); } .b05-route__view-controls .ui-btn { height: 34px; padding: 0 var(--spacing-8); } .b05-route__view-separator { width: 1px; height: 24px; background: color-mix(in srgb, var(--color-border) 75%, transparent); } /* [3D 업데이트] 대기 표시 — 계획선 편집이 3D에 아직 안 들어갔음을 점으로 알린다. */ .b05-route__view-controls .ui-btn.is-pending { position: relative; border-color: var(--color-warning, #d98a00); } .b05-route__view-controls .ui-btn.is-pending::after { content: ""; position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--color-warning, #d98a00); } .b05-route__panel { display: flex; flex-direction: column; width: 100%; min-width: 0; gap: var(--spacing-16); } /* 스크롤 영역 상단 여유 — 첫 컨테이너(구조물 배치)가 패널 상단 경계에 붙어 답답하다는 보고(2026-08-18 사용자 지시). */ .b05-route__panel .ui-sidebar-scroll { padding-top: var(--spacing-8); /* 하단 여유 패딩은 두지 않는다 — 액션 dock이 최하단에 붙는 지금은 버튼 아래 빈 띠로만 남는다(2026-08-18). 공용 body 패딩(16px)은 dock의 sticky bottom:-16px가 덮는다. */ } .b05-route__panel-section { display: flex; flex-direction: column; width: 100%; min-width: 0; gap: var(--spacing-8); padding: calc(var(--spacing-8) + var(--spacing-4)); /* 테두리는 공통 ui-sidebar-section이 전담 — 로컬 border 선언이 공통 색을 덮던 문제 제거(2026-08-06 사용자 보고). */ border-radius: var(--radius-cards); background: var(--color-surface-raised); } /* 제목 행 클릭 접기/펼치기는 공용 collapsible(ui_template_theme.css)에서 처리한다. */ /* 사용여부 미결정 컨테이너(경로 계산 설정) — 숨기지 않고 "조작 안 되는 항목"임이 보이게 글자·배경을 가라앉힌다(2026-08-18 사용자 지시). 입력 차단은 본문 inert가 맡고, 여기서는 시각만 담당한다. 제목(접기)은 살아 있으므로 흐림에서 제외하지 않는다 — 컨테이너 전체가 한 덩어리로 비활성으로 읽혀야 한다. */ .b05-route__panel-section.is-disabled { background: color-mix(in srgb, var(--color-surface-raised) 60%, var(--color-canvas)); } .b05-route__panel-section.is-disabled > * { opacity: 0.45; } .b05-route__panel-section h3 { margin: 0; color: var(--color-text); font-size: var(--text-body-sm); } .b05-route__panel-body, .b05-route__field, .b05-route__metrics { display: flex; flex-direction: column; min-width: 0; gap: var(--spacing-8); } .b05-route__contour-row { display: flex; align-items: end; gap: var(--spacing-8); } /* 2열 그리드 — 각 열은 항목명(위)+값 입력(아래). '공사 시작점' 등 나란한 입력에 쓴다. */ .b05-route__field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-8); } .b05-route__contour-row .b05-route__field { flex: 1; } .b05-route__contour-row .ui-btn { flex: 0 0 auto; } .b05-route__field, .b05-route__check, .b05-route__metrics { color: var(--color-text-body); font-size: var(--text-caption); } .b05-route__field input, .b05-route__field select, .b05-route__panel-section > select, .b05-route__textarea { width: 100%; min-width: 0; padding: var(--spacing-8); border: 1px solid var(--color-border); border-radius: var(--radius-inputs); background: var(--color-surface); color: var(--color-text-body); } /* ─── 비정규 측점(구조물) 섹션 ─────────────────────────────────────────── */ .b05-route__irregular-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-8); } .b05-route__irregular-actions { display: flex; gap: var(--spacing-8); } .b05-route__irregular-btn { flex: 1 1 0; padding: var(--spacing-8); border: 1px solid var(--color-border); border-radius: var(--radius-inputs); background: var(--color-surface); color: var(--color-text-body); font-size: var(--text-caption); cursor: pointer; } .b05-route__irregular-btn.is-primary { border-color: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 55%, transparent); color: var(--color-text); } .b05-route__irregular-btn.is-danger { border-color: color-mix(in srgb, var(--color-danger) 50%, transparent); color: var(--color-danger); } .b05-route__irregular-btn:disabled { opacity: 0.45; cursor: default; } .b05-route__irregular-list { display: flex; flex-direction: column; gap: var(--spacing-4); margin: 0; padding: 0; list-style: none; /* 목록이 5개를 넘으면 사이드 패널을 밀어내지 않고 내부 스크롤로 돈다(2026-08-04 사용자 지시). 상한 = 항목 5개 높이(항목 약 30px + gap 4px) — 5개까지는 현행과 동일하게 다 보이고 6개째부터 스크롤이 생긴다. */ max-height: 170px; overflow-y: auto; } .b05-route__irregular-item { display: flex; align-items: baseline; gap: var(--spacing-8); padding: var(--spacing-4) var(--spacing-8); border: 1px solid var(--color-border); border-radius: var(--radius-inputs); background: var(--color-surface); cursor: pointer; } .b05-route__irregular-item.is-selected { border-color: var(--color-royal-amethyst, rgb(109 40 217)); background: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 12%, transparent); } .b05-route__irregular-item strong { color: var(--color-text); font-variant-numeric: tabular-nums; } /* 항목 = [측점(좌측)][구조물 이름(우측)] — 이름이 주 정보라 본문색, 남는 폭은 왼쪽 마진이 먹어 오른쪽 끝에 붙는다(2026-08-18 사용자 지시). */ .b05-route__irregular-item span { overflow: hidden; margin-left: auto; color: var(--color-text); font-size: var(--text-caption); text-align: right; text-overflow: ellipsis; white-space: nowrap; } .b05-route__irregular-empty { padding: var(--spacing-4) 0; color: var(--color-text-muted); font-size: var(--text-caption); list-style: none; } .b05-route__check { display: flex; align-items: center; gap: var(--spacing-8); } .b05-route__button-grid, .b05-route__palette { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); min-width: 0; gap: var(--spacing-8); } .b05-route__chip { padding: var(--spacing-8); border: 1px solid var(--color-border); border-radius: var(--radius-inputs); background: var(--color-surface); color: var(--color-text-body); font-size: var(--text-caption); cursor: pointer; } .b05-route__chip.is-ep, .b05-route__chip.is-fp { color: var(--color-danger); } .b05-route__chip.is-bp { color: var(--color-success); } .b05-route__chip.is-cp, .b05-route__stale { color: var(--color-warning); } /* 사이드 최하단 고정 영역 — 공용 ui-sidebar-actions(sticky·배경·상단 구분선)를 그대로 쓰되, 안쪽은 [구조물 목록][중간 구분선][액션 버튼 행] 세로 배치로 되돌린다 (2026-08-18 사용자 지시). */ .b05-route__dock.ui-sidebar-actions { flex-direction: column; } /* 공용 규칙(.ui-sidebar-actions > * { flex: 1 })이 목록·구분선까지 늘리지 않도록 같은 자리에서 되돌린다 — 로드 순서에 기대지 않게 선택자를 한 단계 더 좁혔다. */ .b05-route__dock.ui-sidebar-actions > * { flex: none; } .b05-route__actions { display: flex; gap: var(--spacing-8); } .b05-route__actions > * { flex: 1; } .b05-route__stale { font-size: var(--text-caption); font-weight: var(--font-weight-medium); } .b05-route__panel details { color: var(--color-text-body); font-size: var(--text-caption); } /* 계획선 설계 폼 안내문 */ .b05-route__note { margin: 0; color: var(--color-text-muted, var(--color-plum-velvet)); font-size: var(--text-caption); line-height: 1.4; } /* 종단면도 상단 절·성토 균형 지표 바 */ .b05-route-profile__balance { display: flex; flex: 0 0 auto; flex-wrap: nowrap; gap: var(--spacing-16); align-items: center; /* 유토곡선 총괄값이 이 줄로 올라와(2026-09-06) 항목이 늘었다 — 두 픽셀 높여 글자가 위아래로 눌리지 않게 한다. */ height: 28px; padding: 0 var(--spacing-8); overflow-x: auto; overflow-y: hidden; font-size: var(--text-caption); white-space: nowrap; } .b05-route-profile__balance-item { display: inline-flex; gap: var(--spacing-8); align-items: center; } .b05-route-profile__balance-item em { color: var(--color-text-muted, var(--color-plum-velvet)); font-style: normal; } .b05-route-profile__balance-item.is-cut em { color: rgb(220 38 38); } .b05-route-profile__balance-item.is-fill em { color: rgb(37 99 235); } .b05-route-profile__balance-item.is-over, .b05-route-profile__balance-item.is-unsaved { color: rgb(180 83 9); font-weight: var(--font-weight-medium); } .b05-route-profile__balance-item.is-edited em { color: var(--color-royal-amethyst, rgb(109 40 217)); } .b05-route-profile__balance-warning { overflow: hidden; color: rgb(180 83 9); text-overflow: ellipsis; } /* 도구줄 — 요약줄 맨 앞(최대 기울기 칩 왼쪽). 버튼 크기는 그래프 위 틸팅 버튼과 같다 (21×17px, 2026-09-02 사용자 지시). */ .b05-route-profile__tools { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 2px; margin-right: var(--spacing-8); } .b05-route-profile__tool { height: 17px; min-width: 21px; padding: 0 3px; border: 1px solid color-mix(in srgb, var(--color-border) 75%, transparent); border-radius: 3px; background: color-mix(in srgb, var(--color-surface-raised) 80%, transparent); color: var(--color-text); font-size: 9px; line-height: 1; cursor: pointer; } .b05-route-profile__tool:disabled { opacity: 0.35; cursor: default; } .b05-route-profile__tool.is-active { border-color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 22%, transparent); } .b05-route-profile__tool-hint { color: var(--color-text-muted); font-size: var(--text-caption); font-style: normal; }