/* Inter di-vendor lokal (assets/fonts) — tanpa Google Fonts, tanpa internet.
   Inter v20 = font VARIABEL: satu berkas melayani seluruh bobot 100–900, jangan
   dipecah per bobot. Diletakkan di style.css (bukan tailwind.css) karena wallboard
   hanya memuat style.css. Regenerasi/unduh ulang: lihat CLAUDE.md. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('fonts/inter-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
        U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
        U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('fonts/inter-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
        U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
        U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Palet TUNGGAL untuk seluruh konsol. Nilai di sini WAJIB sama persis dengan
   theme.extend.colors di build/tailwind/tailwind.config.js — halaman yang sudah
   memakai Tailwind dan yang masih memakai style.css berdiri berdampingan, dan
   selisih warna sedikit saja langsung terlihat sebagai dua aplikasi berbeda.
   Tailwind tidak bisa membaca variable ini: modifier opasitas (bg-up/10) mati
   diam-diam pada nilai var(), jadi penyamaannya manual. */
:root {
    --bg: #0f172a;
    --bg-2: #1e293b;
    --panel: #1e293b;
    --panel-2: #334155;
    --border: #334155;
    --text: #f8fafc;
    --muted: #94a3b8;
    --accent: #3b82f6;
    --up: #10b981;
    --down: #ef4444;
    --warn: #f59e0b;
    --sec: #a98bff;              /* aksen domain keamanan */
    /* Triple RGB dari warna di atas — untuk rgb(var(--x-rgb) / alpha).
       Wajib ikut diubah kalau hex-nya berubah; keduanya harus menyebut warna
       yang sama, kalau tidak latar transparan akan menyimpang dari teksnya. */
    --accent-rgb: 59 130 246;
    --up-rgb: 16 185 129;
    --down-rgb: 239 68 68;
    --warn-rgb: 245 158 11;
    --sec-rgb: 169 139 255;
    --rail: 86px;               /* lebar rail navigasi */
    --sitbar: 50px;             /* tinggi situation bar */
    /* Inter di-vendor di assets/fonts (dimuat oleh tailwind.css). Bahnschrift &
       Segoe UI tinggal sebagai cadangan untuk wallboard bila berkas font gagal dimuat. */
    --font-display: "Inter", "Bahnschrift", "Segoe UI Semibold", system-ui, sans-serif;
    --font-body: "Inter", "Segoe UI", system-ui, sans-serif;
    --font-mono: "Cascadia Mono", Consolas, ui-monospace, monospace;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
    background: var(--bg);
    color: var(--text);
    font: 14px/1.5 var(--font-body);
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.topbar {
    display: flex; align-items: center; gap: 24px;
    background: var(--panel); border-bottom: 1px solid var(--border);
    padding: 10px 20px;
}
.brand { font-weight: 700; font-size: 16px; display: flex; align-items: center; gap: 7px; }
.brand-logo { height: 24px; width: auto; }
.login-logo { height: 64px; width: auto; }
.brand-sub { font-weight: 400; color: var(--muted); font-size: 12px; margin-left: 6px; }
.topbar nav { display: flex; gap: 16px; flex: 1; }
.topbar nav a { color: var(--text); }
.userbox { color: var(--muted); font-size: 13px; }

/* Hanya untuk <main> tanpa kelas. Layout utama (Tailwind) dan wallboard mengatur
   lebarnya sendiri; selektor elemen polos di sini pernah diam-diam mengunci konsol
   ke 1200px + margin 20px, mengalahkan max-w-[1400px] di markup. */
main:not([class]) { max-width: 1200px; margin: 20px auto; padding: 0 16px; }

.stat-row { display: flex; gap: 14px; margin-bottom: 18px; }
.stat {
    background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
    border-top: 3px solid var(--border);
    padding: 12px 22px 14px; min-width: 120px; text-align: center;
}
.stat-num { font-size: 28px; font-weight: 700; }
.stat-up { border-top-color: var(--up); }
.stat-warn { border-top-color: var(--warn); }
.stat-down { border-top-color: var(--down); }
.stat-up .stat-num { color: var(--up); }
.stat-warn .stat-num { color: var(--warn); }
.stat-down .stat-num { color: var(--down); }
.stat-paused .stat-num { color: var(--muted); }
.stat-alert { background: rgb(var(--down-rgb) / .14); border-color: var(--down); }
.stat-label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }

/* Komponen bersama 16 view yang belum dikonversi. Disegarkan mengikuti bahasa
   visual dashboard Tailwind (radius 12px, judul font-display, tabel berpadding
   lebih lega) — satu suntingan di sini menyentuh seluruh halaman lama sekaligus,
   jauh lebih murah dan aman daripada menulis ulang markup-nya satu per satu. */
.panel {
    background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
    padding: 18px 20px; margin-bottom: 24px;
    box-shadow: 0 1px 2px rgb(0 0 0 / .35);
}
.panel-narrow { max-width: 560px; }
.panel h2 {
    font-family: var(--font-display); font-size: 15px; font-weight: 700;
    margin-bottom: 14px; display: flex; align-items: center; gap: 8px;
}
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 20px; }
.page-head h1, .page-head h2 {
    margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 700;
    letter-spacing: -.01em;
}

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 11px 12px; border-bottom: 1px solid var(--border); }
th {
    color: var(--muted); font-size: 10px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .1em;
}
tr:last-child td { border-bottom: none; }
tbody tr:hover td { background: rgb(var(--accent-rgb) / .05); }
.row-down td { background: rgb(var(--down-rgb) / .08); }
.row-warn td { background: rgb(var(--warn-rgb) / .07); }
.mono { font-family: Consolas, monospace; font-size: 13px; }
.nowrap { white-space: nowrap; }
.muted { color: var(--muted); }

.badge {
    display: inline-block; padding: 2px 9px; border-radius: 999px;
    font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.badge-up { background: rgb(var(--up-rgb) / .15); color: var(--up); }
.badge-warn { background: rgb(var(--warn-rgb) / .18); color: var(--warn); }
.badge-down { background: rgb(var(--down-rgb) / .2); color: var(--down); }
.badge-unknown { background: var(--panel-2); color: var(--muted); }

.sev { font-size: 11px; font-weight: 700; text-transform: uppercase; }
.sev-info { color: var(--accent); }
.sev-warning { color: var(--warn); }
.sev-critical { color: var(--down); }

.btn {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--accent); color: #06111f;
    border: 1px solid transparent; border-radius: 8px; padding: 7px 14px;
    font: inherit; font-weight: 600; cursor: pointer;
    transition: filter .15s, border-color .15s, background .15s;
}
.btn:hover { filter: brightness(1.1); text-decoration: none; }
.btn-sm { padding: 5px 11px; font-size: 12px; border-radius: 7px; }
.btn-ghost {
    background: transparent; border-color: var(--border);
    color: var(--text); font-weight: 500;
}
.btn-ghost:hover { border-color: var(--accent); background: var(--panel-2); filter: none; }
.btn-danger { background: rgb(var(--down-rgb) / .85); color: #fff; }
.inline { display: inline; }

.form label { display: block; margin-bottom: 12px; color: var(--muted); font-size: 13px; }
.form input[type=text], .form input[type=password], .form input[type=number], .form select {
    display: block; width: 100%; margin-top: 4px;
    background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 7px; padding: 8px 10px; font: inherit;
}
.form input:focus, .form select:focus { outline: none; border-color: var(--accent); }
.form fieldset { border: 1px solid var(--border); border-radius: 8px; padding: 12px; margin-bottom: 12px; }
.form legend { color: var(--muted); font-size: 12px; padding: 0 6px; }
.form .check { display: flex; align-items: center; gap: 8px; color: var(--text); }
.form-actions { display: flex; gap: 10px; margin-top: 14px; }

.alert {
    background: rgb(var(--down-rgb) / .12); border: 1px solid rgb(var(--down-rgb) / .4);
    color: #ff9d92; border-radius: 8px; padding: 10px 14px; margin-bottom: 14px;
}
.alert-ok { background: rgb(var(--up-rgb) / .1); border-color: rgb(var(--up-rgb) / .4); color: #7ee2a8; }
/* Pipeline berhenti: lebih keras daripada .alert biasa — semua angka di
   halaman ini sedang berbohong, bukan sekadar satu bagian yang bermasalah. */
.alert-basi {
    background: rgb(var(--down-rgb) / .22); border-width: 2px;
    color: #ffc9c2; font-size: 15px;
}
.alert-basi b { color: #fff; }

/* Kesegaran feed intel di Konsol Keamanan. "kosong" (tak pernah diunduh) sengaja
   lebih keras daripada "basi": aturan deteksinya tak pernah menyala sama sekali. */
.feed-status { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.feed-item {
    font-size: 12px; padding: 4px 10px; border-radius: 999px;
    border: 1px solid var(--border); color: var(--muted); background: var(--panel-2);
}
.feed-item b { color: var(--text); font-weight: 600; }
.feed-segar { border-color: rgb(var(--up-rgb) / .35); }
.feed-basi { border-color: rgb(var(--warn-rgb) / .5); background: rgb(var(--warn-rgb) / .1); color: var(--warn); }
.feed-kosong { border-color: rgb(var(--down-rgb) / .5); background: rgb(var(--down-rgb) / .12); color: #ff9d92; }
/* Tabelnya berisi tapi waktu unduhnya belum pernah dicatat — bukan masalah,
   cuma belum diketahui. Jangan diberi warna alarm. */
.feed-takcatat { border-style: dashed; }

/* Sinyal SOC di tampilan NOC (papan status & diagram topologi). Sengaja
   penanda kecil, BUKAN mengubah warna tile: warna tile berarti kesehatan
   operasional, dan mesin yang UP tapi punya temuan kritis harus tetap
   terbaca UP. Kedua hal itu jawaban atas pertanyaan yang berbeda. */
.temuan-tanda, .nd-tmn {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 16px; height: 16px; padding: 0 4px; flex: none;
    border-radius: 999px; font-size: 10px; font-weight: 700; line-height: 1;
    background: rgb(var(--warn-rgb) / .9); color: #1c1917; text-decoration: none;
}
.temuan-kritis, .nd-tmn-kritis { background: rgb(var(--down-rgb) / .95); color: #fff; }
.nd-tmn { margin-left: 6px; }
.nd-tmn:hover { filter: brightness(1.15); }
/* Kebalikan .wk-dev: dari daftar PERANGKAT menuju baris workstation-nya. */
.dev-wk {
    font-size: 11px; margin-left: 6px; color: var(--muted);
    border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px;
    text-decoration: none; white-space: nowrap;
}
.dev-wk:hover { color: var(--text); border-color: var(--accent); }

.kv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }

.chart-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 16px; }
.chart-box { background: var(--panel-2); border-radius: 8px; padding: 10px 12px; }
.chart-box h3 { font-size: 12px; color: var(--muted); margin-bottom: 6px; font-weight: 600; }
.chart { width: 100%; height: 180px; cursor: crosshair; }
.chart-lg { height: 220px; }

/* Legenda tabel di bawah grafik: min/rata/maks/terakhir per seri */
.chart-stats { margin-top: 6px; }
.chart-stats table { width: 100%; border-collapse: collapse; font-size: 11px; }
.chart-stats th {
    color: var(--muted); font-weight: 600; text-align: right;
    padding: 2px 0 3px; border-bottom: 1px solid var(--border);
}
.chart-stats th:first-child { text-align: left; }
.chart-stats td { text-align: right; padding: 3px 0; font-variant-numeric: tabular-nums; }
.chart-stats td:first-child { text-align: left; color: var(--muted); }
.chart-stats i {
    display: inline-block; width: 8px; height: 8px; border-radius: 2px;
    margin-right: 6px; vertical-align: baseline;
}
.chart-stats .stat-pk { color: var(--text); font-weight: 600; }
.range-picker { display: flex; gap: 6px; }

/* ---- Workstation & Top Talkers ---- */
.searchbox {
    background: var(--bg-2); color: var(--text);
    border: 1px solid var(--border); border-radius: 8px;
    padding: 7px 12px; font: inherit; width: 260px;
}
.searchbox::placeholder { color: var(--muted); }
.searchbox:focus { outline: none; border-color: var(--accent); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 999px; padding: 5px 14px; color: var(--muted); font-size: 12.5px;
    font-family: inherit; font-weight: 500; cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
.chip:hover { color: var(--text); }
.chip b { color: var(--accent); margin-left: 4px; }
.chip b.chip-up { color: var(--up); }
.chip:hover { text-decoration: none; border-color: var(--accent); }
.chip-active { border-color: var(--accent); background: rgb(var(--accent-rgb) / .12); }
.chip-static { cursor: default; }

.cat {
    display: inline-block; padding: 1px 9px; border-radius: 10px;
    font-size: 11px; font-weight: 600;
}
.cat-workstation { background: rgb(var(--accent-rgb) / .15); color: var(--accent); }
.cat-server { background: rgb(var(--up-rgb) / .15); color: var(--up); }
.cat-cctv { background: rgba(155, 89, 182, .18); color: #c39bd3; }
.cat-lainnya { background: var(--panel-2); color: var(--muted); }

/* Leaderboard Top Talkers */
.lb { display: flex; flex-direction: column; gap: 8px; }
.lb-card {
    display: flex; gap: 14px; align-items: center;
    background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
    padding: 10px 16px; color: var(--text);
}
a.lb-card:hover { text-decoration: none; border-color: var(--accent); }
.lb-rank { font-size: 22px; font-weight: 700; color: var(--muted); min-width: 34px; text-align: center; }
.lb-body { flex: 1; min-width: 0; }
.lb-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.lb-name { font-weight: 700; font-size: 14px; }
.lb-total { margin-left: auto; font-size: 16px; font-weight: 700; }
.lb-bar { background: var(--bg); border-radius: 3px; height: 9px; margin: 6px 0 5px; overflow: hidden; }
.lb-fill { height: 100%; border-radius: 3px; background: var(--accent); }
.lb-server { background: var(--up); }
.lb-cctv { background: #9b59b6; }
.lb-lainnya { background: var(--muted); }
.lb-meta { display: flex; gap: 16px; font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.lb-live { color: var(--up); font-weight: 600; }

.minibar { background: var(--bg); border-radius: 2px; height: 6px; margin-bottom: 4px; overflow: hidden; }
.minibar div { background: var(--accent); height: 100%; }

/* Grid kartu workstation */
.wk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.wk-card {
    display: block; background: var(--panel); border: 1px solid var(--border);
    border-left: 3px solid var(--border); border-radius: 8px;
    padding: 9px 12px; color: var(--text); font-size: 13px;
}
.wk-card:hover { text-decoration: none; border-color: var(--accent); }
.wkb-workstation { border-left-color: var(--accent); }
.wkb-server { border-left-color: var(--up); }
.wkb-cctv { border-left-color: #9b59b6; }
.wkb-lainnya { border-left-color: var(--muted); }
.wk-off { opacity: .6; }
.wk-top { display: flex; align-items: center; gap: 7px; min-width: 0; }
.wk-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); flex: none; }
.wk-dot.wk-on { background: var(--up); }
.wk-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wk-ip { font-size: 12px; color: var(--muted); margin: 2px 0 5px; }
.wk-mid { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-bottom: 6px; }
.wk-traffic { font-size: 11px; margin-top: 3px; }

table.sortable th[data-sort] { cursor: pointer; user-select: none; white-space: nowrap; }
table.sortable th[data-sort]:hover { color: var(--text); }
th.sort-desc::after { content: ' ▼'; font-size: 9px; }
th.sort-asc::after { content: ' ▲'; font-size: 9px; }

.row-extra { display: none; }
.table-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; }
.wk-foot { display: flex; justify-content: center; margin: 8px 0 4px; }

/* ---- Dashboard: papan status ---- */
.dash-bar { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.refresh-ind { color: var(--up); font-size: 12px; }
.refresh-ind #refresh-ago { color: var(--muted); }
.refresh-ind.stale { color: var(--down); }
.refresh-ind.stale::after { content: ' — gagal memperbarui'; color: var(--down); }

.banner-ok {
    background: rgb(var(--up-rgb) / .12); border: 1px solid rgb(var(--up-rgb) / .45);
    color: var(--up); border-radius: 10px; padding: 14px 18px; margin-bottom: 18px;
    font-size: 16px; font-weight: 700; text-align: center;
}
.panel-alarm { border-color: rgb(var(--down-rgb) / .55); }
.panel-alarm h2 { color: var(--down); }

.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.tile {
    display: block; background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 8px; padding: 9px 12px 10px; color: var(--text); min-height: 84px;
}
.tile:hover { text-decoration: none; border-color: var(--accent); }
.tile-top {
    display: flex; justify-content: space-between; gap: 8px;
    font-size: 10px; font-weight: 700; letter-spacing: .6px; opacity: .85;
}
.tile-name { font-weight: 700; font-size: 14px; margin: 3px 0 1px; }
.tile-host { font-size: 11px; opacity: .75; }
.tile-note {
    font-size: 11px; margin-top: 5px; opacity: .9;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.spark { display: block; width: 100%; height: 26px; margin-top: 4px; color: var(--accent); }

.tile-up .tile-top { color: var(--up); }
.tile-down {
    background: #b03427; border-color: var(--down); color: #fff;
    animation: pulse-down 2.2s ease-out infinite;
}
.tile-warn { background: #a36a0a; border-color: var(--warn); color: #fff; }
.tile-warn .spark { color: #fff; }
.tile-down:hover, .tile-warn:hover { border-color: #fff; }
.tile-unknown { color: var(--muted); }
.tile-paused { opacity: .55; border-style: dashed; }

@keyframes pulse-down {
    0% { box-shadow: 0 0 0 0 rgb(var(--down-rgb) / .55); }
    70% { box-shadow: 0 0 0 8px rgb(var(--down-rgb) / 0); }
    100% { box-shadow: 0 0 0 0 rgb(var(--down-rgb) / 0); }
}
@media (prefers-reduced-motion: reduce) {
    .tile-down { animation: none; }
}

/* ---- Peta jaringan (diagram kotak + garis sambung) ---- */
.topo-wrap { overflow-x: auto; }
.topo { min-width: 980px; }
.topo-title { text-align: center; font-size: 17px; margin-bottom: 16px; }
.topo-svg { display: block; margin: 0 auto; width: 100%; height: auto; }
/* Panel yang butuh lebih lebar dari kolom 1200px — melebar ke tepi layar */
.full-bleed {
    position: relative; left: 50%; transform: translateX(-50%);
    width: min(1720px, calc(100vw - 40px));
}
.tiles-group {
    color: var(--muted); font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .6px; margin: 14px 0 8px;
}
.panel h2 + .tiles-group, .tiles-group:first-child { margin-top: 0; }
.topo-center { display: flex; justify-content: center; }
.topo-drop { width: 1px; height: 22px; background: var(--border); margin: 0 auto; }

/* Bus bercabang gaya bagan: garis atas + tetes vertikal per cabang */
ul.obranch { list-style: none; display: flex; margin: 0; padding: 0; align-items: flex-start; }
ul.obranch > li { position: relative; flex: 1; min-width: 230px; padding: 26px 7px 0; }
ul.obranch > li::before {
    content: ''; position: absolute; top: 0; right: 50%; width: 50%; height: 26px;
    border-top: 1px solid var(--border);
}
ul.obranch > li::after {
    content: ''; position: absolute; top: 0; left: 50%; width: 50%; height: 26px;
    border-top: 1px solid var(--border); border-left: 1px solid var(--border);
}
ul.obranch > li:first-child::before { border-top: none; }
ul.obranch > li:last-child::after { border-top: none; }
.branch-link {
    position: absolute; top: 3px; left: calc(50% + 7px);
    font-size: 9px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
    color: var(--muted); background: var(--panel); border: 1px solid var(--border);
    border-radius: 8px; padding: 0 7px; white-space: nowrap; z-index: 1;
}
.link-fiber { color: var(--warn); border-color: var(--warn); }

.branch { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.branch-head { font-weight: 700; font-size: 13px; margin-bottom: 8px; }

/* Pohon dalam cabang: garis vertikal + tik horizontal ke tiap kotak simpul */
ul.tree { list-style: none; margin: 0; padding-left: 0; }
ul.tree ul.tree { padding-left: 18px; margin-left: 8px; border-left: 1px solid var(--border); }
ul.tree ul.tree > li { position: relative; }
ul.tree ul.tree > li::before {
    content: ''; position: absolute; left: -18px; top: 15px; width: 14px;
    border-top: 1px solid var(--border);
}
.nd {
    display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
    background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 6px; padding: 4px 9px; margin: 4px 0; font-size: 13px;
}
.nd a { color: var(--text); }
.nd-root { display: inline-flex; padding: 8px 18px; font-weight: 700; font-size: 14px; }
.nd-struktur { background: var(--panel); border-style: dashed; }
.nd-dot {
    width: 9px; height: 9px; border-radius: 50%; flex: none; align-self: center;
    background: var(--border);
}
.nd-ket { color: var(--muted); font-size: 11px; }
.nd-up .nd-dot { background: var(--up); }
.nd-warn .nd-dot { background: var(--warn); }
.nd-down .nd-dot { background: var(--down); }
.nd-unknown .nd-dot, .nd-paused .nd-dot { background: var(--muted); }
.nd-up { border-color: rgb(var(--up-rgb) / .4); }
.nd-warn { background: rgb(var(--warn-rgb) / .12); border-color: var(--warn); }
.nd-down { background: rgb(var(--down-rgb) / .16); border-color: var(--down); }
.nd-down a { color: #ff9d92; font-weight: 700; }
.nd-paused { opacity: .55; }
.nd-hilang .nd-dot { background: transparent; border: 1px dashed var(--muted); }

/* Simpul switch akses: tak punya telemetri, jadi titiknya menandai PEMETAAN
   (ada PC terpeta yang terlihat di ARP), bukan kesehatan switch-nya. */
.nd-sw { border-style: solid; background: var(--bg-2); }
.nd-sw-aktif .nd-dot { background: var(--up); }
.nd-sw-sepi .nd-dot { background: var(--muted); }
.nd-sw-kosong { border-color: rgb(var(--warn-rgb) / .45); }
.nd-sw-kosong .nd-dot { background: transparent; border: 1px dashed var(--warn); }
.nd-sw-hilang { border-color: rgb(var(--warn-rgb) / .45); border-style: dashed; }
.nd-sw-hilang .nd-dot { background: transparent; border: 1px dashed var(--warn); }
.nd-sw-kosong .nd-ket, .nd-sw-hilang .nd-ket { color: var(--warn); }
.nd-swc {
    font-family: var(--font-display); font-size: 12px; font-weight: 700;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 20px; padding: 1px 9px; color: var(--muted);
}
.nd-swc-on b { color: var(--up); }
.swt-pc-lain { color: var(--accent); }

.login-body {
    display: flex; align-items: center; justify-content: center;
    min-height: 100vh; background: var(--bg); color: var(--text);
    font: 14px/1.5 var(--font-body);
}
.login-wrap { width: 360px; max-width: calc(100vw - 32px); }
.login-card {
    background: var(--panel); border: 1px solid var(--border); border-radius: 14px;
    padding: 30px 32px;
}
.login-brand { text-align: center; margin-bottom: 22px; }
.login-brand .login-logo { display: block; margin: 0 auto 12px; }
.login-card h1 { font-family: var(--font-display); font-size: 30px; font-weight: 700; letter-spacing: 1px; margin-bottom: 4px; }
.login-brand .login-tag { color: var(--text); font-size: 13.5px; font-weight: 600; margin-bottom: 2px; }
.login-brand .login-sub { color: var(--muted); font-size: 10.5px; letter-spacing: 1.2px; text-transform: uppercase; margin-bottom: 0; }
.login-card p { margin-bottom: 18px; }
.login-copy { text-align: center; color: var(--muted); font-size: 12px; margin-top: 16px; letter-spacing: .3px; }
.login-card label { display: block; margin-bottom: 12px; color: var(--muted); font-size: 13px; }
.login-card input {
    display: block; width: 100%; margin-top: 4px;
    background: var(--bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 7px; padding: 9px 11px; font: inherit;
}
.login-card button {
    width: 100%; margin-top: 8px; background: var(--accent); color: #0b1220;
    border: none; border-radius: 7px; padding: 10px; font: inherit; font-weight: 700; cursor: pointer;
}

@media (max-width: 640px) {
    .topbar { flex-wrap: wrap; gap: 10px; }
    .stat-row { flex-wrap: wrap; }
    .chart-grid { grid-template-columns: 1fr; }
    th, td { padding: 6px; font-size: 13px; }
}

/* =========================================================
   Shell aplikasi — Konsol Mission-Control (rail + situation bar)
   ========================================================= */
h1, h2, h3, .stat-num, .stat-label, .tiles-group {
    font-family: var(--font-display);
}
.mono { font-family: var(--font-mono); }

body.app {
    display: grid;
    grid-template-columns: var(--rail) 1fr;
    grid-template-rows: var(--sitbar) 1fr;
    grid-template-areas: "brand situation" "rail canvas";
    height: 100vh;
    height: 100dvh; /* mobile: 100vh tertutup address bar browser */
    overflow: hidden;
}

/* pojok kiri-atas: mark logo di atas rail */
.brand-cell {
    grid-area: brand;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg-2); border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.brand-cell .brand-logo { height: 46px; width: auto; }

/* situation bar — selalu tampil, ringkas status keseluruhan */
.situation {
    grid-area: situation;
    display: flex; align-items: center; gap: 16px;
    background: var(--bg-2); border-bottom: 1px solid var(--border);
    padding: 0 18px; overflow-x: auto; white-space: nowrap;
}
.situation::-webkit-scrollbar { height: 0; }
.sit-brand { display: inline-flex; flex-direction: column; line-height: 1.05; color: var(--text); }
.sit-brand:hover { text-decoration: none; }
.sit-brand b { font-family: var(--font-display); font-size: 17px; font-weight: 700; letter-spacing: .5px; }
.sit-brand small { font-size: 10px; color: var(--muted); letter-spacing: .8px; text-transform: uppercase; }
.tally { display: inline-flex; align-items: center; gap: 8px; }
.tally b {
    font-family: var(--font-display); font-size: 15px; font-weight: 700;
    letter-spacing: 1.5px;
}
.tally-lamp { width: 11px; height: 11px; border-radius: 50%; background: var(--muted); flex: none; }
.tally-aman  .tally-lamp { background: var(--up);   box-shadow: 0 0 8px var(--up); }
.tally-aman  b { color: var(--up); }
.tally-waspada .tally-lamp { background: var(--warn); box-shadow: 0 0 8px var(--warn); }
.tally-waspada b { color: var(--warn); }
.tally-kritis .tally-lamp { background: var(--down); box-shadow: 0 0 11px var(--down); animation: pulse-down 1.6s ease-out infinite; }
.tally-kritis b { color: var(--down); }

.sit-sep { width: 1px; height: 24px; background: var(--border); flex: none; }
.sit-item { display: inline-flex; align-items: baseline; gap: 7px; color: var(--text); }
.sit-k { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .6px; }
.sit-v { font-family: var(--font-display); font-size: 17px; font-weight: 700; }
.sit-slash { color: var(--muted); font-size: 13px; font-weight: 400; }
a.sit-link:hover { text-decoration: none; }
a.sit-link:hover .sit-v { color: var(--accent); }
.sit-bad .sit-v { color: var(--down); }
.sit-warn .sit-v { color: var(--warn); }
.sit-search {
    margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
    background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
    color: var(--muted); padding: 5px 10px; font: inherit; font-size: 12px; cursor: pointer;
}
.sit-search svg { width: 14px; height: 14px; }
.sit-search:hover { color: var(--text); border-color: var(--accent); }
.sit-search-k { font-family: var(--font-mono); font-size: 10.5px; border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; }
.sit-clock {
    font-family: var(--font-mono); font-size: 14px;
    color: var(--muted); letter-spacing: 1px;
}
.sit-user { color: var(--muted); font-size: 12px; }

/* rail navigasi — ikon + label, gaya activity-bar aplikasi desktop */
.rail {
    grid-area: rail;
    display: flex; flex-direction: column; gap: 2px;
    background: var(--bg-2); border-right: 1px solid var(--border);
    padding: 8px 6px; overflow-y: auto;
    scrollbar-width: none; /* jendela pendek (webview PWA): tetap bisa digulir, tanpa scrollbar */
}
.rail::-webkit-scrollbar { width: 0; height: 0; }
.rail-item {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 10px 4px 8px; border-radius: 9px; color: var(--muted);
    font-size: 10.5px; letter-spacing: .3px; text-align: center;
    border: 1px solid transparent; position: relative;
}
.rail-install { margin-top: auto; color: var(--up); border-style: dashed; border-color: var(--border); background: none; cursor: pointer; font: inherit; font-size: 10.5px; }
.rail-install:hover { color: var(--up); border-color: var(--up); background: rgb(var(--up-rgb) / .08); }
.rail-badge {
    position: absolute; top: 4px; right: 8px;
    background: var(--down); color: #fff; font-size: 9.5px; font-weight: 700;
    border-radius: 14px; padding: 1px 5px; min-width: 16px; line-height: 1.4;
}
.rail-item svg { width: 22px; height: 22px; }
.rail-item:hover { color: var(--text); background: var(--panel); text-decoration: none; }
.rail-on { color: var(--accent); background: rgb(var(--accent-rgb) / .1); border-color: rgb(var(--accent-rgb) / .28); }
.rail-on:hover { color: var(--accent); background: rgb(var(--accent-rgb) / .14); }

/* kanvas utama — mengisi penuh, scroll sendiri */
.canvas {
    grid-area: canvas;
    max-width: none; margin: 0; padding: 20px 24px 40px;
    overflow-y: auto;
}
.app .full-bleed { position: static; left: auto; transform: none; width: 100%; }

.page-title { font-size: 22px; font-weight: 700; letter-spacing: .5px; }
.head-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.back-link { display: inline-block; color: var(--muted); font-size: 12.5px; margin-bottom: 6px; }
.back-link:hover { color: var(--accent); text-decoration: none; }
.empty-note { padding: 18px 4px; text-align: center; }

/* toast umpan balik aksi — muncul sebentar di kanan-bawah */
.toast {
    position: fixed; right: 22px; bottom: 22px; z-index: 50;
    background: var(--panel-2); border: 1px solid rgb(var(--up-rgb) / .5);
    border-left: 3px solid var(--up); color: var(--text);
    border-radius: 10px; padding: 11px 18px; font-size: 13.5px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .45); cursor: pointer;
    animation: toast-in .25s ease-out;
    max-width: min(420px, calc(100vw - 44px));
}
.toast-hide { opacity: 0; transform: translateY(8px); transition: opacity .6s, transform .6s; }
@keyframes toast-in {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; }
}
.page-sub {
    font-size: 11px; font-weight: 700; letter-spacing: 2px; color: var(--sec);
    border: 1px solid var(--sec); border-radius: 5px; padding: 1px 7px; vertical-align: 3px; margin-left: 6px;
}
.page-title + * { margin-top: 0; }

/* =========================================================
   Navigasi mobile — tab bar bawah + bottom-sheet "Menu"
   (dirender selalu, tampil hanya di layar sempit)
   ========================================================= */
.tabbar { display: none; }
.tab-item {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    min-height: 50px; padding: 7px 2px 5px; justify-content: center;
    color: var(--muted); font-size: 10px; letter-spacing: .3px;
    background: none; border: none; border-radius: 10px; position: relative;
    font-family: inherit; cursor: pointer;
}
.tab-item svg { width: 23px; height: 23px; }
.tab-item:hover { text-decoration: none; color: var(--text); }
.tab-on { color: var(--accent); }
.tab-badge {
    position: absolute; top: 3px; left: calc(50% + 5px);
    background: var(--down); color: #fff; font-size: 9.5px; font-weight: 700;
    border-radius: 14px; padding: 1px 5px; min-width: 16px; line-height: 1.4; text-align: center;
}

.sheet[hidden] { display: none; }
.sheet {
    position: fixed; inset: 0; z-index: 85;
    background: rgba(5, 8, 14, .6); backdrop-filter: blur(2px);
    display: flex; align-items: flex-end;
}
.sheet-box {
    width: 100%; background: var(--panel);
    border: 1px solid var(--border); border-bottom: none;
    border-radius: 16px 16px 0 0;
    padding: 8px 14px calc(14px + env(safe-area-inset-bottom));
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .5);
    animation: sheet-in .22s ease-out;
}
@keyframes sheet-in {
    from { transform: translateY(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .sheet-box { animation: none; }
}
.sheet-grip {
    width: 38px; height: 4px; border-radius: 3px; background: var(--border);
    margin: 2px auto 12px;
}
.sheet-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.sheet-item {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
    min-height: 62px; padding: 8px 4px; border-radius: 11px;
    background: var(--bg-2); border: 1px solid var(--border);
    color: var(--text); font-size: 11px; font-family: inherit; cursor: pointer; text-align: center;
}
.sheet-item svg { width: 22px; height: 22px; color: var(--muted); }
.sheet-item:hover { text-decoration: none; border-color: var(--accent); }
.sheet-item.tab-on { border-color: rgb(var(--accent-rgb) / .4); color: var(--accent); }
.sheet-item.tab-on svg { color: var(--accent); }
.sheet-install { color: var(--up); border-style: dashed; }
.sheet-install svg { color: var(--up); }
.sheet-user {
    display: flex; justify-content: space-between; align-items: center;
    border-top: 1px solid var(--border); margin-top: 12px; padding: 12px 4px 0;
    font-size: 13px;
}

@media (max-width: 760px) {
    body.app {
        grid-template-columns: 1fr;
        grid-template-rows: var(--sitbar) 1fr;
        grid-template-areas: "situation" "canvas";
    }
    .brand-cell, .rail { display: none; }
    .tabbar {
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
        display: flex; gap: 2px;
        background: var(--bg-2); border-top: 1px solid var(--border);
        padding: 4px max(6px, env(safe-area-inset-right)) calc(4px + env(safe-area-inset-bottom)) max(6px, env(safe-area-inset-left));
    }
    .canvas { padding: 14px 12px calc(78px + env(safe-area-inset-bottom)); }

    /* situation bar ringkas: tally + Down/Warn/Ancaman + cari — brand,
       Perangkat, dan Hygiene sudah terwakili di judul halaman & kartu Ringkasan */
    .sit-user, .sit-clock, .sit-search-k, .sit-brand, .sit-sep, .sit-opt { display: none; }
    .situation { gap: 14px; padding: 0 12px 0 max(12px, env(safe-area-inset-left)); }
    .sit-search { margin-left: auto; padding: 7px 9px; }

    /* kartu statistik: grid rapat, bukan baris melebar */
    .stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
    .stat { min-width: 0; padding: 10px 8px 12px; }
    .stat-num { font-size: 24px; }

    /* papan status & kartu workstation: 2 kolom di layar HP */
    .tiles { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); gap: 8px; }
    .wk-grid { grid-template-columns: repeat(auto-fill, minmax(156px, 1fr)); }

    /* input 16px agar iOS tidak auto-zoom saat fokus */
    .searchbox, .form input[type=text], .form input[type=password], .form input[type=number],
    .form select, .pal-box input, .ins-note-form textarea, .login-card input { font-size: 16px; }

    /* tabel lebar: scroll di dalam panel, bukan melebarkan halaman */
    .panel { overflow-x: auto; }
    .panel table { min-width: 460px; }

    /* kepala halaman & alat: turun ke bawah, kotak cari melebar penuh */
    .page-head { flex-wrap: wrap; gap: 10px; }
    .head-tools { width: 100%; }
    .head-tools .searchbox, .page-head > .searchbox { flex: 1 1 160px; width: auto; min-width: 0; }
    .range-picker { flex-wrap: wrap; }
    .chips { gap: 6px; }
    .chip { padding: 7px 13px; font-size: 12.5px; }

    /* kartu temuan: aksi menumpuk rapi, sentuh nyaman */
    .finding { flex-direction: column; gap: 7px; }
    .fnd-sev { align-self: flex-start; }
    .btn { padding: 9px 16px; }
    .btn-sm { padding: 7px 13px; }

    .kv-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
    .pal { padding-top: max(14px, env(safe-area-inset-top)); }
    .pal-list { max-height: 40vh; }
    .pal-jenis { min-width: 0; }
    .pal-sub { display: none; }
    .lb-card { padding: 9px 12px; gap: 10px; }
    .lb-rank { font-size: 17px; min-width: 24px; }
    .toast { right: 12px; left: 12px; max-width: none; bottom: calc(72px + env(safe-area-inset-bottom)); }
}

/* =========================================================
   Konsol Keamanan (SOC)
   ========================================================= */
.empty-soc {
    max-width: 560px; margin: 60px auto; text-align: center; color: var(--muted);
}
.empty-soc svg { color: var(--sec); margin-bottom: 12px; }
.empty-soc h2 { color: var(--text); margin-bottom: 8px; }

.soc-hero {
    display: flex; align-items: center; gap: 26px;
    background: linear-gradient(120deg, var(--panel), var(--bg-2));
    border: 1px solid var(--border); border-radius: 14px;
    padding: 20px 26px; margin-bottom: 18px;
}
.postur-aman  { border-color: rgb(var(--up-rgb) / .4);  --gauge-c: var(--up); }
.postur-waspada { border-color: rgb(var(--warn-rgb) / .45); --gauge-c: var(--warn); }
.postur-kritis { border-color: rgb(var(--down-rgb) / .5);   --gauge-c: var(--down); }

.gauge {
    width: 118px; height: 118px; border-radius: 50%; flex: none;
    background: conic-gradient(var(--gauge-c) calc(var(--v) * 1%), var(--panel-2) 0);
    display: flex; align-items: center; justify-content: center;
}
.gauge-hole {
    width: 88px; height: 88px; border-radius: 50%; background: var(--bg-2);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.gauge-num { font-family: var(--font-display); font-size: 38px; font-weight: 700; line-height: 1; color: var(--gauge-c); }
.gauge-cap { font-size: 10px; text-transform: uppercase; letter-spacing: 1.5px; color: var(--muted); margin-top: 3px; }

.hero-body { flex: 1; min-width: 0; }
.hero-postur { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.hero-word { font-family: var(--font-display); font-size: 30px; font-weight: 700; letter-spacing: 2px; }
.postur-aman  .hero-word { color: var(--up); }
.postur-waspada .hero-word { color: var(--warn); }
.postur-kritis .hero-word { color: var(--down); }
.hero-line { font-size: 15px; margin-bottom: 4px; }
.hero-line b { font-family: var(--font-display); font-size: 18px; }
.hero-meta { font-size: 12px; }
.hero-act { margin-top: 10px; }
.ref-wait { font-size: 12.5px; color: var(--warn); font-weight: 600; }

.soc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.soc-grid .panel-span { grid-column: 1 / -1; }
.h2-note { font-family: var(--font-body); font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 8px; letter-spacing: 0; }

/* daftar temuan */
.findings { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.finding { display: flex; gap: 12px; background: var(--bg-2); border: 1px solid var(--border); border-left-width: 3px; border-radius: 9px; padding: 11px 14px; }
.fnd-critical { border-left-color: var(--down); }
.fnd-warning  { border-left-color: var(--warn); }
.fnd-info     { border-left-color: var(--accent); }
.fnd-sev {
    font-family: var(--font-display); font-size: 10px; font-weight: 700; letter-spacing: 1px;
    padding: 3px 8px; border-radius: 5px; height: fit-content; white-space: nowrap;
}
.fnd-critical .fnd-sev { background: rgb(var(--down-rgb) / .16); color: var(--down); }
.fnd-warning  .fnd-sev { background: rgb(var(--warn-rgb) / .16); color: var(--warn); }
.fnd-info     .fnd-sev { background: rgb(var(--accent-rgb) / .14); color: var(--accent); }
.fnd-title { font-weight: 700; font-size: 14px; margin-bottom: 2px; }
.fnd-detail { font-size: 12.5px; margin-bottom: 6px; }
.fnd-fix { font-size: 12.5px; }
.fnd-fix-k { color: var(--up); font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; margin-right: 4px; }

.nf-rule {
    font-family: var(--font-display); font-size: 10px; font-weight: 700;
    letter-spacing: 1px; color: var(--sec); border: 1px solid var(--sec);
    border-radius: 4px; padding: 1px 7px; margin-right: 6px; vertical-align: 1px;
}
.fnd-title a { font-size: 12px; font-weight: 400; }

/* Chip identitas: IP yang dikenali inventaris tampil sebagai NAMA bertaut ke
   halaman entitasnya. 85% temuan tak punya MAC, jadi tanpa ini kartunya buntu
   dan petugas harus mencocokkan IP sendiri. */
.inv-chip {
    display: inline-block; font-size: 11.5px; font-weight: 600; line-height: 1.5;
    border-radius: 5px; padding: 0 7px; vertical-align: 1px; margin-right: 4px;
    border: 1px solid var(--border); color: var(--text); text-decoration: none;
}
a.inv-chip:hover { border-color: var(--accent); color: var(--accent); }
.inv-perangkat { border-color: rgb(var(--accent-rgb) / .5); color: var(--accent); }
.inv-workstation { border-color: rgb(var(--sec-rgb) / .5); color: var(--sec); }
.inv-arah { color: var(--muted); font-size: 12px; margin-right: 4px; }
/* penanda "baris ini juga ada di daftar Perangkat" pada kartu workstation */
.wk-dev {
    font-size: 10px; font-weight: 700; letter-spacing: .4px; border-radius: 4px;
    padding: 1px 6px; border: 1px solid var(--border); color: var(--muted);
}
/* nama layanan untuk nomor port — port manajemen ditandai lebih keras */
.svc-nama { font-size: 12px; color: var(--muted); }
.svc-mgmt {
    font-size: 11px; font-weight: 700; border-radius: 4px; padding: 1px 6px;
    background: rgb(var(--warn-rgb) / .16); color: var(--warn);
}

/* Layanan publik yang bermuara di host ini — panel NOC yang membawa kabar SOC */
.panel-ekspos { border-left: 3px solid var(--warn); }
.ekspos-list { list-style: none; margin: 0; padding: 0; }
.ekspos {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
    padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px;
}
.ekspos:last-child { border-bottom: 0; }
.ekspos-port {
    font-size: 11.5px; font-weight: 700; border-radius: 4px; padding: 1px 7px;
    background: rgb(var(--warn-rgb) / .16); color: var(--warn);
}
.ekspos.r-hi .ekspos-port { background: rgb(var(--down-rgb) / .16); color: var(--down); }
.ekspos.r-op .ekspos-port { background: rgb(var(--up-rgb) / .14); color: var(--up); }
.ekspos-nama { font-weight: 600; }
/* router asal aturan — hanya muncul untuk router SELAIN gateway */
.ekspos-router, .srf-router a {
    font-size: 11px; border: 1px solid var(--border); border-radius: 20px;
    padding: 1px 8px; color: var(--muted); text-decoration: none;
}
.ekspos-router:hover, .srf-router a:hover { color: var(--text); border-color: var(--accent); }
.srf-router { font-size: 11px; margin-top: 4px; }
.srf-inv { margin-top: 6px; }

/* Pemilih router di Konsol Keamanan — tiap router punya snapshot hygiene sendiri */
.router-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.router-tabs .chip b { margin-left: 6px; }

/* Keadaan port router tempat switch menggantung. BUKAN kesehatan switch —
   switch unmanaged tak punya telemetri; yang diukur portnya, bukan switch-nya. */
.nd-up {
    font-family: var(--font-mono); font-size: 10px; font-weight: 700;
    border-radius: 4px; padding: 0 5px; margin-left: 6px;
    background: rgb(var(--up-rgb) / .14); color: var(--up);
}
.nd-up-mati { background: rgb(var(--down-rgb) / .18); color: var(--down); }
.sw-up { color: var(--up); font-weight: 600; }
.sw-up-mati { color: var(--down); font-weight: 700; }
.sw-up-entah { color: var(--muted); }

/* Pemetaan PC massal — tanpa ini kolom switch_id tinggal 0 dari 913 terisi */
.sw-bulk {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    padding: 9px 12px; margin-bottom: 12px; border-radius: 8px;
    background: var(--panel-2); border: 1px solid var(--border); font-size: 13px;
}
.sw-bulk-n b { color: var(--accent); }
.sw-bulk-msg { color: var(--muted); font-size: 12px; }
.map-pick { margin-right: 2px; }

/* =========================================================
   Laporan Mingguan (ramah cetak) & Wallboard TV
   ========================================================= */
.lap-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.lap-bar {
    display: inline-block; width: 110px; height: 9px; vertical-align: 2px;
    background: var(--bg); border-radius: 3px; overflow: hidden; margin-right: 8px;
}
.lap-bar span { display: block; height: 100%; border-radius: 3px; }
.lap-ok  { background: var(--up); }
.lap-mid { background: var(--warn); }
.lap-low { background: var(--down); }
.lap-foot { text-align: center; font-size: 11.5px; margin-top: 6px; }
@media (max-width: 900px) { .lap-grid { grid-template-columns: 1fr; } }

/* ---------- Laporan berkop ---------- */
.lap-kop {
    display: flex; align-items: center; gap: 16px;
    padding-bottom: 12px; margin-bottom: 4px;
    border-bottom: 3px double var(--border);
}
.lap-kop-logo { width: 54px; height: 54px; flex: none; object-fit: contain; }
.lap-kop-teks { display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
.lap-kop-teks b { font-family: var(--font-display); font-size: 18px; letter-spacing: .3px; }
.lap-kop-teks span { font-size: 13px; color: var(--text); }
.lap-kop-teks small { font-size: 11.5px; color: var(--muted); }
.lap-kop-sistem {
    margin-left: auto; text-align: right; display: flex; flex-direction: column;
    line-height: 1.35; flex: none;
}
.lap-kop-sistem b { font-family: var(--font-display); font-size: 14px; }
.lap-kop-sistem small { font-size: 10.5px; color: var(--muted); letter-spacing: .6px; }

.lap-judul { text-align: center; margin: 14px 0 6px; }
.lap-judul h1 {
    font-family: var(--font-display); font-size: 19px; letter-spacing: .4px;
    text-transform: uppercase; margin: 0;
}
.lap-jenis {
    font-family: var(--font-display); font-size: 14px; font-weight: 700;
    letter-spacing: 2px; text-transform: uppercase; margin-top: 4px;
}
.lap-periode { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.lap-tools { display: flex; gap: 10px; align-items: center; margin: 12px 0 16px; flex-wrap: wrap; }
.lap-tools select { padding: 5px 8px; }

.lap-sec { margin-bottom: 16px; }
.lap-sec h2 { display: flex; align-items: baseline; gap: 8px; }
.lap-no {
    font-family: var(--font-display); font-size: 12px; letter-spacing: 1px;
    color: var(--accent); border: 1px solid var(--border); border-radius: 4px;
    padding: 1px 7px; flex: none;
}
.lap-h3 { font-size: 13px; margin: 18px 0 4px; font-weight: 700; }
.lap-narasi { font-size: 13.5px; line-height: 1.65; margin-bottom: 10px; text-align: justify; }
.lap-catatan {
    font-size: 12px; line-height: 1.6; margin-top: 12px; padding: 9px 12px;
    border-left: 3px solid var(--warn); background: rgb(var(--warn-rgb) / .08);
}
.lap-catatan-berat { border-left-color: var(--down); background: rgb(var(--down-rgb) / .1); }
.lap-num { text-align: right; }
.lap-angka td:first-child { width: 42%; }

.lap-delta { font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.lap-delta-baik { color: var(--up); }
.lap-delta-buruk { color: var(--down); }
.lap-delta-rata { color: var(--muted); }

.lap-kpi { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 6px; }
.lap-kpi-item {
    flex: 1 1 150px; border: 1px solid var(--border); border-radius: 8px;
    padding: 10px 12px; background: var(--panel-2);
}
.lap-kpi-angka { display: block; font-family: var(--font-display); font-size: 24px; font-weight: 700; }
.lap-kpi-angka small { font-size: 13px; color: var(--muted); font-weight: 400; }
.lap-kpi-label { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }
.lap-skor-aman { color: var(--up); }
.lap-skor-waspada { color: var(--warn); }
.lap-skor-kritis { color: var(--down); }

.lap-rekom-list { margin: 0; padding-left: 22px; }
.lap-rekom-list li { margin-bottom: 10px; font-size: 13.5px; line-height: 1.6; }
.lap-rekom-list .sev { margin-right: 6px; }

@media print {
    /* !important wajib: layout baru memakai utility class (.flex/.h-screen/.overflow-hidden)
       yang spesifisitasnya mengalahkan selektor elemen `body` polos. */
    body, body.app {
        background: #fff !important; color: #111;
        display: block !important; height: auto !important; overflow: visible !important;
    }
    .rail, .situation, .brand-cell, .no-print, .toast, .pal, .tabbar, .sheet { display: none !important; }
    .canvas { overflow: visible; padding: 0; }
    /* <main> layout baru: kelasnya Tailwind, jadi tak tertangkap .canvas di atas.
       background WAJIB dipaksa: tanpa itu <main> tetap biru gelap dan seluruh
       halaman tercetak di atas blok tinta gelap. */
    main { overflow: visible !important; padding: 0 !important; height: auto !important;
           background: #fff !important; }
    .panel { background: #fff; border-color: #ccc; break-inside: avoid; }
    /* tautan yang ditambahkan supaya laporan di LAYAR tidak buntu tak boleh
       terbawa ke kertas sebagai teks biru bergaris — di kertas ia sekadar nama */
    .panel h2, .page-title, td, th, .muted, a { color: #111 !important; }
    a { text-decoration: none !important; }
    .h2-note, .sev, .mono { color: #444 !important; }
    .lap-bar { background: #eee; border: 1px solid #ccc; }
    .lap-grid { display: block; }
    .lap-grid .panel { margin-bottom: 14px; }

    /* --- Laporan di kertas --- */
    @page { size: A4 portrait; margin: 14mm 13mm; }

    /* Reset warna MENYELURUH untuk laporan, bukan daftar selektor.
       Aturan cetak lama hanya menyebut `.panel h2, .page-title, td, th, .muted, a`
       — cukup selama halaman ini isinya tabel saja. Begitu laporan berisi
       PROSA (narasi ringkasan, catatan, butir rekomendasi), semua elemen yang
       tak masuk daftar itu tetap berwarna teks tema #f8fafc: putih di atas
       kertas putih. Terukur 2026-08-12: seluruh isi bagian Kesimpulan &
       Rekomendasi tercetak tak terbaca, tanpa satu pun error. */
    .lap-kop, .lap-kop *, .lap-judul, .lap-judul *,
    .lap-sec, .lap-sec *, .lap-foot { color: #111 !important; }
    .lap-sec .muted, .lap-sec .h2-note, .lap-kpi-label,
    .lap-kop-teks small, .lap-kop-sistem small, .lap-periode { color: #444 !important; }

    .lap-kop { border-bottom-color: #111; }
    .lap-no { border-color: #888; }
    /* Panel laporan tak boleh terpotong di tengah halaman; seksi panjang
       (ketersediaan 30+ baris) tetap boleh mengalir supaya tak menyisakan
       halaman kosong sepertiga. */
    .lap-sec { break-inside: auto; page-break-inside: auto; }
    .lap-sec h2 { break-after: avoid; page-break-after: avoid; }
    .lap-kpi-item { border-color: #bbb; background: #fafafa; }
    .lap-kpi-angka, .lap-kpi-label { color: #111 !important; }
    .lap-catatan { background: #f4f4f4; border-left-color: #888; }
    .lap-delta-baik, .lap-delta-buruk, .lap-delta-rata { color: #111 !important; }
    /* Severity di kertas: hitam-putih, dibedakan bingkai — printer kantor
       umumnya mono, warna saja tak membedakan apa pun di sana. */
    .sev { border: 1px solid #666; background: #fff !important; color: #111 !important; }
    .sev-critical { border-width: 2px; font-weight: 700; }
    thead th { border-bottom: 1px solid #111; }
    tr { break-inside: avoid; page-break-inside: avoid; }
}

body.wallboard {
    background: var(--bg); color: var(--text);
    font: 15px/1.5 var(--font-body);
    height: 100vh; height: 100dvh; overflow: hidden;
    display: flex; flex-direction: column;
}
.wb-head {
    display: flex; align-items: center; gap: 20px;
    background: var(--bg-2); border-bottom: 1px solid var(--border);
    padding: 10px 26px;
}
.wb-logo { height: 42px; }
.wb-brand { display: flex; flex-direction: column; line-height: 1.1; }
.wb-brand b { font-family: var(--font-display); font-size: 21px; letter-spacing: .5px; }
.wb-brand small { font-size: 10.5px; color: var(--muted); letter-spacing: 1px; text-transform: uppercase; }
.wb-head .tally b { font-size: 21px; }
.wb-head .tally-lamp { width: 15px; height: 15px; }
.wb-head .refresh-ind { margin-left: auto; }
.wb-head .sit-clock { margin-left: 0; font-size: 26px; color: var(--text); }
.wb-fs {
    background: none; border: 1px solid var(--border); border-radius: 7px;
    color: var(--muted); font-size: 16px; padding: 3px 10px; cursor: pointer;
}
.wb-fs:hover { color: var(--text); border-color: var(--accent); }
/* Kanvas wallboard = SATU layar TV, tanpa scroll; grid: strip atas,
   Papan Status kiri (inti), Masalah + Kejadian kolom kanan */
.wb-canvas {
    flex: 1; overflow: hidden; padding: 16px 22px 18px; min-height: 0;
    max-width: none; margin: 0; /* lepas dari aturan main{max-width:1200px} */
}
.wallboard .live-region, .wb-grid { height: 100%; }
.wb-grid {
    display: grid; gap: 14px; min-height: 0;
    grid-template-columns: minmax(0, 1fr) 400px;
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "strip strip" "tiles side";
}
.wb-strip { grid-area: strip; display: grid; grid-template-columns: 1.3fr 1fr 1fr 1.4fr; gap: 14px; }
.wb-strip .noc-big { font-size: 34px; }
.wb-strip .noc-wan { font-size: 14px; }
.wb-nums { display: flex; gap: 18px; align-items: baseline; flex-wrap: wrap; padding-top: 2px; }
.wb-num { font-size: 13px; color: var(--muted); }
.wb-num b { font-family: var(--font-display); font-size: 32px; font-weight: 700; margin-right: 4px; }
.wbn-up b { color: var(--up); }
.wbn-warn b { color: var(--warn); }
.wbn-down b { color: var(--down); }
.wbn-off b { color: var(--muted); }

.wb-tiles { grid-area: tiles; overflow: hidden; margin-bottom: 0; min-height: 0; }
.wallboard .tiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 7px; }
.wallboard .tiles-group { margin: 10px 0 6px; }
.wallboard .panel h2 + .tiles-group, .wallboard .tiles-group:first-child { margin-top: 0; }
.wallboard .tile { min-height: 62px; padding: 6px 10px 8px; }
.wallboard .tile-name { font-size: 13.5px; margin: 2px 0 0; }
.wallboard .tile-top { font-size: 9px; }
.wallboard .spark { height: 18px; margin-top: 3px; }
/* Pemadat otomatis (app.js): isi > 1 layar -> wb-dense (tanpa spark),
   masih lebih -> wb-denser (nama saja, tile mungil) */
.wb-tiles.wb-dense .spark { display: none; }
.wb-tiles.wb-dense .tiles { grid-template-columns: repeat(auto-fill, minmax(126px, 1fr)); gap: 6px; }
.wb-tiles.wb-dense .tile { min-height: 44px; }
.wb-tiles.wb-dense .tile-name { font-size: 12px; }
.wb-tiles.wb-denser .tiles { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 5px; }
.wb-tiles.wb-denser .tile { min-height: 34px; padding: 4px 8px 5px; }
.wb-tiles.wb-denser .tile-top { display: none; }

.wb-side { grid-area: side; display: flex; flex-direction: column; gap: 14px; min-height: 0; }
.wb-masalah { flex: 1; overflow: hidden; margin-bottom: 0; min-height: 0; }
.wb-masalah h2 { font-size: 18px; }
.wb-events { flex: none; margin-bottom: 0; }
.wb-events h2 { font-size: 14px; color: var(--muted); }
.wb-aman {
    height: 100%; display: flex; align-items: center; justify-content: center;
    text-align: center; color: var(--up); font-family: var(--font-display);
    font-size: 26px; font-weight: 700; line-height: 1.5;
}
.wb-plist { list-style: none; display: flex; flex-direction: column; gap: 7px; }
.wbp {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg-2); border: 1px solid var(--border); border-left-width: 3px;
    border-radius: 8px; padding: 7px 12px;
}
.wbp-down { border-left-color: var(--down); background: rgb(var(--down-rgb) / .1); }
.wbp-warn { border-left-color: var(--warn); background: rgb(var(--warn-rgb) / .08); }
.wbp-name { font-weight: 700; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wbp-ago { margin-left: auto; color: var(--muted); font-size: 12.5px; flex: none; }
.wbp-more { color: var(--down); font-weight: 700; font-size: 13px; margin-top: 8px; text-align: center; }
.wb-elist { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.wb-elist li { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; min-width: 0; }
.wbe-ts { color: var(--muted); flex: none; font-size: 11.5px; }
.wbe-dot { font-size: 9px; flex: none; }
.wbe-msg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* palet pencarian global (Ctrl+K) */
/* [hidden] bawaan browser KALAH oleh display:flex di bawah — wajib ditegaskan */
.pal[hidden] { display: none; }
.pal {
    position: fixed; inset: 0; z-index: 90;
    background: rgba(5, 8, 14, .72); backdrop-filter: blur(2px);
    display: flex; justify-content: center; align-items: flex-start;
    padding: 12vh 12px 0;
}
.pal-box {
    width: min(580px, 100%); background: var(--panel);
    border: 1px solid var(--border); border-radius: 13px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .5); overflow: hidden;
}
.pal-box input {
    width: 100%; background: var(--bg-2); color: var(--text);
    border: none; border-bottom: 1px solid var(--border);
    padding: 14px 16px; font: inherit; font-size: 15px;
}
.pal-box input:focus { outline: none; }
.pal-list { list-style: none; max-height: 46vh; overflow-y: auto; }
.pal-item {
    display: flex; align-items: baseline; gap: 9px;
    padding: 9px 14px; cursor: pointer; border-bottom: 1px solid var(--bg-2);
}
.pal-item:hover, .pal-item.pal-on { background: rgb(var(--accent-rgb) / .1); }
.pal-jenis {
    font-family: var(--font-display); font-size: 9.5px; font-weight: 700;
    letter-spacing: .8px; text-transform: uppercase; color: var(--muted);
    border: 1px solid var(--border); border-radius: 4px; padding: 1px 6px;
    flex: none; min-width: 74px; text-align: center;
}
.pal-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; align-self: center; }
.pal-dot.pal-up { background: var(--up); }
.pal-dot.pal-warn { background: var(--warn); }
.pal-dot.pal-down { background: var(--down); }
.pal-label { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-sub { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: auto; flex: none; max-width: 45%; }
.pal-kosong { padding: 14px 16px; color: var(--muted); font-size: 13px; }
.pal-hint { font-size: 11px; padding: 7px 14px; border-top: 1px solid var(--bg-2); }

/* timeline investigasi per host */
.tl { list-style: none; margin-left: 4px; }
.tl-item { display: flex; gap: 12px; position: relative; padding-bottom: 13px; }
.tl-item::before {
    content: ''; position: absolute; left: 4px; top: 14px; bottom: -2px;
    width: 1px; background: var(--border);
}
.tl-item:last-child::before { display: none; }
.tl-dot {
    width: 9px; height: 9px; border-radius: 50%; background: var(--muted);
    flex: none; margin-top: 5px; z-index: 1;
}
.tl-temuan .tl-dot { background: var(--sec); }
.tl-sev-critical .tl-dot { background: var(--down); box-shadow: 0 0 6px var(--down); }
.tl-sev-warning .tl-dot { background: var(--warn); }
.tl-ip .tl-dot { background: var(--accent); }
.tl-audit .tl-dot { background: var(--accent); }
.tl-meta { font-size: 11px; color: var(--muted); margin-bottom: 1px; }
.tl-tag {
    font-family: var(--font-display); font-size: 9px; font-weight: 700;
    letter-spacing: .8px; border: 1px solid var(--border); border-radius: 4px;
    padding: 0 5px; margin-left: 6px; vertical-align: 1px;
}
.tl-teks { font-size: 13px; }
.tl-sev-critical .tl-teks { color: #ff9d92; }

/* halaman Insiden — siklus hidup temuan */
.ins-status {
    font-family: var(--font-display); font-size: 10px; font-weight: 700;
    letter-spacing: 1px; border-radius: 4px; padding: 1px 7px; vertical-align: 1px;
}
.ins-open     { background: rgb(var(--down-rgb) / .16);  color: var(--down); }
.ins-ack      { background: rgb(var(--warn-rgb) / .16); color: var(--warn); }
.ins-resolved { background: rgb(var(--up-rgb) / .14); color: var(--up); }
.fnd-done { opacity: .6; }
.ins-cat {
    font-size: 12.5px; background: var(--panel); border: 1px dashed var(--border);
    border-radius: 7px; padding: 6px 10px; margin-top: 6px;
}
.ins-act { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; margin-top: 9px; }
.ins-note summary { list-style: none; cursor: pointer; }
.ins-note summary::-webkit-details-marker { display: none; }
.ins-note-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; min-width: min(340px, 100%); }
.ins-note-form textarea {
    background: var(--bg); color: var(--text); border: 1px solid var(--border);
    border-radius: 7px; padding: 8px 10px; font: inherit; font-size: 13px; resize: vertical;
}
.ins-note-form textarea:focus { outline: none; border-color: var(--accent); }
.ins-note-form .btn { align-self: flex-start; }
.table-wrap { overflow-x: auto; }

/* ---- Ringkasan insiden per jenis ---- */
.ins-sum td, .ins-sum th { padding: 5px 10px; }
.ins-sum .num { text-align: right; font-variant-numeric: tabular-nums; }
.ins-sum tr.ins-sum-on td { background: rgb(var(--accent-rgb) / .08); }
.ins-sum a { text-decoration: none; }
.ins-sum .sev-c { color: var(--down); font-weight: 600; }
.ins-count { margin: -6px 0 10px; }

/* Rekap deteksi di halaman Keamanan: pil per jenis, angka = masih hidup/total */
.nf-rekap { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.nf-pil {
    display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
    padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
    background: rgba(130, 145, 173, .06); font-size: 11px;
}
.nf-pil:hover { border-color: var(--accent); }
.nf-pil b { color: var(--muted); font-variant-numeric: tabular-nums; }
.nf-pil-on b { color: var(--accent); }
.nf-rekap-ket { margin: -4px 0 10px; font-size: 11px; }

/* tekanan serangan (blacklist bars) */
.pressure { list-style: none; display: flex; flex-direction: column; gap: 11px; }
.pr-top { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; margin-bottom: 4px; }
.pr-top b { font-family: var(--font-display); font-size: 16px; color: var(--down); }
.pr-bar { background: var(--bg); border-radius: 3px; height: 8px; overflow: hidden; }
.pr-bar div { height: 100%; background: linear-gradient(90deg, #c0392b, var(--down)); border-radius: 3px; }
.pr-foot { font-size: 11.5px; margin-top: 12px; }

/* permukaan serangan (kartu layanan ter-ekspos) */
.surface { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.srf { background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px; }
.srf-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; }
.srf-tag { font-family: var(--font-display); font-size: 9.5px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase; padding: 2px 7px; border-radius: 20px; }
.srf-port { font-size: 12px; color: var(--muted); }
.srf-name { font-weight: 700; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.srf-flow { font-size: 11px; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.r-hi  { border-color: rgb(var(--down-rgb) / .5); background: rgb(var(--down-rgb) / .08); }
.r-hi  .srf-tag { background: rgb(var(--down-rgb) / .18); color: var(--down); }
.r-mid .srf-tag { background: rgb(var(--warn-rgb) / .16); color: var(--warn); }
.r-op  .srf-tag { background: rgb(var(--up-rgb) / .15); color: var(--up); }

/* bidang manajemen */
.mgmt { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.mg { display: flex; justify-content: space-between; align-items: center; padding: 7px 11px; border-radius: 7px; background: var(--bg-2); border: 1px solid var(--border); }
.mg-name { font-size: 13px; }
.mg-port { color: var(--muted); }
.mg-state { font-family: var(--font-display); font-size: 10.5px; font-weight: 700; letter-spacing: .8px; padding: 2px 9px; border-radius: 5px; }
.mg-state-open { background: rgb(var(--down-rgb) / .18); color: var(--down); }
.mg-state-safe { background: rgb(var(--up-rgb) / .14); color: var(--up); }
.mg-open { border-color: rgb(var(--down-rgb) / .4); }

@media (max-width: 760px) {
    .soc-hero { flex-direction: column; text-align: center; }
    .soc-grid { grid-template-columns: 1fr; }
}

/* judul halaman seragam */
.page-head h2 { font-size: 21px; font-weight: 700; letter-spacing: .5px; }
.page-sub-noc { color: var(--accent); border-color: var(--accent); }

/* =========================================================
   Ringkasan / NOC — strip konteks jaringan
   ========================================================= */
.noc-strip { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.noc-card {
    background: var(--panel); border: 1px solid var(--border); border-radius: 11px;
    padding: 13px 16px; color: var(--text);
}
a.noc-card:hover { text-decoration: none; border-color: var(--accent); }
.noc-cap { font-family: var(--font-display); font-size: 10.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.noc-big { font-family: var(--font-display); font-size: 30px; font-weight: 700; line-height: 1; }
.noc-slash { font-size: 15px; color: var(--muted); font-weight: 400; }
.noc-sub { font-size: 12px; color: var(--muted); margin-top: 3px; }
.noc-air { color: var(--up); font-weight: 700; }

.noc-wan { display: flex; align-items: center; gap: 9px; padding: 4px 0; font-size: 13px; }
.wan-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--muted); }
.wan-main .wan-dot { background: var(--up); box-shadow: 0 0 7px var(--up); }
.wan-bak  .wan-dot { background: var(--warn); }
.wan-off  .wan-dot { background: var(--muted); }
.wan-role { font-family: var(--font-display); font-weight: 700; letter-spacing: .5px; min-width: 74px; }
.wan-off .wan-role, .wan-off .wan-ip { opacity: .5; }
.wan-if { margin-left: auto; font-size: 12px; }

.noc-sec .noc-big { color: var(--muted); }
.noc-postur-aman .noc-big { color: var(--up); }
.noc-postur-waspada .noc-big { color: var(--warn); }
.noc-postur-kritis .noc-big { color: var(--down); }

@media (max-width: 900px) { .noc-strip { grid-template-columns: 1fr 1fr; } .noc-uplink { grid-column: 1 / -1; } }
@media (max-width: 560px) { .noc-strip { grid-template-columns: 1fr; } }

/* =========================================================
   Layanan Publik
   ========================================================= */
.lyn-sum {
    display: flex; align-items: center; gap: 26px; flex-wrap: wrap;
    background: linear-gradient(120deg, var(--panel), var(--bg-2));
    border: 1px solid var(--border); border-radius: 12px; padding: 16px 22px; margin-bottom: 18px;
}
.lyn-stat { text-align: center; }
.lyn-n { font-family: var(--font-display); font-size: 30px; font-weight: 700; line-height: 1; }
.lyn-k { font-size: 11px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); margin-top: 3px; }
.lyn-air { color: var(--up); }
.lyn-file { color: var(--accent); }
.lyn-hi { color: var(--down); }
.lyn-src { margin-left: auto; font-size: 12px; }

.lyn-head { display: flex; align-items: center; gap: 10px; padding-left: 12px; border-left: 3px solid var(--border); }
.lyn-count { font-family: var(--font-mono); font-size: 12px; color: var(--muted); border: 1px solid var(--border); border-radius: 20px; padding: 1px 9px; }
.lyn-ket { font-size: 12px; margin: -6px 0 12px 15px; }
.g-air  { border-left-color: var(--up); }
.g-file { border-left-color: var(--accent); }
.g-rdp  { border-left-color: var(--down); }
.g-etc  { border-left-color: var(--muted); }

/* =========================================================
   Peta Switch (pemetaan PC -> switch)
   ========================================================= */
.sw-note { margin: -6px 0 14px; font-size: 12.5px; }
.sw-on { color: var(--up); }

.sw-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.sw-item { display: flex; align-items: center; gap: 14px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 9px; padding: 9px 14px; }
.sw-main { display: flex; align-items: baseline; gap: 10px; min-width: 210px; }
.sw-name { font-weight: 700; font-size: 14px; }
.sw-loc { font-size: 12px; color: var(--accent); }
.sw-meta { font-size: 12px; flex: 1; }
.sw-act { display: flex; gap: 6px; }
.sw-topo { color: var(--accent); }
.sw-topo-lepas { color: var(--warn); border-bottom: 1px dotted rgb(var(--warn-rgb) / .5); cursor: help; }
/* baris yang dituju dari tautan #sw-<id> di diagram topologi */
.sw-item:target { border-color: var(--accent); box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / .18); }

.sw-form { border-top: 1px dashed var(--border); padding-top: 14px; }
.sw-form-row { display: flex; gap: 12px; flex-wrap: wrap; }
.sw-form-row label { flex: 1; min-width: 150px; margin-bottom: 0; }
.sw-form-row .sw-ports { flex: 0 0 80px; min-width: 80px; }

.sw-tools { display: flex; align-items: center; gap: 16px; margin-bottom: 14px; flex-wrap: wrap; }
.sw-only { display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: 13px; }

.map-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 7px; margin-bottom: 8px; }
.map-row { display: flex; align-items: center; gap: 9px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 7px; padding: 6px 10px; }
.map-unmapped { border-color: rgb(var(--warn-rgb) / .4); background: rgb(var(--warn-rgb) / .06); }
.map-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; }
.map-dot.map-on { background: var(--up); }
.map-name { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.map-ip { font-size: 12px; flex: none; }
.map-sel { background: var(--panel); color: var(--text); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; font-size: 12px; max-width: 150px; }
.map-sel:focus { outline: none; border-color: var(--accent); }
.map-sel.map-ok { border-color: var(--up); }
.map-sel.map-err { border-color: var(--down); }

/* panel Switch Akses di Topologi */
.swtopo { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.swt-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.swt-head { display: flex; align-items: center; gap: 10px; }
.swt-ico { font-size: 18px; color: var(--accent); }
.swt-id { flex: 1; min-width: 0; }
.swt-name { font-weight: 700; font-size: 14px; }
.swt-loc { font-size: 11.5px; }
.swt-count { font-family: var(--font-display); font-size: 15px; font-weight: 700; }
.swt-up { font-size: 11px; margin: 4px 0 0; }
.swt-pcs { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.swt-pc { display: inline-flex; align-items: center; gap: 5px; background: var(--panel); border: 1px solid var(--border); border-radius: 20px; padding: 2px 10px 2px 8px; font-size: 12px; color: var(--text); }
.swt-pc:hover { text-decoration: none; border-color: var(--accent); }
.pc-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); }
.pc-on .pc-dot { background: var(--up); }
.pc-off { opacity: .62; }
.swt-empty { font-size: 12px; margin-top: 8px; }
.sw-hint { font-size: 12.5px; margin: 0 0 8px; }

/* Pelindung global: [hidden] SELALU menang atas display apa pun di atas —
   akar bug palet Ctrl+K terbuka permanen (v2.1.1); jangan dihapus. */
[hidden] { display: none !important; }
