Files
Aislo/B05_Profile/B05_Profile_UI_Style.css
T
eomsangdonandClaude Sonnet 5.5 9814c0ae34 style(B05): 종단 그래프 머리 [초기화]~▼ 단추 크기 = [배수유역도] · [새 창] 크기 · 공용 줄 단추 토큰(187-1)
- 왼쪽 단추 높이 17 · 글자 9 · 좌우 여백 3 → 높이 16 · 글자 12 · 좌우 여백 8
- theme 토큰 --btn-bar-padding · --btn-bar-font-size 하나로 세 곳이 씀
- test_187_1 신규

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3
2026-10-10 13:05:02 +09:00

606 lines
17 KiB
CSS

.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);
}
/* 3D 방식 고르기 한 줄 머리(115-5). */
.b05-route__view-label {
align-self: center;
font-size: var(--font-size-12, 12px);
color: var(--color-text-secondary, inherit);
white-space: nowrap;
}
.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:hover {
border-color: var(--color-royal-amethyst, rgb(109 40 217));
}
.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;
}
/* 도구줄 — 요약줄 맨 앞(최대 기울기 칩 왼쪽). 단추 크기는 같은 줄 오른쪽 [배수유역도] · [새 창]
과 같은 공용 토큰(`--btn-bar-*`). */
.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 {
padding: var(--btn-bar-padding);
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-family: var(--font-body);
font-size: var(--btn-bar-font-size);
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;
}