$transport-gradient: linear-gradient( 180deg, rgb(96, 79, 50) 0%, rgb(85, 75, 49) 7%, rgb(64, 51, 39) 11%, rgb(40, 34, 22) 100% ); $tool-gradient: linear-gradient( 180deg, rgb(96, 79, 50) 0%, rgb(59, 52, 34) 7%, rgb(54, 43, 31) 11%, rgb(66, 55, 35) 100% ); $group-border: linear-gradient( 180deg, rgba(255, 182, 135, 0.5) 0%, rgba(255, 255, 255, 0) 100%, ); $default-border: linear-gradient( 180deg, rgba(255, 255, 255, 0.25) 25%, rgba(153, 122, 101, 0.63) 63%, rgba(98, 62, 39, 0.81) 81%, rgba(80, 67, 60, 1) 100% ); $hover-border: linear-gradient( 180deg, #ffa812 8%, #ffdfa7 38%, #ffa812 72%, #a96e09 95% ); // ── 컨트롤 패널 치수 (이 값들만 바꾸면 관련 위치/크기가 자동 계산됨) ── $panel-h: 96.67px; // transportGroup 높이 $panel-inset: 2px; // 그룹 가장자리 공통 인셋 // 재생·정지·측점입력 그룹 $transport-group-w: 161.33px; $transport-btn-w: 78px; $transport-btn-h: 55px; $transport-btn-left: 3px; // 첫(재생) 버튼 좌측 인셋 $transport-btn-top: 4px; $transport-btn-gap: 1px; // 재생 ↔ 정지 간격 // 화면캡처·측점선 그룹 $tool-group-w: 76px; $tool-group-h: 96px; $tool-btn-h: 47px; $tool-btn-top: 0.5px; // 화면캡처(첫 버튼) top — 47×2가 96 안에 들어가도록 축소 $tool-btn-gap: 1px; // 화면캡처 ↔ 측점선 간격 (47px 버튼이 바 안에 들어가도록) /* 컨트롤 묶음 — bottomBar flex 자식 (좌측 정렬, 세로 중앙) */ .controlsRow { position: relative; display: inline-flex; gap: 4px; padding-left: 1.33px; align-items: center; z-index: 4; } %control-button { position: absolute; z-index: 4; box-sizing: border-box; padding: 0; display: flex; align-items: center; justify-content: center; border: 1.5px solid transparent; border-radius: 4px; appearance: none; cursor: pointer; overflow: hidden; background: $transport-gradient padding-box, $default-border border-box; box-shadow: 0 0 0 2px rgb(0, 0, 0); transition: box-shadow 150ms ease-out; &:hover { background: $transport-gradient padding-box, $hover-border border-box; box-shadow: 0 0 0 2px #000, 0 0 8px rgba(255, 168, 18, 0.35); } } /* 플레이·정지·측점 입력 패널 */ .transportGroup { position: relative; width: $transport-group-w; height: $panel-h; } .leftPanel { position: absolute; left: -1px; top: 0; width: calc(100% + 4px); height: 100%; /* 그라데이션 테두리 두께 = 이 border 폭 (숫자를 키우면 더 굵어짐) */ border: 2px solid transparent; box-sizing: border-box; border-radius: 4px; background: linear-gradient(rgb(38, 29, 13), transparent) padding-box, $group-border border-box; z-index: 3; } .transportBtn { @extend %control-button; left: $transport-btn-left; top: $transport-btn-top; width: $transport-btn-w; height: $transport-btn-h; } .stopBtn { @extend %control-button; // 재생 버튼 우측 + 간격 → 폭이 바뀌면 자동으로 따라옴 left: $transport-btn-left + $transport-btn-w + $transport-btn-gap + 1px; top: $transport-btn-top; width: $transport-btn-w; height: $transport-btn-h; } /* 버튼 아이콘: 실제 SVG 파일(그라데이션·그림자·테두리 포함)을 배경으로 사용. 호버 시 버튼의 :hover 로 _on 버전으로 교체한다. 박스 크기는 SVG viewBox의 2/3 (= 기존 렌더 크기 유지). 새 아이콘은 SVG만 교체하면 되어 유지보수가 쉽다. */ %btn-icon { background-repeat: no-repeat; background-position: center; background-size: contain; pointer-events: none; } .playIcon { @extend %btn-icon; width: 40px; // 60 × 2/3 height: 40px; background-image: url('/assets/icons/ico_play.png'); } .transportBtn:hover .playIcon { background-image: url('/assets/icons/ico_play_on.png'); } .pauseIcon { @extend %btn-icon; width: 33.33px; // 50 × 2/3 height: 33.33px; background-image: url('/assets/icons/icon_pause.png'); } .transportBtn:hover .pauseIcon { background-image: url('/assets/icons/icon_pause_on.png'); } .stopIcon { @extend %btn-icon; width: 40px; // 60 × 2/3 height: 40px; background-image: url('/assets/icons/icon_stop.png'); } .stopBtn:hover .stopIcon { background-image: url('/assets/icons/icon_stop_on.png'); } .mileageInput { position: absolute; left: $transport-btn-left; top: 62px; z-index: 4; width: $transport-group-w - $transport-btn-left - $panel-inset; height: 32.67px; border: none; border-radius: 4px; background: rgba(0, 0, 0, 0.65); box-shadow: 0 0 0 2px rgb(0, 0, 0), 0 0.5px 0 0 rgba(255, 255, 255, 0.1); box-sizing: border-box; padding: 0 8px; font-family: 'Noto Sans KR', var(--font-ui); font-size: 16px; font-weight: 400; letter-spacing: 0.04em; color: #fff; &::placeholder { color: rgba(255, 255, 255, 0.5); } &:focus { outline: none; } } /* '측점 없음' 안내 — 입력창 위에 겹쳐 표시(패널 자식이 absolute 라 일반 흐름은 가려짐). */ .notFound { position: absolute; left: $transport-btn-left; top: 62px; height: 32.67px; width: $transport-group-w - $transport-btn-left - $panel-inset; display: flex; align-items: center; justify-content: center; gap: 4px; z-index: 6; // mileageInput(z:4) 위 border-radius: 4px; background: rgba(20, 0, 0, 0.88); box-shadow: 0 0 0 2px #000; color: #ff6b6b; font-family: 'Noto Sans KR', var(--font-ui); font-size: 14px; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; pointer-events: none; } /* 화면캡처·측점선 보기 패널 */ .toolGroup { position: relative; width: $tool-group-w; height: $tool-group-h; margin-left: 1px; // transportGroup 패널 확장분만큼 1px 우측 이동 border-radius: 4px; background: #1a1309; } .toolBtn { @extend %control-button; left: $panel-inset; width: $tool-group-w - 2 * $panel-inset; // 좌우 인셋 제외 → 그룹 폭 바뀌면 자동 height: $tool-btn-h; // 바 영역을 벗어나지 않도록 축소 + 두 버튼 사이 간격 확보 display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; background: $tool-gradient padding-box, $default-border border-box; &:hover { background: $tool-gradient padding-box, $hover-border border-box; box-shadow: 0 0 0 2px #000, 0 0 8px rgba(255, 168, 18, 0.35); } } .captureBtn { top: $tool-btn-top + $tool-btn-top; } /* 화면캡처 아래 = 첫 버튼 top + 높이 + 간격 → 높이/간격 바꾸면 자동으로 따라옴 */ .lineBtn { top: $tool-btn-top + $tool-btn-h + $tool-btn-gap + $tool-btn-top + 1px; } .cameraIcon { @extend %btn-icon; width: 24px; // 확대 height: 20px; background-image: url('/assets/icons/icon-camera-body.png'); } .captureBtn:hover .cameraIcon { background-image: url('/assets/icons/icon-camera-body_on.png'); } .lineIcon { @extend %btn-icon; width: 19.2px; // 확대 height: 20px; background-image: url('/assets/icons/icon-sturn.png'); } .lineBtn:hover .lineIcon { background-image: url('/assets/icons/icon-sturn_on.png'); } .toolLabel { font-family: 'Noto Sans KR', var(--font-ui); font-weight: 700; font-size: 13.33px; // 살짝 축소 (기존 14.67) line-height: 1.2; letter-spacing: -0.04em; white-space: nowrap; color: rgb(204, 199, 189); text-shadow: 0 0.5px 1px rgb(0, 0, 0); } .toolBtn:hover .toolLabel { color: #ffa812; } /* 측점선 보기 토글 ON 상태(클릭): 호버와 동일한 아이콘·라벨 색에, 눌린 어두운 그라데이션 배경 + 주황 그라데이션 테두리. 별도 동작 없음. (채움 레이어는 padding-box, 테두리 그라데이션은 border-box) */ .lineBtn.active { background: linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%) padding-box, linear-gradient( 180deg, #211601 5%, #211601 10%, #352509 15%, #352509 85%, #231700 90%, #000 95% ) padding-box, $hover-border border-box; box-shadow: 0 0 0 2px #000; } .lineBtn.active .lineIcon { background-image: url('/assets/icons/icon-sturn_on.png'); } .lineBtn.active .toolLabel { color: #ffa812; }