/* The panel look the owner approved (P1, W29), carried over from the previous
   build unchanged except for test-mode rules the new panel does not have. */
:root{
  --bg:#000; --panel:#0b0b0b; --card:#161616; --card-hi:#1e1e1e; --line:#242424;
  --field:#252525; --ink:#fff; --mut:#a0a0a0; --faint:#6a6a6a;
  --acc:#1ed760; --acc-dim:rgba(30,215,96,.12); --acc-hi:#3be477;
  --warn:#ffa42b; --bad:#f15e6c; --rail:248px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);
  font:15px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  -webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}

/* The bar shown while the cloud cannot be reached. */
#netbar{display:none;position:fixed;top:0;left:0;right:0;z-index:999;background:var(--warn);color:#000;
  font-weight:700;font-size:13px;text-align:center;padding:7px 12px}

.rail{position:fixed;top:0;left:0;bottom:0;width:var(--rail);background:var(--panel);
  border-right:1px solid var(--line);padding:18px 14px;display:flex;flex-direction:column;z-index:50}
body.dev .rail{top:36px}
.brand{display:flex;align-items:center;gap:10px;font-size:19px;font-weight:800;
  letter-spacing:-.02em;padding:0 10px 22px}
.brand::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--acc);
  box-shadow:0 0 12px rgba(30,215,96,.7);flex:none}
.nav{display:flex;flex-direction:column;gap:2px}
.nav a{display:flex;align-items:center;gap:13px;padding:11px 12px;border-radius:7px;
  color:var(--mut);font-weight:600;font-size:14.5px;transition:color .15s,background .15s}
.nav a svg{width:19px;height:19px;flex:none;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.nav a:hover{color:var(--ink);background:#ffffff0a}
.nav a.on{color:var(--ink);background:#ffffff12}
.nav a.on svg{color:var(--acc)}
.count{margin-left:auto;background:var(--acc);color:#000;font-size:11px;font-weight:800;
  min-width:19px;height:19px;border-radius:99px;display:grid;place-items:center;padding:0 5px}
.railfoot{margin-top:auto;padding:14px 12px 0;border-top:1px solid var(--line);
  font-size:12px;color:var(--faint)}
.railfoot .dot{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--acc);flex:none}
.railfoot .dot.off{background:var(--bad)}
.unit{display:flex;align-items:center;gap:8px}
.unit b{font-size:14px;font-weight:700;color:var(--ink);letter-spacing:-.01em}
/* A lab unit is not dangerous the way an unauthenticated one is -- it just
   must never be mistaken for a customer box. Quiet marker, not an alarm. */
.envchip{display:none;margin-left:auto;background:#ffffff14;color:var(--mut);
  font-size:9.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  padding:3px 7px;border-radius:4px}
.envchip.show{display:inline-block}
.unitmeta{margin-top:3px;font-size:11.5px;color:var(--faint);padding-left:15px}
.unitmeta.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.02em}

.main{margin-left:var(--rail);min-height:100vh;display:flex;flex-direction:column}
.topbar{position:sticky;top:0;z-index:40;background:rgba(0,0,0,.82);
  backdrop-filter:saturate(180%) blur(16px);-webkit-backdrop-filter:saturate(180%) blur(16px);
  border-bottom:1px solid var(--line);padding:18px 30px;display:flex;align-items:center;gap:14px}
body.dev .topbar{top:36px}
.topbar h1{font-size:23px;font-weight:800;letter-spacing:-.035em;margin:0}
.who{margin-left:auto;display:flex;align-items:center;gap:12px;font-size:13px;color:var(--mut)}
.avatar{width:29px;height:29px;border-radius:50%;flex:none;
  background:linear-gradient(140deg,#1ed760,#0e8f3e);color:#000;font-weight:800;font-size:12px;
  display:grid;place-items:center}
.content{padding:26px 30px 96px;max-width:1120px;width:100%}
.view{display:none} .view.on{display:block}

.card{background:var(--card);border-radius:12px;padding:20px 22px}
.sec{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--faint);
  font-weight:700;margin:30px 0 13px}
.sec:first-child{margin-top:0}
.empty{color:var(--faint);font-size:13.5px;padding:22px 2px;text-align:center;line-height:1.7}
.muted{color:var(--mut)}

button{font:inherit;font-weight:700;letter-spacing:.01em;cursor:pointer;background:var(--acc);
  color:#000;border:none;border-radius:999px;padding:11px 22px;
  transition:transform .1s ease,background .15s,border-color .15s,color .15s}
button:hover:not(:disabled){background:var(--acc-hi);transform:scale(1.04)}
button:active:not(:disabled){transform:scale(.98)}
button.ghost{background:transparent;color:var(--ink);border:1px solid #4a4a4a;font-weight:600}
button.ghost:hover:not(:disabled){background:transparent;border-color:var(--ink)}
button.tiny{padding:6px 13px;font-size:12.5px}
button.icon{background:transparent;color:var(--faint);border:none;padding:6px 9px;
  font-size:17px;line-height:1}
button.icon:hover{color:var(--bad);background:transparent;transform:none}
button:disabled{opacity:.4;cursor:default}
/* A link that does a button's job: the way to Premium (plan.go). */
a.btn{display:inline-block;font-weight:700;letter-spacing:.01em;background:var(--acc);color:#000;
  border-radius:999px;padding:10px 20px;font-size:14px;text-decoration:none;transition:background .15s}
a.btn:hover{background:var(--acc-hi)}
a.btn.ghost{background:transparent;color:var(--ink);border:1px solid #4a4a4a;font-weight:600}
.card.premium{border:1px solid rgba(30,215,96,.35)}

select,input[type=text],input[type=password],input:not([type]){font:inherit;font-size:16px;
  color:var(--ink);background:var(--field);border:1px solid transparent;border-radius:7px;
  padding:11px 13px;transition:border-color .15s,background .15s}
select:focus,input:focus{outline:none;border-color:var(--ink);background:#303030}
select{cursor:pointer} ::placeholder{color:var(--faint)}

.hero{background:linear-gradient(150deg,#123020 0%,var(--card) 58%);border-radius:14px;
  padding:26px 26px 24px;margin-bottom:20px}
.hero.alert{background:linear-gradient(150deg,#3a2a10 0%,var(--card) 58%)}
.hero h2{font-size:26px;font-weight:800;letter-spacing:-.035em;margin:0 0 6px;line-height:1.2}
.hero p{margin:0;color:var(--mut);font-size:14.5px}
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(124px,1fr));gap:11px;margin-top:22px}
.tile{background:#ffffff0d;border-radius:10px;padding:13px 15px}
.tile b{display:block;font-size:24px;font-weight:800;letter-spacing:-.03em;line-height:1.15}
.tile span{font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:var(--faint);font-weight:700}

.cmd{display:flex;gap:10px}
.cmd input{flex:1;padding:14px 16px}
.chips{display:flex;gap:7px;flex-wrap:wrap;margin-top:12px}
.chip{background:#ffffff0d;border-radius:999px;padding:6px 13px;font-size:12.5px;color:var(--mut);
  cursor:pointer;transition:background .15s,color .15s}
.chip:hover{background:#ffffff1a;color:var(--ink)}
.preview{margin-top:14px;padding:16px 18px;border-radius:10px;background:#0a0a0a;
  border-left:3px solid var(--acc);display:none}
.preview.show{display:block}
.preview .eff{font-size:15.5px;font-weight:600}
.preview .meta{color:var(--faint);font-size:12px;margin-top:6px}
.prow{display:flex;gap:10px;margin-top:14px}
.badge{font-size:10px;padding:3px 9px;border-radius:999px;background:#2a2a2a;color:var(--mut);
  text-transform:uppercase;letter-spacing:.08em;font-weight:800}
.badge.ai{background:var(--acc-dim);color:var(--acc)}
.warnbox{color:var(--warn)}
/* Ad switches. A switch says "this is a thing that is on or off"; the three
   positions they replaced made the box's list arrangement the parent's. */
.asw{display:flex;gap:13px;align-items:flex-start;padding:15px 0;border-top:1px solid var(--line);cursor:pointer}
.asw:first-child{border-top:none;padding-top:2px}
.asw.nest{padding-left:26px;border-top:none;padding-top:2px}
.asw input{position:absolute;opacity:0;pointer-events:none}
.asw .box{width:40px;height:24px;border-radius:999px;background:#2f2f2f;flex:none;position:relative;
 margin-top:1px;transition:background .15s}
.asw .box::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;
 background:#8a8a8a;transition:transform .15s,background .15s}
.asw input:checked+.box{background:var(--acc)}
.asw input:checked+.box::after{transform:translateX(16px);background:#000}
.asw .lbl{font-size:15px;font-weight:600;letter-spacing:-.01em}
.asw.nest .lbl{font-weight:500}
.asw .d{display:block;color:var(--mut);font-size:13px;line-height:1.5;margin-top:4px}
.asw .c{display:block;color:var(--warn);font-size:12.5px;line-height:1.5;margin-top:7px}
.asw.dim{opacity:.4}
.reading{color:var(--ink)}

.modes{display:flex;gap:8px;flex-wrap:wrap}
.mode{background:#ffffff0d;border:1px solid transparent;border-radius:999px;padding:9px 17px;
  font-size:13.5px;font-weight:600;color:var(--mut);cursor:pointer;transition:all .15s}
.mode:hover{color:var(--ink);background:#ffffff1a;transform:none}
.mode.on{background:var(--acc);border-color:var(--acc);color:#000;font-weight:700}

.people{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:13px}
.person{background:var(--card);border-radius:12px;padding:18px;transition:background .2s}
.person:hover{background:var(--card-hi)}
.phead{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.phead .avatar{width:40px;height:40px;font-size:15px}
.phead b{font-size:16.5px;font-weight:700;letter-spacing:-.01em;display:block}
.phead small{color:var(--faint);font-size:12.5px}
.pstat{font-size:13px;padding:8px 12px;border-radius:8px;background:var(--acc-dim);
  color:var(--acc);margin-bottom:13px;font-weight:600}
.pstat.paused{background:rgba(255,164,43,.12);color:var(--warn)}
.pacts{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.pacts select{max-width:100%;min-width:0;box-sizing:border-box}

.row{display:flex;align-items:center;gap:14px;padding:14px 16px;background:var(--card);
  border-radius:10px;margin-bottom:8px;transition:background .2s}
.row:hover{background:var(--card-hi)}
.tag{background:#ffffff12;border-radius:999px;padding:4px 11px;font-size:11.5px;
  font-weight:700;color:var(--mut);white-space:nowrap}
.tag.on{background:var(--acc-dim);color:var(--acc)}
.tag.warn{background:rgba(255,164,43,.14);color:var(--warn)}

/* Devices. A card names the device in words a parent recognises; the
   addresses a technician would want sit behind Details. */
.dintro{color:var(--mut);font-size:13.5px;margin:0}
.dsub{color:var(--mut);font-size:13px;margin:-6px 0 12px}
.dtip{color:var(--faint);font-size:12.5px;margin:-4px 0 12px;line-height:1.5}
.qrcard{display:flex;gap:18px;align-items:center;margin:0 0 14px}
.selbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 12px;position:sticky;top:8px;z-index:3}
.selbar select,.selbar input{width:auto;min-width:150px}
.selall{display:flex;gap:8px;align-items:center;font-weight:600;cursor:pointer}
.selall input,.selbox input{width:18px;height:18px;min-width:0;padding:0;margin:0;accent-color:var(--acc);flex:none}
.selmsg{flex-basis:100%;color:var(--mut);font-size:13px}
.selwrap{position:relative}
.selbox{position:absolute;left:-2px;top:14px;z-index:2;cursor:pointer}
.selwrap>.dcard,.selwrap>div:not(.selbox){margin-left:30px}
.selbox input{width:18px;height:18px;accent-color:var(--acc);cursor:pointer}
.qrcard .qr{width:132px;height:132px;border-radius:8px;background:#fff;padding:6px;flex:none;image-rendering:pixelated}
.qrh{font-weight:700;font-size:15px;margin-bottom:4px}
.qrs{color:var(--mut);font-size:13px;line-height:1.5}
@media (max-width:520px){.qrcard{flex-direction:column;text-align:center}}
.dper{font-size:12px;font-weight:700;color:var(--faint);margin:14px 0 7px}
.dfold{margin:4px 0 12px}
.dcard{display:flex;gap:14px;align-items:flex-start;padding:14px 16px;background:var(--card);
  border-radius:10px;margin-bottom:8px;transition:background .2s}
.dcard:hover{background:var(--card-hi)}
.kic{width:38px;height:38px;border-radius:50%;background:#ffffff0f;display:grid;place-items:center;
  flex:none;color:var(--ink)}
.kic svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.kic.faint{color:var(--faint)}
.dbody{flex:1;min-width:0}
.dtop{display:flex;align-items:center;gap:8px}
.dtitle{flex:1;min-width:0;font-size:14.5px;font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.dtags{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.dline{font-size:12.5px;color:var(--mut);margin-top:2px;line-height:1.5}
.odot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--acc);
  margin-right:5px;vertical-align:1px}
.dctl{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin-top:10px}
.dctl details{margin-left:auto}
.dctl details[open]{flex-basis:100%;margin-left:0}
.dctl summary{display:block;width:max-content;margin-left:auto;cursor:pointer;list-style:none;
  font-size:12.5px;font-weight:600;color:var(--mut)}
.dctl summary::-webkit-details-marker{display:none}
.dctl summary:hover{color:var(--ink)}
.dctl .sd-o,.dctl details[open] .sd-c{display:none}
.dctl details[open] .sd-o{display:inline}
.dmore{margin-top:10px;padding-top:12px;border-top:1px solid var(--line);font-size:13px}
.dsec{margin-bottom:16px}
.fl{display:block;font-size:12.5px;font-weight:600;color:var(--mut);margin-bottom:6px}
.drow{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.drow input,.drow select{flex:1;min-width:150px;max-width:340px;padding:8px 11px}
.dhelp{font-size:12px;color:var(--faint);margin-top:5px}
.devi{margin:0;padding-left:18px}
.devi li{margin:3px 0;line-height:1.5}
.dfacts{display:grid;grid-template-columns:max-content 1fr;gap:4px 14px;margin:0;font-size:12.5px}
.dfacts dt{color:var(--mut)}
.dfacts dd{margin:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;overflow-wrap:anywhere}
/* The note on a card that is really a second router. Tinted, not coloured:
   it explains the row, it does not warn -- nothing is wrong. */
.dnote{font-size:12.5px;line-height:1.5;color:var(--mut);background:#ffffff0a;
  border-radius:8px;padding:9px 12px;margin-top:10px}
.dmsg{font-size:13px;margin-top:9px;color:var(--acc)}
.dmsg.bad{color:var(--warn)}
.aflow{margin-top:12px;padding:14px;border-radius:10px;background:#ffffff08}
.aflow input:not([type=checkbox]){display:block;width:100%;max-width:340px;padding:8px 11px}
.aq{font-weight:600;font-size:14px;margin-bottom:9px}
.pchips{display:flex;gap:7px;flex-wrap:wrap}
.abtns{display:flex;gap:8px;margin-top:14px}
button.pchip{background:#ffffff12;color:var(--mut);padding:6px 13px;font-size:12.5px;font-weight:600}
button.pchip:hover:not(:disabled){background:#ffffff1f;color:var(--ink);transform:none}
button.pchip.on,button.pchip.on:hover:not(:disabled){background:var(--acc);color:#000}
button.lnk{background:none;border:none;border-radius:0;padding:0;color:var(--acc);
  font-size:12.5px;font-weight:600}
button.lnk:hover:not(:disabled){background:none;transform:none;text-decoration:underline}
.asw.cmp{padding:0;border-top:none}
.asw.cmp .lbl{font-size:13.5px}
.asw.cmp .d{font-size:12.5px;margin-top:1px}
.asw.ro{cursor:default}
.pdevs{font-size:12.5px;color:var(--mut);margin-top:12px}
.pvpn{border-top:1px solid var(--line);margin-top:14px;padding-top:12px}
.pvpn .asw{padding:0;border-top:none}
.vpnnote{color:var(--mut);font-size:13px;margin-top:12px;line-height:1.5}

.rule{display:flex;align-items:center;gap:12px;padding:13px 16px;background:var(--card);
  border-radius:10px;margin-bottom:7px;font-size:14px}
.rule .who{font-weight:700;min-width:78px}
.rgroup{margin:0 0 18px}
.rhead{font-weight:700;font-size:14px;margin:0 0 6px}
.rsub{color:var(--faint);font-size:12.5px;margin:-2px 0 8px}
.rule .rwhat{flex:1;min-width:0}
.rule .when{color:var(--mut);font-size:13px;margin:0 10px;text-align:right}
.moderow{display:flex;align-items:center;gap:14px;padding:6px 0}
.moderow .mode{flex:none;min-width:112px}
.modewhat{color:var(--mut);font-size:13px;line-height:1.45}
@media (max-width:520px){.moderow{flex-direction:column;align-items:flex-start;gap:6px}}
.rule .when{color:var(--faint);font-size:12.5px}
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.72);display:none;align-items:center;
  justify-content:center;padding:20px;z-index:50}
.scrim.show{display:flex}
.dlg{background:var(--card);border-radius:12px;padding:24px 22px;width:100%;max-width:380px}
.dlg h3{margin:0 0 8px;font-size:19px;letter-spacing:-.02em}
.dlg p{margin:0 0 16px;color:var(--mut);font-size:14px;line-height:1.45}
.dlg input{width:100%;margin-bottom:10px}
.dlgerr{color:var(--bad);font-size:13.5px;min-height:20px;margin-bottom:8px}
.dlgacts{display:flex;gap:10px;justify-content:flex-end}
.acctlink{display:flex;align-items:center;gap:12px;color:inherit;text-decoration:none}
.asec{font-size:13px;color:var(--mut);font-weight:600;margin:0 0 6px}
.needs{margin-bottom:14px;box-shadow:inset 0 0 0 1px #f5c04a55}
.arow{display:flex;align-items:center;gap:12px;padding:11px 0;border-top:1px solid var(--line)}
.arow:first-child{border-top:none}
.aav{width:36px;height:36px;border-radius:50%;background:#ffffff0f;display:grid;place-items:center;
  font-size:12.5px;font-weight:700;color:var(--mut);flex:none}
.anm{font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.asub{font-size:12.5px;color:var(--mut);line-height:1.5;margin-top:1px}
.ast{margin-left:auto;text-align:right;flex:none;padding-left:8px}
.apill{display:inline-block;font-size:12px;font-weight:700;padding:3px 10px;border-radius:999px}
.apill.stop{background:var(--acc-dim);color:var(--acc)}
.apill.used{background:#ffffff12;color:var(--ink)}
.apill.warn{background:#f5c04a22;color:#f5c04a}
.aper{font-size:12px;font-weight:700;color:var(--faint);margin:12px 0 2px}
.techlink{text-align:center;margin:18px 0 10px}
.ev .by{color:var(--faint);white-space:nowrap}
.ev{display:flex;gap:13px;padding:10px 4px;border-bottom:1px solid var(--line);font-size:13.5px}
.ev:last-child{border-bottom:none}
.ev .t{color:var(--faint);font-variant-numeric:tabular-nums;white-space:nowrap;
  font-size:12px;min-width:60px}
.ev .k{color:var(--acc);width:62px;flex:none;font-size:10px;text-transform:uppercase;
  letter-spacing:.09em;font-weight:800;padding-top:2px}
.ev.block .k{color:var(--warn)}
.ev span:last-child{min-width:0;overflow-wrap:anywhere}

.tabs{display:none;position:fixed;bottom:0;left:0;right:0;z-index:50;
  background:rgba(11,11,11,.96);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  border-top:1px solid var(--line);padding:8px 4px calc(8px + env(safe-area-inset-bottom))}
.tabs a{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 2px;
  color:var(--faint);font-size:10px;font-weight:700}
.tabs a svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.tabs a.on{color:var(--acc)}

@media(max-width:860px){
  .rail{display:none} .main{margin-left:0} .tabs{display:flex}
  .topbar{padding:15px 18px} .topbar h1{font-size:20px}
  .content{padding:20px 18px 112px}
  .hero{padding:22px 20px} .hero h2{font-size:22px}
  .cmd{flex-direction:column} .cmd button{width:100%}
  .row{flex-wrap:wrap}
  .who span{display:none}
}
/* On a phone the tags go under the title, so a long name keeps its line. */
@media(max-width:560px){
  .drow input,.drow select{min-width:0;max-width:100%;flex-basis:100%}
  .dtop{flex-wrap:wrap} .dtitle{flex-basis:100%} .dtags{justify-content:flex-start}
  .dfacts{grid-template-columns:1fr} .dfacts dd{margin-bottom:5px}
}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
