:root{--bg: #09090b;--surface: #121116;--surface-2: #1b1a21;--surface-3: #24222c;--line: #27252f;--line-2: #3a3745;--text: #f4f2f8;--text-2: #b0acbb;--text-3: #7d7a88;--accent: #a855f7;--accent-hover: #9333ea;--accent-2: rgba(168, 85, 247, .14);--accent-ink: #d8b4fe;--pink: #ec4899;--on-accent: #fff;--ok: #34d399;--ok-bg: rgba(52, 211, 153, .12);--bad: #f87171;--bad-bg: rgba(248, 113, 113, .12);--warn: #fbbf24;--warn-bg: rgba(251, 191, 36, .12);--ext: #38bdf8;--canvas: #0d0c11;--canvas-dot: #2b2834;--cable: #8b8698;--scrim: rgba(5, 4, 8, .7);--term-bg: #060509;--term-text: #e4dcf2;--radius: 10px;--shadow-lg: 0 14px 44px rgba(0, 0, 0, .6), 0 0 0 1px rgba(168, 85, 247, .12);--mono: ui-monospace, "Cascadia Mono", Consolas, "DejaVu Sans Mono", monospace;--sans: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;--side-w: 400px;--log-h: 200px;--pal-w: 92px;color-scheme:dark}@media (prefers-color-scheme: light){:root:not([data-theme=dark]){--bg: #f6f5f9;--surface: #ffffff;--surface-2: #f1eff6;--surface-3: #e7e4ef;--line: #e2dfea;--line-2: #cfcade;--text: #1a1720;--text-2: #4b4757;--text-3: #767283;--accent: #9333ea;--accent-hover: #7e22ce;--accent-2: rgba(147, 51, 234, .1);--accent-ink: #7e22ce;--canvas: #fbfaff;--canvas-dot: #d9d4e6;--cable: #8a8598;--scrim: rgba(20, 16, 30, .45);--ok: #059669;--bad: #dc2626;--warn: #b45309;--ext: #0284c7;color-scheme:light}}:root[data-theme=dark]{color-scheme:dark}*{box-sizing:border-box}html,body{margin:0;height:100%}body{background:var(--bg);color:var(--text);font:14px/1.45 var(--sans)}button{font:inherit;color:inherit}code,.mono{font-family:var(--mono);font-size:.92em}code{background:var(--surface-3);padding:1px 5px;border-radius:4px}h2,h3{margin:0}.muted{color:var(--text-2)}.small{font-size:12.5px}.ok{color:var(--ok)}.bad{color:var(--bad)}.spacer{flex:1}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.btn{display:inline-flex;align-items:center;gap:6px;background:var(--accent);color:var(--on-accent);border:0;border-radius:8px;padding:7px 12px;cursor:pointer;font-weight:500}.btn:hover:not(:disabled){background:var(--accent-hover)}.btn:disabled{opacity:.5;cursor:default}.btn.small{padding:4px 9px;font-size:12.5px}.btn.ghost{background:transparent;color:var(--text);border:1px solid var(--line-2)}.btn.ghost:hover{background:var(--surface-3)}.btn.danger{background:transparent;color:var(--bad);border:1px solid var(--bad);margin-top:12px}.icon-btn{display:inline-grid;place-items:center;min-width:32px;height:32px;border:0;background:transparent;border-radius:8px;cursor:pointer;color:var(--text-2)}.icon-btn:hover:not(:disabled){background:var(--surface-3);color:var(--text)}.icon-btn:disabled{opacity:.35;cursor:default}.icon-btn.accent{color:var(--accent)}.icon-btn.danger:hover{color:var(--bad)}.link-btn{background:none;border:0;color:var(--accent-ink);text-decoration:underline;cursor:pointer;padding:0}.input{width:100%;background:var(--surface-2);color:var(--text);border:1px solid var(--line-2);border-radius:7px;padding:6px 9px;font:inherit}.input.small{width:auto;padding:3px 6px;font-size:12.5px}.input:focus{border-color:var(--accent);outline:none}textarea.input{resize:vertical}.field{display:flex;flex-direction:column;gap:3px;margin:8px 0;min-width:0}.field-label{font-size:12px;color:var(--text-2);font-weight:500}.field-hint{font-size:11.5px;color:var(--text-3)}.field-warn{font-size:11.5px;color:var(--warn)}.row2{display:grid;grid-template-columns:1fr 1fr;gap:10px}.row3{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.toggle{display:inline-flex;align-items:center;gap:8px;cursor:pointer;margin:6px 0}.toggle input{position:absolute;opacity:0}.toggle-track{width:34px;height:20px;border-radius:10px;background:var(--line-2);position:relative;transition:background .15s}.toggle-thumb{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .15s}.toggle input:checked+.toggle-track{background:var(--accent)}.toggle input:checked+.toggle-track .toggle-thumb{transform:translate(14px)}.toggle input:focus-visible+.toggle-track{outline:2px solid var(--accent);outline-offset:2px}.check{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;color:var(--text-2)}.badge{display:inline-flex;align-items:center;gap:3px;font-size:11px;padding:1px 6px;border-radius:999px;margin-right:6px}.badge.ext{background:#38bdf826;color:var(--ext)}.app{display:grid;grid-template-rows:auto 1fr;height:100vh}.toolbar{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--surface);border-bottom:1px solid var(--line);flex-wrap:wrap}.brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:16px}.toolbar .group{display:flex;align-items:center;gap:2px;padding-right:10px;border-right:1px solid var(--line)}.tool-btn{display:inline-flex;align-items:center;gap:6px;border:0;background:transparent;padding:6px 10px;border-radius:8px;cursor:pointer;color:var(--text-2)}.tool-btn.active{background:var(--accent-2);color:var(--accent-ink)}.tool-btn:hover{color:var(--text)}.speed input{width:90px;accent-color:var(--accent)}.tick{font-family:var(--mono);font-size:12px;color:var(--text-3);min-width:64px}.lab-name{color:var(--text-2);max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.net-status{display:inline-flex;align-items:center;gap:5px;font:inherit;font-size:12.5px;color:var(--text-2);background:transparent;border:1px solid var(--line-2);border-radius:999px;padding:3px 10px;cursor:pointer}.net-status:hover{border-color:var(--text-3)}.net-status.online{color:var(--ext);border-color:#38bdf873;background:#38bdf81a}.net-status.policy-off{color:var(--warn);border-color:#fbbf2466}.workspace{display:grid;grid-template-columns:var(--pal-w) 1fr var(--side-w);min-height:0}.center{display:flex;flex-direction:column;min-width:0;min-height:0}.center>.canvas-wrap{flex:1}.center>.log{flex:0 0 var(--log-h)}.center>.lesson{flex:0 0 auto}.palette{display:flex;flex-direction:column;gap:4px;padding:8px 6px;background:var(--surface);border-right:1px solid var(--line);overflow-y:auto}.pal-item{display:flex;flex-direction:column;align-items:center;gap:2px;background:transparent;border:1px solid transparent;border-radius:9px;padding:6px 2px;cursor:grab;font-size:11.5px;color:var(--text-2)}.pal-item:hover{background:var(--surface-2);border-color:var(--line-2);color:var(--text)}.canvas-wrap{position:relative;min-height:200px;background:var(--canvas);overflow:hidden}.canvas{width:100%;height:100%;display:block;touch-action:none;-webkit-user-select:none;user-select:none}.canvas .dot{fill:var(--canvas-dot)}.tool-cable .node,.tool-delete .node{cursor:pointer}.tool-delete .node:hover .node-hit,.tool-delete .link:hover .link-line{stroke:var(--bad)}.node{cursor:grab}.node-hit{fill:transparent;stroke:transparent;stroke-width:2}.node.selected .node-hit{stroke:var(--accent);fill:var(--accent-2)}.node.pending .node-hit{stroke:var(--pink);stroke-dasharray:5 4}.node.off{opacity:.45}.node-name{fill:var(--text);font-size:13px;font-weight:600;text-anchor:middle}.node-ip{fill:var(--text-2);font-size:11px;font-family:var(--mono);text-anchor:middle}.fw-badge circle{fill:#d9472f}.fw-badge text{fill:#fff;font-size:7px;font-weight:700;text-anchor:middle}.link-line{stroke:var(--cable);stroke-width:2.5}.link.wireless .link-line{stroke-dasharray:6 6;stroke:#818cf8}.link.down .link-line{stroke:var(--bad);opacity:.6}.link-hit{stroke:transparent;stroke-width:14;cursor:pointer}.port-label{fill:var(--text-3);font-size:10px;font-family:var(--mono);text-anchor:middle;pointer-events:none}.pkt{pointer-events:none}.paused .pkt{pointer-events:auto;cursor:pointer}.pkt circle{stroke:#0000008c;stroke-width:1.5}.pkt-ext circle{stroke:var(--ext);stroke-width:3}.pkt-drop circle{fill:var(--bad)!important;opacity:.7;transition:opacity .6s}.canvas-empty{position:absolute;inset:0;display:grid;place-content:center;text-align:center;color:var(--text-2);pointer-events:none}.canvas-empty button{pointer-events:auto}.canvas-hint{position:absolute;top:10px;left:50%;transform:translate(-50%);background:var(--surface-2);border:1px solid var(--line-2);padding:6px 12px;border-radius:999px;font-size:13px}.zoom-ctl{position:absolute;right:10px;bottom:10px;display:flex;gap:2px;background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:2px}.port-menu{position:absolute;z-index:5;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--radius);box-shadow:var(--shadow-lg);padding:10px;width:260px}.port-menu-head{font-weight:600;margin-bottom:6px}.port-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;margin-bottom:8px}.port-btn{border:1px solid var(--line-2);background:var(--surface-2);border-radius:6px;padding:4px 2px;font-family:var(--mono);font-size:11.5px;cursor:pointer}.port-btn:hover:not(:disabled){border-color:var(--accent)}.port-btn.used{opacity:.35;cursor:not-allowed}.panel{background:var(--surface);border-left:1px solid var(--line);display:flex;flex-direction:column;min-height:0}.panel.empty{padding:20px;gap:8px}.panel-head{display:flex;align-items:center;gap:10px;padding:12px 14px 6px}.panel-head h2{font-size:17px}.tabs{display:flex;flex-wrap:wrap;gap:2px;padding:0 10px;border-bottom:1px solid var(--line)}.tab{border:0;background:transparent;padding:7px 9px;cursor:pointer;color:var(--text-2);border-bottom:2px solid transparent}.tab.active{color:var(--accent-ink);border-bottom-color:var(--accent)}.panel-body{flex:1;overflow-y:auto;padding:10px 14px 20px}.panel-body.tab-terminal{display:flex;padding:0;overflow:hidden}.dev-intro{display:flex;gap:12px;align-items:center;color:var(--text-2)}.section{margin-top:14px}.section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px}.section-head h3{font-size:13.5px;color:var(--text)}.card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);padding:8px 10px;margin:8px 0}.card-head{display:flex;align-items:center;gap:6px}.rule.disabled{opacity:.55}.rule-allow{border-left:3px solid var(--ok)}.rule-deny,.rule-reject{border-left:3px solid var(--bad)}.rule-nr{font-weight:700;color:var(--text-2);min-width:18px}.rule-text{margin:4px 0 0;font-size:12.5px;color:var(--accent-ink)}.hits{font-family:var(--mono);font-size:12px;color:var(--text-3);margin-left:auto}.rec-row{display:flex;align-items:end;gap:6px;margin:4px 0}.rec-row>span{padding-bottom:7px;color:var(--text-3)}.tbl{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:4px}.tbl th{text-align:left;color:var(--text-3);font-weight:500;border-bottom:1px solid var(--line);padding:4px}.tbl td{border-bottom:1px solid var(--line);padding:4px;vertical-align:top}.live{background:var(--surface-2);border-radius:8px;padding:6px 10px}.live p{margin:4px 0 8px}.terminal{flex:1;display:flex;flex-direction:column;background:var(--term-bg);color:var(--term-text);font-family:var(--mono);font-size:12.5px;min-height:0}.term-out{flex:1;overflow-y:auto;padding:10px 12px;white-space:pre-wrap;word-break:break-word}.term-hint{color:var(--text-3)}.term-in{display:flex;align-items:center;gap:6px;padding:8px 12px;border-top:1px solid var(--line)}.term-in input{flex:1;background:transparent;border:0;color:inherit;font:inherit;outline:none}.prompt{color:var(--accent-ink)}.browser-bar{display:flex;gap:6px}.browser-page{margin-top:10px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px;min-height:200px}.browser-meta{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:6px}.page-title{font-size:18px;margin-bottom:6px}.browser-error h2{font-size:16px;color:var(--bad)}.md h2{font-size:18px;margin:8px 0 4px}.md h3,.md h4{font-size:15px;margin:8px 0 4px}.md p{margin:6px 0}.log{display:flex;flex-direction:column;background:var(--surface);border-top:1px solid var(--line);min-height:0}.log-head{display:flex;align-items:center;gap:8px;padding:6px 10px;border-bottom:1px solid var(--line);flex-wrap:wrap}.log-head h2{font-size:13.5px}.log-list{flex:1;overflow-y:auto;font-size:12.5px;padding:2px 0}.log-row{display:grid;grid-template-columns:48px 92px 1fr;gap:8px;width:100%;text-align:left;border:0;background:transparent;padding:2px 10px;cursor:pointer}.log-row:disabled{cursor:default}.log-row:hover:not(:disabled){background:var(--surface-2)}.log-tick{font-family:var(--mono);color:var(--text-3)}.log-dev{color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lv-frame .log-text{color:var(--text-2)}.lv-ok .log-text{color:var(--ok)}.lv-warn .log-text{color:var(--warn)}.lv-error .log-text,.lv-drop .log-text{color:var(--bad)}.lesson{background:var(--surface);border-bottom:1px solid var(--line);max-height:30vh;display:flex;flex-direction:column}.lesson.collapsed{max-height:none}.lesson-head{display:flex;align-items:center;gap:8px;padding:6px 10px}.lesson-head h2{font-size:14.5px;display:flex;align-items:center;gap:6px;flex:1}.progress{font-family:var(--mono);color:var(--accent-ink)}.lesson-body{overflow-y:auto;padding:0 16px 12px}.lesson-body h3{font-size:13px;margin:10px 0 4px;color:var(--text-2);text-transform:uppercase;letter-spacing:.04em}.steps{margin:0;padding-left:20px}.steps li{margin:3px 0}.checks{list-style:none;padding:0;margin:0}.checks li{display:flex;align-items:center;gap:8px;margin:3px 0;color:var(--text-2)}.checks li.done{color:var(--ok)}.check-ico{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:50%;border:1.5px solid var(--line-2)}.checks li.done .check-ico{background:var(--ok);border-color:var(--ok);color:#06281c}.quiz{padding-left:18px}.quiz-opt{display:block;width:100%;text-align:left;margin:3px 0;padding:6px 10px;border-radius:7px;border:1px solid var(--line-2);background:var(--surface-2);cursor:pointer}.quiz-opt.right{border-color:var(--ok);background:var(--ok-bg)}.quiz-opt.wrong{border-color:var(--bad);background:var(--bad-bg)}.scrim{position:fixed;inset:0;background:var(--scrim);display:grid;place-items:center;z-index:20;padding:16px}.modal{background:var(--surface);border-radius:14px;box-shadow:var(--shadow-lg);width:min(560px,100%);max-height:86vh;display:flex;flex-direction:column;outline:none}.modal.wide{width:min(860px,100%)}.modal-head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--line)}.modal-head h2{font-size:16px}.modal-body{overflow-y:auto;padding:12px 16px 18px}.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}.pick-card{display:flex;flex-direction:column;gap:4px;text-align:left;padding:12px;border-radius:var(--radius);border:1px solid var(--line-2);background:var(--surface-2);cursor:pointer}.pick-card:hover{border-color:var(--accent)}.level{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--accent-ink)}.layer{border:1px solid var(--line);border-radius:var(--radius);padding:8px 10px;margin:8px 0}.layer header{margin-bottom:4px}.layer-n{font-size:11px;color:var(--text-3);text-transform:uppercase}.layer dl{display:grid;grid-template-columns:130px 1fr;gap:2px 10px;margin:0}.layer dt{color:var(--text-2)}.layer dd{margin:0;word-break:break-all}.pkt-route{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.pkt-dot{width:12px;height:12px;border-radius:50%;display:inline-block}.toast{position:fixed;bottom:18px;left:50%;transform:translate(-50%);z-index:30;max-width:min(560px,92vw);padding:10px 16px;border-radius:10px;background:var(--surface-3);box-shadow:var(--shadow-lg);cursor:pointer}.toast.error{background:#3b1518;color:#fecaca;border:1px solid var(--bad)}.toast.ok{border:1px solid var(--ok)}.d-body{fill:#6a6680}.d-screen{fill:#c4b5fd}.d-scr-line{stroke:#fff;stroke-width:2;stroke-linecap:round;opacity:.75;fill:none}.d-srv{fill:#5a5670}.d-slot{fill:#7a7690}.d-led{fill:#45e09a}.d-led2{fill:#f0abfc}.d-sw{fill:#0e9fb8}.d-hub{fill:#7d7a8c}.d-ap{fill:#4f46e5}.d-wave{stroke:#818cf8;stroke-width:2.4;fill:none;stroke-linecap:round}.d-wave-dot{fill:#818cf8}.d-antenna{stroke:#6a6680;stroke-width:3.2;stroke-linecap:round;fill:none}.d-dot{fill:#fff;opacity:.85}.d-arrow{stroke:#fff;stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round}.d-arrow2{stroke:#fff;stroke-width:2.2;fill:none;stroke-linecap:round}.d-rt{fill:#7e22ce}.d-rt-top{fill:#a855f7}.d-fw{fill:#d9472f}.d-brick{stroke:#f2c2b8;stroke-width:2;fill:none}.d-cloud{fill:#0ea5e9}.d-globe{fill:#e0f2fe}.d-globe-line{stroke:#0284c7;stroke-width:1.6;fill:none}.d-link{fill:#db2777}@media (max-width: 1100px){:root{--side-w: 340px;--log-h: 160px}.tool-btn span,.lab-name{display:none}}@media (max-width: 760px){.workspace{grid-template-columns:1fr;grid-template-rows:auto minmax(320px,1fr) auto}.palette{flex-direction:row;overflow-x:auto;border-right:0;border-bottom:1px solid var(--line)}.pal-item{min-width:64px}.panel{border-left:0;border-top:1px solid var(--line);max-height:60vh}.row3{grid-template-columns:1fr 1fr}}.callout{background:var(--accent-2);border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px;margin:10px 0}.callout p{margin:0 0 6px}.callout.warn{background:var(--warn-bg);border-color:#fbbf2473}.btn-row{display:flex;gap:6px;flex-wrap:wrap}.route.ok{border-left:3px solid var(--ok)}.route.bad{border-left:3px solid var(--warn)}.route-text{margin:4px 0 0;font-size:12.5px}.route-text.bad{color:var(--warn)}.addr-card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);padding:8px 10px;margin:6px 0}.addr-card.down{opacity:.6}.addr-name{font-weight:600;margin-bottom:4px}.addr{display:grid;grid-template-columns:110px 1fr;gap:3px 10px;margin:0;font-size:13px}.addr dt{color:var(--text-2)}.addr dd{margin:0}.addr-src{color:var(--text-3);font-size:12px}.missing{color:var(--warn);font-size:12.5px}
