.b03-file { min-height: calc(100vh - var(--app-header-height, 0px)); background: linear-gradient( 180deg, var(--color-canvas, #ffffff) 0%, var(--color-mist-violet, #edecff) 100% ); padding: 0 var(--spacing-24) var(--spacing-48) var(--spacing-24); /* 상단 여백은 main-layout 마진으로 조정하므로 padding-top은 0 */ } .b03-file__main-layout { max-width: var(--page-max-width, 1200px); margin: var(--spacing-40) auto 0 auto; /* 상단 구분선(헤더)과의 간격을 확실하게 40px 벌림 */ display: flex; flex-direction: column; gap: var(--spacing-32); } .b03-file__control-panel { display: flex; flex-direction: column; gap: var(--spacing-20); background: var(--color-canvas, #ffffff); padding: var(--spacing-32); border-radius: var(--radius-large, 24px); /* Wiza 24px 대형 둥글기 */ border: 1px solid var(--color-mist, #e6e2e3); box-shadow: var(--shadow-lg); } .b03-file__cards-container-panel { margin-top: 0; /* 단일 layout gap에 의해 제어되도록 설정 */ } .b03-file__subtitle { font-size: var(--text-body-sm, 14px); color: var(--color-slate, #615e6e); margin: 0 0 var(--spacing-8) 0; } .b03-file__native-input, .b03-file__slot-input { display: none; } /* Wiza 스타일 가이드의 Lavender Glow 그라데이션 및 soft purple border hover */ .b03-file__dropzone { min-height: 160px; padding: var(--spacing-32) var(--spacing-24); border: 2px dashed var(--color-mist, #e6e2e3); border-radius: var(--radius-large, 24px); background: var(--color-paper, #f6f7fa); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--spacing-8); cursor: pointer; text-align: center; transition: background var(--transition-base, 0.2s), border-color var(--transition-base, 0.2s), box-shadow var(--transition-base, 0.2s); } .b03-file__dropzone:hover { background: var(--color-mist-violet, #edecff); border-color: var(--color-royal-amethyst, #3e0079); } .b03-file__dropzone:focus-visible, .b03-file__dropzone.is-dragging { outline: none; background: var(--color-mist-violet, #edecff); border-color: var(--color-royal-amethyst, #3e0079); box-shadow: 0 0 0 4px rgba(62, 0, 121, 0.15); } .b03-file__dropzone strong { color: var(--color-deep-iris, #26114a); font-size: var(--text-body, 16px); font-weight: var(--font-weight-medium, 500); } .b03-file__dropzone span { font-size: var(--text-body-sm, 14px); color: var(--color-slate, #615e6e); } .b03-file__error { min-height: var(--spacing-16); color: var(--color-danger, #dc2626); font-size: var(--text-body-sm, 14px); margin: var(--spacing-8) 0; } .b03-file__resume { display: none; align-items: center; gap: var(--spacing-8); flex-wrap: wrap; padding: var(--spacing-12) var(--spacing-16); border: 1px solid var(--color-mist, #e6e2e3); border-radius: var(--radius-cards, 8px); background: var(--color-paper, #f6f7fa); color: var(--color-deep-iris, #26114a); font-size: var(--text-body-sm, 14px); margin-top: var(--spacing-8); } .b03-file__resume.is-visible { display: flex; } /* 재접속 현황(서버 정본) 배너 — 완료 안내와 중단 세션 이어올리기 안내를 담는다. */ .b03-file__overview { display: none; flex-direction: column; gap: var(--spacing-4); margin-top: var(--spacing-8); padding: var(--spacing-12) var(--spacing-16); border: 1px solid var(--color-border); border-radius: var(--radius-cards, 8px); background: var(--color-surface); font-size: var(--text-body-sm, 14px); } .b03-file__overview.is-visible { display: flex; } .b03-file__overview-complete { margin: 0; color: var(--color-success, #3fbb6f); font-weight: 600; } .b03-file__overview-pending { margin: 0; color: var(--color-text-secondary); } /* 완료 슬롯 재업로드 확인 모달 — 페이지 위를 덮는 단순 확인창. */ .b03-file__modal-backdrop { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; background: rgb(0 0 0 / 45%); } .b03-file__modal { display: flex; flex-direction: column; gap: var(--spacing-12); max-width: 420px; padding: var(--spacing-24); border: 1px solid var(--color-border); border-radius: var(--radius-cards, 8px); background: var(--color-surface-raised); box-shadow: 0 12px 32px rgb(0 0 0 / 30%); } .b03-file__modal p { margin: 0; color: var(--color-text-secondary); white-space: pre-line; } .b03-file__modal-actions { display: flex; gap: var(--spacing-8); justify-content: flex-end; } .b03-file__cards-grid { display: grid; grid-template-columns: 1fr; gap: var(--spacing-32); } /* 계획노선 | 지형(LAS) — 컨테이너를 둘로 나눈다(2026-08-31 사용자 지시). 노선은 카드 5장(shapefile 한 벌), 지형은 4장이라 폭을 5:4 비슷하게 준다. */ .b03-file__columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-24); align-items: start; } .b03-file__group { display: flex; flex-direction: column; gap: var(--spacing-20); } .b03-file__group-hint { font-size: var(--text-body-sm, 14px); color: var(--color-slate, #615e6e); margin: calc(var(--spacing-8) * -1) 0 0 0; } .b03-file__group-title { font-size: var(--text-subheading, 24px); color: var(--color-deep-iris, #26114a); font-family: var(--font-britti-sans, inherit); margin: 0 0 var(--spacing-8) 0; } .b03-file__group-content { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-24); } /* 업로드 중에는 화면 조작을 막는다 — 중복 업로드·단계 이동 방지(2026-08-08 사용자 지시). */ .b03-file--busy { pointer-events: none; } .b03-file--busy .b03-file__card-select, .b03-file--busy .b03-file__card-remove, .b03-file--busy .b03-file__dropzone { opacity: 0.5; } /* 업로드 버튼 안에서 도는 원 — 공용 스피너를 버튼 글자 크기에 맞춰 줄인다. */ .b03-file__upload-spinner { width: 14px; height: 14px; border-width: 2px; border-color: rgb(255 255 255 / 40%); border-top-color: var(--color-primary-text); } /* Wiza 8px radius 카드 */ .b03-file__card { min-height: 220px; padding: var(--spacing-24); /* 내부 전체 패딩 확대 */ border: 1px solid var(--color-mist, #e6e2e3); border-radius: var(--radius-cards, 8px); background: var(--color-canvas, #ffffff); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: var(--spacing-20); transition: transform var(--transition-base, 0.2s), border-color var(--transition-base, 0.2s), box-shadow var(--transition-base, 0.2s); } .b03-file__card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); border-color: var(--color-royal-amethyst, #3e0079); } .b03-file__card--selected { border-color: var(--color-royal-amethyst, #3e0079); background: var(--color-paper, #f6f7fa); } .b03-file__card--uploading { border-color: var(--color-royal-amethyst, #3e0079); box-shadow: var(--shadow-lg-2); } .b03-file__card--completed { border-color: #10b981; /* Success Green */ } .b03-file__card--error { border-color: var(--color-danger, #dc2626); } /* 카드가 좁아졌다(컨테이너 2열 × 카드 2열, 2026-08-31). 격자로 고정하면 제목이 글자 단위로 접히므로, 자리가 모자라면 배지·삭제 버튼이 다음 줄로 내려가게 한다. */ .b03-file__card-header { display: flex; flex-wrap: wrap; gap: var(--spacing-8); align-items: center; } .b03-file__card-icon { flex: 0 0 auto; width: 28px; height: 28px; border-radius: var(--radius-icons, 8px); display: inline-flex; align-items: center; justify-content: center; color: var(--color-royal-amethyst, #3e0079); background: var(--color-mist-violet, #edecff); font-size: var(--text-body-sm, 14px); margin-right: var( --spacing-8 ); /* 아이콘 우측 마진 추가 (아이콘 좌측 여유 확대 효과) */ } .b03-file__card-heading { min-width: 0; flex: 1 1 55%; display: flex; flex-direction: column; gap: 2px; margin-top: 2px; /* 제목 상단 여유 추가 */ } .b03-file__card-label { color: var(--color-deep-iris, #26114a); font-size: var(--text-body-sm, 14px); font-weight: var(--font-weight-medium, 500); /* 한글은 글자 단위로 끊기므로 어절을 지켜 준다 — "계획 노선 도형" 방지. */ word-break: keep-all; overflow-wrap: break-word; } .b03-file__card-ext, .b03-file__file-size, .b03-file__progress-info { color: var(--color-slate, #615e6e); font-size: var(--text-caption, 12px); } .b03-file__card-badge-container { display: flex; align-items: center; margin-left: auto; margin-right: var(--spacing-4); } .b03-file__card-remove { width: 24px; height: 24px; border: 1px solid var(--color-mist, #e6e2e3); border-radius: var(--radius-buttons, 8px); color: var(--color-slate, #615e6e); background: var(--color-canvas, #ffffff); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: var(--text-body-sm, 14px); line-height: 1; padding: 0; margin-left: var( --spacing-8 ); /* 취소 버튼 좌측 여유 추가 (취소 버튼 우측 여유 확보) */ transition: all var(--transition-base, 0.2s); } .b03-file__card-remove:hover { color: var(--color-danger, #dc2626); border-color: var(--color-danger, #dc2626); background: #fef2f2; } .b03-file__card-content { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: var(--spacing-16); /* 버튼 하단 및 내부 간격 확대 */ padding-bottom: var(--spacing-8); /* 파일 선택 버튼 하단 패딩 확보 */ } .b03-file__card-select { width: 100%; min-height: 40px; /* 버튼 높이 증가 */ border: 1px solid var(--color-mist, #e6e2e3); border-radius: var(--radius-buttons, 8px); color: var(--color-deep-iris, #26114a); background: var(--color-canvas, #ffffff); font-weight: var(--font-weight-medium, 500); font-size: var(--text-body-sm, 14px); cursor: pointer; margin-bottom: var(--spacing-8); /* 파일 선택 버튼 하단 마진 추가 */ transition: background var(--transition-base, 0.2s), border-color var(--transition-base, 0.2s); } .b03-file__file-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; } .b03-file__file-name { color: var(--color-deep-iris, #26114a); font-size: var(--text-body-sm, 14px); font-weight: var(--font-weight-medium, 500); overflow-wrap: anywhere; } .b03-file__progress-section { display: flex; flex-direction: column; gap: var(--spacing-8); } .b03-file__progress-bar-container { width: 100%; height: 6px; overflow: hidden; border-radius: var(--radius-pills, 1440px); background: var(--color-mist, #e6e2e3); } .b03-file__progress-bar { width: 0; height: 100%; border-radius: var(--radius-pills, 1440px); background: var(--color-royal-amethyst, #3e0079); transition: width var(--transition-base, 0.2s); } .b03-file__progress-info { display: flex; flex-direction: column; gap: 2px; } .b03-file__error-message { display: none; padding: var(--spacing-8) var(--spacing-12); border-radius: var(--radius-cards, 8px); color: var(--color-danger, #dc2626); background: #fef2f2; font-size: var(--text-caption, 12px); border: 1px solid rgba(220, 38, 38, 0.15); } .b03-file__card--empty .b03-file__file-info, .b03-file__card--empty .b03-file__progress-section, .b03-file__card--empty .b03-file__error-message { display: none; } .b03-file__card--selected .b03-file__progress-section { display: none; } .b03-file__card--uploading .b03-file__card-select, .b03-file__card--completed .b03-file__card-select { display: none; } .b03-file__card--error .b03-file__error-message { display: block; } .b03-file__card--error .b03-file__progress-section { display: none; } .b03-file__results { margin: var(--spacing-8) 0 0 0; padding: 0; list-style: none; border: 1px solid var(--color-mist, #e6e2e3); border-radius: var(--radius-cards, 8px); overflow: hidden; background: var(--color-canvas, #ffffff); } .b03-file__results:empty { display: none; } .b03-file__results li { padding: var(--spacing-12) var(--spacing-16); display: flex; flex-direction: column; gap: 2px; border-bottom: 1px solid var(--color-mist, #e6e2e3); color: var(--color-deep-iris, #26114a); font-size: var(--text-body-sm, 14px); } .b03-file__results li:last-child { border-bottom: 0; } @media (max-width: 1440px) { /* 좁아지면 두 컨테이너를 위아래로 쌓는다 — 카드가 눌려 글자가 접히는 것을 막는다. */ .b03-file__columns { grid-template-columns: 1fr; } } @media (max-width: 720px) { .b03-file { padding: var(--spacing-16) var(--spacing-12); } .b03-file__group-content { grid-template-columns: 1fr; /* 모바일에서는 1행 1열 구조 */ } } /* LAS 없는 설계(도엽등고선 기반) 토글 — 2026-08-30 */ .b03-file__lasfree { display: flex; align-items: center; gap: 8px; padding: 4px 2px; font-size: var(--text-body); color: var(--color-text-body); cursor: pointer; user-select: none; } .b03-file__card--disabled { opacity: 0.45; pointer-events: none; }