
*{margin:0;padding:0;box-sizing:border-box}
html,body{width:100%;height:100%;overflow:hidden;font-family:'DM Sans',system-ui,sans-serif}
body{background:var(--bg);color:var(--text);transition:background 0.4s,color 0.4s}

/* ═══════ 2 THEMES ═══════ */
:root,body.midnight{
  --bg:#00142e;--water1:#001a3a;--water2:#001f4d;--water3:#000e20;
  --accent:#3a80e9;--accent2:#6aa4ff;--accentDim:rgba(58,128,233,0.1);
  --walk:#1a3860;--walkS:#2a5080;--fing:#143050;--fingS:#1e4468;
  --gang:rgba(26,56,96,0.4);--gangS:#2a5080;
  --land:#0a1e38;--landS:#163460;
  --text:#d8e0f0;--textDim:rgba(216,224,240,0.25);--textMid:rgba(216,224,240,0.55);
  --card:rgba(58,128,233,0.04);--cardB:rgba(58,128,233,0.1);
  --sidebarBg:rgba(0,20,46,0.95);--hdrBg:rgba(0,20,46,0.96);
  --ttBg:rgba(0,16,36,0.97);--ttB:rgba(58,128,233,0.2);
  --ripple:rgba(58,128,233,1);--rA1:0.035;--rA2:0.022;--rA3:0.014;
  --caustic:rgba(100,160,255,1);--causticA:0.018;
  --normal:#22c55e;--warning:#f59e0b;--critical:#ef4444;--offline:#4a5e78;--nodata:#1a3050;
  --modalBg:rgba(0,20,46,0.93);--modalCard:rgba(0,26,58,0.98);--modalB:rgba(58,128,233,0.12);
}
body.harbour{
  --bg:#dceef8;--water1:#c8e4f0;--water2:#d5edf7;--water3:#b8d8ea;
  --accent:#0a6e8a;--accent2:#2d7dd2;--accentDim:rgba(10,110,138,0.08);
  --walk:#a0b8cc;--walkS:#7a96b0;--fing:#94aec4;--fingS:#708ea8;
  --gang:rgba(140,170,190,0.4);--gangS:#7a96b0;
  --land:#78aa78;--landS:#5a8a5a;
  --text:#1a2a3a;--textDim:rgba(26,42,58,0.2);--textMid:rgba(26,42,58,0.5);
  --card:rgba(10,110,138,0.05);--cardB:rgba(10,110,138,0.12);
  --sidebarBg:rgba(220,238,248,0.96);--hdrBg:rgba(220,238,248,0.97);
  --ttBg:rgba(255,255,255,0.97);--ttB:rgba(10,110,138,0.18);
  --ripple:rgba(0,100,160,1);--rA1:0.06;--rA2:0.04;--rA3:0.025;
  --caustic:rgba(255,255,255,1);--causticA:0.05;
  --normal:#16a34a;--warning:#d97706;--critical:#dc2626;--offline:#94a3b8;--nodata:#b0c8d8;
  --modalBg:rgba(220,238,248,0.92);--modalCard:rgba(255,255,255,0.98);--modalB:rgba(10,110,138,0.1);
}

#app{display:flex;flex-direction:column;height:100vh}
.hdr{height:48px;display:flex;align-items:center;padding:0 16px;background:var(--hdrBg);border-bottom:1px solid var(--cardB);justify-content:space-between;flex-shrink:0;z-index:20;backdrop-filter:blur(12px);transition:background 0.4s}
.hdr-title{font-size:15px;font-weight:700;letter-spacing:-0.3px;color:var(--accent)}
.hdr-sub{font-size:11px;color:var(--textMid);margin-left:10px}
.hdr-stat{padding:4px 10px;border-radius:6px;font-size:11px;font-weight:600;background:var(--card);border:1px solid var(--cardB);transition:background 0.4s}
.hdr-right{display:flex;align-items:center;gap:8px}
.theme-pill{display:flex;gap:3px;padding:3px;border-radius:8px;background:var(--card);border:1px solid var(--cardB)}
.theme-dot{width:18px;height:18px;border-radius:50%;cursor:pointer;border:2px solid transparent;transition:border-color 0.2s,transform 0.15s}
.theme-dot:hover{transform:scale(1.15)}
.theme-dot.active{border-color:var(--text)}
.body-wrap{flex:1;position:relative;overflow:hidden}
canvas{display:block;cursor:grab}
canvas.dragging{cursor:grabbing}

.side{position:absolute;top:0;left:0;bottom:0;width:340px;background:var(--sidebarBg);border-right:1px solid var(--cardB);z-index:15;display:flex;flex-direction:column;transition:width 0.25s,background 0.4s;overflow:hidden;backdrop-filter:blur(10px)}
.side.shut{width:0}
.side-toggle{position:absolute;top:6px;right:-26px;width:26px;height:26px;background:var(--sidebarBg);border:1px solid var(--cardB);border-left:none;border-radius:0 5px 5px 0;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--textMid);z-index:16;transition:background 0.4s}
.side-list{flex:1;overflow-y:auto;padding:4px 0}
.side-list::-webkit-scrollbar{width:4px}
.side-list::-webkit-scrollbar-thumb{background:var(--cardB);border-radius:2px}
.arm-hdr{padding:10px 14px;cursor:pointer;display:flex;justify-content:space-between;align-items:center;color:var(--accent);font-size:13px;font-weight:700;letter-spacing:0.5px;border-top:1px solid var(--cardB);transition:background 0.15s}
.arm-hdr:hover{background:var(--accentDim)}
.arm-hdr .info{color:var(--textMid);font-weight:400;font-size:11px}
.arm-hdr .chev{font-size:8px;transition:transform 0.2s}
.arm-hdr .chev.open{transform:rotate(0)}
.arm-hdr .chev.shut{transform:rotate(-90deg)}
.arm-berths{display:none}
.arm-berths.open{display:block}
.berth-row{padding:8px 12px 8px 14px;cursor:pointer;display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:13px;transition:background 0.1s;border-bottom:1px solid var(--cardB)}
.berth-row:hover{background:var(--accentDim)}
.berth-row:nth-child(even){background:rgba(128,128,128,0.03)}
.berth-row:nth-child(even):hover{background:var(--accentDim)}
.berth-row .skt-icon{width:18px;height:18px;object-fit:contain;flex-shrink:0;opacity:0.85}
.berth-row .dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.berth-row .name{color:var(--text);font-weight:700;min-width:44px;font-size:13px}
.berth-row .rating{color:var(--textMid);font-size:12px;font-family:'JetBrains Mono',monospace}
.berth-row .cur{margin-left:auto;font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:700}
.berth-row .kwh{color:var(--textMid);font-family:'JetBrains Mono',monospace;font-size:10px;white-space:nowrap}
.berth-row .phases{width:100%;display:flex;gap:12px;padding:2px 0 0 20px;font-family:'JetBrains Mono',monospace;font-size:10px}
.berth-row .phases .ph{display:flex;gap:3px;align-items:center}
.berth-row .phases .ph-lbl{color:var(--textMid);font-weight:600;font-size:9px;text-transform:uppercase}
.berth-row .phases .ph-val{font-weight:500}
.load-gauge{width:100%;height:6px;border-radius:3px;background:var(--cardB);position:relative;overflow:hidden;margin-top:3px}
.load-fill{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:3px;background:linear-gradient(90deg,#22c55e,#22c55e 60%,#84cc16 75%,#f59e0b 85%,#ef4444 95%);transform-origin:left;transition:clip-path 0.6s ease}
.load-pct{position:absolute;right:0;top:-12px;font-size:8px;font-family:'JetBrains Mono',monospace;color:var(--textMid);font-weight:600}
.berth-row.hidden-offline{display:none}
.side-foot{padding:8px;display:flex;flex-wrap:wrap;gap:4px;border-top:1px solid var(--cardB)}
.offline-toggle{width:100%;padding:6px 8px;display:flex;align-items:center;justify-content:space-between;font-size:11px;color:var(--textMid);cursor:pointer;border-bottom:1px solid var(--cardB);user-select:none}
.offline-toggle:hover{color:var(--accent)}
.offline-toggle .otog{width:32px;height:16px;border-radius:8px;background:var(--cardB);position:relative;transition:background 0.2s}
.offline-toggle .otog::after{content:'';position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--textMid);transition:transform 0.2s,background 0.2s}
.offline-toggle.on .otog{background:var(--accent)}
.offline-toggle.on .otog::after{transform:translateX(16px);background:#fff}
.berth-row.hidden-offline{display:none}
.ped-popup{position:absolute;z-index:35;background:var(--card);border:1px solid var(--cardB);border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,0.4);min-width:280px;max-width:460px;max-height:85vh;overflow-y:auto;display:none;backdrop-filter:blur(12px)}
.ped-popup.show{display:block}
.ped-popup .pp-hdr{padding:10px 14px;border-bottom:1px solid var(--cardB);display:flex;align-items:center;gap:8px}
.ped-popup .pp-hdr .pp-icon{width:28px;height:28px;border-radius:6px;background:var(--accentDim);display:flex;align-items:center;justify-content:center;font-size:14px}
.ped-popup .pp-hdr .pp-name{font-weight:700;font-size:13px;color:var(--text)}
.ped-popup .pp-hdr .pp-model{font-size:10px;color:var(--accent);font-weight:600;margin-left:auto;font-family:'JetBrains Mono',monospace}
.ped-popup .pp-body{padding:10px 14px}
.ped-popup .pp-row{display:flex;justify-content:space-between;padding:3px 0;font-size:11px;color:var(--textMid)}
.ped-popup .pp-val{color:var(--text);font-weight:500;font-family:'JetBrains Mono',monospace;font-size:10px}
.ped-popup .pp-side{margin-top:6px;padding:6px 8px;background:var(--accentDim);border-radius:6px}
.ped-popup .pp-side-hdr{font-size:10px;font-weight:700;color:var(--accent);margin-bottom:3px}
.ped-popup .pp-close{position:absolute;top:6px;right:8px;background:none;border:none;color:var(--textMid);cursor:pointer;font-size:14px;padding:4px}
.zbtn{flex:1;padding:5px 6px;border:1px solid var(--cardB);border-radius:4px;background:var(--card);color:var(--textMid);font-size:10px;font-weight:600;cursor:pointer;min-width:44px;text-align:center;font-family:'DM Sans',sans-serif;transition:background 0.15s}
.zbtn:hover{background:var(--accentDim);color:var(--accent)}

.tt{position:absolute;pointer-events:none;z-index:30;background:var(--ttBg);border:1px solid var(--ttB);border-radius:8px;backdrop-filter:blur(12px);box-shadow:0 8px 32px rgba(0,0,0,0.3);min-width:200px;overflow:hidden;display:none;transition:background 0.4s}
.tt.show{display:block}
.tt-hdr{padding:8px 12px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--cardB)}
.tt-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.tt-name{font-weight:700;font-size:13px}
.tt-status{margin-left:auto;font-size:10px;font-weight:600}
.tt-body{padding:6px 12px}
.tt-row{display:flex;justify-content:space-between;padding:3px 0;font-size:11px;color:var(--textMid)}
.tt-val{color:var(--text);font-weight:500;font-family:'JetBrains Mono',monospace;font-size:10px}
.updated{font-size:9px;color:var(--textMid)}
.err{font-size:9px;color:var(--critical)}

.modal-overlay{position:fixed;inset:0;background:var(--modalBg);backdrop-filter:blur(8px);z-index:100;display:none;align-items:center;justify-content:center}
.modal-overlay.show{display:flex}
.modal{background:var(--modalCard);border:1px solid var(--modalB);border-radius:12px;width:95%;max-width:1200px;max-height:90vh;overflow:hidden;box-shadow:0 16px 64px rgba(0,0,0,0.4);display:flex;flex-direction:column;transition:background 0.4s}
.modal-hdr{padding:14px 18px;display:flex;align-items:center;gap:10px;border-bottom:1px solid var(--cardB)}
.modal-hdr .dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.modal-hdr .name{font-weight:700;font-size:18px}
.modal-hdr .status{font-size:11px;font-weight:600;margin-left:4px}
.modal-hdr .close{margin-left:auto;cursor:pointer;font-size:20px;color:var(--textMid);width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;transition:background 0.15s}
.modal-hdr .close:hover{background:var(--accentDim)}
.modal-body{display:flex;flex-direction:column;overflow-y:auto;flex:1}
.modal-stats{display:flex;gap:8px;padding:12px 18px;flex-wrap:wrap}
.modal-stat{flex:1;min-width:80px;padding:8px 12px;border-radius:8px;background:var(--card);border:1px solid var(--cardB);text-align:center}
.modal-stat .v{font-size:16px;font-weight:700;font-family:'JetBrains Mono',monospace}
.modal-stat .l{font-size:9px;color:var(--textMid);text-transform:uppercase;letter-spacing:0.6px;margin-top:2px}
.socket-bar{display:flex;align-items:center;gap:6px;padding:8px 18px;border-bottom:1px solid var(--cardB)}
.socket-bar .lbl{font-size:10px;color:var(--textMid);text-transform:uppercase;letter-spacing:0.6px;font-weight:600;margin-right:4px}
.socket-btn{width:64px;height:46px;border:1.5px solid var(--cardB);border-radius:6px;background:var(--card);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all 0.15s;position:relative}
.socket-btn:hover{border-color:var(--accent);background:var(--accentDim)}
.socket-btn.active{border-color:var(--accent);background:var(--accent);color:var(--bg)}
.socket-btn.active img{filter:brightness(2)}
.socket-btn .rating{position:absolute;bottom:-1px;right:2px;font-size:7px;font-weight:700;font-family:'JetBrains Mono',monospace}
.socket-btn.active .rating{color:var(--bg)}
.modal-chart{flex:1;padding:12px 18px 18px;min-height:380px;position:relative}
.modal-chart canvas{width:100%!important;height:100%!important}
.modal-controls{display:flex;gap:6px;padding:0 18px 10px;flex-wrap:wrap;align-items:center}
.range-btn{padding:5px 12px;border:1px solid var(--cardB);border-radius:5px;background:var(--card);color:var(--textMid);font-size:11px;font-weight:600;cursor:pointer;font-family:'DM Sans',sans-serif;transition:all 0.15s}
.range-btn:hover{background:var(--accentDim);color:var(--accent)}
.range-btn.active{background:var(--accent);color:var(--bg);border-color:var(--accent)}
.billing-row{display:flex;align-items:center;gap:8px;padding:8px 18px 12px;border-top:1px solid var(--cardB)}
.billing-row label{font-size:10px;color:var(--textMid);text-transform:uppercase;letter-spacing:0.5px;font-weight:600}
.billing-row input[type=date],.billing-row input[type=datetime-local]{background:var(--card);border:1px solid var(--cardB);border-radius:5px;color:var(--text);padding:4px 8px;font-size:11px;font-family:'DM Sans',sans-serif;max-width:170px}
.billing-row .billing-btn{padding:5px 14px;border:1px solid var(--accent);border-radius:5px;background:var(--accentDim);color:var(--accent);font-size:11px;font-weight:700;cursor:pointer;font-family:'DM Sans',sans-serif;transition:all 0.15s}
.billing-row .billing-btn:hover{background:var(--accent);color:var(--bg)}
.bill-hdr{padding:16px 20px;background:var(--accentDim);border-bottom:1px solid var(--cardB)}
.bill-hdr h2{font-size:15px;color:var(--accent);margin-bottom:2px}
.bill-hdr .period{font-size:11px;color:var(--textMid)}
.bill-summary{display:grid;grid-template-columns:1fr 1fr 1fr;gap:1px;background:var(--cardB);margin:0}
.bill-summary .bs{padding:12px;background:var(--card);text-align:center}
.bill-summary .bs .v{font-size:20px;font-weight:700;font-family:'JetBrains Mono',monospace;color:var(--accent)}
.bill-summary .bs .l{font-size:9px;color:var(--textMid);text-transform:uppercase;letter-spacing:0.5px;margin-top:2px}
.bill-table{width:100%;border-collapse:collapse;font-size:11px}
.bill-table th{background:var(--accentDim);color:var(--accent);padding:6px 10px;text-align:left;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;position:sticky;top:0}
.bill-table td{padding:5px 10px;border-bottom:1px solid var(--cardB)}
.bill-table tr:hover td{background:var(--accentDim)}
.bill-table .num{text-align:right;font-family:'JetBrains Mono',monospace}
.bill-phase{display:grid;grid-template-columns:1fr 1fr 1fr;gap:1px;background:var(--cardB);margin:0}
.bill-phase .bp{padding:10px;background:var(--card);text-align:center}
.bill-phase .bp .pv{font-size:16px;font-weight:700;font-family:'JetBrains Mono',monospace}
.bill-phase .bp .pl{font-size:9px;color:var(--textMid);text-transform:uppercase}
.bill-section{padding:12px 20px 4px;font-size:12px;font-weight:700;color:var(--accent);text-transform:uppercase;letter-spacing:0.5px}
.bill-footer{padding:12px 20px;border-top:1px solid var(--cardB);display:flex;justify-content:space-between;align-items:center}
.bill-footer .gen{font-size:10px;color:var(--textMid)}
.bill-print{padding:6px 16px;border:1px solid var(--accent);border-radius:5px;background:var(--accentDim);color:var(--accent);font-size:11px;font-weight:700;cursor:pointer}
.bill-print:hover{background:var(--accent);color:var(--bg)}

.chart-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--textMid);font-size:12px}


/* ═══ SLD MODAL ═══ */
#sldOverlay .modal { border: 1px solid var(--accent); }
#sldBody { position: relative; }
#sldCanvas { image-rendering: auto; }
