/**
 * Modal — BS .modal override, page-modal-* shell, 사이드탭 + row
 * 로드: app/Views/components/html.php (common.css 이후)
 */

/* 모달 열림 중 배경 스크롤 잠금 (JS common.js 가 top:-scrollY 와 함께 토글).
   body 를 뷰포트에 고정 → <html> 이 스크롤 컨테이너에서 빠져 크롬 휠 latch 제거 +
   배경 스크롤 완전 차단. 모달/백드롭(둘 다 position:fixed)은 뷰포트 기준이라 영향 없음. */
body.modal-bg-lock {
    position: fixed;
    left: 0;
    right: 0;
}

/* 문서 스크롤바 상시 표시.
   모달을 열면 위 잠금(body:fixed)으로 <html> 에 스크롤할 내용이 없어져 루트 스크롤바가
   통째로 사라졌다가 닫을 때 다시 생긴다(깜빡임 + 폭 15px 만큼 흔들림).
   `scrollbar-gutter: stable` 은 이 자리에서 무효 — 크롬 150 실측상 루트(html/body)에는
   자리가 확보되지 않는다(clientWidth 불변). overflow-y:scroll 만 실제로 동작한다.
   ⚠ 위험해 보이지만 아래 .modal 주석의 latch 부작용은 `overflow:hidden` 한정이다.
     scroll 은 잠금 중 스크롤 범위가 0 이라 latch 대상이 되지 않는다(2026-09-10 실측:
     모달 내부 휠 정상, 배경 누수 없음). hidden 으로는 바꾸지 말 것. */
html {
    overflow-y: scroll;
}

/* BS5 ScrollBarHelper 의 스크롤바 폭 보정 무효화 (전 화면폭).
 * BS 는 모달을 열 때 사라질 스크롤바 폭만큼
 *   body → padding-right, .fixed-top → padding-right, .sticky-top → margin-right
 * 를 인라인으로 넣는다. 위 overflow-y:scroll 로 스크롤바가 사라지지 않으므로 보정을 두면
 * 오히려 그 폭만큼 콘텐츠가 한 번 더 밀린다. (모바일은 오버레이 스크롤바라 원래 불필요 —
 * 엉뚱한 값 51px 이 잡혀 오른쪽에 빈 여백으로 남던 것도 여기서 같이 해결.)
 * BS 가 인라인 스타일로 넣으므로 !important 로만 이길 수 있다. */
body.modal-open,
body.modal-open .fixed-top {
    padding-right: 0 !important;
}
body.modal-open .sticky-top {
    margin-right: 0 !important;
}

 .modal {
    --bs-modal-width: 550px;
    /* 모달 안에서 굴린 휠이 뒤 페이지(문서=<html>)로 새지 않게.
       .modal 은 뷰포트 전체를 덮는 스크롤 컨테이너(overflow-y:auto)라, 스크롤영역이 아닌
       헤더/여백 위에서 굴려도 여기서 contain 되어 배경 스크롤을 막는다.
       (주의: <html> 에 overflow:hidden 직접 잠금은 크롬에서 모달 내부 휠 스크롤이
        루트 스크롤러에 latch 되어 안 먹는 부작용 → 사용하지 않음.) */
    overflow: hidden;
    overscroll-behavior: contain;
    max-height: calc(100vh - 1rem);
 }

/* =============================================================
 * 커스텀 오버레이 page-modal-* (common-overlay + page-modal-card)
 * 폼/버튼 범위 override는 common.css .form-control/.btn 와 함께 적용
 * ============================================================= */
.page-modal-card {
    background: var(--bs-white);
    border-radius: 18px;
    width: 100%;
    max-width: 960px;
    box-shadow: 0 20px 60px rgba(2, 132, 199, 0.16), 0 4px 20px rgba(0, 0, 0, 0.12);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: min(calc(100dvh - 2rem), 100%);
}
.page-modal-card .form-feedback {
    font-size: var(--font-small);
    color: var(--bs-danger);
    margin-top: 5px;
}
.page-modal-card.page-modal-card--narrow {
    max-width: 740px;
}
.page-modal-topbar {
    display: none !important;
    height: 5px;
    background: linear-gradient(90deg, #0284c7, #38bdf8, #7dd3fc);
}
.page-modal-header {
    display: flex;
    align-items: center;
    gap: 15px;
    padding: 25px 30px 20px;
    background: var(--bs-white);
    border-bottom: 1px solid var(--bs-border-muted);
    flex-shrink: 0;
}
.page-modal-hicon {
    width: 42px;
    height: 42px;
    border-radius: 15px;
    background: var(--bs-primary-light);
    border: 1.5px solid var(--bs-border-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bs-primary-accent);
    flex-shrink: 0;
}
.page-modal-hicon svg {
    width: 20px;
    height: 20px;
}
.page-modal-htitles {
    flex: 1;
}
.page-modal-htitle {
    font-size: var(--font-large);
    font-weight: 900;
    color: var(--bs-primary-accent);
    letter-spacing: 0.1em;
}
.page-modal-hno {
    font-size: var(--font-small);
    color: var(--bs-primary-dark);
    letter-spacing: 0.1em;
    margin-top: 5px;
}
.page-modal-close {
    width: 32px;
    height: 32px;
    border-radius: var(--bs-radius);
    border: 0;
    background: var(--bs-white);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--bs-muted-accent);
    transition: all 0.15s;
}
.page-modal-close:hover {
    background: var(--bs-danger-light);
    border-color: var(--bs-border-danger);
    color: var(--bs-danger);
}
.page-modal-close svg {
    width: 15px;
    height: 15px;
}
.page-modal-body {
    padding: 25px 30px;
    display: grid;
    grid-template-columns: 0.7fr 1fr;
    grid-template-rows: auto auto;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.page-modal-body.page-modal-body--single {
    grid-template-columns: 1fr;
    gap: 0;
}
.page-modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 20px;
    border-top: 1px solid var(--bs-border-muted);
    background: var(--bs-white);
    flex-shrink: 0;
}

/* 문서삭제 확인 모달 (#documentDeleteConfirmModal — footer.php) */
#documentDeleteConfirmModal .page-modal-card--danger.document-delete-confirm-card {
    max-width: 400px;
    box-shadow: var(--bs-shadow);
}
#documentDeleteConfirmModal .page-modal-topbar--danger {
    background: var(--bs-danger);
}
#documentDeleteConfirmModal .page-modal-header--danger {
    background: var(--bs-danger);
    color: var(--bs-white);
}
#documentDeleteConfirmModal .page-modal-header--danger .page-modal-htitle {
    color: var(--bs-white);
}
#documentDeleteConfirmModal .page-modal-header--danger .page-modal-close {
    background: transparent;
    border: none;
    color: var(--bs-white);
}
#documentDeleteConfirmModal .page-modal-header--danger .page-modal-close svg {
    stroke: currentColor;
}
#documentDeleteConfirmModal .page-modal-header--danger .page-modal-close:hover {
    color: var(--bs-white);
    opacity: 0.85;
}
#documentDeleteConfirmModal .page-modal-body--danger.document-delete-confirm-body {
    grid-template-columns: 1fr;
    background: var(--bs-white);
}
#documentDeleteConfirmModal .page-modal-body--danger-text {
    color: var(--bs-text);
}
#documentDeleteConfirmModal .page-modal-footer--danger {
    background: var(--bs-white);
    border-top: 1px solid var(--bs-border-secondary);
}

/* page-modal-detail-row/-dk (레거시 2열 detail) 전면 제거됨 → view=modal-row / edit=form-fields */

/* =============================================================
 * Bootstrap5 .modal override
 * ============================================================= */
.modal-content {
    border: none;
    border-radius: var(--bs-radius);
    box-shadow: var(--bs-shadow);
    overflow: hidden;              /* 스크롤은 .modal-body 가 담당 (헤더/푸터 고정) */
    max-height: calc(100vh - 2rem);
}
.modal-header {
    align-items: center;
    gap: 15px;
    padding: 20px;
    background: var(--bs-white);
    border-bottom: 1px solid var(--bs-border-muted);
}
.modal-header .btn-close {
    font-size: var(--font-small);
}

.modal-data-id {
    font-size: var(--font-small);   /* 타이틀 대비 위계 확보 — 전 폭 고정(개발자 지시) */
    color: var(--bs-muted);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 600;
} 
.modal-title {
    font-size: var(--font-large);
    font-weight: 900;
    color: var(--bs-primary-accent);
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.modal-body {
    padding: 20px;
    overflow-y: auto;   /* 내용이 넘치면 바디만 스크롤 (전 크기 공통, 데스크톱 포함) */
    min-height: 0;      /* flex 자식이 콘텐츠보다 작게 줄어들 수 있게 → 스크롤 발생 */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.modal-body.modal-body--side {
    padding: 0;
    overflow: hidden;
}
.modal-body.modal-body--side > .modal-side-layout {
    width: 100%;
    min-height: 0;
}
.modal-footer {
    padding: 10px 20px;
    border-top: 1px solid var(--bs-border-muted);
}
.modal-content .form-feedback {
    font-size: var(--font-small);
    color: var(--bs-danger);
    margin-top: 5px;
}
.modal-header-icon {
    width: 42px;
    height: 42px;
    border-radius: 15px;
    background: var(--bs-primary-light);
    border: 1.5px solid var(--bs-border-primary);
    display: none;
    align-items: center;
    justify-content: center;
    color: var(--bs-primary-accent);
    flex-shrink: 0;
}
.modal-header-icon svg {
    width: 20px;
    height: 20px;
}

.modal-danger .modal-header {
    background: var(--bs-danger);
}
.modal-danger .modal-title {
    color: var(--bs-white);
}

/* =============================================================
 * BS .modal-body 내부 — 사이드탭 + 컨텐츠 + 읽기전용 행
 * 마크업: .modal-body.p-0 > .modal-side-layout > .modal-side-nav + .modal-side-content
 * ============================================================= */
.modal-side-layout {
    display: grid;
    grid-template-columns: minmax(180px, 240px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    width: 100%;
    min-height: 0;
    align-items: stretch;
}

.modal-side-layout > .modal-side-nav {
    grid-column: 1;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    max-width: 270px;
    min-width: 0;
    border-right: 1px solid var(--bs-border-secondary);
    border-bottom: 0;
    padding: 15px 0;
}

.modal-side-layout > .modal-side-nav.nav-tabs {
    border-bottom: 0;
    flex-wrap: nowrap;
    overflow-y: auto;
}

.modal-side-nav .nav-item {
    width: 100%;
}

.modal-side-nav .nav-link {
    display: block;
    width: 100%;
    padding: 10px 20px;
    text-align: left;
    border: none !important;
    border-radius: 0;
    font-size: var(--font-normal);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: 0.1em;
    color: var(--bs-muted);
    background: transparent !important;
    box-shadow: none;
    transition: color 0.15s ease;
}

.modal-side-nav .nav-link:hover {
    color: var(--bs-text);
    background: transparent !important;
}

.modal-side-nav .nav-link.active,
.modal-side-nav .nav-item.show .nav-link {
    color: var(--bs-primary);
    background: transparent !important;
    border: none !important;
    box-shadow: none;
}

.modal-side-layout > .modal-side-content {
    grid-column: 2;
    grid-row: 1;
    padding: 20px;
    min-width: 0;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;   /* 경계 넘어도 뒤 페이지로 스크롤 안 새게 */
}

.modal-side-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    margin-bottom: 15px;
}

.modal-lead {
    margin: 0;
    font-size: var(--font-normal);
    font-weight: 700;
    color: var(--bs-primary, #0284c7);
    line-height: 1.45;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    word-break: break-word;
    margin-bottom: 15px;
}

.modal-lead-large {
    font-size: 20px;
    color: var(--bs-text);
    font-weight: 700;
}

.modal-row-section {
    margin-bottom: 0;
}

.modal-row-list {
    display: flex;
    flex-direction: column;
    border-radius: 15px;
    overflow: hidden;
}

.modal-row {
    display: flex;
    align-items: center;
    justify-content: start;
    gap: 20px;
    padding: 12px 0px;
    border-bottom: 1px solid var(--bs-border-secondary);
}

.modal-row:last-child {
    border-bottom: none;
}

.modal-row-label {
    font-size: var(--font-small);
    font-weight: 600;
    color: var(--bs-muted);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: left;
    flex-shrink: 0;
    min-width: 150px;
}

.modal-row-value {
    font-size: var(--font-normal);
    font-weight: 500;
    color: var(--bs-text);
    text-align: left;
    word-break: break-word;
    min-width: 0;
}

/* 값 뒤에 한 줄로 따라붙는 보조 표기 — 예: DUE DATE 의 (5day left).
   --soon / --over 는 목록의 .datatable-due--* 와 같은 뜻이다(임박·경과). 색을 바꾸려면 둘 다 볼 것. */
.modal-row-note {
    font-size: var(--font-small);
    font-weight: 600;
    color: var(--bs-muted);
    /* 값보다 두 단계 작은 글자라 공백 하나로는 값에 붙어 읽힌다. */
    margin-left: 6px;
}
.modal-row-note--soon {
    color: var(--bs-warning);
}
.modal-row-note--over {
    color: var(--bs-danger);
}

.modal-side-scroll {
    overflow-y: auto;
    min-height: 0;
}

.modal-description {
    font-size: var(--font-small);
    font-weight: 500;
    color: var(--bs-muted);
    line-height: 1.5;
    letter-spacing: 0.05em;
}

.modal-hint {
    font-size: var(--font-normal);
    font-weight: 500;
    color: var(--bs-text);
    line-height: 1.5;
}

.modal-empty-hint {
    padding: 25px 0;
    text-align: center;
    color: var(--bs-muted);
    font-size: var(--font-normal);
    font-weight: 600;
    text-transform: uppercase;
}

/* 사이드탭 모달의 모바일 스택 규칙은 responsive.css [G] 로 이관됨(≤992).
   (구 @media 640px 블록 — flex-column·nav-item width:100% 을 못 이겨 탭이 세로로 쌓이던 버그 포함) */

/* 통계 칩 그리드 + 칩 — 모달 안의 KPI/메타 카드 공통 (열 수는 자동 채움) */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px;
}

.stat-card {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 5px;
    padding: 10px;
    background: var(--bs-white);
    border: 1px solid var(--bs-border-secondary);
    border-radius: var(--bs-radius-sm);
}

.stat-card span {
    font-size: var(--font-small);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--bs-muted);
}

.stat-card strong {
    font-size: var(--font-normal);
    font-weight: 600;
    text-align: right;
    word-break: break-word;
    color: var(--bs-text);
}

/* 값 아래 보조 1줄(예: PLANE MODEL 카드의 기체 등록번호) — 비어 있으면 자리 차지 안 함 */
.stat-card-sub {
    font-size: var(--font-small);
    font-style: normal;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-align: right;
    word-break: break-word;
    color: var(--bs-muted);
}

.stat-card-sub:empty {
    display: none;
}

/* 공용 확인 모달 메시지 (footer.php 3종 확인모달 공용 — common/delete/confirm)
   — 구 .font-size-13/14 유틸을 대체한 시맨틱 클래스 */
.confirm-modal-message {
    font-size: var(--font-normal);
    /* 메시지는 .text() 로 주입(HTML 불가) → 여러 줄 안내는 개행문자로만 표현 가능.
       pre-line = 개행은 살리고 들여쓰기 공백은 접고 줄바꿈은 정상 wrap. */
    white-space: pre-line;
}

/* =============================================================
 * 모달 헤더 드래그 이동 (common.js 가 .is-dragging / .is-dragged 토글)
 * ============================================================= */
.modal-header {
    cursor: move;
    user-select: none;    /* 드래그 중 텍스트 블록 선택 방지 */
    touch-action: none;   /* 터치 기기에서 브라우저 팬 제스처가 포인터를 가로채지 않게 */
}
/* 드래그 중에는 BS 의 `.modal.fade .modal-dialog { transition: transform .3s }` 를 꺼야 한다.
   안 끄면 매 프레임 새 transform 마다 0.3초 애니메이션이 걸려 커서를 고무줄처럼 쫓아옴. */
.modal .modal-dialog.is-dragging {
    transition: none !important;
    will-change: transform;
}
/* .modal 은 휠 containment 용으로 overflow:hidden + max-height 라 클리핑 박스가 된다.
   → 옮겨진 모달의 하단/측면이 잘리므로 이동된 동안만 클리핑 해제.
   (배경 스크롤은 body.modal-bg-lock 이 이미 막고 있어 안전) */
.modal.is-dragged {
    overflow: visible;
}
/* =============================================================
 * 레코드 편집 락 배너 (js/common/record-lock.js 와 짝)
 *
 * 모달 푸터 왼쪽에 앉는다. "다른 사용자가 편집 중" 안내 + 락이 풀렸을 때의 인계 버튼.
 * 화면 공용 — 다른 모달에 락을 붙일 때 이 클래스를 그대로 쓴다(마크업만 복제).
 * ============================================================= */
.record-lock-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border: 1px solid var(--bs-border-warning);
    border-radius: 6px;
    background-color: var(--bs-bg-warning);
    color: var(--bs-warning-dark);
    font-size: var(--font-normal);
}

/* 잠금이 풀려 인계할 수 있는 상태 — 경고(대기)와 색을 갈라 한눈에 구분한다. */
.record-lock-banner.is-available {
    border-color: var(--bs-border-primary);
    background-color: var(--bs-bg-primary);
    color: var(--bs-primary-dark);
}

.record-lock-banner-ico {
    flex: 0 0 auto;
}

.record-lock-banner-text {
    /* 소유자 이름이 길어도 푸터 버튼군을 밀어내지 않게. */
    max-width: 520px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 자동 해제 카운트다운 — 상대가 멈춘 뒤에만 나온다(record-lock.js tickState).
   tabular-nums: 1초마다 숫자가 바뀌므로 고정폭이 아니면 글자 폭이 흔들려 배너가 떨린다. */
.record-lock-banner-countdown {
    flex: 0 0 auto;
    padding: 2px 6px;
    border-radius: 4px;
    background-color: var(--bs-warning-dark);
    color: var(--bs-white);
    font-size: var(--font-small);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
