:root{font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;color:#233b34;background:#f4f6f2;font-size:14px;--green:#176b4d;--line:#dfe6df;--muted:#687a70}*{box-sizing:border-box}body{margin:0}button,input,select,textarea,.button{font:inherit}button,.button{cursor:pointer;border:1px solid var(--line);background:white;border-radius:7px;padding:9px 12px;color:inherit;text-decoration:none;white-space:nowrap}button:hover,.button:hover{background:#edf4ed;border-color:#a3b9aa}button:disabled{cursor:default;opacity:.4}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{outline:3px solid #df9e41;outline-offset:3px}header{min-height:86px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;padding:18px 26px;gap:20px}.brand{display:flex;gap:12px;align-items:center;text-decoration:none;color:inherit;font-size:21px;font-weight:750;letter-spacing:-.5px}.brand small{display:block;font-size:9px;letter-spacing:1.6px;color:var(--muted);margin-top:4px}.brand-icon{background:var(--green);color:white;font-size:29px;padding:6px 12px;border-radius:10px}.file-actions{display:flex;gap:8px;flex-wrap:wrap}.workspace{display:grid;grid-template-columns:235px minmax(420px,1fr) 290px;max-width:2000px;margin:auto}.tools,.inspector{padding:28px 21px;background:#fafbf8}.tools{border-right:1px solid var(--line)}.inspector{border-left:1px solid var(--line)}.eyebrow{font-size:10px;font-weight:750;letter-spacing:1.6px;color:var(--green)}h1{font-size:27px;line-height:1.2;font-weight:650;letter-spacing:-1px;margin:15px 0}h2{font-size:20px;letter-spacing:-.5px;margin:7px 0 18px}h3{font-size:14px}.muted{color:var(--muted);font-size:12px;line-height:1.7}.space{margin:30px 0 13px}.tool{width:100%;margin:0 0 8px;display:flex;align-items:center;text-align:left;padding:12px 9px;gap:10px}.tool small{display:block;font-size:10px;color:var(--muted);margin-top:4px}.tool b{margin-left:auto;font-weight:400}.device-icon{display:grid;place-items:center;width:33px;height:35px;background:#edf2e9;border-radius:6px;font-size:24px;color:var(--green)}.connect{margin-top:10px;width:100%;border:1px dashed #9cb6a0;background:#edf3e9}.connect.active{background:#176b4d;color:white}.example-box{border:1px solid var(--line);padding:15px;border-radius:10px;margin-top:35px;background:#f0f3eb}.example-box strong{display:block;font-size:13px;margin-top:12px}.example-box p,.limits p{font-size:11px;line-height:1.8;color:var(--muted)}.example-box button{border:0;background:none;color:var(--green);padding:0;font-size:12px}.local-note{color:var(--muted);font-size:10px;line-height:1.9;margin-top:35px}.canvas-toolbar{height:64px;display:flex;align-items:center;justify-content:space-between;padding:14px 22px;border-bottom:1px solid var(--line);gap:12px}.canvas-toolbar strong{font-size:13px}.canvas-toolbar .muted{margin-left:12px}.canvas-toolbar button{padding:6px 9px;font-size:11px}.live-dot{display:inline-block;background:#4b9667;width:7px;height:7px;border-radius:50%;margin-right:9px}.canvas-wrap{position:relative;background:#f6f8f3}.canvas-wrap svg{display:block;width:100%;height:clamp(330px,42vw,570px);touch-action:none}.canvas-caption{display:flex;justify-content:space-between;padding:12px 22px;font-size:9px;color:#768477;letter-spacing:1.3px;border-bottom:1px solid var(--line)}.canvas-caption span{letter-spacing:0}.node{cursor:grab}.node rect{fill:white;stroke:#c1d0c2;stroke-width:1.5;filter:drop-shadow(0 4px 5px #233b3410)}.node.selected rect{stroke:var(--green);stroke-width:3}.node.connecting rect{stroke:#d48d2d;stroke-width:3}.node .symbol{fill:var(--green);font-size:31px;text-anchor:middle}.node .node-label{font-size:14px;font-weight:600;fill:#233b34;text-anchor:middle}.node .node-address{font-size:11px;fill:#697d6d;text-anchor:middle}.cable{stroke:#9aad9e;stroke-width:3;cursor:pointer}.cable-hit{stroke:transparent;stroke-width:18;cursor:pointer}.cable.down{stroke:#c1bbb2;stroke-dasharray:8 7}.cable.active{stroke:#cf8d2c;stroke-width:5}.simulation{padding:24px;background:white;min-height:330px}.simulation-title{display:flex;justify-content:space-between;align-items:center;gap:15px}.simulation-title h2{margin:6px 0 18px}.simulation-title #result{font-size:11px;background:#f2f5ee;padding:6px 10px;border-radius:20px;color:var(--muted)}#result.success{background:#e3f3e4;color:#176b4d}#result.failure{background:#ffeded;color:#9f3636}label{display:block;font-size:11px;font-weight:600;color:#536a5c}label small{display:block;font-weight:400;line-height:1.5;margin:6px 0}input,select,textarea{display:block;width:100%;border:1px solid #ccd8cc;border-radius:6px;padding:9px;background:white;color:#263f32;margin-top:6px}textarea{font-size:11px;resize:vertical}#ping-form{display:flex;gap:12px;align-items:end}#ping-form label{flex:1}#ping-form .ttl{flex:0 0 65px}.arrow{align-self:center;margin-top:17px;color:var(--muted)}.primary{background:var(--green);color:white;border-color:var(--green)}.primary:hover{background:#105139;color:white}.playback{display:flex;gap:8px;align-items:center;margin:18px 0;flex-wrap:wrap}.playback button{font-size:11px;padding:6px 9px}.playback label{display:flex;align-items:center;gap:6px;margin-left:auto;font-size:10px}.playback select{margin:0;padding:5px;font-size:10px}.playback #progress{font-size:10px}.events{padding:0;margin:0;list-style:none;max-height:270px;overflow:auto}.events li{display:flex;gap:12px;align-items:start;padding:10px 4px;border-bottom:1px solid #edf1ea;cursor:pointer;font-size:12px;line-height:1.6}.events li.current{background:#f2f7ec}.badge{font-size:9px;font-weight:700;min-width:68px;padding:2px 6px;border-radius:4px;background:#ecf0e9;text-align:center}.badge.ARP{background:#fbefdb;color:#966319}.badge.ICMP,.badge.SUCCÈS{background:#e6f2e9;color:#176b4d}.badge.ERREUR{background:#fce4e4;color:#a23939}.badge.IP{background:#e5edf8;color:#40628a}#node-form label{margin:15px 0}.field-heading{display:flex;justify-content:space-between;align-items:center;margin-top:20px}.field-heading button{padding:4px 9px}.interface{margin:9px 0;padding:10px;border:1px solid var(--line);border-radius:7px;background:white}.interface header{padding:0;min-height:0;border:0;font-size:11px}.interface header button{padding:2px 7px}.interface label{margin:9px 0!important}.interface .row{display:flex;gap:8px}.interface .row label{width:50%}.interface input{font-size:11px;padding:7px}.wide{width:100%;margin-top:10px;font-size:12px}.danger{color:#a5433c;border-color:#e8caca}.limits{border-top:1px solid var(--line);margin-top:30px;padding-top:20px}.limits strong{font-size:11px}#tables{margin-top:25px}#tables table{width:100%;border-collapse:collapse;font-size:10px;word-break:break-word}#tables td,#tables th{text-align:left;padding:8px 3px;border-bottom:1px solid var(--line)}#notice{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);max-width:90vw;z-index:20;background:#243d30;color:white;padding:14px 22px;border-radius:9px;box-shadow:0 6px 25px #0003}dialog{border:1px solid #c8d8c8;border-radius:14px;max-width:570px;width:90%;padding:28px;box-shadow:0 20px 80px #1234;color:#233b34}dialog p,dialog li{font-size:13px;line-height:1.8}dialog::backdrop{background:#16332477}dialog label{margin-bottom:18px}.dialog-actions{display:flex;gap:8px;justify-content:flex-end}.connecting-mode .node{cursor:crosshair}[hidden]{display:none!important}@media(min-width:1600px){.workspace{grid-template-columns:260px minmax(420px,1fr) 310px}}@media(max-width:1150px){.workspace{grid-template-columns:190px minmax(390px,1fr)}.tools{padding:22px 14px}.inspector{grid-column:1/-1;border-top:1px solid var(--line);display:block}.inspector #node-form{max-width:650px}.file-actions{gap:5px}header{padding:16px}.file-actions button,.file-actions a{font-size:11px}.canvas-toolbar{padding:12px}#counts{display:none}}@media(max-width:650px){header{align-items:start;flex-direction:column}.workspace{display:flex;flex-direction:column}.tools{border-right:0;border-bottom:1px solid var(--line)}.tools h1,.tools>.muted,.space,.example-box,.local-note{display:none}.tools>.eyebrow{margin-bottom:12px}.tool{display:inline-flex;width:48%;margin-right:1%;padding:8px}.tool small{font-size:9px}.connect{width:auto}.tools #tool-hint{display:block;margin-bottom:0}.canvas-wrap svg{height:330px}.canvas-caption{font-size:8px;padding:10px}.simulation{padding:18px}#ping-form{flex-wrap:wrap}#ping-form label{min-width:100px}#ping-form .ttl{min-width:60px}#ping-form .primary{width:100%}.simulation-title{align-items:start}.playback label{margin-left:0}.arrow{display:none}}
/* Cartes Ethernet, ports et diagnostic du câblage. */
.node .machine-name{font-size:12px;font-weight:650;fill:#233b34}.node .machine-kind{font-size:10px;fill:#687a70}.node .nic{cursor:pointer}.node .nic .nic-board{fill:#e9f0e2;stroke:#9fb39a;stroke-width:1;filter:none}.node.selected .nic .nic-board,.node.connecting .nic .nic-board{stroke-width:1}.node .nic .nic-socket{fill:#3d5143;stroke:#627b60;stroke-width:1;filter:none}.nic-name{font-size:10px;fill:#274731;font-weight:700}.nic-ip{font-size:9px;fill:#486647}.nic-led{fill:#9ba69b;stroke:white;stroke-width:1}.nic.up .nic-led{fill:#26a354}.nic.down .nic-led{fill:#d64b40}.nic.off{opacity:.6}.nic:hover .nic-board{fill:#dcebd4}.nic:focus-visible{outline:none}.nic:focus-visible .nic-board{stroke:#d18f29!important;stroke-width:3!important}.cable.type-droit{stroke:#4a8c6b}.cable.type-croise{stroke:#497ca4;stroke-dasharray:10 4}.cable.type-coaxial{stroke:#9d7541;stroke-width:5}.cable.down{stroke:#c65d56;stroke-dasharray:3 7}.cable.active{stroke:#df9f2d;stroke-width:5}.cable-label{font-size:10px;font-weight:550;fill:#5d7567;paint-order:stroke;stroke:#f6f8f3;stroke-width:4px;stroke-linejoin:round;text-anchor:middle;cursor:pointer}.cable-legend{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.cable-legend i{display:inline-block;width:18px;border-top:2px solid #4a8c6b;margin-left:5px}.cable-legend .legend-croise{border-color:#497ca4;border-top-style:dashed}.cable-legend .legend-coaxial{border-color:#9d7541;border-top-width:4px}.cable-legend .legend-down{border-color:#c65d56;border-top-style:dotted}.checkbox-label{display:flex;align-items:center;gap:7px;font-weight:400;font-size:11px}.checkbox-label input{margin:0;width:auto}.physical-status{font-size:11px;color:#367a4e;line-height:1.6}.physical-status.bad{color:#b33f36}.interface.focused-card{outline:2px solid #d99a35;outline-offset:2px}#edit-cable-form{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:18px 0;margin-bottom:18px}.mode-tabs{display:flex;gap:6px;margin:0 0 16px}.mode-tabs button{font-size:12px}.mode-tabs .chosen{background:#e7f1e5;border-color:#88ab8a;color:#176b4d}#ethernet-form{display:grid;grid-template-columns:1fr 1fr;gap:12px}#ethernet-form .primary{align-self:end;grid-column:1/-1}.badge.PHYSIQUE{background:#fce4e4;color:#a23939}.badge.ETHERNET{background:#ede7f7;color:#6f548f}@media(max-width:650px){.canvas-caption{gap:12px;align-items:start}.cable-legend{justify-content:end;max-width:220px}#ethernet-form{grid-template-columns:1fr}}
/* Uplinks optiques et ports access des switchs. */
.cable.type-fibre{stroke:#9860b0;stroke-width:4}.cable.type-fibre.down{stroke:#c65d56;stroke-dasharray:3 7}.cable.type-fibre.active{stroke:#df9f2d;stroke-width:5}.cable-legend .legend-fibre{border-color:#9860b0;border-top-width:4px}.physical-port{cursor:pointer}.node .physical-port .port-board{fill:#f0f4eb;stroke:#b5c5ae;stroke-width:1;filter:none}.node .physical-port .port-socket{fill:#334d3c;stroke:#6d8668;stroke-width:1;filter:none}.node .physical-port .port-socket.fibre{fill:#80568f;stroke:#b99bc9}.physical-port.up .nic-led{fill:#26a354}.physical-port.down .nic-led{fill:#d64b40}.physical-port.off{opacity:.5}.port-label{font-size:9px;font-weight:600;text-anchor:middle;fill:#304d37}.port-vlan{font-size:8px;text-anchor:middle;fill:#556b50;paint-order:stroke;stroke:#f6f8f3;stroke-width:3px}.physical-port:hover .port-board{fill:#dfecd7}.physical-port:focus-visible{outline:none}.node .physical-port:focus-visible .port-board{stroke:#df9e41;stroke-width:3}
.node .physical-port.traffic .port-board,.node .nic.traffic .nic-board{stroke:#d99624;stroke-width:3;fill:#fff0ca}
/* Table de configuration des prises et VLAN. */
#ports-dialog{width:min(980px,96vw);max-width:980px;max-height:90vh;padding:26px}#ports-dialog form{margin:0}.ports-heading{display:flex;justify-content:space-between;align-items:center;gap:18px}.ports-heading h2{margin-bottom:8px}.ports-heading button{flex-shrink:0}.ports-table-scroll{max-height:55vh;overflow:auto;border:1px solid var(--line);border-radius:8px;margin:18px 0}#ports-config-table{width:100%;min-width:690px;border-collapse:separate;border-spacing:0;font-size:12px;text-align:left}#ports-config-table caption{padding:10px 14px;text-align:left;color:var(--muted);font-size:11px;background:#f8faf5}#ports-config-table thead th{position:sticky;top:0;z-index:1;background:#eaf1e6;font-size:11px;padding:12px 10px;white-space:nowrap}#ports-config-table tbody th,#ports-config-table td{padding:9px 10px;border-top:1px solid var(--line);vertical-align:middle}#ports-config-table tbody tr:hover{background:#f4f8ef}#ports-config-table input,#ports-config-table select{margin:0;padding:7px;font-size:12px}#ports-config-table .port-vlan-input{width:76px}#ports-config-table .port-media{min-width:124px}#ports-config-table input[type=checkbox]{width:17px;height:17px;accent-color:var(--green);cursor:pointer}#ports-config-table button{padding:4px 10px;font-size:18px}.port-row-status{font-size:11px;line-height:1.5;display:block;min-width:145px;color:var(--muted)}.port-row-status.up{color:#287944}.port-row-status.down{color:#b34038}#ports-config-table tr.focused-card{background:#fff1cd;outline:2px solid #d99a35;outline-offset:-2px}#ports-dialog>.dialog-actions{margin-top:18px}@media(max-width:650px){#ports-dialog{padding:18px}.ports-heading{align-items:start;flex-direction:column;gap:8px}.ports-heading h2{font-size:18px}.ports-table-scroll{max-height:48vh}}
/* Trunks, services et tables de simulation. */
.large-dialog{width:min(1180px,96vw);max-width:1180px;max-height:92vh;overflow:auto}.large-dialog h3{margin-top:24px}.large-dialog section{border-top:1px solid var(--line);padding:5px 0 18px}.large-dialog .dialog-actions{margin-top:24px}.data-table-scroll{max-width:100%;overflow:auto;margin:15px 0;border:1px solid var(--line);border-radius:7px}.config-table{width:100%;border-collapse:collapse;font-size:12px;text-align:left;min-width:580px}.config-table th{font-size:11px;background:#edf3e8;padding:11px 10px;white-space:nowrap}.config-table td{padding:9px 10px;border-top:1px solid var(--line)}.config-table input,.config-table select{margin:0;font-size:12px;padding:7px;min-width:70px}.config-table input[type=number]{width:84px}.config-table input[type=checkbox]{min-width:0;width:17px;height:17px;accent-color:var(--green)}.config-table button{padding:4px 8px}.filter-config{min-width:1150px}.filter-config input[type=text]{min-width:105px}.rule-move{display:flex;gap:3px;align-items:center}.rule-move .rule-order{min-width:15px}.table-controls{display:flex;align-items:end;gap:12px;flex-wrap:wrap}.table-controls label{flex:1;min-width:160px}.runtime-data td{white-space:nowrap;font-family:ui-monospace,monospace;font-size:11px}.port-allowed{min-width:130px}.port-native{width:80px}#ports-config-table{min-width:1000px}#ports-dialog{width:min(1240px,96vw);max-width:1240px}#ports-config-table .port-mode{min-width:110px}.node .physical-port .port-socket.trunk{stroke:#3c85c1;stroke-width:3}.badge.NAT{background:#efe4ff;color:#71478d}.badge.FILTRE{background:#ffe7dc;color:#9f4a21}.badge.TCP,.badge.UDP{background:#deecfa;color:#365d85}.mode-tabs{flex-wrap:wrap}.mode-tabs button{font-size:11px}#transport-form{display:grid;grid-template-columns:1fr 1fr;gap:12px}#transport-form .primary{grid-column:1/-1}.limits{font-size:11px}@media(max-width:650px){#transport-form{grid-template-columns:1fr}.table-controls{align-items:stretch}.large-dialog{padding:18px}.ports-heading .dialog-actions{flex-wrap:wrap;justify-content:start}}
.example-box #demo-services{display:block;margin-top:13px;white-space:normal;text-align:left;line-height:1.6}
.dialog-notice{position:sticky;top:0;z-index:5;background:#fff0cf;border:1px solid #dbb46a;color:#6a4a12;padding:12px 15px;border-radius:7px;font-size:12px;line-height:1.6;margin-bottom:14px}
.frame-composition{grid-column:1/-1;border:1px solid var(--line);border-radius:8px;background:#f8faf5;padding:13px;margin-top:3px;min-width:0}.frame-heading{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}.frame-heading h3{margin:0;font-size:12px}.frame-heading>span{font-size:10px;color:var(--muted)}.frame-heading .over-limit{color:#b34038}.frame-fields{display:flex;flex-wrap:wrap;gap:5px;align-items:stretch}.frame-field{flex:1 1 110px;min-width:0;border:1px solid #d6e2d0;border-top:3px solid #5a946e;border-radius:5px;background:white;padding:8px}.frame-field strong,.frame-field small,.frame-field span,.frame-field code{display:block}.frame-field strong{font-size:10px;white-space:nowrap}.frame-field small{font-size:9px;color:var(--muted);margin:4px 0 8px}.frame-field span,.frame-field code{font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.frame-field.frame-sync{border-top-color:#93a49a}.frame-field.frame-tag{background:#f3edfa;border-top-color:#9860b0}.frame-field.frame-data{flex-grow:2;background:#edf5e8}.frame-field.frame-fcs{border-top-color:#b2945c}@media(max-width:650px){.frame-field{flex-basis:125px}.frame-heading{gap:6px}}
