기존 GhiVideo 저장소 HEAD의 트래킹 소스 362개 파일을 복제. (node_modules·storage·빌드 산출물·대용량 미디어는 .gitignore 규칙대로 제외) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
332 lines
8.1 KiB
SCSS
Executable File
332 lines
8.1 KiB
SCSS
Executable File
$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;
|
||
}
|