/* theme_topology.css — demo.css 를 .topo-root 스코프로 격리 이식. keyframes=topo- 접두사. 운영 CSS 무충돌. */


.topo-root{
  --bg:#eef1f6;
  --card:#ffffff;
  --line:#e6eaf1;
  --line-strong:#d7dce6;
  --text:#111827;
  --text-2:#374151;
  --muted:#6b7280;
  --muted-2:#94a3b8;

  --blue:#1070dd;
  --blue-2:#2563eb;
  --blue-soft:#7bbfff;
  --blue-bg:#eff6ff;
  --led:#7bbfff;

  --gray:#99a1af;
  --gray-2:#d1d5dc;
  --green:#16a34a;
  --amber:#f59e0b;
  --red:#ed4545;

  --shadow:0 2px 6px rgba(15,23,42,.08);
  --shadow-md:0 6px 18px rgba(15,23,42,.10);
  --shadow-lg:0 14px 38px rgba(15,23,42,.14);
  --radius:14px;
  --radius-sm:10px;
}

.topo-root *{ box-sizing:border-box; }

.topo-root html, .topo-root body{ margin:0; padding:0; }

.topo-root body{
  font-family:'Pretendard',system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  color:var(--text);
  background:
    radial-gradient(1100px 520px at 78% -8%, rgba(16,112,221,.10), transparent 60%),
    radial-gradient(820px 460px at 8% 4%, rgba(123,191,255,.12), transparent 60%),
    var(--bg);
  background-attachment:fixed;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}


.topo-root .app{ max-width:1480px; margin:0 auto; padding:18px 26px 40px; }

.topo-root .app.app-v{ max-width:1880px; padding:18px 20px 40px; }

.topo-root .app.app-3d{ max-width:1180px; }

.topo-root a{ color:inherit; }


.topo-root .topbar{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  background:#fff;
  border:1px solid var(--line);
  border-radius:14px;
  padding:14px 20px;
  box-shadow:var(--shadow);
  position:sticky; top:10px; z-index:50;
}

.topo-root .brand{ display:flex; align-items:center; gap:14px; min-width:0; }
.topo-root .brand-logo{ height:36px; width:auto; object-fit:contain; }
.topo-root .brand-fallback{
  display:none; align-items:center; height:36px; padding:0 12px;
  font-weight:900; letter-spacing:.06em; color:var(--blue);
  background:var(--blue-bg); border-radius:8px; font-size:18px;
}
.topo-root .brand-divider{ width:1px; height:28px; background:#e5e7eb; }
.topo-root .brand-title{ font-size:18px; font-weight:700; letter-spacing:-.01em; }
.topo-root .brand-sub{ font-size:12px; color:var(--muted); margin-top:2px; }

.topo-root .topbar-right{ display:flex; align-items:center; gap:14px; flex-shrink:0; }

.topo-root .conn-status{
  display:inline-flex; align-items:center; gap:7px;
  font-size:12.5px; font-weight:600; color:#15803d; white-space:nowrap;
}
.topo-root .conn-dot{ width:8px; height:8px; border-radius:50%; background:var(--green); animation: topo-livePulse 1.6s ease-in-out infinite; }

.topo-root .topbar-clock{
  display:inline-flex; align-items:center; gap:7px;
  font-size:13px; font-weight:600; color:var(--text-2);
  padding:7px 12px; border-radius:8px; background:#f3f4f6;
  font-variant-numeric:tabular-nums;
}
.topo-root .topbar-clock i{ color:var(--muted-2); }

.topo-root .topbar-user{ display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:700; color:var(--text-2);
  padding:7px 11px; border-radius:8px; background:#f3f4f6; font-variant-numeric:tabular-nums; white-space:nowrap; }
.topo-root .topbar-user i{ color:var(--muted-2); }
.topo-root .topbar-logout{ display:inline-flex; align-items:center; gap:6px; font-family:inherit; font-size:12.5px; font-weight:700;
  color:#64748b; background:#fff; border:1px solid var(--line-strong); border-radius:8px; padding:7px 12px; cursor:pointer;
  white-space:nowrap; transition:all .12s ease; }
.topo-root .topbar-logout:hover{ border-color:var(--red); color:var(--red); background:#fef2f2; }
.topo-root .topbar-logout i{ font-size:12px; }


.topo-root .summary{
  display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin:16px 0;
}
.topo-root .sum-card{
  background:var(--card); border-radius:var(--radius); padding:15px 18px;
  box-shadow:var(--shadow); display:flex; align-items:center; gap:14px;
  border:1px solid var(--line);
}
.topo-root .sum-ic{
  width:44px; height:44px; border-radius:50%; flex-shrink:0;
  display:flex; align-items:center; justify-content:center; font-size:17px; color:#fff;
}
.topo-root .sum-ic.ctrl{ background:#475569; }
.topo-root .sum-ic.unit{ background:var(--blue); }
.topo-root .sum-ic.run{ background:var(--green); }
.topo-root .sum-ic.stop{ background:#94a3b8; }
.topo-root .sum-ic.o2{ background:var(--blue); }
.topo-root .sum-info{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.topo-root .sum-label{ font-size:12px; color:var(--muted); font-weight:600; }
.topo-root .sum-val{ display:flex; align-items:baseline; gap:3px; }
.topo-root .sum-num{ font-size:23px; font-weight:800; color:var(--text); font-variant-numeric:tabular-nums; line-height:1; }
.topo-root .sum-unit{ font-size:13px; font-weight:600; color:var(--text-2); }


.topo-root .master{
  background:var(--card); border-radius:var(--radius); padding:14px 18px;
  box-shadow:var(--shadow); border:1px solid var(--line);
  display:flex; align-items:center; gap:22px; flex-wrap:wrap; margin-bottom:20px;
}
.topo-root .master-title{ font-size:14px; font-weight:800; color:var(--text-2); display:flex; align-items:center; gap:8px; }
.topo-root .master-title i{ color:var(--blue); }
.topo-root .master-groups{ display:flex; gap:26px; flex-wrap:wrap; flex:1; }
.topo-root .mgroup{ display:flex; align-items:center; gap:12px; }
.topo-root .mgroup-label{ font-size:12.5px; font-weight:700; color:var(--muted); }
.topo-root .mgroup-btns{ display:flex; gap:8px; }
.topo-root .mbtn{
  border:none; cursor:pointer; font-weight:800; font-size:13px; letter-spacing:.02em;
  padding:9px 16px; border-radius:9px; color:#fff;
  box-shadow:0 1px 3px rgba(15,23,42,.14);
  transition:transform .08s ease, filter .12s ease, box-shadow .12s ease;
}
.topo-root .mbtn:hover{ transform:translateY(-1px); filter:brightness(1.05); box-shadow:var(--shadow-md); }
.topo-root .mbtn:active{ transform:translateY(1px) scale(.98); }
.topo-root .mbtn.on{ background:var(--blue); }
.topo-root .mbtn.off{ background:var(--gray); }
.topo-root .mbtn.led-on{ background:var(--led); }
.topo-root .mbtn.led-off{ background:var(--gray); }


.topo-root .layout-switch{ margin-left:auto; }
.topo-root .layout-switch .mgroup-label{ display:inline-flex; align-items:center; gap:6px; }
.topo-root .layout-switch .mgroup-label i{ color:var(--blue); }
.topo-root .layout-select{
  font-family:inherit; font-size:13px; font-weight:700; color:var(--text-2);
  background:#fff; border:1px solid #d7dce6; border-radius:9px; padding:9px 32px 9px 12px;
  cursor:pointer; appearance:none; -webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' stroke='%23667085' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 11px center;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.topo-root .layout-select:hover{ border-color:var(--blue); }
.topo-root .layout-select:focus{ outline:none; border-color:var(--blue); box-shadow:0 0 0 3px rgba(16,112,221,.12); }



.topo-root .zone{
  background:var(--card); border-radius:12px; border:1px solid #e1e5ec;
  box-shadow:0 1px 2px rgba(15,23,42,.04); padding:16px 20px 20px; margin-bottom:16px;
  position:relative; overflow:hidden;
}
.topo-root .zone::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--blue);
}


.topo-root .zones.layout-v1, .topo-root .zones.layout-v2{
  display:grid; grid-template-columns:repeat(3,1fr); gap:16px; align-items:start;
}
.topo-root .zones.layout-v1 .zone, .topo-root .zones.layout-v2 .zone{ margin-bottom:0; }

.topo-root .zones.layout-v1 .zone::before, .topo-root .zones.layout-v2 .zone::before{
  left:0; right:0; top:0; bottom:auto; width:auto; height:3px;
}

.topo-root .zone-head{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding-bottom:14px; margin-bottom:2px; border-bottom:1px solid #eef0f4;
  flex-wrap:wrap;
}
.topo-root .zone-title{ display:flex; align-items:center; gap:13px; min-width:0; }
.topo-root .zone-ic{
  width:42px; height:42px; border-radius:12px; flex-shrink:0;
  display:flex; align-items:center; justify-content:center; font-size:18px; color:#fff;
  background:#334155;
}
.topo-root .zt-name{ font-size:17px; font-weight:800; letter-spacing:-.01em; display:inline-flex; align-items:center; gap:6px; }
.topo-root .zt-sub{ font-size:12px; color:var(--muted); margin-top:2px; font-variant-numeric:tabular-nums; }


.topo-root .name-edit{
  border:none; background:transparent; cursor:pointer; padding:2px 3px; line-height:1;
  color:var(--muted-2); font-size:10px; opacity:.4; border-radius:5px;
  transition:opacity .12s ease, color .12s ease, background .12s ease; flex:0 0 auto;
}
.topo-root .zt-name:hover .name-edit, .topo-root .ctrl-name:hover .name-edit, .topo-root .cpop-head:hover .name-edit{ opacity:.85; }
.topo-root .name-edit:hover{ opacity:1; color:var(--blue); background:rgba(16,112,221,.10); }
.topo-root .cpop-head .name-edit{ font-size:9px; }
.topo-root .name-input{
  font:inherit; font-weight:800; letter-spacing:-.01em; color:#111827;
  border:1.5px solid var(--blue); border-radius:6px; padding:1px 7px;
  width:180px; max-width:100%; min-width:7ch; background:#fff; outline:none;
  box-shadow:0 0 0 3px rgba(16,112,221,.14);
}
.topo-root .cpop-head .name-input{ width:140px; font-size:12.5px; }
.topo-root .zone-meta{ display:flex; align-items:center; gap:14px; }
.topo-root .zmeta{ font-size:12.5px; font-weight:700; color:var(--text-2); display:inline-flex; align-items:center; gap:7px; }
.topo-root .zmeta.comm{ color:#15803d; }
.topo-root .zmeta .cdot{ width:8px; height:8px; border-radius:50%; background:var(--green); animation: topo-livePulse 1.4s ease-in-out infinite; }
.topo-root .zmeta.avg b{ font-size:15px; color:var(--blue); font-variant-numeric:tabular-nums; }


.topo-root .zone-topology{
  position:relative; display:grid;
  grid-template-columns: minmax(360px, 410px) 1fr;
  grid-template-areas: "ctrl dcg" "units units";
  align-items:start; gap:46px 90px; padding:16px 4px 6px;
}
.topo-root .zone-topology > .controller-node{ grid-area:ctrl; align-self:start; }
.topo-root .zone-topology > .discharger-group{ grid-area:dcg; align-self:stretch; }
.topo-root .zone-topology > .units-row{ grid-area:units; }
.topo-root .wires{
  position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; z-index:1; overflow:visible;
}

.topo-root .wire-dcg-line{ fill:none; stroke:var(--blue); stroke-width:3; opacity:.7; stroke-linecap:round; }
.topo-root .wire-dcg-dot{ fill:#fff; stroke:var(--blue); stroke-width:3.5; opacity:.95; }


.topo-root .controller-node{
  position:relative; z-index:2; align-self:start;
  display:flex; flex-direction:column; gap:13px;
  background:#eff5ff; border:1px solid #d4e4fb; border-radius:16px;
  padding:15px 16px 17px;
}


.topo-root .ctrl-head{ display:flex; align-items:center; gap:12px; }
.topo-root .ctrl-chip{
  position:relative; flex-shrink:0; width:54px; height:54px; border-radius:13px;
  background:#f3f7fd; border:1px solid #d4ddeb;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
}
.topo-root .ctrl-chip .radar{
  position:absolute; left:50%; top:50%; width:54px; height:54px; border-radius:50%;
  border:1.5px solid rgba(16,112,221,.26);
  transform:translate(-50%,-50%) scale(.5); opacity:0;
  animation: topo-radar 2.9s ease-out infinite; pointer-events:none;
}
.topo-root .ctrl-chip .fa-tower-broadcast{ font-size:20px; color:var(--blue); }
.topo-root .ctrl-chip .ctrl-signal{ display:flex; align-items:flex-end; gap:2.5px; height:10px; }
.topo-root .ctrl-chip .ctrl-signal span{ width:3.5px; border-radius:2px; background:var(--blue-soft); }
.topo-root .ctrl-chip .ctrl-signal span:nth-child(1){ height:4px; }
.topo-root .ctrl-chip .ctrl-signal span:nth-child(2){ height:6px; }
.topo-root .ctrl-chip .ctrl-signal span:nth-child(3){ height:8px; }
.topo-root .ctrl-chip .ctrl-signal span:nth-child(4){ height:10px; background:var(--blue); animation: topo-sigBlink 1.1s steps(1) infinite; }
.topo-root .ctrl-chip-led{ position:absolute; right:6px; top:6px; width:8px; height:8px; border-radius:50%;
  background:var(--green); animation: topo-ledBlink 1.6s ease-in-out infinite; }

.topo-root .ctrl-idblock{ flex:1; min-width:0; }
.topo-root .ctrl-name{ font-size:16px; font-weight:800; letter-spacing:-.01em; line-height:1.2; display:inline-flex; align-items:center; gap:6px; }
.topo-root .ctrl-sub{ font-size:12px; color:var(--muted); margin-top:2px; font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topo-root .ctrl-online{ flex-shrink:0; display:inline-flex; align-items:center; gap:6px;
  font-size:12px; font-weight:700; color:#15803d;
  background:#e8f8ef; border:1px solid #c6efd6; border-radius:999px; padding:4px 10px; white-space:nowrap; }
.topo-root .ctrl-online .dot{ width:7px; height:7px; border-radius:50%; background:var(--green); animation: topo-livePulse 1.5s ease-in-out infinite; }


.topo-root .ctrl-stats{ display:grid; grid-template-columns:repeat(3,1fr);
  background:#fff; border:1px solid #e1e9f5; border-radius:11px; overflow:hidden; }
.topo-root .cstat{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:4px; padding:9px 12px; min-width:0; }
.topo-root .cstat + .cstat{ border-left:1px solid #eaf0f9; }
.topo-root .cstat-k{ font-size:11px; color:var(--muted); font-weight:600; display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.topo-root .cstat-k i{ color:var(--muted-2); font-size:10px; }
.topo-root .cstat-v{ font-size:13.5px; font-weight:800; color:var(--text-2); font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topo-root .cstat-v.is-idle{ color:var(--muted-2); font-weight:700; }
.topo-root .ctrl-timer .cstat-v b{ color:var(--blue); font-weight:800; }

.topo-root .cstat-btn{ font-family:inherit; border:none; background:transparent; cursor:pointer; transition:background .12s ease; }
.topo-root .cstat-btn:hover{ background:#eef5ff; }
.topo-root .cstat-btn:focus-visible{ outline:2px solid var(--blue); outline-offset:-2px; }
.topo-root .cstat-edit{ font-size:8.5px !important; color:var(--muted-2) !important; opacity:0; transition:opacity .12s ease; }
.topo-root .cstat-btn:hover .cstat-edit{ opacity:.85; }


.topo-root .ctrl-controls{ display:flex; flex-direction:column; gap:8px; }
.topo-root .ctrl-actions{ display:flex; gap:8px; }
.topo-root .ctrl-toggle{
  flex:1; border:none; cursor:pointer; font-weight:800; font-size:13px; letter-spacing:-.01em; color:#fff;
  padding:11px 12px; border-radius:10px; background:var(--gray); box-shadow:none; white-space:nowrap;
  display:inline-flex; align-items:center; justify-content:center;
  transition:filter .12s ease, transform .08s ease, background .15s ease;
}
.topo-root .ctrl-toggle.is-on{ background:var(--blue); box-shadow:0 2px 8px rgba(16,112,221,.26); }
.topo-root .ctrl-toggle:hover{ filter:brightness(1.06); }
.topo-root .ctrl-toggle:active{ transform:scale(.98); }
.topo-root .ctrl-ledbtn{
  flex:1; border:1px solid #d7dce6; cursor:pointer; font-weight:800; font-size:13px; letter-spacing:-.01em; white-space:nowrap;
  color:#64748b; background:#fff; border-radius:10px; padding:11px 12px;
  display:inline-flex; align-items:center; justify-content:center; gap:6px; transition:all .12s ease;
}
.topo-root .ctrl-ledbtn i{ font-size:12px; }
.topo-root .ctrl-ledbtn:hover{ border-color:var(--blue); }
.topo-root .ctrl-ledbtn.is-active{ background:var(--led); border-color:var(--led); color:#fff; }
.topo-root .ctrl-sim{
  width:100%; border:1px solid #cfdcf2; background:#f3f8ff; color:#1d6fd0; cursor:pointer;
  font-weight:700; font-size:12.5px; padding:9px 12px; border-radius:10px;
  display:inline-flex; align-items:center; justify-content:center; gap:7px; transition:all .12s ease;
}
.topo-root .ctrl-sim i{ font-size:12px; }
.topo-root .ctrl-sim:hover{ background:#e7f1ff; border-color:var(--blue); transform:translateY(-1px); }

.topo-root .ctrl-actions-sub .ctrl-sim{ width:auto; flex:1; }
.topo-root .ctrl-graph{
  flex:1; border:1px solid #cfe3d6; background:#f1faf5; color:#15966a; cursor:pointer;
  font-weight:700; font-size:12.5px; padding:9px 12px; border-radius:10px;
  display:inline-flex; align-items:center; justify-content:center; gap:7px; transition:all .12s ease;
}
.topo-root .ctrl-graph i{ font-size:12px; }
.topo-root .ctrl-graph:hover{ background:#e3f5ec; border-color:var(--green); transform:translateY(-1px); }

.topo-root .cpop-graph{
  width:100%; margin-top:7px; border:1px solid #cfe3d6; background:#f1faf5; color:#15966a; cursor:pointer;
  font-weight:700; font-size:12px; padding:8px 10px; border-radius:9px;
  display:inline-flex; align-items:center; justify-content:center; gap:6px; transition:all .12s ease;
}
.topo-root .cpop-graph i{ font-size:11px; }
.topo-root .cpop-graph:hover{ background:#e3f5ec; border-color:var(--green); }

.topo-root .ctrl-port{
  position:absolute; left:50%; bottom:0; transform:translate(-50%,50%);
  width:14px; height:14px; border-radius:50%;
  background:#fff; border:3px solid var(--blue);
  box-shadow:0 0 0 4px rgba(16,112,221,.14);
  z-index:3;
}


.topo-root .units-row{
  width:100%; display:grid; grid-template-columns:repeat(3,1fr); gap:16px;
  z-index:2; position:relative;
}

.topo-root .unit-card{
  position:relative; background:#fff; border:1px solid #e3e6ec;
  border-radius:12px; box-shadow:0 1px 2px rgba(15,23,42,.03);
  display:flex; flex-direction:column; gap:8px;
  padding:12px 14px; overflow:hidden;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.topo-root .unit-card.running{ border-color:#bcd6f6; box-shadow:0 3px 12px rgba(16,112,221,.10); }
.topo-root .unit-card.pulse{ animation: topo-cardPulse .55s ease; }

.topo-root .unit-port{
  position:absolute; left:50%; top:0; transform:translate(-50%,-50%);
  width:13px; height:13px; border-radius:50%;
  background:#fff; border:3px solid var(--gray-2); z-index:5;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.topo-root .unit-card.running .unit-port{ border-color:var(--blue); box-shadow:0 0 0 4px rgba(16,112,221,.12); }


.topo-root .unit-cardhead{ display:flex; align-items:center; justify-content:space-between; gap:8px; }


.topo-root .unit-illust{ position:relative; align-self:center; width:98px; height:64px; display:flex; align-items:flex-end; justify-content:center; }
.topo-root .unit-machine{
  position:relative; width:86px; height:58px; border-radius:8px;
  background:#eef1f6;
  border:1px solid #d4d9e2;
  box-shadow:none;
  overflow:hidden;
}
.topo-root .unit-machine::before{ 
  content:""; position:absolute; left:10px; right:10px; top:8px; height:3px; border-radius:3px;
  background:repeating-linear-gradient(90deg,#c4ccd9 0 7px,transparent 7px 11px);
  opacity:.7;
}
.topo-root .unit-feet{ position:absolute; left:50%; bottom:-6px; transform:translateX(-50%); width:96px; height:6px; }
.topo-root .unit-feet::before, .topo-root .unit-feet::after{ content:""; position:absolute; bottom:0; width:14px; height:6px; border-radius:0 0 3px 3px; background:#9aa6b6; }
.topo-root .unit-feet::before{ left:6px; } .topo-root .unit-feet::after{ right:6px; }


.topo-root .unit-fan{ position:absolute; left:50%; top:52%; transform:translate(-50%,-50%); width:46px; height:46px; }
.topo-root .grille-face{ fill:#eef2f7; stroke:#cdd6e2; stroke-width:1.5; }
.topo-root .fan-blades{ transform-origin:50px 50px; animation: topo-fanSpin 2.6s linear infinite; animation-play-state:paused; }
.topo-root .unit-card.running .fan-blades{ animation-play-state:running; animation-duration:1.1s; }
.topo-root .fan-blades ellipse{ fill:#c2ccd9; }
.topo-root .unit-card.running .fan-blades ellipse{ fill:#6aa6ea; }
.topo-root .grille{ fill:none; }
.topo-root .grille circle, .topo-root .grille line{ fill:none; stroke:#aeb9c9; stroke-width:1.4; stroke-linecap:round; }
.topo-root .fan-hub{ fill:#8593a4; }
.topo-root .unit-card.running .fan-hub{ fill:#1070dd; }


.topo-root .unit-statuslight{
  position:absolute; right:9px; top:8px; width:8px; height:8px; border-radius:50%;
  background:#b8c2d0; z-index:3;
}
.topo-root .unit-card.running .unit-statuslight{ background:var(--green); box-shadow:0 0 7px rgba(34,197,94,.8); animation: topo-ledBlink 1.5s ease-in-out infinite; }


.topo-root .unit-underglow{
  position:absolute; left:8px; right:8px; bottom:5px; height:7px; border-radius:7px;
  background:var(--led); opacity:0; filter:blur(3px); transition:opacity .25s ease; z-index:2;
}
.topo-root .unit-card.led-on .unit-underglow{ opacity:.9; animation: topo-ledGlow 2.2s ease-in-out infinite; }
.topo-root .unit-machine .led-bar{
  position:absolute; left:14px; right:14px; bottom:7px; height:3px; border-radius:3px;
  background:#cdd6e3; transition:background .25s ease, box-shadow .25s ease; z-index:3;
}
.topo-root .unit-card.led-on .unit-machine .led-bar{ background:var(--led); box-shadow:0 0 8px rgba(123,191,255,.9); }


.topo-root .bubbles{ position:absolute; left:0; right:0; bottom:40px; height:44px; pointer-events:none; z-index:4; opacity:0; transition:opacity .3s ease; }
.topo-root .unit-card.running .bubbles{ opacity:1; }
.topo-root .bubble{ position:absolute; bottom:0; width:7px; height:7px; border-radius:50%;
  background:radial-gradient(circle at 35% 30%, rgba(255,255,255,.95), rgba(123,191,255,.55) 60%, rgba(16,112,221,.25));
  border:1px solid rgba(16,112,221,.18);
  animation: topo-bubbleRise 2.6s ease-in infinite; }
.topo-root .bubble:nth-child(1){ left:24%; width:6px; height:6px; animation-delay:0s; }
.topo-root .bubble:nth-child(2){ left:42%; width:9px; height:9px; animation-delay:.5s; }
.topo-root .bubble:nth-child(3){ left:56%; width:5px; height:5px; animation-delay:1s; }
.topo-root .bubble:nth-child(4){ left:68%; width:8px; height:8px; animation-delay:1.5s; }
.topo-root .bubble:nth-child(5){ left:35%; width:6px; height:6px; animation-delay:2s; }


.topo-root .unit-state{ display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:800;
  color:#64748b; background:#eef1f5; border:1px solid #e3e6ec; padding:4px 10px 4px 8px; border-radius:999px; }
.topo-root .unit-state .sdot{ width:7px; height:7px; border-radius:50%; background:var(--gray); }
.topo-root .unit-card.running .unit-state{ color:#0e8a4f; background:#e8f8ef; border-color:#c6efd6; }
.topo-root .unit-card.running .unit-state .sdot{ background:var(--green); animation: topo-livePulse 1.3s ease-in-out infinite; }


.topo-root .unit-tag{ font-size:11px; font-weight:700; color:#64748b; background:#f1f3f6; border:1px solid #e3e6ec;
  padding:3px 7px; border-radius:5px; display:inline-flex; align-items:center; gap:5px; flex-shrink:0;
  letter-spacing:.02em; }
.topo-root .unit-tag i{ color:var(--muted-2); font-size:10px; }


.topo-root .unit-name{ font-size:13.5px; font-weight:800; color:var(--text); text-align:center;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }


.topo-root .unit-o2box{ background:#f6f7f9; border:1px solid #ebedf1; border-radius:10px; padding:9px 12px;
  display:flex; flex-direction:column; gap:6px; transition:background .25s ease, border-color .25s ease; }
.topo-root .unit-card.running .unit-o2box{ background:#eef5ff; border-color:#d3e4fb; }
.topo-root .unit-o2head{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.topo-root .unit-o2-label{ font-size:12px; font-weight:700; color:var(--muted); }
.topo-root .unit-o2{ display:flex; align-items:baseline; gap:1px; line-height:1; color:var(--gray); transition:color .3s ease; }
.topo-root .unit-o2 b{ font-size:24px; font-weight:800; font-variant-numeric:tabular-nums; }
.topo-root .unit-o2 i{ font-size:12px; font-weight:700; font-style:normal; }
.topo-root .unit-card.running .unit-o2{ color:var(--blue); }
.topo-root .unit-o2.bump b{ animation: topo-numBump .45s ease; }

.topo-root .progress{ position:relative; width:100%; height:8px; border-radius:999px; background:#e4e8ee; overflow:hidden; }
.topo-root .progress-fill{ position:absolute; inset:0; border-radius:inherit; background:var(--gray-2);
  transform-origin:left center; transform:scaleX(0);
  transition:transform .6s cubic-bezier(.4,0,.2,1), background .3s ease; }
.topo-root .unit-card.running .progress-fill{ background:linear-gradient(90deg,#0a5fd6,#46a8ff); }

.topo-root .unit-meta{ display:flex; align-items:center; justify-content:center; gap:14px; font-size:11.5px;
  color:var(--muted); font-variant-numeric:tabular-nums; }
.topo-root .unit-meta .um{ display:inline-flex; align-items:center; gap:6px; }
.topo-root .unit-meta i{ color:var(--muted-2); }
.topo-root .unit-meta b{ font-weight:700; color:var(--text-2); }


.topo-root .unit-ctrl{ display:flex; gap:7px; margin-top:1px; }
.topo-root .unit-ctrl .ubtn{ flex:1; }
.topo-root .ubtn{
  border:none; cursor:pointer; font-size:12.5px; font-weight:800; letter-spacing:.02em;
  padding:8px 10px; border-radius:8px; color:#fff; background:var(--gray);
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  box-shadow:0 1px 2px rgba(15,23,42,.12);
  transition:transform .08s ease, filter .12s ease, opacity .12s ease;
}
.topo-root .ubtn:hover{ filter:brightness(1.06); transform:translateY(-1px); }
.topo-root .ubtn:active{ transform:translateY(1px) scale(.98); }
.topo-root .ubtn.on.is-active{ background:var(--blue); }
.topo-root .ubtn.off.is-active{ background:var(--gray); }
.topo-root .ubtn.led{ background:#cbd5e1; color:#475569; }
.topo-root .ubtn.led.is-active{ background:var(--led); color:#fff; }
.topo-root .ubtn.is-idle{ background:#e5e9f0; color:#9aa3b2; box-shadow:none; }
.topo-root .ubtn i{ font-size:11px; }


.topo-root .unit-overlay{
  position:absolute; inset:0; border-radius:14px; z-index:8;
  background:rgba(15,23,42,.52); backdrop-filter:blur(2px);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
  color:#fff; opacity:0; visibility:hidden; transition:opacity .15s ease, visibility .15s ease;
}
.topo-root .unit-overlay.show{ opacity:1; visibility:visible; }
.topo-root .ovl-spin{ width:26px; height:26px; border-radius:50%;
  border:3px solid rgba(255,255,255,.35); border-top-color:#fff; animation: topo-spin .8s linear infinite; }
.topo-root .unit-overlay span{ font-size:12.5px; font-weight:700; letter-spacing:.04em; }



.topo-root .layout-v1 .units-row, .topo-root .layout-v2 .units-row{ display:flex; flex-direction:column; gap:12px; }
.topo-root .layout-v1 .units-row{ padding-left:36px; }   
.topo-root .layout-v2 .units-row{ padding-left:14px; }    
.topo-root .layout-v1 .discharger-group, .topo-root .layout-v2 .discharger-group{ justify-content:center; gap:16px; padding:18px 10px; }
.topo-root .layout-v1 .dcg-header, .topo-root .layout-v2 .dcg-header{ flex-direction:column; align-items:center; gap:2px; }
.topo-root .layout-v1 .dcg-types, .topo-root .layout-v2 .dcg-types{ flex-direction:column; align-items:center; gap:18px; }
.topo-root .layout-v1 .dcg-illusts, .topo-root .layout-v2 .dcg-illusts{ justify-content:center; gap:10px; }
.topo-root .layout-v1 .dcg-title, .topo-root .layout-v2 .dcg-title{ font-size:17px; }
.topo-root .layout-v1 .controller-node, .topo-root .layout-v2 .controller-node{ align-self:start; }

.topo-root .layout-v1 .ctrl-port{ left:50%; right:auto; top:auto; bottom:0; transform:translate(-50%,50%); }
.topo-root .layout-v2 .ctrl-port{ left:auto; right:0; top:50%; bottom:auto; transform:translate(50%,-50%); }
.topo-root .layout-v1 .unit-port, .topo-root .layout-v2 .unit-port{ left:0; top:50%; right:auto; transform:translate(-50%,-50%); }


.topo-root .layout-v1 .zone-topology{
  display:grid; grid-template-columns: minmax(0,2.2fr) minmax(0,1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas: "ctrl dcg" "units dcg";
  align-items:start; gap:20px 58px; padding:14px 4px 6px;
}
.topo-root .layout-v1 .zone-topology > .controller-node{ grid-area:ctrl; }
.topo-root .layout-v1 .zone-topology > .units-row{ grid-area:units; }
.topo-root .layout-v1 .zone-topology > .discharger-group{ grid-area:dcg; align-self:stretch; }


.topo-root .layout-v2 .zone-topology{
  display:grid; grid-template-columns: minmax(0,1.18fr) minmax(0,1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas: "ctrl units" "dcg units";
  align-items:start; gap:20px 50px; padding:14px 4px 6px;
}
.topo-root .layout-v2 .zone-topology > .controller-node{ grid-area:ctrl; }
.topo-root .layout-v2 .zone-topology > .discharger-group{ grid-area:dcg; align-self:stretch; }
.topo-root .layout-v2 .zone-topology > .units-row{ grid-area:units; }


.topo-root .scene-3d{ position:relative; width:100%; margin:10px 0 2px; }
.topo-root .scene-svg{ width:100%; height:auto; display:block; overflow:visible; }


.topo-root .scene-render{ width:100%; aspect-ratio:1000/650; object-fit:cover; object-position:center top;
  display:block; border-radius:14px; background:#eef2f7; }
.topo-root .scene-3d.render-fail .scene-render{ visibility:hidden; }


.topo-root .scene-flow{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:5; overflow:visible; }
.topo-root .sflow-ref{ fill:none; stroke:none; }

.topo-root .sflow-glow{ fill:none; stroke-width:9; stroke-linecap:round; stroke-linejoin:round; }
.topo-root .sflow-glow.on{ stroke:#37c0ff; opacity:.30; }
.topo-root .sflow-glow.off{ stroke:#9aa6b6; opacity:.18; }
.topo-root .sflow-core{ fill:none; stroke-width:2.6; stroke-linecap:round; stroke-linejoin:round; }
.topo-root .sflow-core.on{ stroke:#e2f3ff; opacity:.95; }
.topo-root .sflow-core.off{ stroke:#cdd6e3; opacity:.65; }

.topo-root .sflow-dash{ fill:none; stroke:#ffffff; stroke-width:2.6; stroke-linecap:round;
  stroke-dasharray:2 13; animation: topo-dashFlow3d 1s linear infinite; }

.topo-root .sflow-packet .core{ fill:#ffffff; }
.topo-root .sflow-packet .halo{ fill:rgba(55,192,255,.50); }
.topo-root .sflow-packet.rev .core{ fill:#bfe7ff; }
.topo-root .sflow-packet.rev .halo{ fill:rgba(123,191,255,.42); }


.topo-root .scene-fx{ position:absolute; inset:0; display:none; pointer-events:none; border-radius:14px; overflow:hidden; }
.topo-root .scene-3d.has-render .scene-fx{ display:block; }
.topo-root .scene-fx::before{ content:""; position:absolute; top:-25%; left:-30%; width:60%; height:150%;
  background:linear-gradient(115deg, transparent 42%, rgba(120,200,255,.16) 50%, transparent 58%);
  animation: topo-sceneSweep 5s linear infinite; }
@keyframes topo-sceneSweep{ 0%{ transform:translateX(-40%); } 100%{ transform:translateX(280%); } }


.topo-root .pipe-glow{ fill:none; stroke:#37c0ff; stroke-width:11; stroke-linecap:round; stroke-linejoin:round; opacity:.55; filter:url(#glow3d); }
.topo-root .pipe-core{ fill:none; stroke:#bfe7ff; stroke-width:3.6; stroke-linecap:round; stroke-linejoin:round; }
.topo-root .pipe-flow{ fill:none; stroke:#ffffff; stroke-width:3.4; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:1.5 15; animation: topo-dashFlow3d 1s linear infinite; }
@keyframes topo-dashFlow3d{ to{ stroke-dashoffset:-16.5; } }


.topo-root .scene-packet .core{ fill:#ffffff; }
.topo-root .scene-packet .halo{ fill:rgba(55,192,255,.45); }
.topo-root .scene-packet.rev .core{ fill:#bfe7ff; }
.topo-root .scene-packet.rev .halo{ fill:rgba(123,191,255,.40); }


.topo-root .o2glow{ opacity:0; transition:opacity .5s ease; }
.topo-root .o2glow.on{ opacity:1; }
.topo-root .o2glow .rays{ animation: topo-o2pulse 2.8s ease-in-out infinite; transform-box:fill-box; transform-origin:center bottom; }
@keyframes topo-o2pulse{ 0%,100%{ opacity:.45; } 50%{ opacity:1; } }


.topo-root .layout-3d .units-row{ display:none; }
.topo-root .scene-3d{ margin-bottom:6px; }


.topo-root .scene-pins{ position:absolute; inset:0; pointer-events:none; z-index:6; }
.topo-root .scene-pin-wrap{ position:absolute; transform:translate(-50%,-50%); pointer-events:auto; }

.topo-root .scene-pin{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  background:rgba(255,255,255,.94); border:1px solid #d3dcea; border-radius:999px;
  padding:4px 9px 4px 6px; box-shadow:0 4px 12px rgba(15,23,42,.20);
  font-family:inherit; font-weight:800; font-size:12px; color:#64748b;
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  transition:transform .1s ease, box-shadow .15s ease; line-height:1;
}
.topo-root .scene-pin:hover{ transform:translateY(-1px); box-shadow:0 6px 16px rgba(15,23,42,.26); }
.topo-root .scene-pin .pin-dot{ width:9px; height:9px; border-radius:50%; background:#9aa6b6; flex-shrink:0; }
.topo-root .scene-pin .pin-name{ color:#374151; max-width:92px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.topo-root .scene-pin .pin-o2{ color:#111827; font-variant-numeric:tabular-nums; margin-left:1px; }
.topo-root .scene-pin .pin-pct{ font-size:10px; color:#94a3b8; margin-left:-2px; }
.topo-root .scene-pin-wrap.running .scene-pin{ color:#0e6fd0; border-color:#bcd9fb; background:rgba(239,246,255,.96); }
.topo-root .scene-pin-wrap.running .pin-name{ color:#0e6fd0; }
.topo-root .scene-pin-wrap.running .pin-o2{ color:#1070dd; }
.topo-root .scene-pin-wrap.running .pin-dot{ background:#16a34a; box-shadow:0 0 0 0 rgba(22,163,74,.5); animation: topo-pinPulse 1.7s ease-out infinite; }
@keyframes topo-pinPulse{ 0%{ box-shadow:0 0 0 0 rgba(22,163,74,.5);} 100%{ box-shadow:0 0 0 9px rgba(22,163,74,0);} }


.topo-root .scene-pin-wrap.pending .scene-pin{ pointer-events:none; }
.topo-root .scene-pin-wrap.pending .pin-dot{ width:11px; height:11px; background:transparent !important;
  border:2px solid rgba(16,112,221,.3); border-top-color:#1070dd; animation: topo-spin .7s linear infinite; box-shadow:none; }


.topo-root .scene-pin-wrap::after{
  content:""; position:absolute; left:50%; top:calc(50% + 11px); width:1px; height:14px;
  background:linear-gradient(#9aa6b6, transparent); transform:translateX(-50%); opacity:.5; pointer-events:none;
}
.topo-root .scene-pin-wrap.running::after{ background:linear-gradient(#1070dd, transparent); opacity:.6; }

.topo-root .scene-pop{
  position:absolute; bottom:calc(100% + 10px); left:50%; transform:translateX(-50%) scale(.95);
  width:208px; background:#fff; border:1px solid #e3e6ec; border-radius:13px;
  box-shadow:0 16px 38px rgba(15,23,42,.24); padding:12px 13px;
  opacity:0; visibility:hidden; transition:opacity .14s ease, transform .14s ease; z-index:20;
}
.topo-root .scene-pin-wrap.open .scene-pop{ opacity:1; visibility:visible; transform:translateX(-50%) scale(1); }
.topo-root .scene-pop::after{ content:""; position:absolute; top:100%; left:50%; transform:translateX(-50%);
  border:7px solid transparent; border-top-color:#fff; filter:drop-shadow(0 1px 0 #e3e6ec); }

.topo-root .pop-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:9px; }
.topo-root .pop-name{ font-size:13.5px; font-weight:800; color:#111827; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topo-root .pop-code{ font-size:10px; font-weight:700; color:#64748b; background:#f1f3f6; border:1px solid #e3e6ec;
  padding:2px 6px; border-radius:5px; display:inline-flex; align-items:center; gap:4px; flex-shrink:0; }
.topo-root .pop-code i{ color:#94a3b8; font-size:9px; }

.topo-root .pop-o2row{ display:flex; align-items:flex-end; justify-content:space-between; gap:8px; }
.topo-root .pop-state-chip{ display:inline-flex; align-items:center; gap:5px; font-size:11.5px; font-weight:800;
  color:#64748b; background:#eef1f5; border:1px solid #e3e6ec; padding:3px 9px 3px 7px; border-radius:999px; }
.topo-root .pop-state-chip .sdot{ width:6px; height:6px; border-radius:50%; background:#9aa6b6; }
.topo-root .scene-pin-wrap.running .pop-state-chip{ color:#0e8a4f; background:#e8f8ef; border-color:#c6efd6; }
.topo-root .scene-pin-wrap.running .pop-state-chip .sdot{ background:#16a34a; }
.topo-root .pop-o2{ display:flex; align-items:baseline; gap:2px; line-height:1; color:#9aa6b6; }
.topo-root .pop-o2-label{ font-size:10px; font-weight:700; color:#94a3b8; margin-right:3px; }
.topo-root .pop-o2 b{ font-size:23px; font-weight:800; font-variant-numeric:tabular-nums; }
.topo-root .pop-o2 i{ font-size:12px; font-weight:700; font-style:normal; }
.topo-root .scene-pin-wrap.running .pop-o2{ color:#1070dd; }

.topo-root .pop-prog{ position:relative; width:100%; height:7px; border-radius:999px; background:#e4e8ee; overflow:hidden; margin:8px 0; }
.topo-root .pop-fill{ position:absolute; inset:0; border-radius:inherit; background:#d1d5dc; transform-origin:left center; transform:scaleX(0);
  transition:transform .6s cubic-bezier(.4,0,.2,1), background .3s ease; }
.topo-root .scene-pin-wrap.running .pop-fill{ background:linear-gradient(90deg,#0a5fd6,#46a8ff); }

.topo-root .pop-meta{ display:flex; align-items:center; justify-content:space-between; gap:8px;
  font-size:11px; color:#6b7280; font-variant-numeric:tabular-nums; margin-bottom:10px; }
.topo-root .pop-meta i{ color:#94a3b8; }
.topo-root .pop-meta b{ font-weight:700; color:#374151; }

.topo-root .pop-btns{ display:flex; gap:6px; }
.topo-root .pop-btns .ubtn{ flex:1; padding:8px 0; font-size:12px; }
.topo-root .pop-btns .ubtn.led{ flex:0 0 56px; }


.topo-root .scene-badge{
  position:absolute; transform:translate(-50%,-50%); pointer-events:none; white-space:nowrap;
  display:inline-flex; align-items:center; gap:5px; line-height:1;
  background:rgba(255,255,255,.94); border:1px solid #d3dcea; border-radius:999px;
  padding:4px 9px 4px 6px; box-shadow:0 4px 12px rgba(15,23,42,.18);
  font-weight:800; font-size:12px; color:#64748b;
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
.topo-root .scene-badge .bdot{ width:8px; height:8px; border-radius:50%; background:#9aa6b6; flex-shrink:0; }
.topo-root .scene-badge .bname{ color:#374151; max-width:96px; overflow:hidden; text-overflow:ellipsis; }
.topo-root .scene-badge .bo2{ color:#111827; font-variant-numeric:tabular-nums; margin-left:1px; }
.topo-root .scene-badge .bpct{ font-size:10px; color:#94a3b8; margin-left:-1px; }
.topo-root .scene-badge.running{ border-color:#bcd9fb; background:rgba(239,246,255,.96); }
.topo-root .scene-badge.running .bname{ color:#0e6fd0; }
.topo-root .scene-badge.running .bo2{ color:#1070dd; }
.topo-root .scene-badge.running .bdot{ background:#16a34a; box-shadow:0 0 0 0 rgba(22,163,74,.5); animation: topo-pinPulse 1.7s ease-out infinite; }


.topo-root .scene-pin.ctrl{ background:#1070dd; color:#fff; border-color:#1d6fd0; padding:6px 12px 6px 10px;
  box-shadow:0 6px 16px rgba(16,112,221,.42); animation: topo-ctrlPulse 2.2s ease-out infinite; }
.topo-root .scene-pin.ctrl i{ font-size:12px; }
.topo-root .scene-pin.ctrl .pin-name{ color:#fff; }
.topo-root .scene-pin.ctrl:hover{ filter:brightness(1.05); }
@keyframes topo-ctrlPulse{
  0%{ box-shadow:0 6px 16px rgba(16,112,221,.42), 0 0 0 0 rgba(16,112,221,.5); }
  70%{ box-shadow:0 6px 16px rgba(16,112,221,.42), 0 0 0 13px rgba(16,112,221,0); }
  100%{ box-shadow:0 6px 16px rgba(16,112,221,.42), 0 0 0 0 rgba(16,112,221,0); }
}


.topo-root .ctrl-pop{ bottom:auto; top:calc(100% + 12px); width:248px; padding:12px 13px; }
.topo-root .ctrl-pop::after{ top:auto; bottom:100%; border-top-color:transparent; border-bottom-color:#fff;
  filter:drop-shadow(0 -1px 0 #e3e6ec); }
.topo-root .cpop-head{ display:flex; align-items:center; gap:7px; font-size:12.5px; font-weight:800; color:#111827;
  padding-bottom:9px; margin-bottom:9px; border-bottom:1px solid #eef0f4; }
.topo-root .cpop-head i{ color:#1070dd; }
.topo-root .cpop-sub{ margin-left:auto; font-size:11px; font-weight:700; color:#94a3b8; }
.topo-root .cpop-rows{ display:flex; flex-direction:column; gap:9px; }
.topo-root .ctrl-row{ display:flex; align-items:center; gap:9px; }
.topo-root .ctrl-row .cr-dot{ width:8px; height:8px; border-radius:50%; background:#9aa6b6; flex-shrink:0; }
.topo-root .ctrl-row.running .cr-dot{ background:#16a34a; box-shadow:0 0 0 0 rgba(22,163,74,.5); animation: topo-pinPulse 1.7s ease-out infinite; }
.topo-root .ctrl-row .cr-name{ font-size:12.5px; font-weight:700; color:#374151; flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topo-root .ctrl-row .cr-o2{ font-size:13px; font-weight:800; color:#9aa6b6; font-variant-numeric:tabular-nums; flex-shrink:0; }
.topo-root .ctrl-row.running .cr-o2{ color:#1070dd; }


.topo-root .cpop-actions{ display:flex; gap:7px; margin-top:11px; padding-top:11px; border-top:1px solid #eef0f4; }
.topo-root .cpop-toggle{ flex:1; border:none; cursor:pointer; font-weight:800; font-size:13px; color:#fff;
  padding:10px 0; border-radius:9px; background:var(--blue); box-shadow:0 2px 6px rgba(16,112,221,.25);
  transition:filter .12s ease, transform .08s ease; }
.topo-root .cpop-toggle:hover{ filter:brightness(1.06); }
.topo-root .cpop-toggle:active{ transform:scale(.98); }
.topo-root .cpop-toggle.is-stop{ background:var(--gray); box-shadow:none; }
.topo-root .cpop-led{ flex:0 0 66px; border:1px solid #d7dce6; cursor:pointer; font-weight:800; font-size:12px;
  color:#64748b; background:#fff; border-radius:9px; display:inline-flex; align-items:center; justify-content:center; gap:5px;
  transition:all .12s ease; }
.topo-root .cpop-led i{ font-size:12px; }
.topo-root .cpop-led:hover{ border-color:var(--blue); }
.topo-root .cpop-led.is-active{ background:var(--led); border-color:var(--led); color:#fff; }




.topo-root .discharger{ display:block; overflow:visible; }
.topo-root .discharger .dc-body{ fill:#ffffff; stroke:#cfd6e0; stroke-width:1.4; }
.topo-root .discharger.round .dc-body{ filter:drop-shadow(0 2px 4px rgba(15,23,42,.16)); }
.topo-root .discharger.pill  .dc-body{ filter:drop-shadow(0 2px 4px rgba(15,23,42,.14)); }

.topo-root .discharger .dc-glow{ fill:none; stroke:#3fdcea; stroke-width:3; opacity:.8; }                
.topo-root .discharger .dc-cyan{ fill:none; stroke:#1fcfe0; stroke-width:2.2; opacity:.95; }            
.topo-root .discharger .dc-cap{ stroke:#e0e5ec; stroke-width:.8; }                                       
.topo-root .discharger .dc-grilleshadow{ fill:none; stroke:#000; stroke-width:2; opacity:.16; }          
.topo-root .discharger .dc-slats rect{ fill:#9aa6b4; }                                                   
.topo-root .discharger .dc-sensor{ fill:#8b95a2; }                                                       
.topo-root .discharger .dc-grilleline{ fill:none; stroke:#c6cfda; stroke-width:1; opacity:.9; }          
.topo-root .discharger .dc-leaf{ fill:#8b95a2; }                                                          
.topo-root .discharger.round .dc-logo{ fill:#97a1ae; font-size:6.6px; letter-spacing:.2px; }
.topo-root .discharger .dc-window{ fill:none; stroke:#22d3ee; stroke-width:2.2; opacity:.7; }           
.topo-root .discharger .dc-fan ellipse{ fill:#c2ccd9; }                                                  
.topo-root .discharger .dc-hub{ fill:#8593a4; }
.topo-root .discharger .dc-logo{ fill:#aeb6c2; font-family:inherit; font-size:8px; font-weight:800; letter-spacing:.4px; }
.topo-root .discharger.round.mini{ width:44px; height:44px; }
.topo-root .discharger.pill.mini{ width:27px; height:44px; }
.topo-root .discharger.round.big{ width:56px; height:56px; }
.topo-root .discharger.pill.big{ width:54px; height:88px; }


.topo-root .discharger-group{ display:flex; flex-direction:column; align-items:center; gap:14px;
  background:linear-gradient(180deg,#fbfdff,#f2f6fc); border:1.5px solid #cfe0f6; border-radius:20px;
  padding:16px 24px; }
.topo-root .dcg-header{ display:flex; align-items:baseline; justify-content:center; flex-wrap:wrap; gap:4px 10px; }
.topo-root .dcg-title{ font-size:20px; font-weight:800; color:#1d3a63; letter-spacing:-.01em; white-space:nowrap; }
.topo-root .dcg-total{ font-size:12.5px; color:#7c8694; font-weight:700; white-space:nowrap; }
.topo-root .dcg-types{ display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:center; gap:18px 30px; }
.topo-root .dcg-type{ display:flex; flex-direction:column; align-items:center; gap:9px; }
.topo-root .dcg-illusts{ display:flex; align-items:flex-end; justify-content:center; gap:12px; flex-wrap:wrap; }
.topo-root .dcg-illust{ display:flex; align-items:flex-end; justify-content:center; }
.topo-root .dcg-typelabel{ font-size:13px; font-weight:700; color:#334155; letter-spacing:-.01em; }
.topo-root .dcg-typelabel b{ color:var(--blue); font-weight:800; }


.topo-root .unit-id{ display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:800; color:#334155; letter-spacing:-.01em; }
.topo-root .unit-id i{ color:var(--blue); font-size:11px; }


.topo-root .unit-card.has-error .unit-state{ color:#b91c1c; background:#fee2e2; border-color:#fbb4ad; }
.topo-root .unit-card.has-error .unit-state .sdot{ background:var(--red); box-shadow:none; animation: none; }
.topo-root .unit-card.has-error{ border-color:#f7c8c3; }


.topo-root .unit-graph{ height:22px; margin-top:1px; }
.topo-root .spark{ width:100%; height:22px; display:block; }
.topo-root .spark-line{ fill:none; stroke:#9aa6b6; stroke-width:1.7; stroke-linejoin:round; }
.topo-root .spark-area{ fill:rgba(148,163,184,.10); stroke:none; }
.topo-root .spark.on .spark-line{ stroke:#1070dd; }
.topo-root .spark.on .spark-area{ fill:rgba(16,112,221,.12); }


.topo-root .unit-stats{ display:flex; flex-direction:column; gap:4px; padding-top:8px; margin-top:1px; border-top:1px solid #eef0f4; }
.topo-root .ust-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:11px; line-height:1.2; }
.topo-root .ust-k{ color:var(--muted); font-weight:600; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.topo-root .ust-k i{ color:var(--muted-2); font-size:10px; width:13px; text-align:center; }
.topo-root .ust-v{ color:var(--text-2); font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; text-align:right; }
.topo-root .ust-v.is-error{ color:var(--red); }




.topo-root .sim-backdrop{ position:fixed; inset:0; z-index:100; background:rgba(15,23,42,.42);
  display:flex; align-items:center; justify-content:center; padding:20px;
  opacity:0; visibility:hidden; transition:opacity .16s ease, visibility .16s ease; }
.topo-root .sim-backdrop.show{ opacity:1; visibility:visible; }
.topo-root .sim-card{ width:440px; max-width:100%; max-height:88vh; overflow:auto; background:#fff; border-radius:16px;
  box-shadow:0 24px 60px rgba(15,23,42,.30); padding:20px 22px 18px; transform:translateY(8px) scale(.98); transition:transform .16s ease; }
.topo-root .sim-backdrop.show .sim-card{ transform:none; }
.topo-root .sim-h{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.topo-root .sim-h b{ font-size:16px; font-weight:800; color:var(--text); display:flex; align-items:center; gap:8px; }
.topo-root .sim-h b i{ color:var(--blue); font-size:14px; }
.topo-root .sim-h span{ display:block; font-size:12px; color:var(--muted); margin-top:3px; font-variant-numeric:tabular-nums; }
.topo-root .sim-x{ border:none; background:#f1f3f6; width:30px; height:30px; border-radius:8px; cursor:pointer;
  font-size:20px; line-height:1; color:#64748b; flex-shrink:0; }
.topo-root .sim-x:hover{ background:#e5e9f0; color:#111827; }
.topo-root .sim-desc{ font-size:12.5px; color:var(--text-2); line-height:1.55; margin:12px 0 14px; }
.topo-root .sim-desc b{ color:var(--blue); } .topo-root .sim-desc em{ color:var(--muted-2); font-style:normal; font-size:11.5px; }
.topo-root .sim-spaces{ display:flex; flex-direction:column; gap:12px; }
.topo-root .sim-space{ background:#f7f8fb; border:1px solid #eaedf2; border-radius:11px; padding:11px 13px; }
.topo-root .sim-space-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.topo-root .sim-space-head b{ font-size:13.5px; font-weight:800; color:var(--text); }
.topo-root .sim-space-head .on{ font-size:11px; font-weight:800; color:#0e8a4f; background:#e8f8ef; border:1px solid #c6efd6; padding:2px 8px; border-radius:999px; }
.topo-root .sim-space-head .off{ font-size:11px; font-weight:800; color:#64748b; background:#eef1f5; border:1px solid #e3e6ec; padding:2px 8px; border-radius:999px; }
.topo-root .sim-bar{ position:relative; height:9px; border-radius:999px; background:#e4e8ee; overflow:hidden; }
.topo-root .sim-fill{ position:absolute; inset:0 auto 0 0; border-radius:inherit; background:var(--gray-2); transition:width .5s cubic-bezier(.4,0,.2,1); }
.topo-root .sim-fill.on{ background:linear-gradient(90deg,#0a5fd6,#46a8ff); }
.topo-root .sim-meta{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:7px; font-size:11.5px; color:var(--muted); font-variant-numeric:tabular-nums; }
.topo-root .sim-meta b{ color:var(--text-2); }
.topo-root .sim-foot{ margin-top:14px; font-size:11px; color:var(--muted-2); line-height:1.5; }


.topo-root .sim-card-app{ width:1180px; max-width:96vw; height:92vh; max-height:92vh;
  padding:14px 16px; display:flex; flex-direction:column; overflow:hidden; }
.topo-root .sim-frame-wrap{ flex:1; margin-top:12px; border:1px solid #e6eaf1; border-radius:12px; overflow:hidden; background:#fff; }
.topo-root .sim-frame{ width:100%; height:100%; border:0; display:block; }
.topo-root body.modal-open{ overflow:hidden; }


.topo-root .cm-backdrop{ position:fixed; inset:0; z-index:120; background:rgba(15,23,42,.42);
  display:flex; align-items:center; justify-content:center; padding:20px;
  opacity:0; visibility:hidden; transition:opacity .16s ease, visibility .16s ease; }
.topo-root .cm-backdrop.show{ opacity:1; visibility:visible; }
.topo-root .cm-card{ width:400px; max-width:100%; max-height:90vh; overflow:auto; background:#fff; border-radius:16px;
  box-shadow:0 24px 60px rgba(15,23,42,.30); padding:20px 22px 18px;
  transform:translateY(8px) scale(.98); transition:transform .16s ease; }
.topo-root .cm-backdrop.show .cm-card{ transform:none; }
.topo-root .cm-h{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:16px; }
.topo-root .cm-h b{ font-size:16px; font-weight:800; color:var(--text); display:flex; align-items:center; gap:8px; }
.topo-root .cm-h b i{ color:var(--blue); font-size:14px; }
.topo-root .cm-h span{ display:block; font-size:12px; color:var(--muted); margin-top:3px; font-variant-numeric:tabular-nums; }
.topo-root .cm-x{ border:none; background:#f1f3f6; width:30px; height:30px; border-radius:8px; cursor:pointer;
  font-size:20px; line-height:1; color:#64748b; flex-shrink:0; }
.topo-root .cm-x:hover{ background:#e5e9f0; color:#111827; }

.topo-root .cm-switchrow{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  font-size:13.5px; font-weight:700; color:var(--text-2); padding:4px 0 14px; border-bottom:1px solid #eef0f4; margin-bottom:16px; }
.topo-root .cm-switch{ position:relative; width:44px; height:24px; border-radius:999px; background:#cbd5e1; cursor:pointer; transition:background .15s ease; flex-shrink:0; }
.topo-root .cm-switch.on{ background:var(--blue); }
.topo-root .cm-knob{ position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:50%; background:#fff; transition:left .15s ease; box-shadow:0 1px 2px rgba(0,0,0,.2); }
.topo-root .cm-switch.on .cm-knob{ left:23px; }

.topo-root .cm-body{ display:flex; flex-direction:column; gap:16px; }
.topo-root .cm-body.is-disabled{ opacity:.4; pointer-events:none; }
.topo-root .cm-field{ display:flex; flex-direction:column; gap:8px; }
.topo-root .cm-field > label{ font-size:12px; font-weight:700; color:var(--muted); }
.topo-root .cm-times{ display:flex; align-items:center; gap:10px; }
.topo-root .cm-time{ font-family:inherit; font-size:15px; font-weight:700; color:var(--text); font-variant-numeric:tabular-nums;
  border:1px solid #d7dce6; border-radius:9px; padding:9px 11px; background:#fff; }
.topo-root .cm-time:focus{ outline:none; border-color:var(--blue); box-shadow:0 0 0 3px rgba(16,112,221,.12); }
.topo-root .cm-time-lg{ font-size:20px; padding:12px 14px; width:100%; text-align:center; }
.topo-root .cm-tilde{ color:var(--muted-2); font-weight:700; }
.topo-root .cm-days{ display:flex; gap:6px; }
.topo-root .cm-day{ flex:1; border:1px solid #d7dce6; background:#fff; color:#64748b; font-family:inherit; font-weight:700; font-size:13px;
  padding:9px 0; border-radius:9px; cursor:pointer; transition:all .12s ease; }
.topo-root .cm-day.on{ background:var(--blue); border-color:var(--blue); color:#fff; }
.topo-root .cm-day:hover{ border-color:var(--blue); }
.topo-root .cm-quick, .topo-root .cm-durs{ display:flex; gap:6px; flex-wrap:wrap; margin-top:2px; }
.topo-root .cm-durs{ display:grid; grid-template-columns:repeat(5,1fr); }   
.topo-root .cm-qbtn, .topo-root .cm-dur{ border:1px solid #cfdcf2; background:#f3f8ff; color:#1d6fd0; font-family:inherit; font-weight:700; font-size:12px;
  padding:7px 13px; border-radius:8px; cursor:pointer; transition:all .12s ease; }
.topo-root .cm-dur{ padding:7px 6px; text-align:center; }                   
.topo-root .cm-qbtn:hover, .topo-root .cm-dur:hover{ background:#e7f1ff; border-color:var(--blue); }

.topo-root .cm-foot{ display:flex; gap:8px; margin-top:20px; }


.topo-root .cm-card--wide{ width:560px; }
.topo-root .gc-toolbar{ display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap; }
.topo-root .gc-range{ display:inline-flex; border:1px solid #d7dce6; border-radius:9px; overflow:hidden; }
.topo-root .gc-rbtn{ border:none; background:#fff; color:#64748b; font-family:inherit; font-weight:700; font-size:12.5px;
  padding:7px 15px; cursor:pointer; transition:all .12s ease; }
.topo-root .gc-rbtn + .gc-rbtn{ border-left:1px solid #d7dce6; }
.topo-root .gc-rbtn.on{ background:var(--blue); color:#fff; }
.topo-root .gc-legend{ display:flex; gap:13px; flex-wrap:wrap; }
.topo-root .gc-lg{ display:inline-flex; align-items:center; gap:5px; font-size:12px; font-weight:600; color:var(--text-2); }
.topo-root .gc-lg i{ width:11px; height:11px; border-radius:3px; display:inline-block; }
.topo-root .gc-wrap{ width:100%; min-height:140px; }
.topo-root .gchart{ width:100%; height:auto; display:block; }
.topo-root .gc-grid{ stroke:#eef0f4; stroke-width:1; }
.topo-root .gc-ylab, .topo-root .gc-xlab{ fill:#94a3b8; font-size:10px; font-family:inherit; }
.topo-root .gc-line{ fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.topo-root .gc-loading{ padding:38px 10px; text-align:center; color:#94a3b8; font-size:13px; }
.topo-root .gc-note{ font-size:11.5px; color:#94a3b8; }
.topo-root .cm-cancel{ flex:1; border:1px solid #d7dce6; background:#fff; color:#64748b; font-family:inherit; font-weight:800; font-size:13px;
  padding:11px 0; border-radius:10px; cursor:pointer; transition:all .12s ease; }
.topo-root .cm-cancel:hover{ border-color:#94a3b8; }
.topo-root .cm-clear{ color:#b91c1c; border-color:#f3c9c4; }
.topo-root .cm-clear:hover{ border-color:var(--red); background:#fef2f2; }
.topo-root .cm-save{ flex:1.4; border:none; background:var(--blue); color:#fff; font-family:inherit; font-weight:800; font-size:13px;
  padding:11px 0; border-radius:10px; cursor:pointer; box-shadow:0 2px 8px rgba(16,112,221,.26); transition:filter .12s ease; }
.topo-root .cm-save:hover{ filter:brightness(1.06); }


.topo-root .wire-base{ fill:none; stroke:#e4e8ef; stroke-width:4.5; stroke-linecap:round; }
.topo-root .wire-ref{ fill:none; stroke:none; }
.topo-root .wire-line{ fill:none; stroke-width:2.2; stroke-linecap:round; }
.topo-root .wire-line.active{ stroke:#1070dd; opacity:.85; }
.topo-root .wire-line.idle{ stroke:#cbd5e1; }


.topo-root .packet .halo{ fill:rgba(16,112,221,.18); }
.topo-root .packet .core{ fill:#1070dd; }

.topo-root .packet.rev .halo{ fill:rgba(123,191,255,.22); }
.topo-root .packet.rev .core{ fill:#7bbfff; }

.topo-root .packet.idle .halo{ fill:rgba(148,163,184,.14); }
.topo-root .packet.idle .core{ fill:#a3acbb; }

.topo-root .packet.command .halo{ fill:rgba(16,112,221,.42); }
.topo-root .packet.command .core{ fill:#fff; stroke:#1070dd; stroke-width:1.5; }


.topo-root .foot{ margin-top:22px; padding:18px 6px 6px; border-top:1px solid var(--line); }
.topo-root .foot-row{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  font-size:12.5px; color:var(--muted); }
.topo-root .foot-tel{ font-weight:700; color:var(--text-2); display:inline-flex; align-items:center; gap:7px; }
.topo-root .foot-tel i{ color:var(--blue); }
.topo-root .foot-tel a{ color:var(--blue); text-decoration:none; font-weight:800; }
.topo-root .foot-copy{ margin-top:8px; font-size:11.5px; color:var(--muted-2); }
.topo-root .foot-copy b{ color:var(--text-2); }


@keyframes topo-spin{ to{ transform:rotate(360deg); } }
@keyframes topo-fanSpin{ to{ transform:rotate(360deg); } }
@keyframes topo-dashFlow{ to{ stroke-dashoffset:-12.4; } }
@keyframes topo-radar{
  0%{ transform:translate(-50%,-50%) scale(.45); opacity:.7; }
  80%{ opacity:0; }
  100%{ transform:translate(-50%,-50%) scale(1.5); opacity:0; }
}
@keyframes topo-livePulse{ 0%,100%{ opacity:1; transform:scale(1); } 50%{ opacity:.45; transform:scale(.82); } }
@keyframes topo-ledBlink{ 0%,100%{ opacity:1; } 50%{ opacity:.35; } }
@keyframes topo-sigBlink{ 0%{ opacity:1; } 50%{ opacity:.25; } 100%{ opacity:1; } }
@keyframes topo-ledGlow{ 0%,100%{ opacity:.9; } 50%{ opacity:.45; } }
@keyframes topo-bubbleRise{
  0%{ transform:translateY(8px) scale(.6); opacity:0; }
  15%{ opacity:.9; }
  100%{ transform:translateY(-52px) scale(1); opacity:0; }
}
@keyframes topo-numBump{ 0%{ transform:scale(1); } 40%{ transform:scale(1.18); } 100%{ transform:scale(1); } }
@keyframes topo-cardPulse{ 0%{ box-shadow:0 0 0 0 rgba(16,112,221,.35); } 100%{ box-shadow:0 0 0 12px rgba(16,112,221,0); } }
@keyframes topo-legendFlow{ to{ transform:translateX(24px); } }



@media (max-width:1280px){
  .topo-root .zones.layout-v1, .topo-root .zones.layout-v2{ grid-template-columns:1fr; }
  .topo-root .app.app-v{ max-width:1480px; }
}
@media (max-width:1100px){
  .topo-root .summary{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:880px){
  .topo-root .app{ padding:12px 14px 32px; }
  .topo-root .topbar{ flex-direction:column; align-items:stretch; gap:12px; }
  .topo-root .topbar-right{ justify-content:flex-start; flex-wrap:wrap; gap:10px; }
  .topo-root .master{ flex-direction:column; align-items:stretch; gap:14px; }
  .topo-root .master-groups{ flex-direction:column; gap:14px; }

  
  .topo-root .zone-topology{ display:flex !important; flex-direction:column; align-items:stretch; gap:16px; padding:8px 0 0; }
  .topo-root .wires{ display:none; }
  .topo-root .controller-node{ width:100%; justify-content:center; }
  .topo-root .ctrl-port{ display:none; }
  .topo-root .units-row{ grid-template-columns:1fr; }
  .topo-root .unit-port{ display:none; }
}
@media (max-width:560px){
  .topo-root .summary{ grid-template-columns:1fr 1fr; gap:10px; }
  .topo-root .controller-node{ flex-direction:column; text-align:center; }
  .topo-root .ctrl-meta{ text-align:center; }
}


@media (prefers-reduced-motion:reduce){
  .topo-root *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; }
}

/* v1: 토폴로지 예약/타이머 = 표시 전용(편집 비활성, 연필 숨김) */
.topo-root .ctrl-reserve, .topo-root .ctrl-timer{ cursor:default; }
.topo-root .ctrl-reserve .cstat-edit, .topo-root .ctrl-timer .cstat-edit{ display:none; }

/* 실외기 카드 = 기획안 레이아웃: 헤더 / 팬(좌)+스탯(우) / 산소농도 바(하단) */
.topo-root .unit-card{ display:grid; grid-template-columns:98px minmax(0,1fr); column-gap:14px; row-gap:11px; align-items:center; grid-template-areas:'head head' 'illust stats' 'o2 o2'; }
.topo-root .unit-cardhead{ grid-area:head; }
.topo-root .unit-illust{ grid-area:illust; align-self:center; }
.topo-root .unit-stats{ grid-area:stats; border-top:none; padding-top:0; margin-top:0; align-self:center; }
.topo-root .unit-o2box{ grid-area:o2; }
.topo-root .unit-graph{ display:none; }

/* 상단 연결 포트(동그라미)가 카드에 잘려 반원으로 보이는 것 수정: 카드 overflow 해제 + 버블은 일러스트 안에서만 클립 */
.topo-root .unit-card{ overflow:visible; }
.topo-root .unit-illust{ overflow:hidden; }

/* 가로/세로 정렬 시 화면 꽉 채우기 + 위 마스터 제어 바와 동일 폭 (.app 좌우 패딩 제거) */
.topo-root{ width:100%; }
.topo-root .app, .topo-root .app.app-v, .topo-root .app.app-3d{ max-width:none; width:100%; margin:0; padding-left:0; padding-right:0; }
