:root{
  --bg:#12151a;
  --panel:#1b1f27;
  --panel-2:#232833;
  --line:#2f3644;
  --ink:#e6e9ef;
  --ink-dim:#98a1b3;
  --accent:#4da3ff;
  --accent-ink:#04121f;
  --danger:#ff6b6b;
  --side-w:308px;
}
*{box-sizing:border-box}
html,body{height:100%;margin:0}
body{
  font:13px/1.45 "Segoe UI",system-ui,-apple-system,sans-serif;
  background:var(--bg);color:var(--ink);overflow:hidden;
}
#app{display:flex;height:100%}

/* ---------- sidebar ---------- */
#side{
  width:var(--side-w);flex:0 0 var(--side-w);
  background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0;
}
.side-head{padding:14px 16px 12px;border-bottom:1px solid var(--line)}
.side-head h1{margin:0;font-size:16px;font-weight:600;letter-spacing:.2px}
.side-head .sub{color:var(--ink-dim);font-size:11px;margin-top:2px}

/* switches between the map tool and the power visualiser — both pages carry it */
/* four pages do not fit across a 290 px sidebar without "Site planner"
   breaking over two lines, so they wrap into a 2 x 2 grid instead */
.side-head .nav{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.side-head .nav a{
  flex:1 1 calc(50% - 6px);white-space:nowrap;
  text-align:center;text-decoration:none;font-size:11px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:5px;
  padding:4px 8px;color:var(--ink-dim);
}
.side-head .nav a:hover{background:#2c3340;color:var(--ink)}
.side-head .nav a.on{
  background:var(--accent);border-color:var(--accent);
  color:var(--accent-ink);font-weight:600;
}
.scroll{overflow-y:auto;overflow-x:hidden;flex:1;min-height:0;padding-bottom:24px}
.scroll::-webkit-scrollbar{width:10px}
.scroll::-webkit-scrollbar-thumb{background:#39414f;border-radius:6px;border:3px solid var(--panel)}

.panel{padding:12px 16px;border-bottom:1px solid var(--line)}
.panel h2{
  margin:0 0 10px;font-size:10.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-dim);
  transition:margin-bottom .18s ease;
}
.panel h2 .count{
  float:right;background:var(--panel-2);border:1px solid var(--line);
  border-radius:9px;padding:0 7px;color:var(--ink);letter-spacing:0;font-weight:600;
}

/* ---------- collapsible panels (js/panels.js) ----------
 * Every rule here hangs off markup that panels.js creates, so with the script
 * removed or broken the sidebar renders exactly as it used to: all open,
 * correctly padded, no dead chevrons. */

/* The heading becomes a full-width button but keeps looking like a heading —
 * inheriting the h2's own type so there is one place to change it. */
.panel h2>.ph{
  display:block;width:100%;text-align:left;position:relative;
  background:none;border:0;padding:0 0 0 15px;margin:0;
  font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit;
  cursor:pointer;
}
.panel h2>.ph:hover{color:var(--ink)}
.panel h2>.ph:focus-visible{
  outline:none;color:var(--ink);
  box-shadow:0 0 0 2px rgba(77,163,255,.32);border-radius:3px;
}
.panel h2>.ph .chev{
  position:absolute;left:2px;top:50%;width:5px;height:5px;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:translateY(-70%) rotate(-45deg);
  transition:transform .18s ease;
}
.panel:not(.collapsed) h2>.ph .chev{transform:translateY(-75%) rotate(45deg)}

/* grid-template-rows 0fr/1fr animates to the content's real height without
 * anyone having to guess a max-height. The inner div needs min-height:0 or the
 * grid row refuses to shrink below its content. */
.panel-body{display:grid;grid-template-rows:1fr;transition:grid-template-rows .18s ease}
.panel-body>.pb-in{min-height:0;overflow:hidden}
.panel.collapsed .panel-body{grid-template-rows:0fr}
.panel.collapsed{padding-bottom:12px}
.panel.collapsed>h2{margin-bottom:0}

/* Group labels: a word and a rule running off to the right. Purely a divider —
 * the panels underneath are ordinary siblings, so nothing has been reordered
 * and nothing nests. */
.grp{
  display:flex;align-items:center;gap:9px;
  padding:15px 16px 7px;font-size:9px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:#8b95a8;
}
.grp::after{content:'';flex:1 1 auto;height:1px;background:#3a4353}
.grp:first-child{padding-top:4px}

.panel-tools{display:flex;justify-content:flex-end;padding:8px 16px 0}
.panel-tools button{
  background:none;border:0;padding:2px 0;font:inherit;font-size:10.5px;
  color:var(--ink-dim);cursor:pointer;letter-spacing:.02em;
}
.panel-tools button:hover{color:var(--accent)}
hr{border:0;border-top:1px solid var(--line);margin:10px 0}

.row{display:flex;align-items:center;gap:8px;margin-bottom:7px}
.row>span{flex:0 0 66px;color:var(--ink-dim);font-size:11.5px}
.row>input,.row>select{flex:1;min-width:0}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.grid2 .row{margin-bottom:7px}
.grid2 .row>span{flex:0 0 46px}

input[type=text],input[type=number],select{
  background:#141821;color:var(--ink);border:1px solid var(--line);
  border-radius:5px;padding:5px 7px;font:inherit;font-size:12.5px;width:100%;
}
input[type=text]:focus,input[type=number]:focus,select:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 2px rgba(77,163,255,.18);
}
input[type=range]{width:100%;accent-color:var(--accent);margin:2px 0 8px}
.chk{display:flex;align-items:center;gap:7px;margin:6px 0;color:var(--ink-dim);font-size:11.5px;cursor:pointer}
.chk input{accent-color:var(--accent);margin:0}

.btn{
  background:var(--panel-2);color:var(--ink);border:1px solid var(--line);
  border-radius:5px;padding:6px 10px;font:inherit;font-size:12px;cursor:pointer;
  white-space:nowrap;
}
.btn:hover{background:#2c3340;border-color:#3d465a}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:600}
.btn.primary:hover{background:#63b0ff}
.btn.danger:hover{background:#3a2226;border-color:#6d3239;color:var(--danger)}
.btn.wide{width:100%}
.btn:disabled{opacity:.38;cursor:default}
.btn:disabled:hover{background:var(--panel-2);border-color:var(--line)}
.btn.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:600}
.btnrow{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.btnrow .btn{flex:1 1 auto}

.hint{color:var(--ink-dim);font-size:11px;line-height:1.5;margin-top:8px}
.hint em{color:var(--ink);font-style:normal;font-weight:600}
.hint kbd{font-size:10px}
.prov-note{color:#ffd166}

/* ---------- presets ---------- */
.presets{display:flex;flex-direction:column;gap:5px}
.preset{
  display:flex;align-items:center;gap:9px;text-align:left;width:100%;
  background:var(--panel-2);border:1px solid var(--line);border-radius:5px;
  padding:6px 9px;color:var(--ink);font:inherit;cursor:pointer;
}
.preset:hover{background:#2c3340;border-color:#3d465a}
.preset.on{border-color:var(--accent);box-shadow:0 0 0 2px rgba(77,163,255,.2)}
.preset .sw{width:11px;height:11px;border-radius:2px;flex:0 0 11px;border:1px solid rgba(0,0,0,.45)}
.preset .cd{
  font-size:9px;font-weight:700;color:#0b0e13;background:var(--ink-dim);
  border-radius:2px;padding:1px 3px;letter-spacing:.02em;
}
.preset.prov .nm::after{content:'*';color:#ffd166;margin-left:3px;font-weight:700}
.preset .nm{flex:1;font-size:12.5px}
.preset .dm{color:var(--ink-dim);font-size:10.5px;font-variant-numeric:tabular-nums}

/* ---------- tally ---------- */
.tally{display:flex;flex-direction:column;gap:4px;font-size:12px}
.tally .t{display:flex;align-items:center;gap:8px;color:var(--ink-dim)}
.tally .t .sw{width:9px;height:9px;border-radius:2px;flex:0 0 9px}
.tally .t .n{margin-left:auto;color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.tally .t.total{border-top:1px solid var(--line);padding-top:5px;margin-top:2px;color:var(--ink)}
.tally .none{color:var(--ink-dim);font-size:11.5px}
.tally .head{
  color:var(--ink-dim);font-size:9.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;margin-top:7px;
}
.tally .head:first-child{margin-top:0}
.tally .t .m{color:var(--ink-dim);font-variant-numeric:tabular-nums;font-size:11px}

.keys{margin:0;padding-left:0;list-style:none;color:var(--ink-dim);font-size:11px;line-height:1.9}
kbd{
  background:var(--panel-2);border:1px solid var(--line);border-bottom-width:2px;
  border-radius:3px;padding:0 4px;font:inherit;font-size:10.5px;color:var(--ink);
}


/* playback */
.btnrow.play .btn:first-child{flex:1 1 auto}
.btnrow.play .btn:last-child{flex:0 0 42px}
.clock{
  display:flex;justify-content:space-between;align-items:center;
  font-size:10.5px;color:var(--ink-dim);font-variant-numeric:tabular-nums;
  margin:-4px 0 6px;
}
.clock span:last-child{color:var(--accent);text-transform:uppercase;letter-spacing:.06em;font-weight:700}

.disabled-wrap.off{opacity:.4;pointer-events:none}

/* provisional-footprint note, and the cable run / warning lines */
.note{
  background:#1d2432;border:1px solid var(--line);border-left:2px solid var(--accent);
  border-radius:4px;padding:6px 8px;margin-bottom:9px;
  color:var(--ink-dim);font-size:11px;line-height:1.5;
}
.run{
  background:#141821;border:1px solid var(--line);border-radius:4px;
  padding:6px 8px;margin-bottom:9px;font-size:11.5px;color:var(--ink);
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
}
.run .arrow{color:var(--ink-dim)}
.run .len{margin-left:auto;font-weight:600;font-variant-numeric:tabular-nums}
.run .sw{width:9px;height:9px;border-radius:2px;flex:0 0 9px}
.panel h3{
  margin:12px 0 7px;font-size:9.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-dim);
  border-top:1px solid var(--line);padding-top:9px;
}

/* computed-result block: monospace figures, verdict tinted by outcome */
.calc{
  background:#141821;border:1px solid var(--line);border-radius:4px;
  padding:7px 9px;margin:9px 0;font-size:11.5px;line-height:1.65;
  color:var(--ink-dim);font-variant-numeric:tabular-nums;
}
.calc .k{display:inline-block;min-width:70px;color:var(--ink-dim)}
.calc b{color:var(--ink);font-weight:600}
.calc .big{font-size:14px;font-weight:700}
.calc.ok{border-left:2px solid #4be0a8}
.calc.ok .big{color:#4be0a8}
.calc.bad{border-left:2px solid var(--danger);background:#241a1d}
.calc.bad .big{color:var(--danger)}
.calc .sub{display:block;color:var(--ink-dim);font-size:10.5px;margin-top:3px}

/* bill of materials */
.bom{margin:10px 0 2px;font-size:11.5px;font-variant-numeric:tabular-nums}
.bom .b{display:flex;gap:8px;align-items:baseline;color:var(--ink-dim);padding:2px 0}
.bom .b .nm{flex:1;color:var(--ink)}
.bom .b .q{color:var(--ink-dim)}
.bom .b .e{min-width:62px;text-align:right;color:var(--ink);font-weight:600}
.bom .b.tot{border-top:1px solid var(--line);margin-top:5px;padding-top:5px}
.bom .b.grand .nm,.bom .b.grand .e{color:var(--accent);font-weight:700}
.bom .b.noprice .e{color:#ffd166;font-weight:400}
.bom .head{
  color:var(--ink-dim);font-size:9.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;margin:9px 0 3px;
}
.bom .none{color:var(--ink-dim)}

.warn{
  background:#33241f;border:1px solid #6b4326;border-left:2px solid #ff9f43;
  border-radius:4px;padding:6px 8px;margin-bottom:9px;
  color:#ffc48a;font-size:11px;line-height:1.5;
}

/* what is laid in a trench: one clickable row per run, so the list doubles as
   a way of getting to the cable you want to look at */
.occ{font-size:11.5px;font-variant-numeric:tabular-nums;margin:2px 0 4px}
.occ .o{
  display:flex;gap:7px;align-items:baseline;width:100%;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--line);
  padding:4px 2px;color:var(--ink-dim);cursor:pointer;font:inherit;
}
.occ .o:last-child{border-bottom:0}
.occ .o:hover{background:#1a1f2b}
.occ .o .sw{width:8px;height:8px;border-radius:2px;flex:0 0 8px}
.occ .o .nm{flex:1;color:var(--ink)}
.occ .o .q{color:var(--ink-dim);font-size:10.5px}
.occ .none{color:var(--ink-dim);padding:3px 0}

/* the hand-off to the NEN 1010 page is a link, not a button, so it opens in a
   new tab on middle-click like any other link — but it has to look the same */
a.btn{display:block;text-decoration:none;text-align:center;line-height:1.5}
a.btn:hover{color:var(--ink)}
.calc.stale{border-left:2px solid #ffd166;background:#2a2417}
.calc.stale .k{color:#ffd166}

/* ---------- stage ---------- */
#stage{position:relative;flex:1;min-width:0}
#map{position:absolute;inset:0;background:#0c0e12}
#sp-canvas{position:absolute;inset:0;z-index:500;pointer-events:none}
#map.sp-place{cursor:crosshair}
#map.sp-move{cursor:move}
#map.sp-rot{cursor:grab}
#map.sp-size{cursor:nwse-resize}
#map.sp-cable{cursor:crosshair}

#readout{
  position:absolute;left:10px;bottom:10px;z-index:700;
  background:rgba(18,21,26,.86);border:1px solid var(--line);border-radius:5px;
  padding:5px 9px;font-size:11px;color:var(--ink-dim);
  font-variant-numeric:tabular-nums;pointer-events:none;backdrop-filter:blur(3px);
}
#readout b{color:var(--ink);font-weight:600}

#toast{
  position:absolute;left:50%;top:14px;transform:translateX(-50%) translateY(-140%);
  z-index:900;background:rgba(18,21,26,.94);border:1px solid var(--line);
  border-left:3px solid var(--accent);border-radius:5px;padding:8px 14px;
  font-size:12px;transition:transform .22s ease;pointer-events:none;max-width:70%;
}
#toast.show{transform:translateX(-50%) translateY(0)}

/* leaflet reskin */
.leaflet-container{background:#0c0e12;font:inherit}
.leaflet-bar,.leaflet-control-scale-line{
  border-color:var(--line)!important;
}
.leaflet-bar a{
  background:rgba(27,31,39,.94)!important;color:var(--ink)!important;
  border-bottom-color:var(--line)!important;
}
.leaflet-bar a:hover{background:#2c3340!important}
.leaflet-control-scale-line{
  background:rgba(18,21,26,.82);color:var(--ink);border:1px solid var(--line);
  border-top:none;font-size:10.5px;padding:1px 5px;
}
.leaflet-control-attribution{
  background:rgba(18,21,26,.82)!important;color:var(--ink-dim)!important;font-size:10px!important;
}
.leaflet-control-attribution a{color:var(--accent)!important}

@media (max-width:820px){
  :root{--side-w:100%}
  #app{flex-direction:column}
  #side{height:46%;border-right:none;border-bottom:1px solid var(--line)}
  #stage{flex:1}
}
