/* ──────────────────────────────────────────────────────────
 * (참고) 이전엔 .app-header::after 로 헤더 우측에 1px 가로선을 그렸으나
 *  탭 위쪽에 거추장스러운 라인이 보여 제거. 헤더와 콘텐츠는 배경색 차로만 구분.
 * ──────────────────────────────────────────────────────────
 * .app-wrap height 강제 (단일 프레임 SPA 가정)
 *
 * SmartAdmin 기본은 .app-wrap { min-height: 100vh } 라서 콘텐츠가
 * 커지면 wrap 자체가 viewport 너머로 확장됨. 그 결과 .app-body /
 * .app-content / #content-container / .js-tab-pane 의 h-100 사슬이
 * 깨져 그리드(panel-list) 가 콘텐츠 합으로 부풀고 페이지 세로 스크롤 발생.
 *
 * 이 프로젝트는 frame.do 단일 페이지 안에서 탭으로 화면을 전환하는
 * SPA 라 페이지 자체가 스크롤될 일이 없으므로 viewport에 고정한다.
 * (각 화면 콘텐츠는 #content-container 의 overflow-auto 가 처리)
 * ────────────────────────────────────────────────────────── */
html, body {
    height: 100vh !important;
    max-height: 100vh !important;
    overflow: hidden !important;          /* 페이지 세로 스크롤 차단 */
}
.app-wrap {
    /* 헤더 — SmartAdmin 기본 5.5rem(88px) → 4rem(64px).
     * 탭/아이콘이 한 줄로 들어가면서도 위아래 여백이 답답하지 않은 높이. */
    --app-header-height: 4rem;
    /* 사이드바 폭 — SmartAdmin 기본 18rem(288px) → 15rem(240px).
     * 한글 메뉴명("그룹별사용메뉴관리" 등) 이 한 줄에 들어가는 최소선. */
    --menu-width: 15rem;
    height: 100vh !important;             /* SmartAdmin 기본 min-height → height 강제 */
    max-height: 100vh !important;
    overflow: hidden !important;          /* 자식이 넘쳐도 wrap은 절대 안 늘어나도록 */
    /* SmartAdmin 기본 grid-template-rows 의 두번째 row 가 'auto' 라 콘텐츠로 부풀어
     * h-100 사슬이 깨짐. '1fr' 로 강제하여 main 영역이 남는 높이를 차지하게. */
    grid-template-rows: var(--app-header-height) 1fr !important;
}
/* main(.app-body) — flex column. footer를 자르면 안 되므로 overflow: hidden 금지.
 * 대신 .app-content 에 min-height:0 + overflow:hidden 을 부여하여
 * 내부에서 줄어들 수 있게 (그러면 안의 #content-container 가 자체 스크롤 처리). */
.app-body {
    min-height: 0 !important;
}
.app-content {
    min-height: 0 !important;
    overflow: hidden !important;
}

/* ── 헤더 로고와 사이드바 시각적 통합 + 탭 내장 지원 ──
 * - .set-nav-dark가 .app-header .app-logo 배경을 사이드바와 동일하게 맞춤
 * - 헤더 안 모든 자식(탭 포함) 수직 중앙 정렬
 * - border-bottom: 1px — 헤더와 콘텐츠 영역 시각적 구분 (SmartAdmin 데모 스타일)
 */
.app-header {
    border-bottom: 1px solid var(--bs-border-color, #dee2e6) !important;
    align-items: center !important;
    overflow: visible !important;
}

/* 로고 자체 스타일 (사이드바와 매끄럽게 연결되도록 border-right 투명) */
.app-header .app-logo {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    border-right-color: transparent !important;   /* 로고-사이드바 사이 세로 구분선 제거 */
    transition: background 0.2s ease;
    min-width: 0;
}
.app-header .app-logo:hover {
    background-color: rgba(255, 255, 255, 0.05);  /* set-nav-dark 배경 위 hover */
}
.app-header .app-logo .custom-logo {
    letter-spacing: -0.02em;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

/* ── 모바일 (lg 미만 = 992px 미만) 헤더 보정 ──
 * SmartAdmin 데모와 동일하게 모바일 헤더에는 로고 자체를 표시하지 않는다.
 * 사이드바가 햄버거 드로어로 빠지므로 로고도 그 안에 있게 된다.
 *
 * 정책: 모바일 헤더 = 햄버거(좌측) + 비어있는 오른쪽. 알림/프로필/테마는
 *      햄버거 → 사이드바 드로어 안에서 접근.
 */
@media (max-width: 991.98px) {
    .app-header {
        padding: 0 0.75rem;
        gap: 0.5rem;
        overflow: hidden;
    }
    .app-header > * {
        flex-shrink: 0;
    }
    /* 로고 완전 숨김 (SmartAdmin 데모와 동일) */
    .app-header > .app-logo {
        display: none !important;
    }
    /* 햄버거를 헤더 좌측 첫 자리로 */
    .app-header > .mobile-menu-icon {
        margin-left: 0 !important;
        order: 0;
    }
    /* 모바일: 탭은 햄버거 옆에서 가용 폭 모두 사용. 우측 4 아이콘은 그대로 노출.
     * (.dropdown-menu 는 Bootstrap 이 토글하므로 강제 숨김 금지) */
    .app-header > #js-main-tabs {
        margin-left: 0.5rem !important;
    }
}
/* primary-nav가 남은 공간만 차지하고 스크롤되도록 */
.app-sidebar .primary-nav {
    min-height: 0;
}

/* ═══════════════════════════════════════════════════
   기계실 운전분석(aiaa01) 모바일 스크롤 보정
   - 이 화면은 고정높이(h-100) flex 컬럼 + 차트영역만 내부 스크롤 구조.
   - 데스크톱은 KPI 4장이 가로 한 줄(col-md-3)이라 위가 짧아 차트영역이
     남는 공간을 차지하고 그 안에서 스크롤된다.
   - 모바일(<768px)은 KPI 4장이 세로로 쌓이고(col-12) 종합진단 카드까지
     더해져 고정(flex-shrink-0) 영역 합이 패널 높이를 넘긴다. 그러면
     flex-grow-1 차트영역이 0으로 눌려 차트가 안 보이고, 바깥 레이아웃은
     height:100vh + overflow:hidden 으로 잠겨 있어 스크롤도 안 생긴다.
   - 보정: 모바일에선 패널 자체를 세로 스크롤 컨테이너로 바꾸고,
     차트영역은 자연 높이(flex 해제)로 풀어 패널이 통째로 스크롤되게 한다.
═══════════════════════════════════════════════════ */
@media (max-width: 767.98px) {
    [data-page-id="aiaa01"] {
        overflow-y: auto !important;        /* 패널 전체가 세로 스크롤 */
    }
    [data-page-id="aiaa01"] > .flex-grow-1 {
        flex: 0 0 auto !important;          /* 차트영역: 자연 높이 */
        min-height: auto !important;
        overflow: visible !important;       /* 내부 자체 스크롤 해제 */
    }
}

/* ═══════════════════════════════════════════════════
   메인 탭 — Bootstrap 클래식 nav-tabs 스타일 (SmartAdmin Default Tabs)
   - 헤더 안에서 하단 절반(50%)만 차지, 자식 탭은 하단 라인에 valign:bottom
   - 활성 탭: 상단/좌/우 회색 테두리 + 하단 보더 가림(노치 효과)
   - 비활성: 테두리 없음, 회색 텍스트
   - 탭바 하단 가로선이 탭 아래로 이어짐
   - X 닫기 버튼: 평소 옅게, 탭 hover 시 진해짐
═══════════════════════════════════════════════════ */
#js-main-tabs {
    /* 헤더 풀 높이를 차지하되, 자식 탭은 하단 라인에 valign:bottom */
    align-self: stretch;
    height: 100%;
    align-items: flex-end;          /* 자식 li 들이 헤더 하단 라인에 붙음 */

    gap: 0;
    padding: 0 0.5rem;
    background: transparent;
    list-style: none;
    margin-bottom: 0;
    /* Default Tabs 하단 가로선 — 헤더 하단 보더와 정확히 겹쳐서 한 줄로 보임 */
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);

    /* 좌측 collapse / 우측 4아이콘 사이 공간을 모두 차지 */
    overflow-x: auto;
    overflow-y: hidden;             /* 세로 스크롤바 발생 차단 */
    min-width: 0;
    /* macOS overlay 스크롤바 숨김 — 가로 스크롤 trackpad/wheel 제스처는 그대로 동작 */
    scrollbar-width: none;          /* Firefox */
    position: relative;             /* ::before/::after 기준 */
}
/* 좌(토글-탭 사이) / 우(탭-아이콘 사이) 세로 분리선 — 헤더 높이의 약 50% */
#js-main-tabs::before,
#js-main-tabs::after {
    content: '';
    position: absolute;
    top: 25%;
    bottom: 25%;
    width: 1px;
    background-color: var(--bs-border-color, #dee2e6);
    pointer-events: none;
}
#js-main-tabs::before { left: 0; }
#js-main-tabs::after  { right: 0; }
#js-main-tabs::-webkit-scrollbar {  /* Chrome/Safari */
    display: none;
}
#js-main-tabs .nav-item {
    margin-bottom: -1px;            /* 활성 탭이 하단 라인을 1px 덮어쓰면서 노치 효과 */
}

/* 탭 단위 wrapper (.tab-unit) — Default Tabs: 상단 코너만 둥글게, 하단 보더 없음 */
#js-main-tabs .tab-unit {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.4rem 0.85rem;
    cursor: default;
    border: 1px solid transparent;
    border-bottom: 0;
    border-radius: 0.35rem 0.35rem 0 0;
    background: transparent;
    transition: background-color 0.12s ease, border-color 0.12s ease;
    line-height: 1.4;
}
#js-main-tabs .tab-unit:hover {
    background-color: rgba(0, 0, 0, 0.03);
    border-color: var(--bs-border-color, #dee2e6) var(--bs-border-color, #dee2e6) transparent;
}

/* 활성 탭: 상/좌/우 보더 + 하단을 헤더 배경색으로 덮어 컨테이너 라인을 잘라낸 노치 효과 */
#js-main-tabs .nav-item:has(.nav-link.active) .tab-unit {
    background-color: var(--bs-body-bg, #fff);
    border-color: var(--bs-border-color, #dee2e6);
    /* 하단 보더는 컨테이너 라인을 가리는 같은 색의 1px (margin-bottom:-1px와 합쳐져 노치) */
    border-bottom: 1px solid var(--bs-body-bg, #fff);
    padding-bottom: calc(0.4rem + 1px);
}

/* 텍스트 버튼 (.js-tab-btn) — 보더 없는 텍스트만 */
#js-main-tabs .tab-unit .nav-link {
    border: 0 none !important;
    background: transparent !important;
    color: #6c757d;
    font-size: 0.8125rem;
    font-weight: 500;
    padding: 0;
    line-height: 1.4;
    border-radius: 0;
    margin-bottom: 0;
    min-width: 0;
    text-align: left;
    cursor: pointer;
    transition: color 0.12s ease;
}
#js-main-tabs .tab-unit .nav-link:hover {
    color: #2d3748;
}
#js-main-tabs .tab-unit .nav-link.active {
    color: #212529;
    font-weight: 600;
    background: transparent !important;
}

/* X 닫기 버튼 — 평소 옅게, 탭 hover 시 진해짐, X hover 시 빨강 */
#js-main-tabs .tab-unit .js-tab-close {
    flex-shrink: 0;
    color: #adb5bd;
    opacity: 0.4;
    font-size: 0.7rem;
    line-height: 1;
    padding: 0.1rem 0.2rem;
    margin: 0;
    border: 0;
    background: transparent;
    border-radius: 50%;
    transition: opacity 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}
#js-main-tabs .tab-unit:hover .js-tab-close {
    opacity: 0.85;
}
#js-main-tabs .tab-unit .js-tab-close:hover {
    opacity: 1;
    color: #dc3545;
    background-color: rgba(220, 53, 69, 0.1);
}

/* 다크 테마 보정 */
[data-bs-theme="dark"] #js-main-tabs {
    border-bottom-color: rgba(255, 255, 255, 0.15);
}
[data-bs-theme="dark"] #js-main-tabs::before,
[data-bs-theme="dark"] #js-main-tabs::after {
    background-color: rgba(255, 255, 255, 0.15);
}
[data-bs-theme="dark"] #js-main-tabs .tab-unit:hover {
    background-color: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.15) rgba(255, 255, 255, 0.15) transparent;
}
[data-bs-theme="dark"] #js-main-tabs .nav-item:has(.nav-link.active) .tab-unit {
    background-color: var(--bs-body-bg, #1a1d21);
    border-color: rgba(255, 255, 255, 0.20);
    border-bottom-color: var(--bs-body-bg, #1a1d21);
}
[data-bs-theme="dark"] #js-main-tabs .tab-unit .nav-link {
    color: #adb5bd;
}
[data-bs-theme="dark"] #js-main-tabs .tab-unit .nav-link.active {
    color: #f1f3f5;
}

/* 헤더 안 조회조건·버튼 1줄 고정 (ui-panels Form Inputs + forms-groups input-group 참조) */
.ccaa02-panel-hdr {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    overflow-x: auto;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
.ccaa02-hdr-form {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.5rem;
    min-width: min-content;
    width: 100%;
}
/* 헤더 내 input-group 스타일 (forms-groups.html, 밝은 헤더용) */
.ccaa02-hdr-input-group {
    flex-shrink: 0;
    width: auto;
}
.ccaa02-panel-hdr .input-group-text {
    font-size: 0.8125rem;
}
.ccaa02-panel-hdr .form-control {
    font-size: 0.8125rem;
}
/* 버튼 그룹: 반드시 1줄 */
.ccaa02-toolbar-btns {
    display: inline-flex;
    flex-wrap: nowrap;
    flex-shrink: 0;
    gap: 0.4rem;
}
.ccaa02-toolbar-btn,
.ccaa02-btn-fullscreen {
    display: inline-flex;
    align-items: center;
    flex-wrap: nowrap;
    flex-shrink: 0;
    padding: 0.4rem 0.75rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    white-space: nowrap;
}
/* 툴바 버튼 아이콘·텍스트 흰색으로 눈에 띄게 */
.ccaa02-toolbar-btns .ccaa02-toolbar-btn,
.ccaa02-toolbar-btns .ccaa02-btn-fullscreen {
    color: #fff;
}
.ccaa02-toolbar-btns .ccaa02-toolbar-btn:hover,
.ccaa02-toolbar-btns .ccaa02-btn-fullscreen:hover {
    color: #fff;
}
.ccaa02-toolbar-btn .sa-icon,
.ccaa02-btn-fullscreen .sa-icon {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    vertical-align: -0.2em;
    fill: #fff;
    color: #fff;
}
/* 전체화면 버튼: 보라/인디고 */
.ccaa02-btn-fullscreen {
    background-color: #5867dd;
    color: #fff;
    border-color: #5867dd;
}
.ccaa02-btn-fullscreen:hover {
    background-color: #4653c9;
    color: #fff;
    border-color: #4653c9;
}

/* ── 그리드 패널 상단 여백 축소 (기본값 절반) ── */
.panel-content {
    padding-top: 0.5rem !important;
}
.panel-content > p.mb-2 {
    margin-bottom: 0.25rem !important;
}

/* ═══════════════════════════════════════════════════
   DataTables (tablecomm) — SmartAdmin smarttables 데모 매칭
   - SmartAdmin .table { font-weight: 300 } 이 헤더까지 가볍게 만들고
     기본 dataTable 정렬화살표가 큰 유니코드(↑↓)로 떠서 어색함을
     이 섹션에서 일괄 보정.
═══════════════════════════════════════════════════ */

/* 본문 — SmartAdmin .table { font-weight: 300 } 오버라이드 */
.dataTables_wrapper table.dataTable {
    font-weight: 400;
    color: #212529;
}

/* 헤더 — 회색 음영 + 굵게 + 가독성 폰트 + 세로 구분선 */
.dataTables_wrapper table.dataTable > thead > tr > th {
    font-weight: 600;
    color: #212529;
    background-color: #f1f3f5;             /* 회색 음영 */
    border-top: 1px solid #dee2e6;
    border-bottom: 1px solid #c8cdd3;      /* 본문과 분리 */
    padding: 0.65rem 0.75rem;
    font-size: 0.9rem;
    text-transform: none;
    vertical-align: middle;
    white-space: nowrap;
}

/* 본문 셀 — 가로 보더 + 세로 구분선 추가 + 가독성 폰트 */
.dataTables_wrapper table.dataTable > tbody > tr > td {
    font-size: 0.9rem;
    color: #212529;
    border-top: 0;
    border-bottom: 1px solid #e9ecef;
    padding: 0.55rem 0.75rem;
    vertical-align: middle;
    background-color: #fff;
}

/* 컬럼 사이 세로 구분선 (첫 컬럼 제외) — 헤더/본문 모두 */
.dataTables_wrapper table.dataTable > thead > tr > th + th,
.dataTables_wrapper table.dataTable > tbody > tr > td + td {
    border-left: 1px solid #e9ecef;
}

/* hover/selected — SmartAdmin 톤의 옅은 강조 */
.dataTables_wrapper table.dataTable.table-hover > tbody > tr:hover > * {
    background-color: rgba(var(--bs-primary-rgb, 13, 110, 253), 0.05);
}
.dataTables_wrapper table.dataTable > tbody > tr.selected > * {
    background-color: rgba(var(--bs-primary-rgb, 13, 110, 253), 0.10);
}

/* SmartAdmin .table-hover의 outline 강조 무력화 (한 줄 위로 튀어나옴 방지) */
.dataTables_wrapper table.dataTable.table-hover > tbody > tr:hover {
    outline: 0 none !important;
}

/* 정렬 화살표 — 더 작고 얇게 (큰 유니코드 ↑↓ → 부드럽게) */
.dataTables_wrapper table.dataTable > thead .sorting:before,
.dataTables_wrapper table.dataTable > thead .sorting:after,
.dataTables_wrapper table.dataTable > thead .sorting_asc:before,
.dataTables_wrapper table.dataTable > thead .sorting_asc:after,
.dataTables_wrapper table.dataTable > thead .sorting_desc:before,
.dataTables_wrapper table.dataTable > thead .sorting_desc:after {
    font-size: 0.75rem;
    opacity: 0.4;
    bottom: 0.7em;
    color: #6c757d;
}
.dataTables_wrapper table.dataTable > thead .sorting_asc:before,
.dataTables_wrapper table.dataTable > thead .sorting_desc:after {
    opacity: 1;
    color: #212529;
}

/* ── 풋터 (페이지길이 select / 정보 라벨 / 페이지네이션) 통일 ──
   세 요소 모두 같은 line-height + vertical center 로 정렬 */
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
    font-size: 0.875rem;
    color: #6c757d;
    line-height: 32px;          /* select 높이와 동일 */
}
.dataTables_wrapper .dataTables_info {
    padding-top: 0 !important;  /* 번들 기본 padding-top: 0.85em 무력화 (높이 정렬용) */
    margin-left: 0.5rem;
}
.dataTables_wrapper .dataTables_length label {
    margin-bottom: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* 페이지길이 select — Bootstrap form-select 스타일 적용 (예쁘게) */
.dataTables_wrapper .dataTables_length select.form-control,
.dataTables_wrapper .dataTables_length select {
    width: auto;
    min-width: 4.5rem;
    height: 32px;
    padding: 0.25rem 1.75rem 0.25rem 0.65rem;
    font-size: 0.875rem;
    line-height: 1.4;
    color: #212529;
    background-color: #fff;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23495057' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 12px 12px;
    border: 1px solid #ced4da;
    border-radius: 0.375rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
    -webkit-transition: border-color 0.15s ease, box-shadow 0.15s ease;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.dataTables_wrapper .dataTables_length select:hover {
    border-color: #adb5bd;
}
.dataTables_wrapper .dataTables_length select:focus {
    border-color: #86b7fe;
    box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.15);
    outline: 0;
}

/* 페이지네이션 — 컴팩트 + select와 같은 32px 높이 */
.dataTables_wrapper .dataTables_paginate .pagination {
    margin: 0;
    align-items: center;
}
.dataTables_wrapper .dataTables_paginate .pagination .page-link {
    padding: 0 0.65rem;
    height: 32px;
    line-height: 30px;
    font-size: 0.875rem;
}

/* 빈 상태(데이터 없음) 메시지 */
.dataTables_wrapper table.dataTable td.dataTables_empty {
    padding: 2rem 0.5rem;
    color: #adb5bd;
    font-size: 0.9rem;
}

/* 체크박스 컬럼 셀 패딩 축소 */
.dataTables_wrapper table.dataTable > thead > tr > th.js-tc-check-cell,
.dataTables_wrapper table.dataTable > tbody > tr > td.js-tc-check-cell {
    padding-left: 0;
    padding-right: 0;
}
.dataTables_wrapper table.dataTable .form-check-input {
    margin: 0;
    cursor: pointer;
}

/* 다크 테마 보정 */
[data-bs-theme="dark"] .dataTables_wrapper table.dataTable {
    color: #e6e8eb;
}
[data-bs-theme="dark"] .dataTables_wrapper table.dataTable > thead > tr > th {
    color: #e6e8eb;
    background-color: #2b2f36;
    border-top-color: #3a3f47;
    border-bottom-color: #4a505a;
}
[data-bs-theme="dark"] .dataTables_wrapper table.dataTable > tbody > tr > td {
    color: #e6e8eb;
    background-color: transparent;
    border-bottom-color: #2b2f36;
}
[data-bs-theme="dark"] .dataTables_wrapper table.dataTable > thead > tr > th + th,
[data-bs-theme="dark"] .dataTables_wrapper table.dataTable > tbody > tr > td + td {
    border-left-color: #2b2f36;
}
[data-bs-theme="dark"] .dataTables_wrapper .dataTables_length select {
    background-color: #1f2329;
    color: #e6e8eb;
    border-color: #3a3f47;
}

/* ═══════════════════════════════════════════════════
   AG Grid Community 커스텀 스타일 v3
   심플·모던 — 전체 테마와 자연스럽게 어울리는 디자인
═══════════════════════════════════════════════════ */

/* ── CSS 변수 ── */
.ag-theme-alpine {
    --ag-font-size: 13px;                /* 12 → 13 */
    --ag-font-family: 'Malgun Gothic', 'Noto Sans KR', sans-serif;
    --ag-header-height: 38px;            /* 34 → 38 (폰트 ↑ 대응) */
    --ag-row-height: 34px;               /* 30 → 34 (폰트 ↑ 대응) */
    --ag-header-background-color: #e8ebef;
    --ag-header-foreground-color: #374151;
    --ag-background-color: #ffffff;
    --ag-foreground-color: #1e293b;
    --ag-secondary-foreground-color: #64748b;
    --ag-border-color: #d1d5db;
    --ag-row-border-color: #f1f5f9;
    --ag-selected-row-background-color: #eff6ff;
    --ag-row-hover-color: #f8fafc;
    --ag-checkbox-checked-color: #6366f1;
    --ag-checkbox-unchecked-color: #cbd5e1;
    --ag-input-focus-border-color: #a5b4fc;
    --ag-alpine-active-color: #6366f1;
    --ag-cell-horizontal-padding: 10px;
    --ag-header-column-separator-display: none;
    --ag-header-column-resize-handle-display: block;
    --ag-header-column-resize-handle-color: #9ca3af;
    --ag-header-column-resize-handle-width: 2px;
    --ag-header-column-resize-handle-height: 50%;
}

/* ── 전체 래퍼 ── */
.ag-theme-alpine .ag-root-wrapper {
    border: 1px solid #d1d5db;
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}

/* ── 헤더 ── */
.ag-theme-alpine .ag-header {
    font-family: 'Malgun Gothic', 'Noto Sans KR', sans-serif;
    font-size: 13px;
    font-weight: 600;
    background-color: #e8ebef;
    border-bottom: 2px solid #c4c9d0;
}

/* 헤더 셀 — 중앙 정렬 + 구분선 */
.ag-theme-alpine .ag-header-cell {
    padding: 0 8px;
    border-right: 1px solid #d1d5db !important;
}
.ag-theme-alpine .ag-header-cell:last-child {
    border-right: none !important;
}
.ag-theme-alpine .ag-header-cell:hover {
    background-color: #dde0e5 !important;
}

/* 헤더 텍스트 가운데 정렬 */
.ag-theme-alpine .ag-header-cell-label {
    justify-content: center;
}
.ag-theme-alpine .ag-header-cell-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #374151;
    font-weight: 600;
}

/* 헤더 아이콘 */
.ag-theme-alpine .ag-header-icon {
    color: #6b7280;
}
/* AG Grid 기본 메뉴 버튼은 숨김 — 우리 커스텀 헤더(_GcMenuHeaderComp) 안의 ⋮ 사용 */
.ag-theme-alpine .ag-header-cell-menu-button {
    display: none !important;
}

/* 커스텀 헤더 ⋮ 버튼 + 한글 dropdown 메뉴 스타일 */
.ag-theme-alpine .js-gc-menu-btn {
    color: #6b7280;
    transition: opacity 0.15s ease;
}
.ag-theme-alpine .ag-header-cell:hover .js-gc-menu-btn {
    opacity: 0.75 !important;
}
.js-gc-col-menu {
    border: 1px solid rgba(0, 0, 0, 0.08);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    border-radius: 0.375rem;
    background: #fff;
}
.js-gc-col-menu .dropdown-item {
    color: #2d3748;
    transition: background-color 0.1s ease;
}
.js-gc-col-menu .dropdown-item:hover {
    background-color: #f1f3f5;
    color: #2d3748;
}
.js-gc-col-menu .dropdown-item.active {
    background-color: rgba(99, 102, 241, 0.08);
    color: #4338ca;
    font-weight: 500;
}
.js-gc-col-menu .dropdown-divider {
    border-top-color: #e9ecef;
}

/* SelectFilter 드롭다운 (헤더 필터 아이콘) */
.js-gc-col-filter {
    border: 1px solid rgba(0, 0, 0, 0.08);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    border-radius: 0.375rem;
    background: #fff;
}
.js-gc-col-filter .form-check {
    margin-bottom: 0.15rem;
    padding-left: 1.5rem;
}
.js-gc-col-filter .form-check-label {
    cursor: pointer;
    font-size: 0.825rem;
    user-select: none;
}
.js-gc-col-filter .js-gc-fil-search {
    font-size: 0.8rem;
}
/* 다크 테마 보정 */
[data-bs-theme="dark"] .js-gc-col-menu,
[data-bs-theme="dark"] .js-gc-col-filter {
    background: #1f2329;
    border-color: #3a3f47;
}
[data-bs-theme="dark"] .js-gc-col-menu .dropdown-item {
    color: #e6e8eb;
}
[data-bs-theme="dark"] .js-gc-col-menu .dropdown-item:hover {
    background-color: #2b2f36;
    color: #e6e8eb;
}
[data-bs-theme="dark"] .js-gc-col-menu .dropdown-item.active {
    background-color: rgba(99, 102, 241, 0.15);
    color: #a5b4fc;
}
.ag-theme-alpine .ag-icon-asc,
.ag-theme-alpine .ag-icon-desc {
    color: #6366f1;
}

/* ── 행(row) ── */
.ag-theme-alpine .ag-row {
    font-family: 'Malgun Gothic', 'Noto Sans KR', sans-serif;
    font-size: 13px;
    border-bottom: 1px solid #f1f5f9;
    color: #1e293b;
}
.ag-theme-alpine .ag-row:last-child {
    border-bottom: none;
}

/* ── 셀 — 컬럼 구분선 추가 ── */
.ag-theme-alpine .ag-cell {
    line-height: 34px;                   /* row-height와 일치 */
    padding: 0 10px;
    border-right: 1px solid #e9ecef !important;
}
.ag-theme-alpine .ag-cell:last-child {
    border-right: none !important;
}

/* 셀 포커스 */
.ag-theme-alpine .ag-cell-focus:not(.ag-cell-range-selected) {
    border: 1px solid #a5b4fc !important;
    outline: none;
}

/* 편집 중 셀 */
.ag-theme-alpine .ag-cell-inline-editing {
    padding: 0 6px;
    background-color: #fefce8 !important;
    border: 1px solid #f59e0b !important;
}

/* ── 선택된 행 ── */
.ag-theme-alpine .ag-row-selected {
    background-color: #eff6ff !important;
}
.ag-theme-alpine .ag-row-selected .ag-cell {
    color: #1d4ed8;
}

/* ── 순번 컬럼 ── */
.ag-theme-alpine .ag-header-cell[col-id="__rowNum"] {
    background-color: #dde0e5 !important;
}
.ag-theme-alpine .ag-header-cell[col-id="__rowNum"] .ag-header-cell-text {
    font-size: 10px;
    color: #6b7280;
}
.ag-theme-alpine .ag-cell[col-id="__rowNum"] {
    color: #9ca3af;
    font-size: 11px;
    padding: 0 4px;
    background-color: #fafafa;
}

/* ── 체크박스 컬럼 — 커스텀 렌더러가 JS로 정중앙 정렬 처리 ── */
/* 헤더/셀 배경색만 CSS로 처리, 정렬은 JS cellRenderer/headerComponent에서 수행 */
.ag-theme-alpine .ag-header-cell[col-id="__check"] {
    padding: 0 !important;
    background-color: #dde0e5 !important;
}
.ag-theme-alpine .ag-cell[col-id="__check"] {
    padding: 0 !important;
    background-color: #fafafa;
}

/* ── 체크박스 심플 스타일 ── */
.ag-theme-alpine .ag-checkbox-input-wrapper {
    width: 14px;
    height: 14px;
    border-radius: 2px;
    border: 1.5px solid #d1d5db;
    background: #ffffff;
    box-shadow: none !important;
    transition: border-color 0.15s, background 0.15s;
}
.ag-theme-alpine .ag-checkbox-input-wrapper::after {
    color: #ffffff;
    font-size: 10px;
}
.ag-theme-alpine .ag-checkbox-input-wrapper.ag-checked {
    background-color: #6366f1;
    border-color: #6366f1;
}
.ag-theme-alpine .ag-checkbox-input-wrapper.ag-indeterminate {
    background-color: #a5b4fc;
    border-color: #a5b4fc;
}
.ag-theme-alpine .ag-checkbox-input-wrapper:hover {
    border-color: #6366f1;
}

/* ── 핀 고정 컬럼 우측 테두리 ── */
.ag-theme-alpine .ag-pinned-left-cols-container {
    border-right: 2px solid #d1d5db;
}

/* ── 드롭다운 에디터 ── */
.ag-theme-alpine .ag-select-cell-editor select {
    font-family: 'Malgun Gothic', sans-serif;
    font-size: 12px;
}

/* ── 스크롤바 ── */
.ag-theme-alpine ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}
.ag-theme-alpine ::-webkit-scrollbar-track {
    background: transparent;
}
.ag-theme-alpine ::-webkit-scrollbar-thumb {
    background: #cbd5e1;
    border-radius: 3px;
}
.ag-theme-alpine ::-webkit-scrollbar-thumb:hover {
    background: #94a3b8;
}

/* ── 데이터 없음 오버레이 ── */
.ag-theme-alpine .ag-overlay-no-rows-wrapper {
    font-family: 'Malgun Gothic', sans-serif;
    font-size: 13px;
    color: #94a3b8;
}

/* ── 다크 테마 ── */
[data-bs-theme="dark"] .ag-theme-alpine {
    --ag-background-color: #1e293b;
    --ag-foreground-color: #e2e8f0;
    --ag-secondary-foreground-color: #94a3b8;
    --ag-header-background-color: #273549;
    --ag-header-foreground-color: #e2e8f0;
    --ag-border-color: #334155;
    --ag-row-border-color: #1e293b;
    --ag-selected-row-background-color: #1e3a5f;
    --ag-row-hover-color: #263348;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-header {
    background-color: #273549;
    border-bottom-color: #334155;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-header-cell {
    border-right-color: #334155 !important;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-header-cell-text {
    color: #e2e8f0;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-header-cell:hover {
    background-color: #2e3f55 !important;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-header-cell[col-id="__rowNum"],
[data-bs-theme="dark"] .ag-theme-alpine .ag-header-cell[col-id="__check"] {
    background-color: #1e2d3d !important;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-root-wrapper {
    border-color: #334155;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-row {
    border-bottom-color: #1e293b;
    color: #e2e8f0;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-cell {
    border-right-color: #334155 !important;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-row-selected {
    background-color: #1e3a5f !important;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-row-selected .ag-cell {
    color: #93c5fd;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-cell[col-id="__rowNum"],
[data-bs-theme="dark"] .ag-theme-alpine .ag-cell[col-id="__check"] {
    background-color: #172033;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-checkbox-input-wrapper {
    border-color: #475569;
    background: #1e293b;
}
[data-bs-theme="dark"] .ag-theme-alpine .ag-cell-inline-editing {
    background-color: #2d2a1a !important;
    border-color: #f59e0b !important;
}

/* ═══════════════════════════════════════════════════
   게이트웨이 상세 — 모달 잔여 높이 기반 이력 그리드
   - SPA fragment 로드가 JSP 내부 style 태그를 보존하지 않으므로 공용 로드 CSS에 둔다.
   - 데스크톱에서는 이력 그리드가 남은 높이를 채우고, 작은 화면에서는 최소 높이와 탭 스크롤을 보장한다.
═══════════════════════════════════════════════════ */
.gateway-management-modal .gateway-field-label {
    display: flex;
    align-items: center;
    white-space: nowrap;
}
.gateway-management-modal .gateway-help-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.3rem;
    color: #0d6efd !important;
    cursor: pointer;
    font-size: 0.75rem;
    line-height: 1;
    text-decoration: none;
}
.gateway-management-modal .gateway-help-trigger:hover,
.gateway-management-modal .gateway-help-trigger:focus-visible {
    color: #084298 !important;
}
.gateway-management-modal .gateway-help-trigger.gateway-help-required {
    color: #dc3545 !important;
}
.gateway-management-modal .gateway-help-trigger.gateway-help-required:hover,
.gateway-management-modal .gateway-help-trigger.gateway-help-required:focus-visible {
    color: #b02a37 !important;
}
.gateway-management-modal .gateway-help-trigger:focus-visible {
    outline: 2px solid #86b7fe;
    outline-offset: 2px;
    border-radius: 50%;
}
.gateway-management-modal .gateway-help-trigger.gateway-help-required:focus-visible {
    outline-color: #f1aeb5;
}
.gateway-management-modal .form-control[readonly] {
    background-color: var(--bs-tertiary-bg, #f3f3f3);
    color: var(--bs-secondary-color, #495057);
    cursor: not-allowed;
    opacity: 1;
    box-shadow: none;
}
.gateway-help-popover {
    --bs-popover-max-width: 420px;
}
.gateway-help-popover .popover-body {
    font-size: 12px;
    line-height: 1.55;
    text-align: left;
}
.gateway-management-modal .modal-content {
    height: 100%;
    overflow: hidden;
}
.gateway-management-modal .modal-body {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}
.gateway-management-modal .js-form-view {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}
.gateway-management-modal .js-form-view > .nav-tabs {
    flex: 0 0 auto;
}
.gateway-management-modal .js-form-view > .tab-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}
.gateway-management-modal .js-form-view > .tab-content > .tab-pane {
    height: 100%;
    min-height: 0;
    overflow-y: auto;
}
.gateway-management-modal .js-form-view > .tab-content > .tab-pane.active {
    display: flex;
    flex-direction: column;
}
.gateway-management-modal .js-gateway-basic-card,
.gateway-management-modal .js-gateway-config-card,
.gateway-management-modal .js-gateway-run-card {
    flex: 0 0 auto;
}
.gateway-management-modal .js-gateway-data-receive-history-card,
.gateway-management-modal .js-gateway-config-history-card,
.gateway-management-modal .js-gateway-run-history-card {
    display: flex;
    flex: 1 0 260px;
    flex-direction: column;
    min-height: 260px;
}
.gateway-management-modal .js-gateway-data-receive-history-card > .card-body,
.gateway-management-modal .js-gateway-config-history-card > .card-body,
.gateway-management-modal .js-gateway-run-history-card > .card-body {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}
.gateway-management-modal .js-gateway-data-receive-history-grid,
.gateway-management-modal .js-gateway-config-history-grid,
.gateway-management-modal .js-gateway-run-history-grid {
    flex: 1 1 auto;
    width: 100%;
    height: 100%;
    min-height: 180px;
}

/* 태그 상세: 항목 제목 오른쪽의 키보드 접근 가능한 풍선 도움말. */
.tag-field-label { display: flex; align-items: center; white-space: nowrap; }
.tag-field-help-trigger {
    border: 0; background: transparent; padding: 0; margin-left: .3rem;
    color: #0d6efd; cursor: pointer; font-size: .75rem; line-height: 1;
}
.tag-field-help-trigger:focus-visible { outline: 2px solid #86b7fe; outline-offset: 2px; border-radius: 50%; }

/* 태그 요청과 실제 ACK 조회: 상세 카드 및 삭제 태그 조회 대화상자. */
.tag-history-grid { width: 100%; height: 260px; min-height: 180px; }
.tag-history-detail { margin-top: .75rem; padding: .75rem 1rem; background: #f8f9fa; border: 1px solid #dee2e6; border-radius: .25rem; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 160px; overflow: auto; color: #495057; }
.tag-history-dialog { margin: auto; width: min(1400px, calc(100vw - 2rem)); max-height: 90vh; overflow: auto; padding: 0; border: 0; border-radius: .5rem; }
.tag-history-dialog::backdrop { background: rgba(15, 23, 42, .58); }
.tag-history-dialog .tag-history-grid { height: clamp(200px, 40vh, 440px); }


/* 공통 조회·분석 요청의 진행 및 완료 상태. 화면 동작을 가리지 않는다. */
.app-progress-status {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 1080;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: min(360px, calc(100vw - 32px));
    padding: 12px 16px;
    border-radius: 10px;
    background: #163a5b;
    color: #fff;
    box-shadow: 0 8px 24px rgba(14, 39, 64, .26);
    font-size: 13px;
    font-weight: 600;
    pointer-events: none;
}
.app-progress-status[hidden] { display: none; }
.app-progress-status.is-complete { background: #176344; }
.app-progress-spinner {
    width: 17px;
    height: 17px;
    flex: 0 0 17px;
    border: 2px solid rgba(255, 255, 255, .42);
    border-top-color: #fff;
    border-radius: 50%;
    animation: app-progress-spin .8s linear infinite;
}
.app-progress-status.is-complete .app-progress-spinner {
    border: 0;
    animation: none;
}
.app-progress-status.is-complete .app-progress-spinner::before {
    content: '✓';
    font-size: 17px;
    line-height: 17px;
}
@keyframes app-progress-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .app-progress-spinner { animation: none; }
}
