B05/B06 인터페이스 일원화 1차 (2026-08-29 사용자 확정 계획): - A00_Common/b_structures_section.ts: B05 구조물 배치 폼·목록 공용 진입점 (재수출 + 스타일 동봉) - B06 좌측 패널에 [구조물 배치] 섹션 + 하단 dock [목록][구분선][저장버튼] (B05 동일 템플릿). 구조물 조작은 세션 pending으로 쌓여 기존 flushPendingStructures([임시저장]·[확정])로 정본 반영 - 선택 연동: 목록·폼 → 최근접 카드 focusStation, 횡단도 벽·세월교·BOX → 좌측 폼에 소유 측점 시설 로드(wireStructureSelection) - [횡단 조정] 하위 컨테이너(Adjust_Dock): 오버레이 조정창을 같은 deps로 사본 인스턴스 생성해 세움 — 로직 이동 0, 카드 재렌더로 자동 동기. 9키·십자 행은 사본에서 숨김(사용자 지시 7), 방향키 이중 입력 방지 - A군 시설 추가·이동·삭제는 B06에서 안내 토스트(배수유역 체인은 B05 몫) 검증: 공용 브라우저 — 구간값 길이 사본 + 10.0→11.0m 양측 동기, 오버레이 - 원복, ✕ 닫기 시 사본 해제. B05 회귀 없음. typecheck 통과.
272 lines
6.6 KiB
CSS
272 lines
6.6 KiB
CSS
/* 구조물 위치 조정 오버레이 창. */
|
||
/* 구조물 조정 오버레이 — **위쪽 기준**으로 붙인다(2026-08-24 사용자). 아래를 기준으로
|
||
* 두면 높이가 낮은 횡단도에서 창이 카드 위로 넘쳐 **제목·값 줄이 잘린다**. 카드 안에
|
||
* 넘칠 만큼 길어지면 창 안에서 스크롤한다. z-index는 카드 안 오버레이 중 최상단. */
|
||
.b06-structure-panel {
|
||
position: absolute;
|
||
top: var(--spacing-8);
|
||
left: var(--spacing-8);
|
||
z-index: 20;
|
||
display: flex;
|
||
max-height: calc(100% - 2 * var(--spacing-8));
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
padding: var(--spacing-8);
|
||
border: 1px solid var(--color-danger);
|
||
border-radius: var(--radius-inputs);
|
||
background: color-mix(in srgb, var(--color-surface-raised) 94%, transparent);
|
||
overflow-y: auto;
|
||
overscroll-behavior: contain;
|
||
}
|
||
|
||
/* 연동·경사 — 한 행에 버튼 두 개(2026-08-24 사용자). 켜짐은 채운 색으로 구분한다. */
|
||
.b06-structure-panel__controls.b06-structure-panel__toggles {
|
||
display: flex;
|
||
gap: 2px;
|
||
}
|
||
|
||
.b06-structure-panel__toggle {
|
||
width: auto;
|
||
padding: 0 var(--spacing-8);
|
||
}
|
||
|
||
.b06-structure-panel__toggle.is-on {
|
||
border-color: var(--color-danger);
|
||
background: var(--color-danger);
|
||
color: var(--color-text-inverse, #fff);
|
||
}
|
||
|
||
.b06-structure-panel.is-hidden,
|
||
.b06-structure-panel__value span.is-hidden,
|
||
.b06-structure-panel__btn.is-hidden,
|
||
.b06-structure-panel__buttons.is-hidden,
|
||
.b06-structure-panel__struct.is-hidden {
|
||
display: none;
|
||
}
|
||
|
||
.b06-structure-panel__head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--spacing-8);
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.b06-structure-panel__title {
|
||
color: var(--color-danger);
|
||
font-size: var(--text-caption);
|
||
font-weight: var(--font-weight-medium);
|
||
}
|
||
|
||
.b06-structure-panel__value {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1px;
|
||
color: var(--color-text-secondary);
|
||
font-size: var(--text-caption);
|
||
}
|
||
|
||
.b06-structure-panel__controls.b06-structure-panel__buttons {
|
||
display: grid;
|
||
grid-template-areas: ". up ." "left reset right" ". down equal";
|
||
justify-content: center;
|
||
gap: 2px;
|
||
}
|
||
|
||
.b06-structure-panel__btn--up {
|
||
grid-area: up;
|
||
}
|
||
.b06-structure-panel__btn--down {
|
||
grid-area: down;
|
||
}
|
||
.b06-structure-panel__btn--left {
|
||
grid-area: left;
|
||
}
|
||
.b06-structure-panel__btn--right {
|
||
grid-area: right;
|
||
}
|
||
.b06-structure-panel__btn--reset {
|
||
grid-area: reset;
|
||
}
|
||
.b06-structure-panel__btn--equal {
|
||
grid-area: equal;
|
||
}
|
||
|
||
.b06-structure-panel__controls .b06-structure-panel__btn {
|
||
box-sizing: border-box;
|
||
width: 26px;
|
||
height: 22px;
|
||
padding: 0;
|
||
text-align: center;
|
||
line-height: 1;
|
||
}
|
||
|
||
.b06-structure-panel__hval {
|
||
box-sizing: border-box;
|
||
width: 3.5em;
|
||
text-align: center;
|
||
color: var(--color-text-body);
|
||
font-size: var(--text-caption);
|
||
align-self: center;
|
||
}
|
||
|
||
.b06-structure-panel__struct {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 2px;
|
||
color: var(--color-text-secondary);
|
||
font-size: var(--text-caption);
|
||
}
|
||
|
||
.b06-structure-panel__label {
|
||
color: var(--color-text-muted);
|
||
font-size: var(--text-caption);
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.b06-structure-panel__controls {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 2px;
|
||
}
|
||
|
||
/* 집수정 조작 = 9키(3×3, 2026-08-22 사용자) — 십자 축 이동 · 모서리 크기 · 중앙 초기화.
|
||
기슭막이 십자와 같은 폭·버튼 크기로 맞춰 행열이 어긋나지 않게 한다. */
|
||
.b06-structure-panel__controls.b06-structure-panel__basin-buttons {
|
||
display: grid;
|
||
grid-template-areas:
|
||
"nw up ne"
|
||
"left reset right"
|
||
"sw down se";
|
||
justify-content: center;
|
||
gap: 2px;
|
||
}
|
||
|
||
.b06-structure-panel__btn--nw {
|
||
grid-area: nw;
|
||
}
|
||
|
||
.b06-structure-panel__btn--ne {
|
||
grid-area: ne;
|
||
}
|
||
|
||
.b06-structure-panel__btn--sw {
|
||
grid-area: sw;
|
||
}
|
||
|
||
.b06-structure-panel__btn--se {
|
||
grid-area: se;
|
||
}
|
||
|
||
.b06-structure-panel__basin-reset {
|
||
margin-left: auto;
|
||
}
|
||
|
||
.b06-structure-panel__select {
|
||
flex: 1;
|
||
padding: 1px var(--spacing-4);
|
||
border: 1px solid var(--color-border);
|
||
border-radius: var(--radius-inputs);
|
||
background: var(--color-surface);
|
||
color: var(--color-text);
|
||
font-size: var(--text-caption);
|
||
}
|
||
|
||
.b06-structure-panel__btn {
|
||
padding: 0 var(--spacing-8);
|
||
border: 1px solid var(--color-border);
|
||
border-radius: var(--radius-inputs);
|
||
background: var(--color-surface);
|
||
color: var(--color-text-secondary);
|
||
cursor: pointer;
|
||
font-size: var(--text-caption);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.b06-structure-panel__btn:hover {
|
||
border-color: var(--color-danger);
|
||
color: var(--color-danger);
|
||
}
|
||
|
||
.b06-structure-panel__close {
|
||
padding: 0 4px;
|
||
border-color: transparent;
|
||
background: transparent;
|
||
}
|
||
|
||
.b06-cross-card__zoom {
|
||
position: absolute;
|
||
top: var(--spacing-4);
|
||
right: var(--spacing-4);
|
||
z-index: 2;
|
||
display: flex;
|
||
overflow: hidden;
|
||
border: 1px solid var(--color-border);
|
||
border-radius: var(--radius-inputs);
|
||
background: color-mix(in srgb, var(--color-surface-raised) 88%, transparent);
|
||
}
|
||
|
||
.b06-cross-card__zoom-btn {
|
||
width: 22px;
|
||
height: 22px;
|
||
padding: 0;
|
||
border: none;
|
||
border-left: 1px solid var(--color-border);
|
||
background: none;
|
||
color: var(--color-text-secondary);
|
||
font-size: 0.8rem;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.b06-cross-card__zoom-btn:first-child {
|
||
border-left: none;
|
||
}
|
||
|
||
.b06-cross-card__zoom-btn:hover {
|
||
color: var(--color-text);
|
||
background: var(--color-surface);
|
||
}
|
||
|
||
/* ── 좌측 [횡단 조정] 사본(2026-08-29 B05/B06 일원화) ─────────────────────
|
||
* 오버레이 창과 같은 DOM을 좌측 사이드바에 흐름 배치로 세운다. */
|
||
.b06-structure-panel--dock {
|
||
position: static;
|
||
z-index: auto;
|
||
max-height: none;
|
||
margin-top: var(--spacing-8);
|
||
border-color: var(--color-border);
|
||
overflow: visible;
|
||
}
|
||
|
||
/* 9키·십자 위치제어(이동 D-pad·집수정 9키)는 횡단도 오버레이 전용
|
||
* (2026-08-29 사용자 지시 7) — 사본에서는 그 행을 통째로 숨긴다. */
|
||
.b06-structure-panel--dock
|
||
.b06-structure-panel__struct:has(> .b06-structure-panel__controls.b06-structure-panel__buttons),
|
||
.b06-structure-panel--dock
|
||
.b06-structure-panel__struct:has(
|
||
> .b06-structure-panel__controls.b06-structure-panel__basin-buttons
|
||
) {
|
||
display: none;
|
||
}
|
||
|
||
/* [횡단 조정] 하위 컨테이너 — 구조물 배치 폼과 경계 구분(접이식). */
|
||
.b06-adjust-dock {
|
||
margin-top: var(--spacing-8);
|
||
padding-top: var(--spacing-8);
|
||
border-top: 1px solid var(--color-border);
|
||
}
|
||
|
||
.b06-adjust-dock > summary {
|
||
color: var(--color-text-body);
|
||
font-size: var(--text-caption);
|
||
font-weight: var(--font-weight-medium);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.b06-adjust-dock__empty {
|
||
margin: var(--spacing-8) 0 0;
|
||
color: var(--color-text-muted);
|
||
font-size: var(--text-caption);
|
||
}
|