/* ============================================================
   공통 (모든 페이지, partials/head-css.php)
   ============================================================ */

/* 왼쪽 메뉴 폭: 템플릿 250px → 280px (English 메뉴 'Order Management' 옆에 뱃지까지 한 줄로 들어가게) */
:root { --bs-main-nav-width: 280px; }

/* 목록 표: 회원 목록의 색을 기본(A)으로, 한 행씩 아주 조금 다른 색(B)을 번갈아 씁니다.
   B 는 라이트·다크 테마 모두 글자색 쪽으로 2.5% 섞은 색, 롤오버는 3D 모델 카드(assets/css/model.css)와 같은 5% */
.table.list-table {
    --bs-table-hover-bg: rgba(var(--bs-black-rgb), 0.05);
    --list-table-stripe-bg: rgba(var(--bs-emphasis-color-rgb), 0.025);
}
.table.list-table:not(.list-table-group) > tbody > tr:nth-of-type(even) > *,
.table.list-table > tbody > tr.list-table-stripe > * {
    --bs-table-bg-type: var(--list-table-stripe-bg);
}
/* list-table-group: 화면에서 행을 거르거나 같은 주문 행을 한 색으로 묶는 표는 스크립트가 B 행에 list-table-stripe 를 붙입니다. */

/* 목록의 선택 체크박스 칸 (모든 목록 공통): 40px 고정, 체크박스는 기본 크기로 가운데, 칸 어디를 눌러도 선택됩니다.
   <th|td class="list-check"><label class="list-check-label"><input type="checkbox" class="form-check-input" ...></label></th|td> */
.table.list-table > * > tr > .list-check {
    width: 40px;
    min-width: 40px;
    max-width: 40px;
    padding: 0;
    text-align: center;
    vertical-align: middle;
}
.list-check-label {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 2.25rem;
    margin: 0;
    cursor: pointer;
}
.list-check-label .form-check-input {
    float: none;
    margin: 0;
    cursor: pointer;
}

/* 목록 아래 버튼 줄 (예: 왼쪽 전체·선택 삭제, 오른쪽 전체·선택 3D 모델 생성): 버튼은 두 개씩 묶음(.list-actions-group)으로 놓습니다.
   넓은 화면은 한 줄에 왼쪽·오른쪽 묶음, 좁은 화면(768px 미만)은 묶음마다 한 줄을 꽉 채우고 두 버튼을 같은 너비로 나눕니다. */
.list-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: .5rem;
}
.list-actions-group {
    display: flex;
    gap: .5rem;
}
@media (max-width: 767.98px) {
    .list-actions-group {
        width: 100%;
    }
    .list-actions-group > .btn {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* 페이지 번호 (lib/common.lib.php get_paging): 모바일(576px 미만)에서는 가운데 정렬. 오른쪽에 붙이는 감싼 칸(ms-auto 등)도 한 줄을 꽉 채웁니다. */
@media (max-width: 575.98px) {
    :has(> .list-paging) {
        width: 100%;
        margin-left: 0 !important;
    }
}

/* 목록 제목 줄: 데이터가 없어 칸 너비가 제목 글자에만 맞춰질 때도 '관리' 등 제목이 줄바꿈되지 않게 합니다. */
.table.list-table > thead th {
    white-space: nowrap;
}

/* 목록 행 높이: 관리 버튼(높이 32px)이 있는 행에 맞춰 모든 목록의 행 높이를 같게 합니다. (최소 높이라 빈 목록 안내 행은 그대로) */
.table.list-table > tbody > tr {
    height: calc(32px + 1.7rem + var(--bs-border-width));
}

/* 스크롤바 공통 모양 (페이지 안의 모든 스크롤 영역: 드롭다운 메뉴, 창 본문, 목록 상자 등)
   Windows 는 스크롤바가 화살표 버튼이 달린 굵은 막대로 늘 보여 메뉴·버튼과 겹쳐 보이므로, Mac 처럼 얇은 막대(화살표 버튼 없음)로 맞춥니다.
   Chrome·Edge·Safari 는 ::-webkit-scrollbar 로 그립니다. (표준 scrollbar-width·scrollbar-color 를 쓰면 Windows Chrome 에서
   화살표 버튼이 남고 투명한 스크롤바 자리로 뒤쪽 화면이 비쳐 보여, 그 브라우저에는 표준 속성을 쓰지 않습니다)
   페이지 전체 스크롤바(html)와 템플릿 사이드바(simplebar, 자체 스크롤바)는 그대로 둡니다. */
body *::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
body *::-webkit-scrollbar-button {
    display: none;
    width: 0;
    height: 0;
}
/* 스크롤바 바탕은 그 영역의 바탕색으로 칠합니다. (투명하면 Windows Chrome 에서 메뉴 뒤의 화면이 스크롤바 자리로 비쳐 보임) */
body *::-webkit-scrollbar-track,
body *::-webkit-scrollbar-corner {
    background-color: inherit;
}
body *::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(var(--bs-emphasis-color-rgb), 0.3);
}
body *::-webkit-scrollbar-thumb:hover {
    background-color: rgba(var(--bs-emphasis-color-rgb), 0.45);
}
/* ::-webkit-scrollbar 를 모르는 브라우저(Firefox): 표준 속성 */
@supports not selector(::-webkit-scrollbar) {
    body * {
        scrollbar-width: thin;
        scrollbar-color: rgba(var(--bs-emphasis-color-rgb), 0.3) transparent;
    }
}

/* 가로 스크롤: 표·목록이 화면보다 넓어 넘칠 때는 마우스를 올리지 않아도 하단에 스크롤바를 늘 보여 줍니다. (위 공통 모양, 넘치지 않으면 스크롤바 없음) */

/* 택배사 드롭다운 (스토어 설정 기본 택배사, 발송 처리 창): 택배사가 많아 메뉴 높이를 정하고 스크롤합니다. */
.store-courier-menu {
    max-height: 320px;
    overflow-y: auto;
}

/* 창(모달) 위에 창을 하나 더 띄울 때: 두 번째 배경을 처음부터 아래 창 위(1060)에 두어, 나타나는 동안 아래 창이 반짝이지 않게 합니다.
   위에 띄우는 창은 스크립트에서 z-index 1065 로 띄웁니다. (assets/js/confirm-modal.js 등) */
.modal-backdrop ~ .modal-backdrop {
    z-index: 1060;
}
/* 창(모달) 배경: 화면 네 모서리에 맞춥니다. */
.modal-backdrop {
    inset: 0;
    width: auto;
    height: auto;
}

/* 메뉴 아이콘 보기(condensed): 템플릿은 본문 최소 높이를 1300px 로 고정해, 화면이 더 길면 메뉴 배경이 중간에서 끊기고 하단 저작권이 위로 올라옵니다.
   1300px 와 화면 높이(상단바 제외) 중 큰 값으로 맞춰, 메뉴 배경이 화면 끝까지 이어지고 저작권이 화면 맨 아래에 오게 합니다. */
html[data-menu-size="condensed"] .page-content {
    min-height: max(1300px, calc(100vh - var(--bs-topbar-height)));
}

/* 대시보드 차트: 모바일에서 차트 위를 밀어도 페이지가 세로로 스크롤되게 합니다. (차트의 확대·선택 기능은 index.php 에서 끔) */
.dash-chart,
.dash-chart .apexcharts-canvas,
.dash-chart svg {
    touch-action: pan-y;
}

/* 대시보드 위젯 칸 (lib/dashboard.lib.php): 안드로이드 홈 화면처럼 칸에 위젯을 놓습니다. 기기마다 칸 수와 배치를 따로 씁니다. (2026-11-11 DASHBOARD_DEVICES)
   PC(1200px 이상) 가로 10칸, 태블릿(576~1199px, 가로로 돌린 휴대폰 포함) 6칸, 모바일(576px 미만) 4칸. 위젯 크기는 가로 1~칸 수·세로 1~4칸.
   자리: PC --dash-col·--dash-row, 태블릿 --dash-col-t·--dash-row-t, 모바일 --dash-col-m·--dash-row-m (index.php 가 위젯 하나에 세 기기 자리를 모두 넣음)
   편집 화면(.dash-edit)은 편집하는 기기의 칸 수(--dash-half)를 화면 너비와 관계없이 grid 에 직접 넣고, 자리는 --dash-col·--dash-row 만 씁니다. */
.dash-grid {
    --dash-gap: calc(var(--bs-gutter-x, 1.5rem));
    /* 반 칸 수 (가로 칸 × 2, 위젯 가로 크기·자리 0.5칸 단위)와 위젯 안쪽 여백 (기기마다 고정) */
    --dash-half: 20;
    --dash-pad: 1rem;
    display: grid;
    grid-template-columns: repeat(var(--dash-half), minmax(0, 1fr));
    /* 줄은 반 칸 높이 (라벨 위젯 세로 0.5칸): 1칸 = 줄 2개 + 간격 = 120px */
    --dash-cell: 120px;
    grid-auto-rows: calc((var(--dash-cell) - var(--dash-gap)) / 2);
    grid-auto-flow: row dense;
    gap: var(--dash-gap);
    margin-bottom: var(--dash-gap);
}
@media (max-width: 1199.98px) {
    /* 태블릿(가로로 돌린 휴대폰 포함, 1200px 미만): 가로 6칸, 칸 높이 ≒ 칸 너비 (화면 너비에서 좌우 여백 24px·간격 5개를 뺀 6분의 1, 120px 넘지 않게) */
    .dash-grid { --dash-half: 12; --dash-pad: .75rem; --dash-gap: 8px; --dash-cell: min(120px, calc((100vw - 24px - 5 * 8px) / 6)); }
    .dash-grid:not(.dash-edit) .dash-item[style*="--dash-col-t"] { grid-column: var(--dash-col-t); grid-row: var(--dash-row-t); }
}
@media (max-width: 575.98px) {
    /* 모바일: 가로 4칸 */
    .dash-grid { --dash-half: 8; --dash-pad: .625rem; --dash-cell: calc((100vw - 24px - 3 * 8px) / 4); }
    .dash-grid:not(.dash-edit) .dash-item[style*="--dash-col-m"] { grid-column: var(--dash-col-m); grid-row: var(--dash-row-m); }
}
.dash-item { position: relative; min-width: 0; min-height: 0; }
/* 위젯 카드: 안드로이드 위젯처럼 둥근 모서리와 옅은 테두리 */
.dash-item > .card { border-radius: 1rem; border: 1px solid rgba(var(--bs-emphasis-color-rgb), .08); }
/* 위젯 안 글자·아이콘·차트는 위젯 크기(칸 수)에 맞춰 커지고 작아집니다. (컨테이너 크기 단위 cqw: 위젯 너비의 1%, cqh: 높이의 1%) */
.dash-item > .card { container: dash / size; }
/* 가로 칸: 자리가 없을 때 차지할 반 칸 수 (--dash-cols = 가로 칸 × 2, lib/dashboard.lib.php) */
.dash-item { grid-column: span var(--dash-cols, 4); }
.dash-item { grid-row: span var(--dash-rows, 2); }
.dash-grid .dash-item[style*="--dash-col"] { grid-column: var(--dash-col); grid-row: var(--dash-row); }
/* 위젯 안쪽 여백: 위젯 크기와 관계없이 같은 값, 기기마다 고정 (PC 16px·태블릿 12px·모바일 10px, .dash-grid --dash-pad. 위젯 추가 창 미리 보기는 16px) */
.dash-item > .card > .card-body { padding: var(--dash-pad, 1rem); }
/* 나중에 채우는 위젯(외부 서비스)의 원형 로딩 오버레이 (lib/dashboard.lib.php DASHBOARD_LAZY) */
.dash-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(var(--bs-body-bg-rgb), .6); z-index: 1; }
.dash-loading .spinner-border { width: 2rem; height: 2rem; border-width: .2rem; }
.dash-item .min-h-0 { min-height: 0; }
.dash-item .min-w-0 { min-width: 0; }
/* 차트 칸: 위젯에서 제목을 뺀 높이. ApexCharts 가 차트 칸에 min-height(그린 높이)를 넣어, 그대로 두면 다시 잴 때마다 칸이 커지므로 무시합니다. */
.dash-item .dash-chart { flex: 1 1 0; min-height: 0 !important; overflow: hidden; }
/* 위젯 제목·옆 안내: 위젯 크기와 관계없이 모든 위젯에서 같은 크기 (Raydar 카드 제목 1rem) */
.dash-title { font-size: 1rem; }
.dash-note { font-size: .8125rem; }
.dash-label { font-size: clamp(.6rem, min(5cqw, 11cqh), 1.6rem); }
.dash-value { font-size: clamp(.8rem, min(11cqw, 26cqh), 4.5rem); font-weight: 600; line-height: 1.15; }
/* AI 사용량: 요청 수·예상 비용 두 값을 나란히 (1칸 높이에서는 원화 안내를 숨김) */
.dash-ai .dash-label { font-size: clamp(.75rem, min(3cqw, 8cqh), 1.3rem); }
.dash-ai .dash-value { font-size: clamp(1rem, min(7cqw, 18cqh), 3.5rem); }
@container dash (max-height: 150px) { .dash-ai .dash-note { display: none; } }
/* 환율 위젯 (lib/dashboard.lib.php fx): 나라·통화, 큰 원화 값, 전일 대비 (위젯 크기에 맞춰 커짐) */
.dash-fx { gap: clamp(.1rem, 4cqh, .75rem); }
.dash-fx .dash-label { font-size: clamp(.75rem, min(5cqw, 14cqh), 1.3rem); }
.dash-fx .dash-value { font-size: clamp(1rem, min(13cqw, 30cqh), 4rem); font-weight: 700; }
.dash-fx .dash-trend { font-size: clamp(.7rem, min(4.5cqw, 12cqh), 1.1rem); }
/* 건수·금액 위젯: 안드로이드 위젯 모양 — 가운데에 [둥근 아이콘 + 큰 값], 그 아래 이름. 모두 위젯 크기(cq 단위)에 맞춰 커지고 작아집니다. */
.dash-stat { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(.15rem, 5cqh, 1rem); text-align: center; }
.dash-stat-main { display: flex; align-items: center; justify-content: center; gap: clamp(.35rem, 6cqw, 1.25rem); max-width: 100%; min-width: 0; }
.dash-stat-icon { --dash-icon: clamp(26px, min(40cqh, 28cqw), 140px); width: var(--dash-icon); aspect-ratio: 1; border-radius: 26%; display: flex; align-items: center; justify-content: center; }
.dash-stat-icon iconify-icon { font-size: calc(var(--dash-icon) * .6); }
/* 값 크기: 위젯 높이와, 위젯 너비를 글자 수(--dash-chars, 아이콘 몫 포함)로 나눈 값 중 작은 쪽 (긴 금액도 잘리지 않게) */
.dash-stat .dash-value { font-size: clamp(.65rem, min(30cqh, 16cqw, calc(62cqw / (var(--dash-chars, 3) * .62 + 1.6))), 4.5rem); font-weight: 700; min-width: 0; }
.dash-stat .dash-label { font-size: clamp(.6rem, min(14cqh, 8cqw), 1.6rem); max-width: 100%; }
/* 숫자 위젯 아래 비교·보조 글자 (어제 대비 ▲%, 이달 가입 n명). 낮은 위젯에서는 숨김 */
.dash-trend { font-size: clamp(.55rem, min(10cqh, 6cqw), 1.1rem); max-width: 100%; line-height: 1.2; }
.dash-trend i { vertical-align: -.1em; }
@container dash (max-height: 100px) { .dash-trend { display: none; } }
/* 차트 기간 버튼 (월별 매출 3개월·6개월·1년) */
.dash-range .btn { font-size: clamp(.6rem, min(2.4cqw, 5cqh), .8rem); padding: .15em .55em; line-height: 1.4; }
/* 라벨 위젯: 입력한 글자를 가운데에 크게 (두 줄까지, 위젯 크기에 맞춰 커짐) */
.dash-label-box { display: flex; align-items: center; justify-content: center; text-align: center; overflow: hidden; }
.dash-label-box.dash-label-left { justify-content: flex-start; text-align: left; }
.dash-label-box.dash-label-right { justify-content: flex-end; text-align: right; }
/* 왼쪽·오른쪽 정렬 라벨: 글자 옆 여백을 위·아래 여백과 같게 (위젯 높이 100cqh 에서 글자 한 줄 높이 1.2em 을 뺀 반, 카드 안쪽 여백만큼은 이미 있음) */
.dash-label-left .dash-label-text { margin-left: max(0px, calc((100cqh - 1.2em) / 2 - var(--dash-pad, 1rem))); }
.dash-label-right .dash-label-text { margin-right: max(0px, calc((100cqh - 1.2em) / 2 - var(--dash-pad, 1rem))); }
.dash-label-text { white-space: pre-wrap; font-size: clamp(.95rem, min(36cqh, 12cqw), 3.5rem); font-weight: 700; line-height: 1.2; color: var(--bs-emphasis-color); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: keep-all; overflow-wrap: anywhere; }
.dash-label-text.text-muted { color: var(--bs-secondary-color); font-weight: 500; font-size: clamp(1.05rem, min(34cqh, 11cqw), 1.75rem); }
/* 이미지 위젯: 카드를 가득 채움 (비어 있으면 안내) */
.dash-image-body { position: relative; }
.dash-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dash-image-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .25rem; text-align: center; font-size: clamp(.55rem, min(12cqh, 8cqw), .95rem); }
.dash-image-empty i { font-size: clamp(1.1rem, min(36cqh, 22cqw), 3rem); }
.dash-edit .dash-item[data-dash-multi] { cursor: pointer; }
/* 이미지 추가 창: 고른 이미지(또는 지금 이미지)를 끌어다 놓는 칸 안에 크게 보여 줌 (다시 누르거나 끌어다 놓으면 바꿈) */
.dash-dz { position: relative; min-height: 240px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.dash-dz .dash-dz-preview, .dash-dz .dash-dz-current { position: absolute; inset: .5rem; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.dash-dz .dash-dz-current[hidden] { display: none; }
.dash-dz .dash-dz-preview img, .dash-dz .dash-dz-current img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: .5rem; }
.dash-dz.dz-started .dz-message, .dash-dz.dash-dz-has .dz-message { display: none; }
/* 차트 위젯: 낮거나(1칸 높이) 좁으면(모바일 1칸 너비) 차트 대신 합계 */
.dash-chart-summary { display: none; flex: 1 1 0; flex-direction: column; align-items: center; justify-content: center; min-height: 0; }
@container dash (max-height: 150px) or (max-width: 160px) {
    .dash-item .dash-chart { display: none; }
    .dash-chart-summary { display: flex; }
}
/* 목록 위젯 글자: 위젯 크기와 관계없이 같은 크기 (2026-11-11). 가로를 줄이면 글자는 … 으로 줄이고, 세로를 줄이면 보이는 줄 수만 줄어듭니다. */
.dash-list { overflow: hidden; font-size: .875rem; }
.dash-list li > .text-truncate { flex: 1 1 auto; min-width: 0; }
.dash-list li > :not(.text-truncate) { flex-shrink: 0; }
/* 프린터 상태 뱃지 (대시보드 3D 프린터 위젯): "대기 중" 폭에 맞춰 가운데 정렬, 이름이 같은 자리에서 시작 */
.dash-list .dash-status-badge { display: inline-block; min-width: 4.4em; text-align: center; }
/* 통합 운영 위젯의 파트너사명 (제목·이름 앞, lib/dashboard.lib.php dashboard_render) */
.dash-partner { font-size: .75em; vertical-align: .1em; border: 1px solid var(--bs-border-color); }
/* 아주 좁은 위젯(모바일 1칸 등): 아이콘을 값 위로 올려 [아이콘 / 값 / 이름] 세 줄 */
@container dash (max-width: 140px) {
    .dash-item > .card > .card-body.dash-stat { gap: 3cqh; }
    .dash-stat-main { flex-direction: column; gap: 3cqh; }
    .dash-stat-icon { --dash-icon: 38cqmin; }
    .dash-stat .dash-value { font-size: clamp(.55rem, min(17cqw, 17cqh, calc(88cqw / (var(--dash-chars, 3) * .62))), 1.4rem); }
    .dash-stat .dash-label { font-size: clamp(.5rem, min(10cqw, 10cqh), .8rem); }
}
/* 목록이 위젯 높이에 맞게: 줄이 적으면 줄 높이를 늘려 아래 빈자리 없이 채우고(한 줄 최대 3.2em), 넘치는 줄은 숨김(fitLists). 줄은 줄어들지 않습니다. */
.dash-item .dash-list { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.dash-list li { display: flex; justify-content: space-between; align-items: center; gap: .75rem; padding: .4rem 0; border-bottom: 1px dashed var(--bs-border-color); flex: 1 0 auto; max-height: 3.2em; }
.dash-list-member li { max-height: 4.2em; }
.dash-list li:last-child { border-bottom: 0; }
/* 위젯에 다 들어가지 않는 줄은 숨김 (assets/js/dashboard-widgets.js fitLists) */
.dash-list li[hidden] { display: none; }
/* 가로로 두 줄이 들어가는 넓은 목록 위젯(출력 현황): 왼쪽 줄을 위에서부터 먼저 채우고, 넘치면 오른쪽 줄에 이어서 (2026-11-11)
   좁으면 위의 한 줄 목록 그대로. 두 줄에도 다 들어가지 않는 줄은 fitLists 가 숨김 (assets/js/dashboard-widgets.js) */
@container dash (min-width: 460px) {
    .dash-item .dash-list.dash-list-2col { display: block; column-count: 2; column-gap: 1.5rem; column-fill: auto; }
    .dash-list-2col li { break-inside: avoid; max-height: none; }
}
/* 앨범 위젯: 정사각 사진을 칸에 맞춰 채움 (들어가지 않는 줄은 fitLists 가 숨김, lib/dashboard.lib.php album) */
.dash-item .dash-list.dash-album { display: grid; grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); grid-auto-rows: max-content; gap: .4rem; align-content: start; }
.dash-album-thumb { display: flex; align-items: center; justify-content: center; aspect-ratio: 1; overflow: hidden; border-radius: var(--bs-border-radius); background: var(--bs-tertiary-bg); color: var(--bs-secondary-color); font-size: 1.5rem; }
.dash-album-thumb img { width: 100%; height: 100%; object-fit: cover; }
.dash-album > [hidden] { display: none; }
/* 회원 위젯 프로필 사진 (최근 가입·최근 로그인): 사진 또는 첫 글자 원, 최근 로그인은 오른쪽 아래 점(10분 안 초록) */
.dash-list .dash-avatar { width: 1.6em; height: 1.6em; flex-shrink: 0; object-fit: cover; }
.dash-list .dash-avatar .avatar-title { font-size: .75em !important; }
.dash-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
/* 회원 위젯 줄: 다른 목록의 1.5배 높이 (사진·여백 크게) */
.dash-list-member li { padding: .6rem 0; }
.dash-list-member .dash-avatar { width: 2.4em; height: 2.4em; }
.dash-list-member .dash-avatar .avatar-title { font-size: 1em !important; }
.dash-online { position: absolute; right: -1px; bottom: -1px; width: .55em; height: .55em; border-radius: 50%; border: 2px solid var(--bs-card-bg, var(--bs-body-bg)); }
/* 태블릿 2칸·모바일 1칸: 칸 수보다 넓은 위젯은 한 줄 전체 */
/* 대시보드 편집 (dashboard/edit.php): 위젯이 살짝 흔들리고, 끌어 옮기며(모바일은 길게 눌러), 오른쪽 위 ✕ 로 뺍니다. 위젯 안 링크·차트는 누르지 않습니다. */
.dash-edit .dash-item { cursor: move; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.dash-edit .dash-item.dash-dragging { z-index: 20; opacity: .85; transition: none; }
.dash-edit .dash-item.dash-dragging { animation: none; }
.dash-edit .dash-item.dash-dragging > .card { box-shadow: 0 10px 30px rgba(0, 0, 0, .35); }
/* 좁은 화면에서 서로 바꿀 위젯 표시: 바꿀 수 있으면 파란 테두리, 없으면 빨간 테두리 */
.dash-edit .dash-item.dash-swap-ok > .card { outline: 3px solid var(--bs-primary); }
.dash-edit .dash-item.dash-swap-bad > .card { outline: 3px solid var(--bs-danger); }
.dash-edit .dash-item.dash-dragging { pointer-events: none; }
/* 옮길 자리 표시: 들어갈 수 있으면 파란색, 없으면 빨간색 */
.dash-drop { pointer-events: none; border-radius: var(--bs-border-radius); border: 2px dashed var(--bs-primary); background: rgba(var(--bs-primary-rgb), .12); z-index: 1; }
.dash-drop.dash-drop-bad { border-color: var(--bs-danger); background: rgba(var(--bs-danger-rgb), .12); }
.dash-edit .dash-item > .card { pointer-events: none; outline: 2px dashed var(--bs-primary-border-subtle); outline-offset: -2px; }
.dash-resize {
    position: absolute; z-index: 3;
    width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--bs-body-bg); padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--bs-primary); color: #fff; font-size: 13px; box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
    touch-action: none;
}
.dash-resize.dash-resize-top { top: -8px; left: 50%; margin-left: -8px; cursor: ns-resize; }
.dash-resize.dash-resize-bottom { bottom: -8px; left: 50%; margin-left: -8px; cursor: ns-resize; }
.dash-resize.dash-resize-left { left: -8px; top: 50%; margin-top: -8px; cursor: ew-resize; }
.dash-resize.dash-resize-right { right: -8px; top: 50%; margin-top: -8px; cursor: ew-resize; }
/* 커서: 버튼 기본(손가락, bootstrap button:not(:disabled))보다 앞서도록 .dash-resize.dash-resize-* 로 씁니다. */
/* 터치 화면: 버튼(화살표·✕)은 길게 눌러 고른 위젯(.dash-selected)에만 크게 보이고, 그 위젯은 맨 앞에 옵니다. (dashboard/edit.php) */
@media (pointer: coarse) {
    .dash-edit .dash-item:not(.dash-selected) .dash-resize,
    .dash-edit .dash-item:not(.dash-selected) .dash-remove { display: none !important; }
    .dash-edit .dash-item.dash-selected { z-index: 15; }
    .dash-edit .dash-item.dash-selected { animation: none; }
    .dash-edit .dash-item.dash-selected > .card { outline: 2px solid var(--bs-primary); outline-offset: -2px; }
    .dash-edit .dash-selected .dash-resize { width: 22px; height: 22px; font-size: 16px; border-width: 2px; }
    .dash-edit .dash-selected .dash-resize-top { top: -11px; margin-left: -11px; }
    .dash-edit .dash-selected .dash-resize-bottom { bottom: -11px; margin-left: -11px; }
    .dash-edit .dash-selected .dash-resize-left { left: -11px; margin-top: -11px; }
    .dash-edit .dash-selected .dash-resize-right { right: -11px; margin-top: -11px; }
    .dash-edit .dash-selected .dash-remove { width: 20px; height: 20px; font-size: 15px; top: -10px; right: -10px; }
}
/* 작은 버튼(빼기·크기 조절)은 보이는 크기보다 누르는 자리를 넓게 둡니다. */
.dash-remove::after, .dash-resize::after { content: ''; position: absolute; inset: -8px; border-radius: 50%; }
.dash-edit.dash-resizing-x, .dash-edit.dash-resizing-x * { cursor: ew-resize !important; }
.dash-edit.dash-resizing-y, .dash-edit.dash-resizing-y * { cursor: ns-resize !important; }
/* 흔들림: 위젯 전체(카드 + 크기 조절 화살표 + ✕)를 함께 흔듭니다. 끌어 옮길 때 쓰는 transform(translate)과 겹치지 않게 rotate 속성만 움직입니다. */
.dash-edit > .dash-item:nth-child(odd) { animation: dash-wiggle .5s ease-in-out infinite alternate; }
.dash-edit > .dash-item:nth-child(even) { animation: dash-wiggle .5s ease-in-out -.25s infinite alternate; }
.dash-edit.dash-resizing-x > .dash-item, .dash-edit.dash-resizing-y > .dash-item,
.dash-edit.dash-moving > .dash-item,
.dash-edit > .dash-item.dash-dragging, .dash-edit > .dash-item.dash-selected,
.dash-edit > .long-press-dragging { animation: none; }
@keyframes dash-wiggle { from { rotate: -.4deg; } to { rotate: .4deg; } }
@media (prefers-reduced-motion: reduce) { .dash-edit .dash-item { animation: none !important; } }
.dash-remove {
    position: absolute; top: -8px; right: -8px; z-index: 3;
    width: 17px; height: 17px; border-radius: 50%; border: 0; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--bs-danger); color: #fff; font-size: 13px; box-shadow: 0 2px 6px rgba(0, 0, 0, .25);
}
.gu-mirror.dash-item { position: fixed !important; margin: 0 !important; z-index: 9999 !important; opacity: .85; pointer-events: none; }
.gu-mirror.dash-item .dash-remove, .gu-mirror.dash-item .dash-resize { display: none; }
.gu-hide { display: none !important; }
.gu-unselectable { -webkit-user-select: none !important; user-select: none !important; }
.dash-edit .gu-transit > .card { opacity: .35; }
/* 대시보드 편집 오른쪽 위 저장하기: 모바일은 한 줄 전체 */
@media (max-width: 767.98px) {
    .dash-actions { width: 100%; }
    .dash-actions > .btn { flex: 1 1 0; white-space: nowrap; }
}
/* 대시보드 편집 맨 뒤의 위젯 추가 칸: 한 줄 전체·한 칸 높이, 가운데 + */
.dash-add[hidden] { display: none !important; }
.dash-add { grid-column: 1 / -1; grid-row: span 1; display: flex; align-items: center; justify-content: center; border: 2px dashed var(--bs-border-color); border-radius: var(--bs-border-radius); }
/* + 버튼: + 칸 크기에 맞춤 (칸의 짧은 변 60%, 24~52px) */
.dash-add { container-type: size; min-width: 0; min-height: 0; }
.dash-add-button { width: clamp(24px, 60cqmin, 52px); height: clamp(24px, 60cqmin, 52px); border-radius: 50%; border: 0; background: var(--bs-primary); color: #fff; font-size: clamp(16px, 34cqmin, 30px); flex: none; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0, 0, 0, .25); transition: transform .15s; }
.dash-add-button:hover { transform: scale(1.08); }
/* 위젯 선택 창의 미리 보기 카드: 누르면 대시보드에 넣음 (안의 위젯은 지금 값으로 그린 것, 누를 수 없음) */
.dash-pick { cursor: pointer; display: flex; flex-direction: column; gap: .35rem; width: 100%; height: 100%; padding: .6rem; text-align: start; border: 1px solid var(--bs-border-color); border-radius: var(--bs-border-radius-lg, .5rem); background: var(--bs-tertiary-bg, transparent); color: inherit; transition: border-color .15s, box-shadow .15s; }
.dash-pick:hover, .dash-pick:focus-visible { border-color: var(--bs-primary); box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .2); }
.dash-pick-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.dash-pick-group { font-size: .9rem; font-weight: 600; margin: .5rem 0 -.25rem; padding-bottom: .35rem; border-bottom: 1px solid var(--bs-border-color); }
/* 위젯 추가 창: 구분마다 제목을 누르면 펼쳐지는 목록 (공지사항 .notice-accordion 과 같은 모양, dashboard/edit.php) */
.dash-pick-accordion { border-top: 1px solid var(--bs-border-color); }
.dash-pick-section { border-bottom: 1px solid var(--bs-border-color); }
.dash-pick-section-head { font-size: inherit; font-weight: inherit; }
.dash-pick-toggle { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 8px; border: 0; background: none; color: var(--bs-body-color); text-align: left; font-size: 15px; font-weight: 600; }
.dash-pick-toggle:hover > span { color: var(--bs-primary); }
.dash-pick-arrow { font-size: 22px; color: var(--bs-secondary-color); transition: transform .2s ease; }
.dash-pick-toggle:not(.collapsed) .dash-pick-arrow { transform: rotate(180deg); }
.dash-pick-section-body { padding: 0 8px 16px; margin-left: 0; margin-right: 0; }
.dash-pick-loading { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-size: .8rem; }
.dash-pick-note { font-size: .75rem; line-height: 1.3; }
.dash-pick-preview { display: block; position: relative; overflow: hidden; margin-top: .25rem; pointer-events: none; }
/* 미리 보기 높이: 위젯 선택은 모두 1×1 (카드 너비가 대시보드 칸의 반쯤이라 높이도 그에 맞춰 줄임) */
.dash-pick-h1 { height: 90px; }
.dash-pick-h2 { height: 200px; } /* 차트가 보이는 높이 (150px 이하면 합계만) */
.dash-pick-preview .dash-item { width: 100%; height: 100%; }
.dash-pick-preview .dash-remove, .dash-pick-preview .dash-resize { display: none; }
.dash-empty { grid-column: 1 / -1; grid-row: span 2; border: 2px dashed var(--bs-border-color); border-radius: var(--bs-border-radius); display: flex; align-items: center; justify-content: center; text-align: center; color: var(--bs-secondary-color); padding: 1rem; }
.dash-grid:has(.dash-item) .dash-empty { display: none; }

/* 목록 상단 도구 모음(.list-toolbar: 검색 + 처리 버튼, .list-toolbar-buttons: 버튼 묶음)
   좁은 화면에서는 검색을 한 줄 전체로 두고, 버튼은 그 아래에 글자와 함께 2개씩 가로를 꽉 채워 배치합니다.
   버튼이 1개이거나 홀수 개일 때 마지막 버튼은 한 줄 전체를 씁니다. */
@media (max-width: 575.98px) {
    .list-toolbar > [role="search"] {
        flex: 1 1 100%;
    }

    .list-toolbar > [role="search"] .form-control {
        flex: 1 1 auto;
        width: auto !important;
    }

    .list-toolbar > .btn {
        flex: 1 1 100%;
    }

    .list-toolbar-buttons {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        flex: 1 1 100%;
        width: 100%;
    }

    .list-toolbar-buttons > .btn {
        --bs-btn-padding-x: 0.5rem;
    }

    .list-toolbar-buttons > .btn:last-child:nth-child(odd) {
        grid-column: 1 / -1;
    }
}

/* 단순 링크 (공통): 평소에는 글자색 그대로, 마우스를 올리거나 키보드로 포커스하면 시스템 설정 탭처럼 글자색만 바뀝니다. (밑줄 없음)
   예: 발송 완료 목록의 발송 일시, 주문 목록의 옵션명. 앞으로 글자만 누르는 링크·버튼은 이 클래스를 씁니다. */
.text-link {
    color: inherit;
    text-decoration: none;
    transition: color .15s ease-in-out;
}
.text-link:hover,
.text-link:focus-visible {
    color: var(--bs-link-hover-color);
}

/* 날짜 범위 입력란 (assets/js/date-range.js): 'YYYY-MM-DD ~ YYYY-MM-DD' 가 다 보이는 너비. 좁은 화면에서는 검색 줄 전체 */
.date-range-input {
    width: 230px;
    max-width: 100%;
    background-color: var(--bs-body-bg);
}
/* 목록 위 검색 줄의 기간 칸: 날짜 글자(와 안내 글)는 가운데 정렬 */
.list-toolbar .date-range-input {
    text-align: center;
}
@media (max-width: 575.98px) {
    .list-toolbar > [role="search"] .form-control.date-range-input {
        flex: 1 1 100%;
    }
}

/* 목록 기간 고르기 (lib/sales.lib.php sales_period_controls): 좁은 화면(576px 미만)에서는
   1줄 구분·검색창·검색 버튼, 2줄 기간 칸, 3줄 전체·년·월·일 버튼 (가로를 꽉 채우고 같은 너비) */
.list-period-group {
    flex-shrink: 0;
}
@media (max-width: 575.98px) {
    .list-toolbar > [role="search"]:has(.list-period-group) > input[name="q"] {
        flex: 1 1 0;
        width: auto !important;
    }
    .list-toolbar > [role="search"] .list-period-group {
        flex: 1 1 100%;
    }
    .list-period-group > .btn {
        flex: 1 1 0;
    }
    /* 거래 내역의 분기별·반기별 드롭다운: 4줄에 반씩 */
    .list-toolbar > [role="search"] .list-period-select {
        flex: 1 1 0 !important;
        width: auto !important;
    }
}

/* 기간 고르기가 있는 목록(매입·매출·견적서·정산 내역·세금 계산서)의 위쪽 버튼(등록·발급 등)은 576px 이상에서 검색 줄 오른쪽에 나란히 둡니다.
   검색 묶음이 길면 검색 묶음 안에서만 줄을 바꾸고, 버튼은 첫 줄 오른쪽에 그대로 있습니다. */
@media (min-width: 576px) {
    .list-toolbar:has(.list-period-group) {
        flex-wrap: nowrap !important;
        align-items: flex-start !important;
    }
    .list-toolbar:has(.list-period-group) > [role="search"] {
        flex: 1 1 auto !important;
    }
    .list-toolbar:has(.list-period-group) > :not([role="search"]) {
        flex-shrink: 0;
    }
    /* 태블릿처럼 폭이 모자라면 검색창(최대 300px)·기간 칸(최대 230px)이 먼저 줄어들어 전체·년·월·주·일 버튼까지 한 줄에 둡니다. */
    .list-toolbar > [role="search"]:has(.list-period-group) > input[name="q"] {
        flex: 1 1 64px;
        width: auto !important;
        max-width: 300px !important;
    }
    .list-period-group > .btn {
        --bs-btn-padding-x: 0.65rem;
    }
    /* 기간 칸은 날짜 범위('YYYY-MM-DD ~ YYYY-MM-DD')가 잘리지 않는 190px 아래로는 줄지 않습니다. */
    .list-toolbar > [role="search"] .list-period-input {
        flex: 1 1 190px;
        width: auto;
        max-width: 230px;
        min-width: 190px;
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }
}

/* 회원 사진 (lib/auth.lib.php 의 member_avatar): 정사각형이 아닌 사진도 원 안을 채웁니다. */
.avatar-img {
    object-fit: cover;
}
/* 상단 프로필 메뉴 버튼의 사진 (템플릿과 같은 32px) */
.topbar-avatar .avatar-img,
.topbar-avatar .avatar-sm {
    width: 32px;
    height: 32px;
}

/* 선택 상자 공통 모양 (assets/js/select-dropdown.js): 권한 설정의 선택 버튼(.page-tree-map)과 같은 드롭다운.
   글자는 왼쪽, 아래 화살표는 오른쪽 끝, 넘치는 글자는 … 으로 줄입니다. 원래 select 는 값·필수 검사용으로 버튼 뒤에 투명하게 둡니다. */
.select-dropdown {
    position: relative;
    display: block;
    width: 100%;
}
.select-dropdown-toggle {
    position: relative;
    width: 100%;
    padding-right: 1.75rem;
    overflow: hidden;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* 템플릿의 .btn-sm.dropdown-toggle::after(top: 1px)보다 우선하도록 클래스를 겹쳐 씁니다. (작은 선택 상자에서 화살표가 위로 붙지 않게)
   transform 을 쓰지 않고 높이(16px)의 절반만큼 올려, 화살표가 열린 메뉴 위로 비치지 않게 합니다. */
.select-dropdown > .select-dropdown-toggle.dropdown-toggle::after {
    position: absolute;
    top: 50%;
    right: .5rem;
    margin-top: -8px;
    margin-left: 0;
}
/* 열린 메뉴는 표의 다른 줄(선택 상자·화살표)보다 항상 위에 보입니다. */
.select-dropdown:has(> .dropdown-menu.show) {
    z-index: 1090;
}
.select-dropdown > .dropdown-menu.show {
    z-index: 1090;
}
.select-dropdown.is-invalid .select-dropdown-toggle {
    border-color: var(--bs-form-invalid-border-color);
}
.select-dropdown .dropdown-menu {
    max-height: 320px;
    overflow-y: auto;
}
.select-dropdown-native {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
}
/* 비활성(disabled)일 때 템플릿이 .form-select:disabled 로 원래 select 를 다시 보이게 해, 반투명한 버튼 뒤로 화살표가 겹쳐 보이지 않게 합니다. */
.select-dropdown > .form-select.select-dropdown-native:disabled {
    opacity: 0;
}

/* 탭(.nav-tabs): 템플릿은 선택한 탭에만 아래 여백 1px(다른 탭은 -1px)을 줘, 탭이 두 줄로 넘칠 때 선택한 탭이 있는 줄이 2px 높아집니다.
   모든 탭에 같은 여백을 줘 어느 탭을 골라도 줄 높이가 같게 합니다. (한 줄일 때 모양은 그대로) */
.nav-tabs li a.nav-link {
    margin-bottom: 1px;
}

/* 창(모달) 안 목록의 페이지 나누기 (assets/js/list-pager.js): 지금 페이지가 아닌 줄 */
.list-pager-hide {
    display: none !important;
}

/* 상단 오른쪽 (partials/topbar.php): 테마 모드·프로필을 둥근 연한 바탕의 버튼으로 나란히 둡니다. */
.topbar-theme-button,
.topbar-profile-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: .5rem;
    background-color: rgba(var(--bs-emphasis-color-rgb), .06);
    color: var(--bs-body-color);
    transition: background-color .15s ease-in-out;
}
.topbar-theme-button:hover,
.topbar-profile-button:hover,
.topbar-profile-button[aria-expanded="true"] {
    background-color: rgba(var(--bs-emphasis-color-rgb), .12);
}
.topbar-theme-button {
    width: 38px;
    height: 38px;
}
/* 언어 버튼 (지구본 + 한국어/English). 모바일(576px 미만)은 상단이 좁아 지구본만 (2026-11-11) */
.topbar-theme-button.topbar-lang-button {
    width: auto;
    gap: .25rem;
    padding: 0 .625rem;
    font-size: 13px;
    font-weight: 600;
}
@media (max-width: 575.98px) {
    .topbar-theme-button.topbar-lang-button { width: 38px; padding: 0; }
    .topbar-lang-button > span { display: none; }
}
/* 라이트 모드는 달, 다크 모드는 해 (누르면 바뀔 모드) */
.topbar-theme-sun,
[data-bs-theme="dark"] .topbar-theme-moon {
    display: none;
}
[data-bs-theme="dark"] .topbar-theme-sun {
    display: inline-block;
}
.topbar-profile-button {
    gap: .625rem;
    height: 46px;
    /* 사진 앞 여백 = 화살표 뒤에 보이는 여백 (화살표 글꼴 안쪽 빈 곳 약 5px 포함 15px, 2026-11-11) */
    padding: 0 .625rem 0 .9375rem;
}
.topbar-profile-name {
    max-width: 10rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}
.topbar-profile-arrow {
    font-size: 18px;
    transition: transform .15s ease-in-out;
}
.topbar-profile-button[aria-expanded="true"] .topbar-profile-arrow {
    transform: rotate(180deg);
}
/* 프로필 메뉴: 둥근 모서리·그림자, 맨 위 이름과 아이디 */
.topbar-profile-menu {
    min-width: 240px;
    padding: .5rem 0;
    border-radius: .875rem;
    box-shadow: var(--bs-box-shadow-lg);
}
/* 프로필 메뉴가 화면보다 길면(가로 모드 휴대폰 등) 메뉴 안에서 스크롤합니다. 위 고정 막대 높이만큼 빼고, 끝에 닿아도 뒤 화면이 같이 밀리지 않게 */
.topbar-profile-menu {
    max-height: calc(100vh - var(--bs-topbar-height, 70px) - 16px);
    max-height: calc(100dvh - var(--bs-topbar-height, 70px) - 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
}
/* 프로필 메뉴가 열려 있는 동안 뒤 화면 스크롤은 partials/topbar.php 스크립트가 막습니다. (overflow: hidden 은 모바일에서 상단 막대가 맨 위로 돌아가 메뉴가 안 보여 쓰지 않음) */
.topbar-profile-menu .dropdown-item {
    padding: .625rem 1.25rem;
}
.topbar-profile-head {
    padding: .375rem 1.25rem .625rem;
    max-width: 280px;
}
.topbar-profile-email {
    font-family: var(--bs-font-monospace);
    font-size: .8125rem;
    color: var(--bs-secondary-color);
}

/* 모바일(768px 미만) 표: 칸 안 글자를 줄바꿈하지 않고 한 줄로 두어, 표는 가로로 밀어서(가로 스크롤) 봅니다. (모든 목록·창 안 표)
   칸 너비를 0 으로 두고 …으로 줄이던 칸(3D 매핑 목록 등)도 글자만큼 넓히고, 두 줄로 자르던 모델 설명도 한 줄로 둡니다.
   칸이 아주 길어지는 곳은 .list-wrap 으로 줄바꿈을 허용합니다. (고객사 레이아웃의 매핑 칸) */
@media (max-width: 767.98px) {
    .table-responsive > .table > :not(caption) > * > *,
    .table-responsive > .table .text-break {
        white-space: nowrap;
        word-break: normal;
        overflow-wrap: normal;
    }
    .table-responsive > .table .mapping-list-cell {
        max-width: none;
    }
    .table-responsive > .table .text-truncate {
        overflow: visible;
        text-overflow: clip;
    }
    .table-responsive > .table .model3d-description {
        display: block;
        -webkit-line-clamp: unset;
        overflow: visible;
        white-space: nowrap;
    }
    .table-responsive > .table > :not(caption) > * > .list-wrap {
        min-width: 360px;
        white-space: normal;
    }
}

/* 로그인·회원가입·아이디/비밀번호 찾기·파트너사 가입·404 화면 배경 (템플릿 .authentication-bg 의 파랑→보라 그라데이션 대신 테마 기본 배경, 다크·라이트를 따름) */
body.authentication-bg,
.authentication-bg {
    background: var(--bs-body-bg);
}

/* 화면 하단 (partials/footer.php): 카피라이트 위 사업자 정보 2줄·약관 링크까지 들어가도록 하단 높이를 늘립니다. (본문 아래 여백도 같은 변수)
   화면 폭마다 확인 (2026-11-10): 위아래 여백 16px 포함: 768px 이상 내용 82px, 576~767px 최대 120px, 575px 이하 최대 159px(320px) */
:root {
    --bs-footer-height: 104px;
}
@media (max-width: 767.98px) {
    :root {
        --bs-footer-height: 140px;
    }
}
@media (max-width: 575.98px) {
    :root {
        --bs-footer-height: 184px;
    }
}
.footer.footer-business {
    padding-top: .5rem;
    padding-bottom: .5rem;
    line-height: 1.6;
}

/* 로그인 화면 아래 사업자 정보 (partials/business-info.php): 로그인 카드(좁은 열)보다 넓게 잡아 한 줄에 들어가게 합니다. (화면 폭을 넘지 않게, 가운데) */
.auth-business {
    width: min(820px, calc(100vw - 2rem));
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    line-height: 1.7;
}

/* 로그인 화면 아래 약관 링크 (auth/terms·privacy·refund, policy/page.php $policyLayout 'auth'): 세로 가운데 정렬 대신 위에서부터 고정 여백, 탭을 바꿔도 같은 자리 */
body.authentication-bg .account-pages.policy-pages {
    align-items: flex-start;
    padding-top: 3rem !important;
}

/* 서비스 이용약관·개인정보 처리방침·환불정책 (policy/page.php): 로그인 화면과 다른 별도 문서 화면. 위 로고·탭, 가운데 본문(최대 960px), 아래 사업자 정보 */
body.policy-body {
    background: var(--bs-body-bg);
    min-height: 100vh;
}
.policy-container {
    max-width: 960px;
}
.policy-header {
    background: var(--bs-secondary-bg);
}
/* 휴대폰: 문서 탭은 로고 아래 한 줄 (넘치면 옆으로 넘김), 글자를 조금 작게 */
@media (max-width: 575.98px) {
    .policy-header .nav {
        flex-wrap: nowrap;
        overflow-x: auto;
        width: 100%;
        scrollbar-width: none;
    }
    .policy-header .nav-link {
        white-space: nowrap;
        padding-left: .625rem !important;
        padding-right: .625rem !important;
        font-size: .8125rem;
    }
}
/* 약관 본문 표: 모바일(768px 미만)에서도 글자를 줄바꿈해 표가 옆으로 넘치지 않게 (목록 표의 한 줄 규칙보다 먼저, 약관 창·문서 화면 모두)
   칸 너비를 표 폭 안에서 나눔: 항목 이름 칸 30%, 긴 영문·주소도 칸 안에서 줄바꿈 */
@media (max-width: 767.98px) {
    .terms-doc .table-responsive > .table {
        table-layout: fixed;
        width: 100%;
    }
    .terms-doc .table-responsive > .table > :not(caption) > * > * {
        white-space: normal;
        word-break: break-word;
        overflow-wrap: anywhere;
    }
    .terms-doc .table-responsive > .table th[scope="row"] {
        width: 30%;
    }
    /* 괄호 묶음(.paren-nowrap, 괄호 안 줄바꿈 방지)도 좁은 칸에서는 줄바꿈 */
    .terms-doc .table-responsive > .table .paren-nowrap {
        white-space: normal;
    }
}
/* 로고: 라이트 테마는 logo_light, 다크 테마는 logo_dark */
[data-bs-theme="dark"] .policy-logo-light,
[data-bs-theme="light"] .policy-logo-dark {
    display: none;
}

/* 검색어 강조 (assets/js/search-highlight.js): 목록에서 검색어와 같은 글자의 색을 바꿔 바로 알아볼 수 있게 합니다. */
mark.search-mark {
    padding: 0 1px;
    border-radius: 2px;
    background-color: rgba(var(--bs-warning-rgb), 0.35);
    color: var(--bs-danger);
    font-weight: 600;
}

/* 주소 검색 창 (assets/js/address-search.js): 창 높이를 고정해 결과가 늘어도 화면이 늘어나지 않게, 결과 목록만 안에서 넘깁니다. */
.address-search-content {
    height: min(640px, 88vh);
}
@media (max-width: 575.98px) {
    .address-search-content {
        height: 100%;
    }
}
/* 본문(검색칸+결과 목록)이 남은 높이만 쓰고, 결과 목록은 그 안에서만 넘깁니다. (flex 자식의 최소 높이가 내용만큼 늘어나지 않도록) */
.address-search-content > .modal-body {
    min-height: 0;
    overflow: hidden;
}
.address-search-scroll {
    min-height: 0;
}
.address-search-item {
    cursor: pointer;
}
.address-search-item.active,
.address-search-item.active:hover {
    color: inherit;
    background-color: rgba(var(--bs-primary-rgb), .12);
    border-color: var(--bs-list-group-border-color);
}
.address-search-item .min-w-0 {
    min-width: 0;
}

/* 항목·값 두 칸 표 (예: 외부 연동 설정 > 주소 동기화의 주소 DB 상태): 항목 칸은 모두 같은 은은한 배경, 테두리는 표 전체 같은 색 */
.info-table {
    --bs-table-bg: transparent;
    border-color: var(--bs-border-color);
}
.info-table > :not(caption) > * > * {
    border-color: var(--bs-border-color);
    padding: .75rem 1rem;
}
.info-table th {
    width: 180px;
    white-space: nowrap;
    text-align: center;
    font-weight: 600;
    color: var(--bs-emphasis-color);
    background-color: var(--bs-tertiary-bg);
}
.info-table td {
    color: var(--bs-body-color);
}

/* 필수 칸 표시 (assets/js/form-live.js): 이름표 앞에 빨간 * */
.form-label.form-required::before {
    content: '*';
    color: var(--bs-danger);
    font-weight: 600;
    margin-right: .25rem;
}
/* 실시간 안내 (비밀번호 규칙·일치 여부, 아이디 사용 가능 여부): 칸 바로 아래 */
.form-live-feedback {
    margin-top: .25rem;
}
/* 비밀번호 규칙 체크 목록 (assets/js/form-live.js): 입력 전 회색, 맞는 규칙 파랑, 안 맞는 규칙 빨강 */
/* 한 줄로 (2026-11-11): 반쪽 칸(col-md-6)에서도 다섯 규칙이 한 줄에 들어가도록 간격·글자를 줄이고, 아주 좁은 화면에서만 줄바꿈 */
.password-rules {
    display: flex;
    flex-wrap: nowrap;
    gap: .25rem .5rem;
    font-size: .75rem;
    margin: .375rem 0 0;
    padding: 0;
    list-style: none;
}
.password-rules li {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    color: var(--bs-secondary-color);
    white-space: nowrap;
    transition: color .15s;
}
.password-rules li i {
    font-size: .95rem;
}
/* 아주 좁은 화면(360px 미만)만 줄바꿈 (2026-11-13: 가입 화면은 휴대폰에서 안쪽 여백(px-4)을 빼 입력 칸을 넓혀 한 줄로) */
@media (max-width: 359.98px) {
    .password-rules { flex-wrap: wrap; }
}
/* 휴대폰: 간격·글자를 조금 줄여 390px 화면에서 한 줄 */
@media (max-width: 575.98px) {
    .password-rules { gap: .25rem .375rem; font-size: .7rem; }
    .password-rules li { gap: .125rem; }
    .password-rules li i { font-size: .85rem; }
}
.password-rules li.is-met {
    color: var(--bs-primary);
}
.password-rules li.is-unmet {
    color: var(--bs-danger);
}
.password-rules-bad {
    margin-top: .25rem;
}

/* 괄호 설명 묶음 (assets/js/paren-wrap.js): 줄 끝에서 둘로 잘리지 않고 통째로 다음 줄로.
   inline-block 이라 한 줄에 들어가면 통째로, 칸보다 길면(좁은 휴대폰) 넘치지 않고 그 안에서 줄바꿈 (2026-11-13 점검: 약관 390px 가로 넘침) */
.paren-nowrap {
    display: inline-block;
    max-width: 100%;
}

/* 모바일 길게 눌러 순서 바꾸기 (assets/js/long-press-sort.js): 터치 화면에서 줄을 길게 누르면 들린 모양 */
@media (pointer: coarse) {
    [data-long-press-sort] .system-store-handle {
        /* 손가락으로 누르기 쉽게 누르는 자리를 넓힙니다. */
        display: inline-block;
        padding: 8px 10px;
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
    }
}
.long-press-active {
    touch-action: none;
}
.long-press-dragging > td {
    background-color: var(--bs-primary-bg-subtle) !important;
}
.long-press-dragging {
    outline: 2px solid var(--bs-primary);
    outline-offset: -2px;
}

/* 좁은 화면(768px 미만)에서 목록이 비었으면(안내 한 줄만) 표의 최소 너비를 풀어, '등록된 … 없습니다' 안내가 화면 밖으로 잘리지 않게 합니다. */
@media (max-width: 767.98px) {
    .table-responsive > .list-table:has(> tbody > tr:only-child > td[colspan]) {
        min-width: 0 !important;
    }
}

/* 주소 입력(우편번호·주소·지우기·주소 검색): 휴대폰에서도 한 줄 (주소 검색 버튼은 돋보기만, 우편번호 칸은 조금 좁게) */
@media (max-width: 575.98px) {
    [data-address-field] > .input-group,
    [data-address-field] > div > .input-group {
        flex-wrap: nowrap;
    }
    [data-address-field] [data-address-zipcode] {
        width: 76px !important;
    }
}

/* 스토어 구분 탭(전체·스마트스토어·아이디어스·쿠팡): 휴대폰에서는 가로를 꽉 채우고 같은 너비로 두 줄 */
@media (max-width: 575.98px) {
    .nav-pills[aria-label="스토어 구분"] {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .nav-pills[aria-label="스토어 구분"] .nav-link {
        width: 100%;
        text-align: center;
    }
}

/* 화면 아래 주요 버튼 묶음(.page-actions, 마이페이지 저장 버튼 등): 좁은 화면(768px 미만)은 설정 화면(.system-actions)처럼 가로를 꽉 채웁니다. */
@media (max-width: 767.98px) {
    .page-actions {
        display: flex;
        gap: .5rem;
    }
    .page-actions > .btn {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* 약관 본문 (partials/partner-terms.php 파트너사 가입, partials/member-terms.php 파트너사 회원가입, 약관 창 partials/terms-modal.php) */
.terms-doc { font-size: .875rem; line-height: 1.7; }
.terms-doc h4 { font-size: .9375rem; font-weight: 600; margin: 1.25rem 0 .5rem; }
.terms-doc ol, .terms-doc ul { padding-left: 1.25rem; margin-bottom: .75rem; }
.terms-doc li { margin-bottom: .25rem; }
.terms-doc th { width: 1%; background: rgba(var(--bs-emphasis-color-rgb), .04); font-weight: 500; }

/* 주문 추가 창의 상품 목록 (store/manual-order-modal.php): 5줄까지 보이고 그보다 많으면 목록 안에서 스크롤, 머리글은 위에 고정 */
.manual-item-list { overflow-y: auto; }
.manual-item-list thead th { position: sticky; top: 0; z-index: 1; }

/* 상단 장바구니 아이콘 숫자 (쇼핑몰 모듈, partials/topbar.php) */
.topbar-cart-count {
    position: absolute;
    top: 2px;
    right: -2px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    font-size: 11px;
    line-height: 18px;
}

/* English 화면 (lib/i18n.lib.php): 왼쪽 메뉴 이름이 길면 잘리지 않고 줄을 바꿉니다. */
html[lang="en"] .navbar-nav .nav-link .nav-text {
    white-space: normal;
    line-height: 1.25;
}

/* 항목 바로 열기 (assets/js/focus-row.js): 찾은 줄을 잠깐 강조 */
.focus-row-hit,
.focus-row-hit > td {
    background-color: rgba(var(--bs-warning-rgb), .18) !important;
    transition: background-color .6s;
}

/* 달력(flatpickr) 날짜 색: 템플릿 어두운 화면에서는 고를 수 없는 날짜(최대·최소 밖)가 고를 수 있는 날짜보다 더 밝게 보여,
   밝은 날짜를 눌러도 반응이 없는 것처럼 보였습니다. 고를 수 있는 날짜는 본문 색, 고를 수 없는 날짜는 흐리게 + 금지 커서로 맞춥니다. (2026-11-11) */
.flatpickr-day:not(.flatpickr-disabled):not(.selected):not(.startRange):not(.endRange):not(.inRange) { color: var(--bs-body-color); }
.flatpickr-day.prevMonthDay:not(.flatpickr-disabled):not(.selected), .flatpickr-day.nextMonthDay:not(.flatpickr-disabled):not(.selected) { color: var(--bs-secondary-color); }
.flatpickr-day.flatpickr-disabled, .flatpickr-day.flatpickr-disabled:hover, .flatpickr-day.flatpickr-disabled:focus { color: var(--bs-secondary-color) !important; opacity: .35; cursor: not-allowed; background: transparent !important; border-color: transparent !important; }

/* 메인 영역 좌우 여백 고정 (2026-11-11): 왼쪽 메뉴가 보이는 화면(1141px 이상)에서는 해상도와 상관없이 메뉴 끝·화면 끝에서 글자까지 48px.
   템플릿은 1444px 이상에서 폭을 90% 로 줄여 화면이 넓을수록 여백이 커지므로, 폭 제한을 없애고 여백을 px 로 고정합니다.
   본문: 바깥 38px + 안쪽(.container-fluid) 10px = 48px, 상단바·하단 저작권 줄도 같은 48px 에 맞춤. 메뉴가 숨는 화면(1140px 이하)은 템플릿 그대로(20px). */
@media (min-width: 1141px) {
    .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl {
        max-width: none;
    }
    .wrapper .page-content {
        padding-left: 38px;
        padding-right: 38px;
    }
    .topbar .container-fluid {
        padding-left: 48px;
        padding-right: 48px;
    }
    .footer {
        padding-left: 38px;
        padding-right: 38px;
    }
}


/* 달력(flatpickr) 시·분 위아래 버튼 (2026-11-11): 템플릿은 마우스를 올려야 보이고 화살표가 어두워 다크 테마에서 거의 안 보임
   → 늘 보이게, 칸 오른쪽에 위·아래 버튼으로 크게. 모든 달력(assets/js/date-picker.js·일정표 등)의 시계와 연도 칸에 같이 적용 */
.flatpickr-calendar.hasTime .flatpickr-time { height: 46px; max-height: 46px; line-height: 46px; }
.flatpickr-time .numInputWrapper { height: 46px; }
.flatpickr-time input.numInput { padding-right: 28px; font-size: 1rem; }
.flatpickr-calendar .numInputWrapper span { opacity: 1; padding: 0; border: 0; background: var(--bs-tertiary-bg); cursor: pointer; }
.flatpickr-time .numInputWrapper span { right: 6px; width: 22px; height: 19px; }
.flatpickr-time .numInputWrapper span.arrowUp { top: 4px; border-radius: 4px 4px 0 0; }
.flatpickr-time .numInputWrapper span.arrowDown { top: 23px; border-radius: 0 0 4px 4px; }
.flatpickr-calendar .numInputWrapper span:hover { background: var(--bs-primary); }
.flatpickr-calendar .numInputWrapper span::after { left: 50%; top: 50%; transform: translate(-50%, -50%); border-left-width: 5px; border-right-width: 5px; }
.flatpickr-calendar .numInputWrapper span.arrowUp::after { border-bottom: 6px solid var(--bs-body-color); }
.flatpickr-calendar .numInputWrapper span.arrowDown::after { border-top: 6px solid var(--bs-body-color); }
.flatpickr-calendar .numInputWrapper span.arrowUp:hover::after { border-bottom-color: #fff; }
.flatpickr-calendar .numInputWrapper span.arrowDown:hover::after { border-top-color: #fff; }
/* 연도 칸(달력 위 '2026')의 위아래 버튼: 작게 */
.flatpickr-current-month .numInputWrapper span { width: 16px; }
.flatpickr-current-month .numInputWrapper span::after { border-left-width: 4px; border-right-width: 4px; }
.flatpickr-current-month .numInputWrapper span.arrowUp::after { border-bottom-width: 5px; }
.flatpickr-current-month .numInputWrapper span.arrowDown::after { border-top-width: 5px; }
/* 연도 칸 (2026-11-12 사용자: 레이아웃 확인): 위아래 버튼이 '2026' 글자에 붙어 겹치지 않게 칸을 넓히고 글자 오른쪽에 버튼 자리를 둠 */
.flatpickr-current-month .numInputWrapper { width: calc(4ch + 30px); margin-left: 4px; }
.flatpickr-current-month input.cur-year { padding: 0 22px 0 4px; }
.flatpickr-current-month .numInputWrapper span { right: 2px; height: 50%; }
.flatpickr-current-month .numInputWrapper span.arrowUp { top: 0; border-radius: 3px 3px 0 0; }
.flatpickr-current-month .numInputWrapper span.arrowDown { top: 50%; border-radius: 0 0 3px 3px; }
/* 휴대전화 인증 칸 (partials/mobile-verify.php): 휴대폰에서 입력 힌트('휴대전화를 입력해 주세요.')가 잘리지 않게
   인증번호 받기 버튼의 아이콘을 빼고 입력 칸 좌우 여백을 줄입니다. (2026-11-13 사용자) */
@media (max-width: 575.98px) {
    [data-mobile-verify] [data-mobile-send] > i { display: none; }
    [data-mobile-verify] [data-mobile-input] { padding-left: .5rem; padding-right: .5rem; }
}

/* 버튼 진행 표시 (assets/js/button-busy.js, 2026-11-13): 저장·생성 중인 버튼 앞의 원형 로딩 */
.btn .btn-busy-spinner {
    width: 1em;
    height: 1em;
    border-width: .15em;
    margin-right: .35em;
    vertical-align: -.15em;
}

/* 시스템 점검 시간 안내 (assets/js/maintenance-notice.js, 매주 월요일 04:30~05:30)
   - 넓은 화면(992px~): 상단 가운데(통합 관리 모드 표시 옆)
   - 좁은 화면: 상단 바 바로 아래 한 줄 띠 (상단 바와 함께 붙어 있음, 내용은 아래로 밀림)
   - 상단 바가 없는 화면(로그인·서류 링크 등): 화면 위 가운데에 떠 있음 */
.maint-notice { font-size: 13px; line-height: 1.35; white-space: normal; text-align: center; }
.maint-notice .maint-part { white-space: nowrap; }
.maint-notice .maint-time { font-variant-numeric: tabular-nums; }
.maint-notice.badge { padding: .5rem 1rem; font-weight: 600; }
.maint-strip { position: sticky; top: var(--bs-topbar-height); z-index: 1004; padding: .4rem 1rem; text-align: center;
    background-color: var(--bs-topbar-bg); border-bottom: var(--bs-border-width) solid var(--bs-border-color); }
/* 왼쪽 메뉴 자리만큼 비워 상단 바와 같은 가운데 (메뉴 숨김 상태면 그대로) */
.maint-strip { padding-left: calc(var(--bs-main-nav-width) + 1rem); }
html[data-menu-size=hidden] .maint-strip { padding-left: 1rem; }
.maint-strip .maint-notice { display: inline-block; max-width: 100%; }
.maint-float { position: fixed; top: 12px; left: 0; right: 0; margin: 0 auto; width: max-content; z-index: 1090; max-width: calc(100% - 32px); box-shadow: var(--bs-box-shadow); }

/* 크레딧 충전 카드 (point/charge.php, 템플릿 pages-pricing, 2026-11-13): 누르면 선택, 고른 카드는 테두리 */
/* 위로 뜨는 효과(transform)는 쓰지 않음: 카드 아래 겹친 그림자 층(.card::before, z-index -1)이 테두리 위로 올라와 하단이 가려짐 (2026-11-13) */
.point-plan { cursor: pointer; transition: box-shadow .15s; }
.point-plan:hover { box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .45); }
.point-plan.is-selected, .point-plan.is-selected:hover { box-shadow: 0 0 0 3px var(--bs-primary), 0 .5rem 1.25rem rgba(var(--bs-primary-rgb), .18); }
.point-plan .card-pricing-features li { padding: 8px 4px; }
/* 키보드로 고를 때 (숨은 라디오에 초점) */
.point-plan:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--bs-primary), 0 0 0 6px rgba(var(--bs-primary-rgb), .25); }

/* 목록 '관리' 칸 버튼 간격 (2026-11-13 사용자: 1칸 간격, assets/js/manage-gap.js 가 버튼 2개 이상인 칸에 .list-manage)
   버튼 사이 공백 글자를 없애고(font-size 0, 버튼은 자기 글자 크기) 앞 요소 뒤에 같은 간격을 둡니다. */
td.list-manage { font-size: 0; }
td.list-manage > * + *, td.list-manage > form > .btn + .btn { margin-left: .5rem; }
td.list-manage > form, td.list-manage > span { font-size: 0; }
td.list-manage .badge, td.list-manage small, td.list-manage .text-muted { font-size: .8125rem; }

/* 수정할 수 없는 입력란 (2026-11-13 사용자): readonly·disabled 인 입력란·선택란은 바탕색만 달리해 구분합니다. (모든 화면)
   색은 사용자가 보여 준 파트너사 정보 수정 창의 아이디 칸과 같게: 다크 #2f3943(템플릿 --bs-tertiary-bg), 라이트 #eef2f7. 테두리·글자색·마우스 모양은 일반 칸과 같음
   빼는 것: 글자처럼 보이는 칸(form-control-plaintext), 달력 칸(flatpickr, 눌러서 고름), 주소 검색으로 채우는 주소·우편번호 칸 */
:root {
    --fx-locked-bg: #eef2f7;
}
[data-bs-theme="dark"] {
    --fx-locked-bg: #2f3943;
}
.form-control[readonly]:not(.form-control-plaintext):not(.flatpickr-input):not(.flatpickr-alt):not([data-address-main]):not([data-address-zipcode]),
.form-control:disabled,
.form-select:disabled:not(.select-dropdown-native),
.select-dropdown > .select-dropdown-toggle:disabled {
    background-color: var(--fx-locked-bg) !important;
}
.select-dropdown > .select-dropdown-toggle:disabled { opacity: 1; }
