/* =====================================================================
   SiHAS 관제 콘솔 — 디자인 시스템
   계측 콘솔. 제품의 심장은 10초 FC24 하트비트, 진실의 원천은 64개 레지스터.
   장치는 3글자 타입코드로 식별한다 → 아이콘 대신 코드 자체를 쓴다.
   ===================================================================== */

/* --- 한글 UI 서체 (번들) --- */
@font-face { font-family:'ATOZ'; src:url('/static/font/ATOZ-3Light.woff2') format('woff2'); font-weight:300; font-display:swap; }
@font-face { font-family:'ATOZ'; src:url('/static/font/ATOZ-4Regular.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'ATOZ'; src:url('/static/font/ATOZ-5Medium.woff2') format('woff2'); font-weight:500; font-display:swap; }
@font-face { font-family:'ATOZ'; src:url('/static/font/ATOZ-6SemiBold.woff2') format('woff2'); font-weight:600; font-display:swap; }
@font-face { font-family:'ATOZ'; src:url('/static/font/ATOZ-7Bold.woff2') format('woff2'); font-weight:700; font-display:swap; }

/* --- 계측 팔레트: 초록 바이어스 뉴트럴 + 틸 시그널 + 앰버 커맨드 --- */
:root {
    --canvas:      #EFF3F2;
    --surface:     #FFFFFF;
    --surface-2:   #F6F8F7;
    --surface-3:   #E7EDEB;

    --ink:         #0D1A18;
    --ink-2:       #485754;
    --ink-3:       #7A8884;
    --line:        #DBE3E1;
    --line-2:      #C4D0CD;

    --signal:      #0F766E;   /* 주 액션·강조 */
    --signal-700:  #0B5A54;
    --signal-100:  #D2E9E5;
    --signal-50:   #ECF5F4;

    --online:      #059669;   /* 하트비트 수신 중 */
    --online-50:   #E8F6F0;
    --command:     #B45309;   /* 제어 = 서버→장치 */
    --command-50:  #FBF0E2;
    --fault:       #B91C1C;
    --fault-50:    #FBEAEA;

    --panel-ink:   #0F1E1C;   /* 사이드바 */
    --panel-ink-2: #16302C;

    --radius:      10px;
    --radius-sm:   7px;
    --shadow-card: 0 1px 2px rgba(13,26,24,.05);
    --shadow-lift: 0 8px 28px -14px rgba(13,26,24,.35);

    --sans: 'ATOZ', system-ui, -apple-system, 'Malgun Gothic', sans-serif;
    --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    --sidebar-w: 244px;
    --sidebar-w-collapsed: 68px;
}

* { box-sizing: border-box; }

body {
    font-family: var(--sans);
    background: var(--canvas);
    color: var(--ink);
    margin: 0;
    -webkit-font-smoothing: antialiased;
}

/* 자릿수가 줄맞춤돼야 하는 곳에만 모노 */
.mono, .tnum { font-family: var(--mono); font-variant-numeric: tabular-nums; }

a { color: var(--signal-700); }

:focus-visible {
    outline: 2px solid var(--signal);
    outline-offset: 2px;
    border-radius: 4px;
}

/* =====================  레이아웃  ===================== */
.sidebar {
    width: var(--sidebar-w);
    background: var(--panel-ink);
    color: #C9D8D5;
    z-index: 40;
    transition: width .18s ease;
    border-right: 1px solid #0A1614;
}
.sidebar.collapsed { width: var(--sidebar-w-collapsed); }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .sidebar-footer-detail,
.sidebar.collapsed .nav-section { opacity: 0; pointer-events: none; }
.sidebar .border-gray-200 { border-color: #1D3A35 !important; }

.main-content {
    margin-left: var(--sidebar-w);
    transition: margin-left .18s ease;
}
/* app.js SidebarController가 붙이는 클래스명과 일치시킬 것 */
.main-content.sidebar-collapsed { margin-left: var(--sidebar-w-collapsed); }

.topbar {
    height: 54px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    position: sticky;
    top: 0;
    z-index: 20;
}

.breadcrumb { font-size: 13px; color: var(--ink-3); display: flex; align-items: center; gap: 7px; }
.breadcrumb a { color: var(--ink-3); text-decoration: none; }
.breadcrumb a:hover { color: var(--signal-700); }
.breadcrumb .sep { color: var(--line-2); }

/* 사이드바 섹션 라벨 — 대문자 트래킹 대신 조용한 한글 라벨 */
.nav-section {
    font-size: 11px;
    color: #5E7B76;
    padding: 0 20px;
    margin: 18px 0 6px;
    letter-spacing: 0;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 20px;
    color: #A8BEBA;
    text-decoration: none;
    font-size: 14px;
    font-weight: 400;
    border-left: 2px solid transparent;
    transition: background .12s ease, color .12s ease;
}
.nav-link svg { width: 18px; height: 18px; flex-shrink: 0; }
.nav-link:hover { background: var(--panel-ink-2); color: #E4EEEC; }
.nav-link.active {
    background: var(--panel-ink-2);
    color: #FFFFFF;
    border-left-color: var(--signal);
    font-weight: 500;
}
.nav-link.active svg { color: #2DD4BF; }

/* =====================  표면  ===================== */
/* 카드는 역할별로 다르게 — 전부 같은 라운드/그림자를 찍지 않는다 */
.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
}
.card-body { padding: 18px; }

.dashboard-panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

/* 하트비트 현황판 — 이 페이지에서 유일하게 강한 표면 */
.pulse-board {
    background: var(--panel-ink);
    color: #DCE9E7;
    border-radius: var(--radius);
    padding: 22px 24px;
    box-shadow: var(--shadow-lift);
}
.pulse-figure {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 46px;
    line-height: 1;
    font-weight: 600;
    color: #FFFFFF;
    letter-spacing: -.02em;
}
.pulse-total { color: #6E8F8A; font-size: 20px; font-weight: 400; }
.pulse-caption { color: #8AA8A3; font-size: 13px; }

/* 지표: 큰 숫자 나열 대신 얇은 행 */
.stat-card, .kpi-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 15px 17px;
}
.kpi-label { font-size: 12px; color: var(--ink-3); }
.kpi-value {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 26px;
    font-weight: 600;
    color: var(--ink);
    line-height: 1.15;
}

/* =====================  장치 타입 코드 칩  ===================== */
/* SiHAS는 장치를 3글자 코드로 부른다. 그 코드가 곧 아이콘이다. */
.type-code {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: var(--signal-50);
    border: 1px solid var(--signal-100);
    border-radius: 5px;
    padding: 3px 8px 3px 6px;
    white-space: nowrap;
    line-height: 1.35;
}
/* 코드는 식별자라 모노, 이름은 읽는 글자라 본문 서체 */
.type-code .code {
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--signal-700);
}
.type-code .name { font-size: 12px; color: var(--ink-2); }
/* 코드만 쓰는 경우(지도 마커 등)엔 폭을 맞춰 정렬되게 */
.type-code .code:only-child { min-width: 30px; text-align: center; }

.type-code.lg { padding: 5px 11px 5px 8px; }
.type-code.lg .code { font-size: 13px; }
.type-code.lg .name { font-size: 13px; }

.type-code.sensor { background: var(--command-50); border-color: #EBD8BC; }
.type-code.sensor .code { color: var(--command); }

/* =====================  상태  ===================== */
.status-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
    background: var(--line-2);
}
.status-dot.online { background: var(--online); box-shadow: 0 0 0 3px var(--online-50); }
.status-dot.offline { background: var(--ink-3); }
.status-dot.alarm { background: var(--fault); box-shadow: 0 0 0 3px var(--fault-50); }

/* 하트비트: 정보를 담은 유일한 자동 모션 */
.status-dot.online.beating { animation: beat 10s ease-out infinite; }
@keyframes beat {
    0%   { box-shadow: 0 0 0 0 rgba(5,150,105,.55); }
    12%  { box-shadow: 0 0 0 7px rgba(5,150,105,0); }
    100% { box-shadow: 0 0 0 0 rgba(5,150,105,0); }
}

.badge {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12px; font-weight: 500;
    padding: 3px 9px; border-radius: 999px;
    border: 1px solid transparent;
}
.badge-online  { background: var(--online-50); color: #046C4E; border-color: #BCE3D2; }
.badge-offline { background: var(--surface-3); color: var(--ink-2); border-color: var(--line-2); }
.badge-alarm   { background: var(--fault-50); color: var(--fault); border-color: #EFC9C9; }
.badge-warning { background: var(--command-50); color: var(--command); border-color: #EBD8BC; }
/* 상태가 아닌 분류(예: 권한)를 나타낼 때 — 빨강/노랑은 고장·경보에만 쓴다 */
.badge-signal  { background: var(--signal-50); color: var(--signal-700); border-color: var(--signal-100); }

.live-badge {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; color: var(--online); font-weight: 500;
}

/* 상태 막대 */
.status-bar { display: flex; height: 7px; border-radius: 999px; overflow: hidden; background: var(--surface-3); }
.status-bar-segment { height: 100%; }

/* =====================  버튼  ===================== */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    font-family: var(--sans); font-size: 14px; font-weight: 500;
    padding: 9px 16px; border-radius: var(--radius-sm);
    border: 1px solid transparent; cursor: pointer;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
    text-decoration: none; line-height: 1.2; white-space: nowrap;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--signal); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--signal-700); }
.btn-secondary { background: var(--surface); color: var(--ink-2); border-color: var(--line-2); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); }
.btn-danger { background: var(--fault); color: #fff; }
.btn-danger:hover:not(:disabled) { background: #9F1717; }
/* 제어(서버→장치)는 앰버로 일관 */
.btn-command { background: var(--command); color: #fff; }
.btn-command:hover:not(:disabled) { background: #94440A; }
/* 표 안의 파괴적 동작 — 꽉 찬 빨강은 과하므로 조용하게, 호버에서만 드러낸다 */
.btn-quiet-danger { background: var(--surface); color: var(--fault); border-color: var(--line-2); }
.btn-quiet-danger:hover:not(:disabled) { background: var(--fault-50); border-color: #EFC9C9; }
.btn-sm { font-size: 13px; padding: 6px 11px; }

/* =====================  폼  ===================== */
input[type="text"], input[type="password"], input[type="number"], input[type="email"], textarea {
    font-family: var(--sans); font-size: 14px;
    width: 100%; padding: 9px 12px;
    border: 1px solid var(--line-2); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink);
    transition: border-color .12s ease, box-shadow .12s ease;
}
/* select 는 폭을 강제하지 않는다. 필터 바에서는 내용만큼, 폼에서는 .w-full 로 늘린다
   (클래스가 요소 선택자를 이기므로 두 경우가 모두 맞게 동작한다). */
select {
    font-family: var(--sans); font-size: 14px;
    width: auto; max-width: 100%; padding: 9px 12px;
    border: 1px solid var(--line-2); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--ink);
    transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--signal);
    box-shadow: 0 0 0 3px var(--signal-50);
}
label { font-size: 13px; color: var(--ink-2); font-weight: 500; }

.filter-chip {
    font-size: 13px; padding: 6px 13px; border-radius: 999px;
    border: 1px solid var(--line-2); background: var(--surface);
    color: var(--ink-2); cursor: pointer; transition: all .12s ease;
}
.filter-chip:hover { border-color: var(--signal); color: var(--signal-700); }
.filter-chip.active { background: var(--signal); border-color: var(--signal); color: #fff; }

/* 토글 */
.toggle-switch { position: relative; display: inline-block; width: 42px; height: 24px; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
    position: absolute; inset: 0; cursor: pointer;
    background: var(--line-2); border-radius: 999px; transition: background .15s ease;
}
.toggle-slider:before {
    content: ""; position: absolute; height: 18px; width: 18px; left: 3px; bottom: 3px;
    background: #fff; border-radius: 50%; transition: transform .15s ease;
}
input:checked + .toggle-slider { background: var(--online); }
input:checked + .toggle-slider:before { transform: translateX(18px); }

/* =====================  테이블  ===================== */
.pro-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.pro-table thead th {
    text-align: left; font-size: 12px; font-weight: 500; color: var(--ink-3);
    padding: 10px 14px; background: var(--surface-2);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.pro-table tbody td { padding: 11px 14px; border-bottom: 1px solid var(--line); color: var(--ink-2); }
.pro-table tbody tr:last-child td { border-bottom: 0; }
.pro-table tbody tr:hover { background: var(--surface-2); }
.pro-table td.num, .pro-table th.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }

/* 레지스터 뷰어 — 이 제품의 원천 데이터 */
.reg-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
    gap: 6px;
}
.reg-cell {
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 7px;
    background: var(--surface);
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}
.reg-cell .idx { font-size: 10px; color: var(--ink-3); }
.reg-cell .val { font-size: 14px; color: var(--ink); font-weight: 500; }
.reg-cell.nonzero { border-color: var(--signal-100); background: var(--signal-50); }
.reg-cell.nonzero .val { color: var(--signal-700); }

/* =====================  장치 제어  ===================== */
.ctrl-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 18px; padding: 13px 0; border-bottom: 1px solid var(--line);
}
.ctrl-row:last-child { border-bottom: 0; }
.ctrl-label { font-size: 14px; color: var(--ink-2); display: flex; flex-direction: column; gap: 2px; }
.ctrl-hint { font-size: 11px; color: var(--ink-3); }
.ctrl-widget { flex-shrink: 0; }

/* 상태 겸 토글 */
.ctrl-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--sans); font-size: 14px; font-weight: 500;
    padding: 8px 16px; border-radius: var(--radius-sm);
    border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
    cursor: pointer; transition: all .12s ease;
}
.ctrl-toggle .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); }
.ctrl-toggle:hover { border-color: var(--signal); }
.ctrl-toggle.on { background: var(--signal); border-color: var(--signal); color: #fff; }
.ctrl-toggle.on .dot { background: #fff; }

/* 세그먼트 선택 */
.ctrl-seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: var(--radius-sm); overflow: hidden; }
.ctrl-seg button {
    font-family: var(--sans); font-size: 13px; padding: 7px 13px;
    background: var(--surface); color: var(--ink-2); border: 0;
    border-right: 1px solid var(--line); cursor: pointer; transition: all .12s ease;
}
.ctrl-seg button:last-child { border-right: 0; }
.ctrl-seg button:hover { background: var(--surface-2); color: var(--ink); }
.ctrl-seg button.active { background: var(--signal); color: #fff; }

/* 설정값 스테퍼 */
.ctrl-step { display: inline-flex; align-items: center; border: 1px solid var(--line-2); border-radius: var(--radius-sm); overflow: hidden; }
.ctrl-step button {
    width: 36px; height: 36px; border: 0; background: var(--surface);
    color: var(--ink-2); font-size: 17px; cursor: pointer; line-height: 1;
}
.ctrl-step button:hover { background: var(--surface-2); color: var(--signal-700); }
.ctrl-step .val {
    min-width: 78px; text-align: center; font-family: var(--mono);
    font-variant-numeric: tabular-nums; font-size: 15px; font-weight: 500; color: var(--ink);
    border-left: 1px solid var(--line); border-right: 1px solid var(--line); padding: 8px 4px;
}
.ctrl-step .val i { font-style: normal; font-size: 11px; color: var(--ink-3); margin-left: 2px; }

/* 슬라이더 */
.ctrl-slider { display: flex; align-items: center; gap: 12px; min-width: 210px; }
.ctrl-slider input[type=range] { flex: 1; accent-color: var(--signal); cursor: pointer; }
.ctrl-slider span { min-width: 46px; text-align: right; font-size: 13px; font-weight: 500; color: var(--signal-700); }

/* WAP 레지스터 직접 쓰기 */
.ctrl-wap { display: flex; gap: 7px; align-items: center; }
.ctrl-wap input { width: 92px; font-family: var(--mono); }

/* =====================  모달 / 토스트  ===================== */
.modal-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: rgba(13,26,24,.45);
    /* 카드를 화면 중앙에 세운다 */
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
}
/* 숨김은 Tailwind .hidden 으로 토글된다. 클래스 2개라 위 display:flex 를 확실히 이긴다. */
.modal-backdrop.hidden { display: none; }

.modal-card {
    background: var(--surface); border-radius: 12px;
    box-shadow: 0 24px 60px -20px rgba(13,26,24,.5);
    border: 1px solid var(--line);
    max-height: calc(100vh - 40px);
    overflow-y: auto;
}
.toast-item {
    background: var(--panel-ink); color: #E7F0EE;
    padding: 11px 16px; border-radius: var(--radius-sm);
    font-size: 14px; box-shadow: var(--shadow-lift);
    border-left: 3px solid var(--signal);
}
.toast-item.error { border-left-color: var(--fault); }
.toast-item.success { border-left-color: var(--online); }

/* =====================  로그인  ===================== */
.login-split { display: grid; grid-template-columns: 1fr; min-height: 100vh; }
@media (min-width: 1024px) { .login-split { grid-template-columns: 1.05fr .95fr; } }

.login-hero {
    position: relative; overflow: hidden;
    background: var(--panel-ink);
    color: #DCE9E7;
    display: none;
    padding: 56px;
    flex-direction: column;
    justify-content: center;
}
@media (min-width: 1024px) { .login-hero { display: flex; } }

.login-form-side {
    display: flex; align-items: center; justify-content: center;
    padding: 40px 28px; background: var(--surface);
}

/* =====================  상태 표시 유틸  ===================== */
.skeleton {
    background: linear-gradient(90deg, var(--surface-3) 25%, #EFF3F2 37%, var(--surface-3) 63%);
    background-size: 400% 100%;
    animation: shimmer 1.3s ease infinite;
    border-radius: 6px;
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.fade-in { animation: fadeIn .22s ease both; }
.slide-in { animation: slideIn .22s ease both; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* 빈 상태는 지시문이다 */
.empty-state { text-align: center; padding: 44px 20px; color: var(--ink-3); }
.empty-state h3 { color: var(--ink); font-size: 15px; font-weight: 600; margin: 0 0 6px; }
.empty-state p { font-size: 13px; margin: 0 0 16px; }

/* =====================  지도(네이버 지도)  ===================== */
.dashboard-layout { display: grid; gap: 16px; }
.dashboard-map { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); }
.map-legend {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-sm); padding: 10px 12px; font-size: 12px;
}

/* =====================  반응형  ===================== */
@media (max-width: 1023px) {
    .sidebar { transform: translateX(-100%); transition: transform .2s ease; }
    .sidebar.open { transform: none; }
    .main-content, .main-content.sidebar-collapsed { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
    .status-dot.online.beating { animation: none; }
}
