:root {
  --bg: #f4f6fa; --surface: #ffffff; --surface2: #f0f3f9; --border: #e3e8f0;
  --text: #0f1729; --muted: #667085; --accent: #3b6df6; --accent-soft: #e8eefe;
  --ok: #12a46b; --warn: #d98a05; --bad: #e0443a; --off: #98a2b3;
  --shadow: 0 1px 2px rgba(16,24,40,.05), 0 4px 14px rgba(16,24,40,.04);
  --grid: #e9edf4;
}
:root[data-theme="dark"] {
  --bg: #0f172a; --surface: #1b2540; --surface2: #222e4d; --border: #2b3858;
  --text: #e6eaf2; --muted: #94a3c0; --accent: #2f8fe8; --accent-soft: #15304f;
  --ok: #34d399; --warn: #fbbf24; --bad: #f87171; --off: #5b667a;
  --shadow: none; --grid: #26324f;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text);
  font: 14px/1.5 "Pretendard", "Segoe UI", "Malgun Gothic", system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }

.top { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 14px;
  height: 56px; padding: 0 24px; background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; letter-spacing: -.01em; }
.logo { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px; color: #fff;
  background: linear-gradient(135deg, #3b6df6, #7a4dff); }
.crumbs { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.crumbs .sep { opacity: .5; }
.crumbs b { color: var(--text); font-weight: 600; }
.spacer { flex: 1; }
.live { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12.5px; }
.pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--off); }
.live.ok .pulse { background: var(--ok); box-shadow: 0 0 0 0 rgba(18,164,107,.5); animation: pulse 2s infinite; }
.live.err .pulse { background: var(--bad); }
@keyframes pulse { 70% { box-shadow: 0 0 0 7px rgba(18,164,107,0); } 100% { box-shadow: 0 0 0 0 rgba(18,164,107,0); } }
.icon-btn { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border); color: var(--muted); }
.icon-btn:hover { color: var(--text); }

main { max-width: 1440px; margin: 0 auto; padding: 24px; }
h1 { font-size: 22px; letter-spacing: -.02em; margin: 0 0 4px; }
.sub { color: var(--muted); margin-bottom: 20px; }

/* summary */
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 22px; }
.tile { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow); }
.tile .k { color: var(--muted); font-size: 12.5px; display: flex; align-items: center; gap: 7px; }
.tile .v { font-size: 28px; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; font-variant-numeric: tabular-nums; }
.tile .v small { font-size: 14px; font-weight: 500; color: var(--muted); margin-left: 2px; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: var(--off); }
.dot.ok { background: var(--ok); } .dot.warn { background: var(--warn); } .dot.bad { background: var(--bad); }

/* toolbar */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 16px; }
.seg { display: inline-flex; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; padding: 3px; }
.seg button { border: 0; background: transparent; padding: 5px 12px; border-radius: 7px; color: var(--muted); font-size: 13px; }
.seg button.on { background: var(--surface); color: var(--text); box-shadow: var(--shadow); font-weight: 600; }
.search { flex: 1; min-width: 200px; max-width: 320px; margin-left: auto; padding: 8px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text); outline: none; }
.search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* fleet cards */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 14px; }
.card { display: block; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px;
  box-shadow: var(--shadow); transition: transform .12s, border-color .12s; }
.card:hover { transform: translateY(-2px); border-color: var(--accent); }
.card.offline { opacity: .62; }
.card .head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.card .nm { font-weight: 650; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 99px; background: var(--surface2); color: var(--muted); border: 1px solid var(--border); }
.st { font-size: 11.5px; font-weight: 600; padding: 2px 9px; border-radius: 99px; }
.st.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); }
.st.warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 15%, transparent); }
.st.bad { color: var(--bad); background: color-mix(in srgb, var(--bad) 14%, transparent); }
.st.off { color: var(--off); background: color-mix(in srgb, var(--off) 16%, transparent); }
.meter { display: grid; grid-template-columns: 42px 1fr 52px; align-items: center; gap: 10px; margin: 8px 0; font-size: 12.5px; }
.meter .lb { color: var(--muted); }
.meter .bar { height: 6px; border-radius: 99px; background: var(--surface2); overflow: hidden; }
.meter .bar i { display: block; height: 100%; border-radius: 99px; background: var(--ok); transition: width .4s; }
.meter .bar i.warn { background: var(--warn); } .meter .bar i.bad { background: var(--bad); }
.meter .pc { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.card .foot { margin-top: 12px; color: var(--muted); font-size: 12px; }

/* detail */
.detail-head { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-bottom: 18px; }
.detail-head h1 { margin: 0; }
.detail-head .seg { margin-left: auto; }
.panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px 10px; box-shadow: var(--shadow); }
.panel.wide { grid-column: 1 / -1; }
.panel h3 { margin: 0 0 6px; font-size: 14px; display: flex; align-items: center; gap: 8px; }
.panel h3 span { color: var(--muted); font-weight: 400; font-size: 12.5px; }
.chart { height: 230px; }
.disks { display: grid; gap: 4px; }
.empty { color: var(--muted); padding: 40px 0; text-align: center; }

/* logs */
.logs { max-height: 360px; overflow: auto; font: 12.5px/1.55 ui-monospace, "Cascadia Mono", Consolas, monospace; }
.logrow { display: grid; grid-template-columns: 138px 62px 1fr; gap: 10px; padding: 4px 2px; border-top: 1px solid var(--border); }
.logrow:first-child { border-top: 0; }
.logrow .t { color: var(--muted); white-space: nowrap; }
.logrow .sv { font-weight: 600; }
.sv.ERROR, .sv.Error, .sv.FATAL, .sv.CRITICAL { color: var(--bad); }
.sv.WARN, .sv.Warning, .sv.WARNING { color: var(--warn); }
.logrow .m { white-space: pre-wrap; word-break: break-word; }

.toast { position: fixed; bottom: 20px; left: 50%; transform: translate(-50%, 20px); opacity: 0; pointer-events: none;
  background: var(--text); color: var(--bg); padding: 10px 16px; border-radius: 10px; transition: .25s; font-size: 13px; }
.toast.show { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 860px) {
  main { padding: 16px; } .top { padding: 0 16px; }
  .panels { grid-template-columns: 1fr; }
  .detail-head .seg { margin-left: 0; }
}

.logtools { margin-left: auto; display: inline-flex; gap: 8px; }
.logtools select, .logtools input { padding: 5px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface);
  color: var(--text); font-size: 12.5px; outline: none; }
.logtools input:focus, .logtools select:focus { border-color: var(--accent); }
.panel h3 { flex-wrap: wrap; }

.rangebox { position: relative; }
.cal-btn { display: inline-flex; align-items: center; gap: 7px; padding: 7px 12px; border-radius: 10px; font-size: 13px;
  background: var(--surface2); border: 1px solid var(--border); color: var(--muted); }
.cal-btn:hover, .cal-btn.on { color: var(--text); border-color: var(--accent); }
.pop { position: absolute; right: 0; top: calc(100% + 8px); z-index: 20; width: 280px; padding: 14px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.28); display: grid; gap: 10px; }
.pop[hidden] { display: none; }
.pop label { display: grid; gap: 4px; font-size: 12px; color: var(--muted); }
.pop input { padding: 7px 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; color-scheme: light dark; }
:root[data-theme="dark"] .pop input { color-scheme: dark; }
:root[data-theme="light"] .pop input { color-scheme: light; }
.pop-act { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
.pop-act button { padding: 6px 14px; border-radius: 8px; border: 1px solid var(--border); background: transparent; font-size: 13px; }
.pop-act .primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.detail-head .seg { margin-left: auto; }
.detail-head .seg + .rangebox { margin-left: 0; }

.whoami { color: var(--muted); font-size: 12.5px; }
.login-page { min-height: 100vh; }
.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; max-width: none; }
.login-card { width: 100%; max-width: 380px; display: grid; gap: 14px; padding: 28px; border-radius: 16px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: 0 10px 40px rgba(0,0,0,.12); }
.login-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.login-brand .logo { width: 42px; height: 42px; border-radius: 12px; }
.login-title { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.login-sub { color: var(--muted); font-size: 13px; }
.login-card label { display: grid; gap: 6px; font-size: 12.5px; color: var(--muted); }
.login-card input { padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; outline: none; }
.login-card input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.login-btn { margin-top: 4px; padding: 11px; border: 0; border-radius: 10px; background: var(--accent); color: #fff; font-weight: 600; font-size: 14px; }
.login-btn:hover { filter: brightness(1.08); }
.login-err { padding: 10px 12px; border-radius: 10px; font-size: 13px; color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, transparent); }

/* 카드 미니 차트 */
.sparks { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 0 0 6px; }
.sp .sl { font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
.sp .sl small { opacity: .7; margin-left: 2px; }
.sp svg { width: 100%; height: 34px; display: block; overflow: visible; }
.sp .line { fill: none; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.sp .area { opacity: .16; stroke: none; }
.sp .nodata { display: flex; align-items: center; height: 34px; font-size: 11px; color: var(--muted); opacity: .6; }

/* ===== 내비게이션 / 알림 배너 ===== */
.mainnav { display: flex; gap: 4px; margin-left: 18px; }
.mainnav a { padding: 6px 12px; border-radius: 8px; color: var(--muted); font-size: 13.5px; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; }
.mainnav a:hover { color: var(--text); background: var(--surface2); }
.mainnav a.on { color: var(--text); background: var(--surface2); font-weight: 650; }
.cnt { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 99px; font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; color: #fff; background: var(--warn); }
.cnt.crit { background: var(--bad); }
.cnt[hidden] { display: none; }
.alertbar { display: flex; align-items: center; gap: 14px; padding: 12px 16px; border-radius: 12px; margin-bottom: 16px; border: 1px solid; font-size: 13.5px; }
.alertbar.crit { background: color-mix(in srgb, var(--bad) 12%, var(--surface)); border-color: color-mix(in srgb, var(--bad) 45%, var(--border)); }
.alertbar.warn { background: color-mix(in srgb, var(--warn) 12%, var(--surface)); border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); }
.alertbar span { color: var(--muted); } .alertbar .go { margin-left: auto; color: var(--accent); font-weight: 600; }

/* ===== 표 / 등급 ===== */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th { text-align: left; color: var(--muted); font-weight: 500; font-size: 12px; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.tbl td { padding: 9px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.tbl tr:last-child td { border-bottom: 0; }
.tbl .nw { white-space: nowrap; }
.hl { color: var(--accent); font-weight: 600; } .hl:hover { text-decoration: underline; }
.sev { font-size: 11.5px; font-weight: 700; padding: 2px 9px; border-radius: 99px; white-space: nowrap; }
.sev.crit { color: var(--bad); background: color-mix(in srgb, var(--bad) 16%, transparent); }
.sev.warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.sev.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 16%, transparent); }
.sev.dim { color: var(--muted); background: var(--surface2); }
.dimtxt { color: var(--muted); font-size: 12.5px; } .oktxt { color: var(--ok); font-size: 12.5px; } .badtxt { color: var(--bad); font-size: 12.5px; }
.empty.ok { color: var(--ok); padding: 26px 0; }

/* ===== 설정 폼 ===== */
.sect { margin-bottom: 14px; }
.sect h3 { margin-bottom: 8px; }
.frow { display: grid; grid-template-columns: 210px 1fr; gap: 16px; align-items: center; padding: 11px 0; border-top: 1px solid var(--border); }
.frow:first-of-type { border-top: 0; }
.frow.sub { padding-top: 4px; border-top: 0; margin-top: -6px; }
.fl { font-size: 13.5px; font-weight: 600; } .frow.sub .fl { font-weight: 400; color: var(--muted); }
.fl small { display: block; color: var(--muted); font-weight: 400; font-size: 11.5px; margin-top: 2px; line-height: 1.4; }
.fc { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; min-width: 0; }
.fi { background: var(--surface2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 7px 10px; font: inherit; font-size: 13px; outline: none; max-width: 100%; }
.fi:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.fi.wide { width: min(420px, 100%); } textarea.fi { resize: vertical; line-height: 1.5; }
.num { display: inline-flex; align-items: center; gap: 5px; } .num .fi { width: 78px; } .num em { font-style: normal; color: var(--muted); }
.inl { color: var(--muted); }
.sub-h { margin: 14px 0 0; padding: 12px 0 2px; border-top: 1px solid var(--border); font-size: 12px; font-weight: 700; letter-spacing: .02em; color: var(--accent); }
.sw { position: relative; display: inline-block; width: 38px; height: 22px; }
.sw input { opacity: 0; width: 0; height: 0; position: absolute; }
.sw span { position: absolute; inset: 0; background: var(--border); border-radius: 99px; transition: background .2s; cursor: pointer; }
.sw span::before { content: ""; position: absolute; width: 16px; height: 16px; left: 3px; top: 3px; border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.sw input:checked + span { background: var(--accent); } .sw input:checked + span::before { transform: translateX(16px); }
.sw input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-soft); }
.testrow { display: flex; align-items: center; gap: 12px; padding-top: 14px; border-top: 1px solid var(--border); margin-top: 12px; }
.btn { border: 1px solid var(--border); background: var(--surface2); color: var(--text); border-radius: 9px; padding: 8px 16px; font-size: 13px; font-weight: 600; cursor: pointer; }
.btn:hover:not(:disabled) { border-color: var(--accent); } .btn:disabled { opacity: .5; cursor: default; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.idle, .btn.idle:disabled { background: var(--surface2); border-color: var(--border); color: var(--muted); box-shadow: none; opacity: .7; cursor: not-allowed; }   /* 저장할 변경 없음: 회색 비활성 */
.savebar { position: sticky; bottom: 0; display: flex; align-items: center; gap: 12px; padding: 12px 16px; margin-top: 6px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 -6px 18px rgba(0,0,0,.12); }
.savebar .sp { flex: 1; }
.note { padding: 11px 14px; border-radius: 10px; background: var(--accent-soft); color: var(--text); font-size: 13px; margin-bottom: 14px; }
@media (max-width: 760px) { .frow { grid-template-columns: 1fr; gap: 6px; } .mainnav { margin-left: 6px; } .brand-name { display: none; } }

/* 네트워크 장비: 포트 상태 */
.ports { display: grid; gap: 2px; padding-bottom: 8px; }
.prt { display: grid; grid-template-columns: 14px 1fr auto 76px; align-items: center; gap: 10px; padding: 8px 2px; border-bottom: 1px solid var(--border); font-size: 13px; }
.prt:last-child { border-bottom: 0; }
.prt .pn { font-weight: 600; } .prt .pm { color: var(--muted); font-size: 12px; }
.prt .ps { text-align: right; font-variant-numeric: tabular-nums; }
.prt .ps.slow { color: var(--warn); font-weight: 600; }
.clist { padding-bottom: 8px; font-size: 13px; overflow-x: auto; }
.cl { display: grid; grid-template-columns: minmax(90px, 1.3fr) 112px 140px minmax(60px, .8fr) 76px; gap: 10px; align-items: center; padding: 8px 2px; border-bottom: 1px solid var(--border); }
.cl:last-child { border-bottom: 0; }
.cl.h { color: var(--muted); font-size: 12px; padding-top: 2px; }
.cl .r { text-align: right; } .cl .cn { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .cl .cn i { color: var(--muted); font-weight: 400; }
.cl .mono { font-variant-numeric: tabular-nums; } .cl .mac { color: var(--muted); font-size: 12px; } .cl .cp { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl .pg { font-variant-numeric: tabular-nums; } .cl .pg.slow { color: var(--warn); font-weight: 600; } .cl .pg.bad { color: var(--muted); }

/* 토폴로지 */
.gmapbox { padding: 0; overflow: hidden; }
.gmap { height: 440px; border-radius: 14px; background: var(--surface2); z-index: 0; }
.leaflet-container { font: inherit; }
:root[data-theme="dark"] .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.92); }
:root[data-theme="dark"] .leaflet-container { background: #1b2540; }
.leaflet-popup-content-wrapper, .leaflet-popup-tip { background: var(--surface); color: var(--text); }
.pinwrap { overflow: visible; }
.pin { display: flex; align-items: center; gap: 6px; transform: translate(-10px, -34px); white-space: nowrap; padding: 4px 10px 4px 6px; border-radius: 999px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border); box-shadow: 0 2px 8px rgba(16,24,40,.25); font-size: 12.5px; font-weight: 600; width: max-content; }
.pin i { width: 14px; height: 14px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 25%, transparent); }
.pin.st-warn i { background: var(--warn); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 25%, transparent); }
.pin.st-bad i { background: var(--bad); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 25%, transparent); }
.pp .pm { color: var(--muted); font-size: 12px; margin-bottom: 4px; } .pp .pl { display: inline-block; margin-top: 6px; color: var(--accent); font-weight: 600; }
.c-ok { color: var(--ok); } .c-warn { color: var(--warn); } .c-bad { color: var(--bad); }
.sitegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; margin-top: 16px; }
.site { display: block; padding: 14px 16px; border-radius: 12px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow); }
.site:hover { border-color: var(--accent); }
.site .sh { display: flex; align-items: center; gap: 8px; } .site .sd { width: 9px; height: 9px; border-radius: 50%; background: var(--ok); }
.site.st-warn .sd { background: var(--warn); } .site.st-bad .sd { background: var(--bad); }
.site .sp { margin-left: auto; font-size: 12px; color: var(--muted); } .site .sm { color: var(--muted); font-size: 12.5px; margin-top: 4px; }
.site .sm2 { font-size: 12.5px; margin-top: 2px; } .nogeo { color: var(--warn); }
.ghostbtn { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--border); color: var(--muted); font-size: 13px; }
.ghostbtn:hover { color: var(--text); background: var(--surface2); }
.topo { padding: 10px 8px 4px; overflow-x: auto; } .topo svg { min-width: 900px; display: block; }
.tbox { fill: var(--surface2); stroke: var(--border); stroke-width: 1; }
.tt { fill: var(--text); font-size: 13.5px; font-weight: 650; } .ts { fill: var(--muted); font-size: 11.5px; }
.tedge { fill: none; stroke-width: 2; opacity: .75; } .tedge.wan { stroke-width: 3; }
.tn.lk:hover .tbox { stroke: var(--accent); cursor: pointer; }
.tlegend { display: flex; flex-wrap: wrap; gap: 16px; padding: 6px 16px 12px; color: var(--muted); font-size: 12.5px; }
.tlegend i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; }
.leaflet-bar a, .leaflet-bar a:hover { background: var(--surface); color: var(--text); border-bottom-color: var(--border); }
.leaflet-control-attribution { background: color-mix(in srgb, var(--surface) 85%, transparent) !important; color: var(--muted) !important; }

/* 현황: 카드 + 허니콤 2단 */
.fleet-body { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 14px; align-items: start; }
.fleet-body .grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.honey { position: sticky; top: 72px; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px; box-shadow: var(--shadow); }
.honey .ph { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.honey .ph b { font-size: 13.5px; }
.honey .hsub { color: var(--muted); font-size: 12px; }
.honey .seg { margin-left: auto; padding: 2px; }
.honey .seg button { padding: 3px 9px; font-size: 12px; }
.hsvg { display: block; }
.hx { stroke: var(--surface); stroke-width: 1.5; fill: var(--off); fill-opacity: .88; transition: fill-opacity .15s; }
.hx.ok { fill: var(--ok); } .hx.warn { fill: var(--warn); } .hx.bad { fill: var(--bad); } .hx.off { fill: var(--off); }
.hxa:hover .hx { fill-opacity: 1; stroke: var(--text); }
.hxa.dim { opacity: .2; }
.hxn, .hxv { fill: #fff; text-anchor: middle; pointer-events: none; font-weight: 650; }
.hxn { font-size: 10.5px; } .hxv { font-size: 10px; font-weight: 500; opacity: .92; }
.hleg { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; color: var(--muted); font-size: 11.5px; }
.hleg span { display: inline-flex; align-items: center; gap: 5px; }
.hleg i { width: 10px; height: 10px; display: inline-block; border-radius: 3px; stroke: none; }
.hleg i.ok { background: var(--ok); } .hleg i.warn { background: var(--warn); } .hleg i.bad { background: var(--bad); } .hleg i.off { background: var(--off); }
@media (max-width: 1100px) { .fleet-body { grid-template-columns: 1fr; } .honey { position: static; order: -1; } }

/* ---- 일·주·월 통계 ---- */
.tbl.stat th { text-align: center; }
.tbl.stat thead tr.sub th { font-size: 11px; padding-top: 2px; }
.tbl.stat th[rowspan], .tbl.stat td:first-child { text-align: left; }
.tbl.stat td.sv { text-align: right; font-variant-numeric: tabular-nums; }
.tbl.stat td.sv.warn { color: var(--warn); font-weight: 600; }
.tbl.stat td.sv.bad { color: var(--bad); font-weight: 600; }
.grow { flex: 1; }
.tbl.stat th, .tbl.stat td { padding-left: 6px; padding-right: 6px; }
.tbl.stat td.sv { white-space: nowrap; }
.chip { display: inline-block; min-width: 3.2em; padding: 2px 8px; border-radius: 99px; font-weight: 700; font-size: 12.5px; text-align: center;
  box-shadow: 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent), 0 2px 8px color-mix(in srgb, currentColor 28%, transparent); }
.chip.mx { color: #e5484d; background: linear-gradient(135deg, color-mix(in srgb, #e5484d 20%, var(--surface)), color-mix(in srgb, #f59e0b 22%, var(--surface))); }
.chip.mn { color: #2563eb; background: linear-gradient(135deg, color-mix(in srgb, #2563eb 18%, var(--surface)), color-mix(in srgb, #06b6d4 20%, var(--surface))); }
.chip.mx.warn { color: #d97706; } .chip.mx.bad { color: #dc2626; }
[data-theme="dark"] .chip.mx { color: #ff8a8d; } [data-theme="dark"] .chip.mn { color: #7db1ff; }
.panel .stat-wrap, #sbody, #hstats { overflow-x: auto; }
.tbl.stat td.sv { text-align: center; }

/* ---- 리포트 (화면 + 인쇄) ---- */
.ckl { display: inline-flex; align-items: center; gap: 6px; margin-right: 18px; font-size: 13.5px; }
.ckl small { color: var(--muted); }
.rpt-tools { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.rpt { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 26px 30px; box-shadow: var(--shadow); }
.rpt-head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 18px; padding-bottom: 14px; border-bottom: 2px solid var(--accent); }
.rpt-brand { font-size: 12.5px; font-weight: 700; color: var(--accent); letter-spacing: .03em; }
.rpt-head h1 { margin: 2px 0 0; font-size: 26px; }
.rpt-span { color: var(--muted); font-size: 14px; margin-top: 2px; }
.rpt-gen { color: var(--muted); font-size: 12px; }
.rpt .summary { margin-bottom: 16px; }
.rtbl td.rv { text-align: right; white-space: nowrap; }
.rtbl td.rv b { display: block; font-size: 15px; font-variant-numeric: tabular-nums; }
.rtbl td.rv small { display: block; font-size: 11px; color: var(--muted); font-weight: 400; }
.rtbl th { text-align: right; } .rtbl th:first-child { text-align: left; }
.rpt-note { color: var(--muted); font-size: 11.5px; margin-top: 8px; }
.rpt-h { font-size: 14px; margin: 22px 0 6px; }
.rsel { margin-left: 8px; font-size: 12.5px; padding: 3px 8px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text); font-weight: 400; }
@media print { .rsel { border: 0; appearance: none; -webkit-appearance: none; padding: 0; } }
.rtr { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 12px; }
.tr-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; break-inside: avoid; }
.tr-card h4 { margin: 0 0 8px; font-size: 13px; } .tr-card h4 small { color: var(--muted); font-weight: 400; margin-left: 4px; }
.cc { display: flex; align-items: flex-end; gap: 2px; height: 86px; }
.cc .c { flex: 1; position: relative; height: 100%; min-width: 2px; }
.cc .c i { position: absolute; left: 0; right: 0; bottom: 0; display: block; border-radius: 2px 2px 0 0; }
.cc .c .mx { background: rgba(99,102,241,.28); } .cc .c .mx.warn { background: rgba(245,158,11,.55); } .cc .c .mx.bad { background: rgba(239,68,68,.6); }
.cc .c .av { background: #6366f1; }
.cx { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--muted); margin-top: 3px; }
.rk { display: flex; align-items: center; gap: 8px; font-size: 12.5px; margin: 5px 0; }
.rk .rn { flex: 0 0 34%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk .rb { flex: 1; height: 9px; background: rgba(99,102,241,.12); border-radius: 5px; overflow: hidden; }
.rk .rb i { display: block; height: 100%; background: #6366f1; border-radius: 5px; }
.rk b { flex: 0 0 auto; min-width: 64px; text-align: right; font-variant-numeric: tabular-nums; }
.hm { border-collapse: separate; border-spacing: 1px; width: 100%; table-layout: fixed; }
.hm td.hn { width: 150px; font-size: 12px; overflow: hidden; text-overflow: ellipsis; padding-right: 8px; }
.hm td.hc { height: 17px; border-radius: 2px; background: rgba(128,128,128,.1); }
.hm td.hc.fut { background: transparent; box-shadow: inset 0 0 0 1px rgba(128,128,128,.22); }
.rpt { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
@media print {
  @page { size: A4 landscape; margin: 12mm; }
  html, body { background: #fff !important; }
  header.top, .rpt-tools, .toast { display: none !important; }
  main, #view { padding: 0 !important; margin: 0 !important; max-width: none !important; }
  .rpt { border: 0; box-shadow: none; padding: 0; background: #fff; color: #111; }
  .rpt .tile { box-shadow: none; }
  .rpt tr { break-inside: avoid; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* 라이트 테마: 호스트 상세의 지표 패널을 지표별 색조의 머리띠·윗선·옅은 바탕으로 구분 (다크 테마는 그대로) */
:root:not([data-theme="dark"]) { --bg: #eaeef6; }
:root:not([data-theme="dark"]) .panel[id^="p-"], :root:not([data-theme="dark"]) .panel.sect {
  --pc: 59,109,246; border-color: #d3dae7; border-top: 3px solid rgba(var(--pc), .6);
  background: linear-gradient(180deg, rgba(var(--pc), .06), rgba(var(--pc), .015) 60%, #fff 100%), #fff;
  box-shadow: 0 1px 2px rgba(16,24,40,.07), 0 6px 18px rgba(16,24,40,.06);
}
:root:not([data-theme="dark"]) .panel[id^="p-"] > h3, :root:not([data-theme="dark"]) .panel.sect > h3 {
  margin: -13px -18px 10px; padding: 11px 18px; background: rgba(var(--pc), .10); border-bottom: 1px solid rgba(var(--pc), .20);
  border-radius: 11px 11px 0 0; color: rgb(var(--pc)); filter: saturate(1.1);
}
:root:not([data-theme="dark"]) .panel[id^="p-"] > h3 span, :root:not([data-theme="dark"]) .panel.sect > h3 span { color: var(--muted); }
:root:not([data-theme="dark"]) #p-cpu { --pc: 59,109,246; }
:root:not([data-theme="dark"]) #p-mem { --pc: 18,164,107; }
:root:not([data-theme="dark"]) #p-net { --pc: 8,145,178; }
:root:not([data-theme="dark"]) #p-diskio { --pc: 217,138,5; }
:root:not([data-theme="dark"]) #p-disks { --pc: 124,92,240; }
:root:not([data-theme="dark"]) #p-load { --pc: 192,57,150; }
:root:not([data-theme="dark"]) #p-netdev { --pc: 14,116,144; }
:root:not([data-theme="dark"]) #p-clients { --pc: 79,70,229; }
:root:not([data-theme="dark"]) #p-clist { --pc: 100,116,139; }
:root:not([data-theme="dark"]) #p-stats { --pc: 71,85,105; }
:root:not([data-theme="dark"]) #p-logs { --pc: 51,65,85; }
:root:not([data-theme="dark"]) #p-stats > h3, :root:not([data-theme="dark"]) #p-logs > h3, :root:not([data-theme="dark"]) #p-clist > h3 { color: #334155; }
@media print { :root .panel[id^="p-"], :root .panel.sect { background: #fff !important; box-shadow: none !important; } }

:root:not([data-theme="dark"]) .panel.sect-rules { --pc: 224,68,58; }
:root:not([data-theme="dark"]) .panel.sect-notify { --pc: 59,109,246; }
:root:not([data-theme="dark"]) .panel.sect-report { --pc: 18,164,107; }
:root:not([data-theme="dark"]) .panel.sect-exclude { --pc: 100,116,139; }
:root:not([data-theme="dark"]) .panel.sect-exclude > h3 { color: #334155; }

/* ===== 계정 관리 / 모달 / 역할 배지 ===== */
.role { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 99px; font-size: 11px; font-weight: 650; color: var(--muted); background: var(--surface2); border: 1px solid var(--border); }
.role.r-admin { color: var(--accent); background: var(--accent-soft); border-color: transparent; }
.role.r-operator { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); border-color: transparent; }
td .role { margin-left: 0; }
.whoami a { color: inherit; } .whoami a:hover { color: var(--text); text-decoration: underline; }
.btn.sm { padding: 4px 10px; font-size: 12px; border-radius: 7px; }
.btn.danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, var(--border)); }
.btn.danger:hover:not(:disabled) { background: var(--bad); border-color: var(--bad); color: #fff; }
.ut td { vertical-align: middle; } .ua { text-align: right; }
.panel h3 + .toolbar, .panel .toolbar { margin-top: 6px; }
.panel .toolbar .search { margin-left: 0; }
.panel .toolbar #uAdd { margin-left: auto; }
.mbg { position: fixed; inset: 0; z-index: 50; background: rgba(8, 12, 24, .5); display: grid; place-items: center; padding: 20px; overflow: auto; }
.modal { width: min(640px, 100%); background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 16px; box-shadow: 0 24px 70px rgba(0,0,0,.35); padding: 20px 22px 18px; }
.modal.sm { width: min(440px, 100%); }
.modal h3 { margin: 0 0 8px; font-size: 16px; }
.modal .mh { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; } .modal .mh h3 { margin: 0; }
.modal .x { border: 0; background: transparent; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 8px; } .modal .x:hover { color: var(--text); background: var(--surface2); }
.modal .mt { margin: 0 0 14px; color: var(--muted); font-size: 13.5px; line-height: 1.6; } .modal .mt b { color: var(--text); }
.mg { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
.mfl { display: grid; gap: 5px; font-size: 12.5px; color: var(--muted); align-content: start; }
.mfl > span:first-child { font-weight: 600; color: var(--text); } .mfl i { color: var(--bad); font-style: normal; }
.mfl .fi { width: 100%; box-sizing: border-box; } .mfl small { color: var(--muted); font-size: 11.5px; }
.mfl:nth-child(1), .mfl:nth-child(8), .mfl:last-child:nth-child(odd) { grid-column: 1 / -1; }
.inrow { display: flex; gap: 8px; align-items: center; } .inrow .fi { flex: 1; min-width: 0; }
.chk { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; color: var(--text); font-weight: 400 !important; }
.mact { display: flex; align-items: center; gap: 8px; justify-content: flex-end; margin-top: 16px; }
.merr { margin-right: auto; color: var(--bad); font-size: 12.5px; }
.tpw { background: var(--surface2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; margin-bottom: 4px; }
.tpw .tl { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.tpw code { font-size: 19px; font-weight: 700; letter-spacing: .06em; user-select: all; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.login-alt { text-align: center; color: var(--muted); font-size: 13px; padding: 2px; } .login-alt:hover { color: var(--text); }
.pwhint { color: var(--muted); font-weight: 400; }
@media (max-width: 640px) { .mg { grid-template-columns: 1fr; } .mfl:nth-child(n) { grid-column: auto; } .ut th:nth-child(5), .ut td:nth-child(5), .ut th:nth-child(6), .ut td:nth-child(6), .ut th:nth-child(7), .ut td:nth-child(7) { display: none; } }

/* 상단 메뉴: 항목이 늘어도 글자 단위로 줄바꿈되지 않게 한다 */
.top { min-width: 0; }
.brand, .live, .whoami, .mainnav a, .top .icon-btn, .top > button { white-space: nowrap; flex-shrink: 0; }
.mainnav { flex-shrink: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.mainnav::-webkit-scrollbar { display: none; }
@media (max-width: 1100px) { .brand-name { display: none; } }
@media (max-width: 980px) { .live #liveText { display: none; } }
@media (max-width: 760px) { .whoami .role { display: none; } .mainnav a { padding: 6px 9px; } }

/* 접속·감사 기록 */
.sev.info { color: var(--accent); background: var(--accent-soft); }
.ipl { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 13px; }
.ipl b { font-variant-numeric: tabular-nums; }
.at td { vertical-align: top; }
@media (max-width: 760px) { .at th:nth-child(5), .at td:nth-child(5), .at th:nth-child(6), .at td:nth-child(6) { display: none; } }

/* 통계 요약 */
.ov { margin-bottom: 18px; }
.ovtop { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin: 2px 0 8px; }
.ovnum b { font-size: 32px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ovnum small { color: var(--muted); margin-left: 5px; }
.ovdelta { font-size: 13px; color: var(--muted); font-weight: 600; }
.ovdelta.up { color: var(--bad); } .ovdelta.down { color: var(--ok); }
.ovgrid { display: grid; grid-template-columns: 1.7fr 1fr 1.2fr; gap: 16px; }
.ovt { font-size: 12.5px; color: var(--muted); font-weight: 600; margin-bottom: 2px; }
.ovch { height: 230px; }
@media (max-width: 1100px) { .ovgrid { grid-template-columns: 1fr 1fr; } .ovgrid .ovc:first-child { grid-column: 1 / -1; } }
@media (max-width: 640px) { .ovgrid { grid-template-columns: 1fr; } }
@media print { .ov { break-inside: avoid; } }

/* ===== 토폴로지: 관제센터형 ===== */
.topo { position: relative; border-radius: 16px;
  background:
    radial-gradient(1200px 500px at 50% 0%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%),
    radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--muted) 22%, transparent) 1px, transparent 1.2px) 0 0 / 22px 22px; }
.tbox { fill: color-mix(in srgb, var(--surface2) 92%, var(--accent) 8%); stroke: color-mix(in srgb, var(--border) 70%, var(--accent) 30%);
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.28)); transition: stroke .15s, filter .15s; }
.tn.lk:hover .tbox { stroke: var(--accent); filter: drop-shadow(0 0 10px color-mix(in srgb, var(--accent) 55%, transparent)); }
.tt { letter-spacing: -.01em; }
.ts { font-variant-numeric: tabular-nums; }
.tedge { stroke-linecap: round; opacity: .85; }
.tedge.wan { stroke-width: 3.5; }
.tedge:not([stroke-dasharray]) { stroke-dasharray: 7 9; animation: tflow 1.4s linear infinite; animation-delay: var(--tdelay, 0s); }
@keyframes tflow { to { stroke-dashoffset: -32; } }
@keyframes tflowv { to { stroke-dashoffset: var(--dp, -32); } }
@media (prefers-reduced-motion: reduce) { .tedge:not([stroke-dasharray]) { animation: none; stroke-dasharray: none; } }

/* ===== 토폴로지: 항상 다크 캔버스 + 모바일 대응 ===== */
.topo { --surface2: #1d2a4a; --border: #2f3f68; --text: #e6eaf2; --muted: #9fb0d0; --ok: #34d399; --warn: #fbbf24; --bad: #f87171; --off: #5b667a;
  background:
    radial-gradient(1100px 480px at 50% 0%, rgba(47,143,232,.16), transparent 70%),
    radial-gradient(circle at 1px 1px, rgba(148,163,192,.22) 1px, transparent 1.2px) 0 0 / 22px 22px,
    #0f172a;
  border: 1px solid #26324f; padding: 14px 10px 8px; }
.topo svg { min-width: 760px; }
@media (max-width: 700px) { .topo svg { min-width: 680px; } .topo { margin: 0 -6px; } }

/* ===== 현황: 관제센터 톤 ===== */
.tile { position: relative; overflow: hidden; transition: border-color .15s, transform .15s; }
.tile::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent 80%); opacity: .9; }
.tile:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); transform: translateY(-1px); }
.tile .v { background: linear-gradient(180deg, var(--text), color-mix(in srgb, var(--text) 72%, var(--accent)));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.tile .v small { -webkit-text-fill-color: var(--muted); }

.card { transition: transform .15s, border-color .15s, box-shadow .15s; }
.card:hover { box-shadow: 0 8px 24px rgba(15,23,42,.18), 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
:root[data-theme="dark"] .card:hover { box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 35%, transparent); }

.honey { --surface2: #1d2a4a; --border: #26324f; --text: #e6eaf2; --muted: #9fb0d0;
  background:
    radial-gradient(520px 260px at 50% 0%, rgba(47,143,232,.16), transparent 70%),
    radial-gradient(circle at 1px 1px, rgba(148,163,192,.20) 1px, transparent 1.2px) 0 0 / 20px 20px,
    #0f172a;
  box-shadow: 0 10px 30px rgba(15,23,42,.25); }
.honey .seg { background: #1d2a4a; border-color: #2f3f68; }
.honey .seg button.on { background: #2b3d6b; color: #fff; }
.honey { color: var(--text); }
.honey .ph b { color: #e6eaf2; }

/* ===== 현황: 타일 균등 배치 + 상태 발광 ===== */
.summary { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 900px) { .summary { grid-template-columns: repeat(2, 1fr); } .summary .tile:last-child:nth-child(odd) { grid-column: 1 / -1; } }
.card .bar i, .card .fill, .card [class*="bar"] > i { box-shadow: 0 0 8px color-mix(in srgb, currentColor 40%, transparent); }
.card .st.ok { box-shadow: 0 0 10px color-mix(in srgb, var(--ok) 30%, transparent); }
@media (max-width: 900px) {
  .summary .tile:last-child:nth-child(odd) { display: flex; align-items: center; justify-content: space-between; padding-top: 12px; padding-bottom: 12px; }
  .summary .tile:last-child:nth-child(odd) .v { margin-top: 0; font-size: 26px; }
}
.topo { scrollbar-width: thin; scrollbar-color: #3a4a74 #0f172a; }
.topo::-webkit-scrollbar { height: 8px; }
.topo::-webkit-scrollbar-track { background: #0f172a; border-radius: 8px; }
.topo::-webkit-scrollbar-thumb { background: #3a4a74; border-radius: 8px; }
.topo text.ts[text-anchor="middle"] { font-size: 14px; font-weight: 600; fill: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }

/* ===== KPI 타일: 링 게이지 · 트래픽 화살표 · 가동 시간 시계 ===== */
#kpi { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; margin-bottom: 22px; }
@media (max-width: 1200px) { #kpi { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) { #kpi { grid-template-columns: repeat(2, 1fr); } }
.tk { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 100px; }
.tk .tt1 { min-width: 0; }
.tk .tv { font-size: 26px; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text); }
.tk .tv small { font-size: 13px; font-weight: 500; color: var(--muted); margin-left: 2px; }
.ring { width: 62px; height: 62px; flex: none; transform: rotate(-90deg); }
.rt { fill: none; stroke: var(--border); stroke-width: 6; }
.rv { fill: none; stroke: var(--ok); stroke-width: 6; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset .9s cubic-bezier(.2,.8,.2,1), stroke .4s; filter: drop-shadow(0 0 4px var(--ok)); }
.tk.warn .rv { stroke: var(--warn); filter: drop-shadow(0 0 4px var(--warn)); }
.tk.bad .rv { stroke: var(--bad); filter: drop-shadow(0 0 5px var(--bad)); animation: kpibad 1.2s ease-in-out infinite; }
.tk.warn .tv { color: var(--warn); }
.tk.bad .tv { color: var(--bad); }
.arrows { display: flex; flex-direction: column; align-items: center; gap: 1px; flex: none; width: 30px; }
.arrows i { width: 13px; height: 13px; border-right: 3px solid; border-bottom: 3px solid; border-radius: 2px; margin: -3px 0; transform: rotate(45deg);
  opacity: .12; animation: kpiflow var(--spd, 1.2s) ease-in-out infinite; }
.tk-flow.down { color: var(--accent); }
.tk-flow.up { color: var(--ok); }
.tk-flow.up .arrows i { transform: rotate(-135deg); }
.tk-flow.down .arrows i:nth-child(2) { animation-delay: calc(var(--spd, 1.2s) * .22); }
.tk-flow.down .arrows i:nth-child(3) { animation-delay: calc(var(--spd, 1.2s) * .44); }
.tk-flow.up .arrows i:nth-child(2) { animation-delay: calc(var(--spd, 1.2s) * .22); }
.tk-flow.up .arrows i:nth-child(1) { animation-delay: calc(var(--spd, 1.2s) * .44); }
.tk-flow.idle .arrows i { animation: none; opacity: .22; }
.tk-flow:not(.idle) .arrows i { filter: drop-shadow(0 0 4px currentColor); }
.tk-flow:not(.idle)::after { content: ""; position: absolute; inset: 0; pointer-events: none; transform: translateX(-120%);
  background: linear-gradient(110deg, transparent 35%, color-mix(in srgb, currentColor 16%, transparent) 50%, transparent 65%); animation: kpisheen 3.4s ease-in-out infinite; }
.live-dot { width: 12px; height: 12px; margin-right: 6px; border-radius: 50%; flex: none; background: var(--ok); box-shadow: 0 0 0 0 rgba(18,164,107,.5); animation: pulse 2s infinite; }
.tk.flash { animation: kpiflash .9s ease-out; }
.tk-up { position: relative; }
.clk { display: none; width: 62px; height: 62px; flex: none; }
.tk-up.analog .clk { display: block; }
.tk-up.analog .tv { font-size: 17px; }
.cf { fill: var(--surface2); stroke: var(--border); stroke-width: 1.5; }
.tick { stroke: var(--muted); stroke-width: 1.2; stroke-linecap: round; }
.hh, .mh, .sh { transform-origin: 32px 32px; transform-box: view-box; stroke-linecap: round; }
.hh { stroke: var(--text); stroke-width: 3; transition: transform .5s ease; }
.mh { stroke: var(--text); stroke-width: 2.2; transition: transform .5s ease; }
.sh { stroke: var(--bad); stroke-width: 1.3; transition: transform 1s linear; }
.cc { fill: var(--bad); }
.tgl { position: absolute; top: 5px; right: 6px; border: 0; background: transparent; color: var(--muted); padding: 3px; border-radius: 6px; cursor: pointer; line-height: 0; opacity: .7; }
.tgl:hover { opacity: 1; color: var(--accent); }
@keyframes kpiflow { 0%, 100% { opacity: .12; } 35% { opacity: 1; } }
@keyframes kpibad { 50% { opacity: .5; } }
@keyframes kpisheen { 0% { transform: translateX(-120%); } 60%, 100% { transform: translateX(120%); } }
@keyframes kpiflash { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }
@media (prefers-reduced-motion: reduce) {
  .rv, .sh, .mh, .hh { transition: none !important; }
  .tk, .tk *, .tk::after { animation: none !important; }
}

/* KPI 시계: 가동 시간 기준 회색 바늘 */
.um, .uh { display: none; transform-origin: 32px 32px; transform-box: view-box; stroke: var(--muted); stroke-linecap: round; opacity: .6; transition: transform .5s ease; }
.um { stroke-width: 2; }
.uh { stroke-width: 3.2; }
.tk-up.analog .um, .tk-up.analog .uh { display: block; }
.usub { display: none; font-size: 11px; color: var(--muted); margin-top: 2px; white-space: nowrap; }
.tk-up.analog .usub { display: block; }
@media (prefers-reduced-motion: reduce) { .um, .uh { transition: none !important; } }

/* KPI 시계 숫자 강화 */
.clk { width: 84px; height: 84px; }
.clk .tick:nth-child(3n+2) { stroke: none; }

/* KPI 시계 숫자 (클래스명 충돌 회피) */
.clk .clkn { display: block; font-size: 10px; font-weight: 800; fill: var(--text); opacity: 1; text-anchor: middle; dominant-baseline: central; font-family: inherit; }

/* KPI 시계 크기/겹침 보정 */
.tk-up .tt1 { flex: 1 1 auto; min-width: 0; }
.clk { width: 70px; height: 70px; flex: none; }
.tk-up.analog .tv { font-size: 16px; }
.usub { white-space: normal; line-height: 1.35; font-size: 10.5px; }
.clk .clkn { font-size: 9px; }

/* KPI 시계: 12·3·6·9 위치 큰 눈금 복원 */
.clk .tick:nth-child(3n+2) { stroke: var(--text); stroke-width: 2.2; opacity: .85; }

/* KPI 시계 확대 */
.clk { width: 96px; height: 96px; }
.tk-up.analog { min-height: 124px; }

/* KPI 시계: 회색(부팅 시각) 바늘 제거 */
.tk-up.analog .um, .tk-up.analog .uh { display: none; }

/* KPI 타일: 블랙+블루 배경, 노랑/주황 글씨 */
#kpi .tk { background: linear-gradient(135deg, #05070f 0%, #0a1733 55%, #0f2d66 100%); border: 1px solid #1d3b73; box-shadow: 0 6px 18px rgba(5,12,40,.35), inset 0 1px 0 rgba(120,170,255,.12); }
#kpi .tk .k { color: #ff9f1c; font-weight: 600; }
#kpi .tk .tv { color: #ffd23f; text-shadow: 0 0 12px rgba(255,210,63,.28); -webkit-text-fill-color: #ffd23f; background: none; }
#kpi .tk .tv small { color: #ff9f1c; -webkit-text-fill-color: #ff9f1c; }
#kpi .tk.warn .tv { color: #ff8a1f; -webkit-text-fill-color: #ff8a1f; }
#kpi .tk.bad .tv { color: #ff5a4d; -webkit-text-fill-color: #ff5a4d; }
#kpi .tk .rt { stroke: #1a2c52; }
#kpi .tk .rv { stroke: #38bdf8; filter: drop-shadow(0 0 5px #38bdf8); }
#kpi .tk.warn .rv { stroke: #ff9f1c; filter: drop-shadow(0 0 5px #ff9f1c); }
#kpi .tk.bad .rv { stroke: #ff5a4d; filter: drop-shadow(0 0 6px #ff5a4d); }
#kpi .tk-flow.down { color: #38bdf8; }
#kpi .tk-flow.up { color: #ffb02e; }
#kpi .tk .usub { color: #ffb454; }
#kpi .tk .tgl { color: #ff9f1c; opacity: .85; }
#kpi .tk .tgl:hover { color: #ffd23f; opacity: 1; }
#kpi .cf { fill: #07112a; stroke: #2b4f94; }
#kpi .tick { stroke: #7f95c7; }
#kpi .tk .tick:nth-child(3n+2), #kpi .clk .tick:nth-child(3n+2) { stroke: #ffd23f; opacity: 1; }
#kpi .clkn { fill: #ffd23f; }
#kpi .hh { stroke: #ffd23f; }
#kpi .mh { stroke: #ffe58a; }
#kpi .sh { stroke: #ff5a36; }
#kpi .cc { fill: #ff5a36; }

/* 호스트 KPI 보조 */
.live-dot.off { background: #6b7a99; animation: none; box-shadow: none; }
#kpi .tk[data-k="age"] .tv { font-size: 22px; }

/* 호스트 KPI 시계 */
.tk-up.analog .live-dot { display: none; }
#kpi .tk[data-k="age"].analog .tv { font-size: 16px; }

/* 왼쪽 노드 레일 */
.nrail { position: fixed; left: 8px; top: 84px; bottom: 14px; display: none; flex-direction: column; gap: 8px; padding: 12px 10px; border-radius: 14px; z-index: 20; box-sizing: border-box;
  background: linear-gradient(160deg, #05070f 0%, #0a1733 60%, #0f2d66 100%); border: 1px solid #1d3b73; box-shadow: 0 8px 24px rgba(5,12,40,.35), inset 0 1px 0 rgba(120,170,255,.12); }
.nr-h { display: flex; align-items: center; justify-content: space-between; color: #ff9f1c; font-size: 12px; font-weight: 700; letter-spacing: .06em; }
.nr-c { background: rgba(255,159,28,.16); color: #ffd23f; border-radius: 999px; padding: 1px 8px; font-size: 11px; }
.nr-q { width: 100%; box-sizing: border-box; background: #0b1a38; border: 1px solid #23427f; color: #ffe9a8; border-radius: 8px; padding: 6px 9px; font: inherit; font-size: 12px; outline: none; }
.nr-q:focus { border-color: #38bdf8; }
.nr-q::placeholder { color: #7f95c7; }
.nr-f { display: flex; flex-wrap: wrap; gap: 4px; }
.nr-f button { border: 1px solid #23427f; background: transparent; color: #ffb454; border-radius: 999px; padding: 2px 8px; font: inherit; font-size: 11px; cursor: pointer; }
.nr-f button:hover { border-color: #ffb454; }
.nr-f button.on { background: #ff9f1c; border-color: #ff9f1c; color: #07112a; font-weight: 700; }
.nr-l { flex: 1; overflow: auto; display: flex; flex-direction: column; gap: 5px; margin: 0 -4px; padding: 0 4px; scrollbar-width: thin; scrollbar-color: #2b4f94 transparent; }
.nr-e { color: #7f95c7; font-size: 12px; text-align: center; padding: 14px 0; }
.nr-i { display: grid; grid-template-columns: 10px 1fr auto; gap: 5px 8px; align-items: center; padding: 8px 10px; border-radius: 10px; text-decoration: none; color: #ffe9a8;
  background: rgba(255,255,255,.04); border: 1px solid transparent; transition: background .15s, border-color .15s, transform .15s; }
.nr-i:hover { background: rgba(255,210,63,.1); border-color: #2b4f94; transform: translateX(2px); }
.nr-i.cur { background: rgba(56,189,248,.16); border-color: #38bdf8; }
.nr-i .nd { width: 9px; height: 9px; border-radius: 50%; background: #6b7a99; }
.nr-i.ok .nd { background: #22c58b; box-shadow: 0 0 6px #22c58b; }
.nr-i.warn .nd { background: #ff9f1c; box-shadow: 0 0 6px #ff9f1c; animation: pulse 2s infinite; }
.nr-i.off { opacity: .6; }
.nr-i .nm { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nr-i .os { font-size: 10px; font-weight: 800; color: #ff9f1c; border: 1px solid rgba(255,159,28,.45); border-radius: 5px; padding: 0 4px; }
.nr-i .bar { grid-column: 1 / -1; height: 3px; border-radius: 2px; background: #16294f; overflow: hidden; }
.nr-i .bar i { display: block; height: 100%; background: #38bdf8; border-radius: 2px; transition: width .6s; }
.nr-i.warn .bar i { background: #ff9f1c; }
@media print { .nrail { display: none !important; } }

/* 노드 레일: 이름 전체 표시 (배지는 2행으로) */
.nr-i { grid-template-columns: auto 1fr; grid-template-areas: "nd nm" "os bar"; gap: 5px 7px; }
.nr-i .nd { grid-area: nd; }
.nr-i .nm { grid-area: nm; white-space: normal; word-break: break-all; line-height: 1.2; font-size: 12px; }
.nr-i .os { grid-area: os; }
.nr-i .bar { grid-area: bar; grid-column: auto; }

/* 노드 레일: 이름 전폭, 2행에 점·배지·CPU 바 */
.nrail { padding: 12px 8px; }
.nr-i { grid-template-columns: auto auto 1fr; grid-template-areas: "nm nm nm" "nd os bar"; padding: 8px 9px; gap: 6px 6px; }
.nr-i .nm { grid-area: nm; white-space: normal; word-break: normal; overflow-wrap: anywhere; font-size: 12.5px; line-height: 1.25; }
.nr-i .nd { grid-area: nd; }
.nr-i .os { grid-area: os; }
.nr-i .bar { grid-area: bar; grid-column: auto; }

/* ===== 라이트 테마: KPI 타일 · 노드 레일 (다크 테마는 위의 어두운 스타일 유지) ===== */
:root:not([data-theme="dark"]) #kpi .tk { background: linear-gradient(135deg, #ffffff 0%, #f1f6ff 100%); border: 1px solid #dfe7f6; box-shadow: 0 4px 14px rgba(40,70,140,.08); }
:root:not([data-theme="dark"]) #kpi .tk .k { color: #c9660a; }
:root:not([data-theme="dark"]) #kpi .tk .tv { color: #16233f; text-shadow: none; -webkit-text-fill-color: #16233f; }
:root:not([data-theme="dark"]) #kpi .tk .tv small { color: #c9660a; -webkit-text-fill-color: #c9660a; }
:root:not([data-theme="dark"]) #kpi .tk.warn .tv { color: #d97706; -webkit-text-fill-color: #d97706; }
:root:not([data-theme="dark"]) #kpi .tk.bad .tv { color: #dc3545; -webkit-text-fill-color: #dc3545; }
:root:not([data-theme="dark"]) #kpi .tk .rt { stroke: #e3eaf7; }
:root:not([data-theme="dark"]) #kpi .tk .rv { stroke: #2f6bff; filter: drop-shadow(0 0 3px rgba(47,107,255,.4)); }
:root:not([data-theme="dark"]) #kpi .tk.warn .rv { stroke: #f59e0b; filter: drop-shadow(0 0 3px rgba(245,158,11,.5)); }
:root:not([data-theme="dark"]) #kpi .tk.bad .rv { stroke: #ef4444; filter: drop-shadow(0 0 4px rgba(239,68,68,.5)); }
:root:not([data-theme="dark"]) #kpi .tk-flow.down { color: #2f6bff; }
:root:not([data-theme="dark"]) #kpi .tk-flow.up { color: #f59e0b; }
:root:not([data-theme="dark"]) #kpi .tk .usub { color: #b8741a; }
:root:not([data-theme="dark"]) #kpi .tk .tgl { color: #9aa7c2; }
:root:not([data-theme="dark"]) #kpi .tk .tgl:hover { color: #2f6bff; }
:root:not([data-theme="dark"]) #kpi .cf { fill: #f5f8fe; stroke: #d7e1f3; }
:root:not([data-theme="dark"]) #kpi .tick { stroke: #9fb0d0; }
:root:not([data-theme="dark"]) #kpi .clk .tick:nth-child(3n+2) { stroke: #16233f; }
:root:not([data-theme="dark"]) #kpi .clkn { fill: #16233f; }
:root:not([data-theme="dark"]) #kpi .hh { stroke: #16233f; }
:root:not([data-theme="dark"]) #kpi .mh { stroke: #3a4f7a; }
:root:not([data-theme="dark"]) #kpi .sh { stroke: #ef4444; }
:root:not([data-theme="dark"]) #kpi .cc { fill: #ef4444; }

:root:not([data-theme="dark"]) .nrail { background: linear-gradient(160deg, #ffffff 0%, #f1f6ff 100%); border: 1px solid #dfe7f6; box-shadow: 0 6px 20px rgba(40,70,140,.10); }
:root:not([data-theme="dark"]) .nr-h { color: #c9660a; }
:root:not([data-theme="dark"]) .nr-c { background: rgba(245,158,11,.15); color: #b45309; }
:root:not([data-theme="dark"]) .nr-q { background: #fff; border-color: #d7e1f3; color: #16233f; }
:root:not([data-theme="dark"]) .nr-q:focus { border-color: #2f6bff; }
:root:not([data-theme="dark"]) .nr-q::placeholder { color: #9aa7c2; }
:root:not([data-theme="dark"]) .nr-f button { border-color: #d7e1f3; color: #b45309; background: #fff; }
:root:not([data-theme="dark"]) .nr-f button:hover { border-color: #f59e0b; }
:root:not([data-theme="dark"]) .nr-f button.on { background: #f59e0b; border-color: #f59e0b; color: #fff; }
:root:not([data-theme="dark"]) .nr-i { background: #fff; border-color: #e6edf8; color: #16233f; }
:root:not([data-theme="dark"]) .nr-i:hover { background: #eef4ff; border-color: #b9ccf2; }
:root:not([data-theme="dark"]) .nr-i.cur { background: #e8f0ff; border-color: #2f6bff; }
:root:not([data-theme="dark"]) .nr-i .nd { background: #b3bdd1; }
:root:not([data-theme="dark"]) .nr-i.ok .nd { background: #12a46b; box-shadow: 0 0 5px rgba(18,164,107,.5); }
:root:not([data-theme="dark"]) .nr-i.warn .nd { background: #f59e0b; box-shadow: 0 0 5px rgba(245,158,11,.6); }
:root:not([data-theme="dark"]) .nr-i .os { color: #b45309; border-color: rgba(245,158,11,.5); }
:root:not([data-theme="dark"]) .nr-i .bar { background: #e6edf8; }
:root:not([data-theme="dark"]) .nr-i .bar i { background: #2f6bff; }
:root:not([data-theme="dark"]) .nr-i.warn .bar i { background: #f59e0b; }
:root:not([data-theme="dark"]) .nr-e { color: #9aa7c2; }
:root:not([data-theme="dark"]) .nr-l { scrollbar-color: #c5d3ee transparent; }

/* 현황 하단 요약 패널 */
.fx { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-top: 20px; }
@media (max-width: 1100px) { .fx { grid-template-columns: 1fr 1fr; } }
@media (max-width: 700px) { .fx { grid-template-columns: 1fr; } }
.fxp { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; box-shadow: 0 2px 10px rgba(40,70,140,.06); min-width: 0; }
.fxp h3 { margin: 0 0 14px; font-size: 14px; color: var(--text); }
.fxp h3 span { color: var(--muted); font-weight: 400; font-size: 12px; margin-left: 8px; }
.dn-w { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.dn { width: 132px; height: 132px; flex: none; }
.dn-t { fill: none; stroke: var(--border); stroke-width: 14; }
.dn-a { fill: none; stroke-width: 14; transition: stroke-dasharray .6s, stroke-dashoffset .6s; }
.dn-n { text-anchor: middle; dominant-baseline: central; font-size: 24px; font-weight: 700; fill: var(--text); }
.dn-s { text-anchor: middle; font-size: 8px; fill: var(--muted); }
.dn-l { display: grid; gap: 8px; font-size: 13px; color: var(--text); }
.dn-l span { display: flex; align-items: center; gap: 8px; }
.dn-l i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.dn-l b { margin-left: auto; padding-left: 14px; font-variant-numeric: tabular-nums; }
.tp + .tp { margin-top: 12px; }
.tpl { font-size: 11.5px; color: var(--muted); font-weight: 600; letter-spacing: .04em; margin-bottom: 4px; }
.tpr { display: grid; grid-template-columns: minmax(70px, 38%) 1fr auto; gap: 10px; align-items: center; padding: 4px 0; text-decoration: none; color: var(--text); font-size: 12.5px; }
.tpr:hover .tn { color: var(--accent); }
.tn { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.tb i { display: block; height: 100%; border-radius: 3px; background: var(--accent); transition: width .6s; }
.tb i.warn { background: var(--warn); }
.tv { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 42px; text-align: right; }
.tpe { color: var(--muted); font-size: 12px; padding: 4px 0; }
.fa-l { display: grid; gap: 6px; }
.fa { display: grid; grid-template-columns: 10px auto 1fr; gap: 8px; align-items: center; padding: 8px 10px; border-radius: 10px; text-decoration: none; background: var(--surface2); border: 1px solid var(--border); color: var(--text); font-size: 12.5px; }
.fa:hover { border-color: var(--accent); }
.fa i { width: 9px; height: 9px; border-radius: 50%; background: var(--warn); }
.fa.crit i { background: var(--bad); box-shadow: 0 0 6px var(--bad); }
.fa span { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fa.more { display: block; text-align: center; color: var(--accent); font-weight: 600; }
.fa-ok { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 18px 0; color: var(--ok); font-size: 13px; font-weight: 600; }

/* 현황 하단 패널 보정 */
.fxp { display: flex; flex-direction: column; }
.dn-w { flex: 1; justify-content: center; gap: 28px; }
.dn { width: 170px; height: 170px; }
.dn-n { font-size: 26px; }
.dn-s { font-size: 7px; }
.dn-l { font-size: 14px; gap: 12px; }
.fa-l { flex: 1; align-content: start; }
.fa-ok { flex: 1; justify-content: center; padding: 0; }
.tpr { padding: 3px 0; }

/* 모바일: 메뉴를 아래 한 줄로 내리고 전체 폭 스크롤 */
.mainnav { position: relative; }
@media (max-width: 760px) {
  .top { height: auto; flex-wrap: wrap; row-gap: 6px; padding-bottom: 8px; }
  .top .mainnav { order: 10; flex: 1 0 100%; margin: 2px 0 0; padding: 2px 0;
    -webkit-mask-image: linear-gradient(90deg, #000 90%, transparent); mask-image: linear-gradient(90deg, #000 90%, transparent); }
  .mainnav a { padding: 7px 12px; font-size: 14px; }
}

/* 지도: 모바일/인앱 브라우저에서 늘어나지 않게 고정 + 클리핑 */
.gmapbox { contain: layout paint; isolation: isolate; }
.gmap { height: min(440px, 62vh); min-height: 280px; max-height: 480px; overflow: hidden; contain: layout paint; }
.gmap .leaflet-pane, .gmap .leaflet-tile-pane { max-height: none; }

/* 모바일 임시 방어: 차트/표 폭 초과, 기간 탭 줄바꿈 */
@media (max-width: 760px) {
  .panel, .panel.wide, .view, #view { min-width: 0; max-width: 100%; box-sizing: border-box; }
  .panel svg, .panel canvas { max-width: 100%; height: auto; }
  .panel table { display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; }
  .seg, .tabs, .range, .seg-wrap { display: flex; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  .seg button, .tabs button, .range button, .seg a { white-space: nowrap; flex: 0 0 auto; }
}

/* ===== 모바일 v2 ===== */
#crumbs { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#crumbs a, #crumbs b, #crumbs .sep { white-space: nowrap; }
@media (max-width: 760px) {
  .panel, .panel.wide { min-width: 0; max-width: 100%; overflow-x: auto; }
  .seg { max-width: 100%; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .seg button { white-space: nowrap; flex: 0 0 auto; }
  .detail-head { flex-wrap: wrap; gap: 8px; }
  .tbl { display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; }

  /* 알림: 표 → 카드 */
  #aHist .tbl, #aAct .tbl { display: block; white-space: normal; overflow: visible; }
  #aHist thead, #aAct thead { display: none; }
  #aHist tbody, #aAct tbody { display: block; }
  #aHist tr, #aAct tr { display: grid; gap: 4px 8px; align-items: center; padding: 10px 2px; border-bottom: 1px solid var(--border, #e3e8f2); }
  #aHist td, #aAct td { display: block; padding: 0; border: 0; white-space: normal; }
  /* 이력: 시각 · 상태 · 등급 · 호스트 / 내용 */
  #aHist tr { grid-template-columns: auto auto auto 1fr; }
  #aHist td:nth-child(4) { text-align: right; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  #aHist td:nth-child(5) { grid-column: 1 / -1; }
  #aHist td:nth-child(6) { display: none; }
  /* 진행 중: 등급 · 호스트 · 경과 / 항목 / 내용 */
  #aAct tr { grid-template-columns: auto 1fr auto; }
  #aAct td:nth-child(5) { grid-row: 1; grid-column: 3; }
  #aAct td:nth-child(3), #aAct td:nth-child(4) { grid-column: 1 / -1; }
}

/* ===== 모바일 v3: 부모 폭 확장 방지 ===== */
@media (max-width: 760px) {
  #view, #view > *, #sbody, #hstats, .toolbar, .detail-head { min-width: 0; max-width: 100%; box-sizing: border-box; }
  .dn-w { justify-content: center; }
  .chart { max-width: 100%; overflow: hidden; }
  .chart svg, .chart canvas { max-width: 100%; }
  .tbl.stat th, .tbl.stat td { padding: 8px 10px; font-size: 13px; }
}

/* ===== 모바일 내부맵: 세로 카드 목록 ===== */
.mlist { display: flex; flex-direction: column; gap: 6px; padding: 12px 10px; }
.mlist a { text-decoration: none; color: inherit; display: block; }
.mn { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0;
  background: var(--surface2); border: 1px solid var(--border); border-left: 4px solid var(--c, var(--ok)); border-radius: 12px; padding: 10px 12px; }
.mn.off { opacity: .75; border-style: dashed; border-left-style: solid; }
.mb { min-width: 0; }
.mb b { display: block; font-size: 15px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb small { display: block; font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr { font-size: 12px; line-height: 1.5; text-align: right; white-space: nowrap; color: var(--ok); font-variant-numeric: tabular-nums; }
.mgap { height: 12px; margin-left: 20px; border-left: 2px dashed var(--ok); }
.mgap.off { border-left-color: var(--off); }
.mgrp { display: flex; flex-direction: column; gap: 6px; margin-left: 20px; padding-left: 12px; border-left: 2px dashed var(--ok); }
.mgrp.off { border-left-color: var(--off); }

/* 모바일 내부맵 다듬기: 부제목 줄바꿈, 끊긴 포트 컴팩트 */
.mb small { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.45; }
.mn.mp.off { padding: 6px 12px; }
.mn.mp.off .mb b { font-size: 13px; display: inline; }
.mn.mp.off .mb small { display: inline; margin-left: 8px; font-size: 11px; }
.mgap.off { height: 6px; }

/* ===== 모바일 v4: KPI 카드 + 툴팁 클리핑 ===== */
@media (max-width: 760px) {
  .panel, .panel.wide { overflow: visible; }
  .panel.gmapbox { overflow: hidden; }
  .tile.tk { padding: 12px 12px; gap: 6px; }
  .tile .tt1 { min-width: 0; flex: 1 1 auto; }
  .tile .k { white-space: nowrap; font-size: 12px; }
  .tile .tv .num { font-size: clamp(20px, 6.4vw, 26px); white-space: nowrap; }
  .tile .ring { width: 44px; height: 44px; }
  .tile .arrows { transform: scale(.8); transform-origin: right center; }
  .tile.tk-up { grid-column: 1 / -1; }
}

/* 설정: 입력 쌍 묶기 + 모바일 */
.pr { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.fc { gap: 6px 14px; }
@media (max-width: 760px) {
  .num .fi { width: 64px; }
  .savebar { gap: 10px; padding: 10px 12px; }
  .savebar button { white-space: nowrap; flex: none; }
  .savebar #saveMeta { min-width: 0; font-size: 12px; }
}

/* ===== 모바일 로그 ===== */
@media (max-width: 760px) {
  #p-logs h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
  .logtools { margin-left: 0; width: 100%; display: flex; gap: 8px; }
  .logtools select { flex: 0 0 auto; }
  .logtools input { flex: 1 1 0; min-width: 0; width: auto; }
  .logrow { grid-template-columns: auto 1fr; gap: 0 10px; padding: 7px 2px; }
  .logrow .m { grid-column: 1 / -1; }
  .logs { font-size: 12px; }
}

/* ===== 가로 모드: 헤더 한 줄 + 고정 해제 ===== */
@media (orientation: landscape) and (max-width: 950px) {
  .top { flex-wrap: nowrap; height: 56px; padding-bottom: 0; row-gap: 0; }
  .top .mainnav { order: 0; flex: 1 1 0; min-width: 0; margin: 0 0 0 8px; -webkit-mask-image: none; mask-image: none; }
}
@media (max-height: 520px) {
  .top { position: static !important; }
}

/* ===== 모바일: 보안 기록 / 계정 목록 카드 ===== */
@media (max-width: 760px) {
  .tbl.at, .tbl.ut { display: block; white-space: normal; overflow: visible; }
  .tbl.at thead, .tbl.ut thead, .tbl.at tbody, .tbl.ut tbody { display: block; }
  .tbl.at thead, .tbl.ut thead { display: none; }
  .tbl.at tr, .tbl.ut tr { display: grid; gap: 4px 10px; align-items: center; padding: 11px 2px; border-bottom: 1px solid var(--border, #e3e8f2); }
  .tbl.at td, .tbl.ut td { display: block; padding: 0; border: 0; white-space: normal; min-width: 0; word-break: break-word; }
  .tbl.at td:empty, .tbl.ut td:empty { display: none; }

  /* 보안 기록: 시각 | 종류 / 수행자 / 대상 / IP / 내용 */
  .tbl.at tr { grid-template-columns: 1fr auto; }
  .tbl.at tbody td:nth-child(1) { grid-column: 1; grid-row: 1; color: var(--muted); font-size: 12.5px; }
  .tbl.at tbody td:nth-child(2) { grid-column: 2; grid-row: 1; }
  .tbl.at tbody td:nth-child(n+3) { grid-column: 1 / -1; font-size: 13px; }
  .tbl.at tbody td:nth-child(3)::before { content: "수행자 "; color: var(--muted); }
  .tbl.at tbody td:nth-child(4)::before { content: "대상 "; color: var(--muted); }
  .tbl.at tbody td:nth-child(5)::before { content: "IP "; color: var(--muted); }

  /* 계정: 상태 | 아이디 | 권한 / 이름·팀·이메일·전화·최근로그인 / 버튼 */
  .tbl.ut tr { grid-template-columns: auto 1fr auto; }
  .tbl.ut tbody td:nth-child(1) { grid-column: 1; grid-row: 1; }
  .tbl.ut tbody td:nth-child(2) { grid-column: 2; grid-row: 1; font-size: 15px; }
  .tbl.ut tbody td:nth-child(4) { grid-column: 3; grid-row: 1; }
  .tbl.ut tbody td:nth-child(3) { grid-column: 1 / -1; grid-row: 2; }
  .tbl.ut tbody td:nth-child(n+5) { grid-column: 1 / -1; color: var(--muted); font-size: 12.5px; }
  .tbl.ut tbody td:nth-child(8)::before { content: "최근 로그인 "; }
  .tbl.ut tbody td:nth-child(9) { color: inherit; }
}

/* 보안 기록 카드 컴팩트: 시각·종류 / 수행자·대상·IP / 내용 */
@media (max-width: 760px) {
  .tbl.at tr { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 10px; }
  .tbl.at tbody td:nth-child(1) { grid-column: 1 / 3; grid-row: 1; }
  .tbl.at tbody td:nth-child(2) { grid-column: 3; grid-row: 1; justify-self: end; }
  .tbl.at tbody td:nth-child(3) { grid-column: 1; grid-row: 2; }
  .tbl.at tbody td:nth-child(4) { grid-column: 2; grid-row: 2; }
  .tbl.at tbody td:nth-child(5) { grid-column: 3; grid-row: 2; }
  .tbl.at tbody td:nth-child(6) { grid-column: 1 / -1; grid-row: 3; color: var(--muted); }
  .tbl.at tbody td:nth-child(n+3):nth-child(-n+5) { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tbl.at tbody td:nth-child(n+3):nth-child(-n+5)::before { display: block; font-size: 10.5px; color: var(--muted); font-weight: 400; }
}

@media (max-width: 760px) {
  .tbl.at tr { grid-template-columns: minmax(0, .8fr) minmax(0, .8fr) minmax(0, 1.4fr); }
  .tbl.at tbody td:nth-child(5) { overflow: visible; text-overflow: clip; }
}

/* 지도 높이 고정 */
.gmapbox { contain: layout paint; isolation: isolate; }
.gmap { height: 440px; max-height: 62vh; min-height: 280px; overflow: hidden; }
@media (max-width: 760px) { .gmap { height: 52vh; max-height: 440px; } }

.kavg { font-size: 11px; color: var(--muted); margin-top: 3px; white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 760px) { .kavg { white-space: normal; line-height: 1.35; } }

/* 외부 접속 맵 */
.accbox { position: relative; margin-top: 18px; }
.acchd { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.accsub { color: var(--muted); font-size: 12px; }
.accmap { border-radius: 14px; overflow: hidden; border: 1px solid #1d3b73; background: radial-gradient(ellipse at center, #0d2147 0%, #070d1f 55%, #04060d 100%); box-shadow: inset 0 0 60px rgba(30,90,200,.12); }
.accmap .empty { color: #7f95c7; padding: 60px 0; }
.accsvg { display: block; width: 100%; height: auto; max-height: 680px; }
.accring { fill: none; stroke: #1d3b73; stroke-width: 1; opacity: .55; stroke-dasharray: 2 6; }
.achit { fill: none; stroke: transparent; }
.acl { fill: none; stroke-linecap: round; opacity: .55; transition: opacity .15s; }
.acl.live { stroke-dasharray: 10 8; animation: accflow 1.2s linear infinite; }
@keyframes accflow { to { stroke-dashoffset: -18; } }
.ace.hot .acl { opacity: 1; filter: brightness(1.5); }
.acc { stroke: #0a1733; stroke-width: 2; }
.acc.priv { stroke: #cfe0ff; stroke-dasharray: 3 2; }
.acn { font-size: 11.5px; fill: #b6c6ea; pointer-events: none; }
.ace.hot .acn { fill: #fff; font-weight: 700; }
.acchub { fill: #0b1a38; stroke: #38bdf8; stroke-width: 2.5; filter: drop-shadow(0 0 10px #38bdf8); }
.accpulse { fill: none; stroke: #38bdf8; stroke-width: 2; transform-box: fill-box; transform-origin: center; animation: accpulse 2.4s ease-out infinite; }
@keyframes accpulse { 0% { transform: scale(1); opacity: .7; } 100% { transform: scale(1.9); opacity: 0; } }
.acct1 { fill: #ffd23f; font-size: 15px; font-weight: 800; text-anchor: middle; }
.acct2 { fill: #ff9f1c; font-size: 11px; text-anchor: middle; }
.acctip { position: absolute; display: none; z-index: 5; pointer-events: none; min-width: 210px; max-width: 300px; padding: 10px 12px; border-radius: 10px; background: rgba(18,26,48,.95); border: 1px solid #2b4f94; color: #dbe6ff; font-size: 12px; line-height: 1.7; box-shadow: 0 8px 24px rgba(0,0,0,.4); }
.acctip b { color: #ffd23f; }
.acctip small { color: #9fb0d0; }
.acclg { margin-top: 10px; }
.acclg i.dsh { border: 2px dashed #7f95c7; background: transparent !important; border-radius: 50%; }
.acclg small { margin-left: auto; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .acl.live, .accpulse { animation: none; } }

/* 100대 대응: 종류 필터·더 보기 */
.toolbar #kinds{margin-left:8px}
.kmore{grid-column:1/-1;justify-self:center;padding:9px 22px;border:1px solid var(--border);border-radius:10px;background:var(--surface);color:var(--accent);font-weight:600;cursor:pointer}
.kmore:hover{background:var(--surface2)}

/* 시스템 종류 아이콘 */
.sico { vertical-align: -3px; margin-right: 4px; color: var(--accent); flex: none; }
.pin .sico { margin-right: 3px; }
.sico-security { color: var(--warn); }
.sico-windows { color: #4c9be8; }

/* 전체 호스트 타일: 종류별 개수 칩 */
.kchips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.kchip { display: inline-flex; align-items: center; gap: 2px; padding: 2px 9px 2px 7px; font: inherit; font-size: 12px; color: var(--muted); cursor: pointer;
  background: transparent; border: 1px solid color-mix(in srgb, var(--muted) 35%, transparent); border-radius: 999px; }
.kchip b { color: var(--text, inherit); margin-left: 2px; }
.kchip:hover { border-color: var(--accent); color: var(--accent); }
.kchip.on { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* 체험판 배지 */
.licbadge { position: fixed; right: 14px; bottom: 14px; z-index: 50; padding: 6px 14px; font-size: 12px; font-weight: 600; color: var(--accent); background: var(--surface); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); border-radius: 999px; box-shadow: var(--shadow); }
.licbadge.soon { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); background: color-mix(in srgb, var(--warn) 10%, var(--surface)); }
