:root{
  --bg:#131722; --panel:#1E222D; --grid:#2A2E39; --up:#26A69A; --down:#EF5350;
  --text:#D1D4DC; --dim:#787B86; --accent:#2962FF; --radius:6px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
*{box-sizing:border-box}
html,body{height:100%;margin:0}
body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:13px;overflow:hidden;-webkit-font-smoothing:antialiased}
button,select,input{font-family:inherit;font-size:13px;color:var(--text)}

#app{display:grid;grid-template-rows:40px 1fr 26px;height:100vh}

/* top bar */
#topbar{display:flex;align-items:center;gap:8px;padding:0 10px;background:var(--bg);border-bottom:1px solid var(--grid);min-width:0}
.brand{display:flex;align-items:center;gap:7px;font-weight:600;letter-spacing:.2px;margin-right:4px}
.brand .mark{width:22px;height:22px;border-radius:5px;background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}
.brand .brandtxt{color:var(--text)}
@media(max-width:760px){.brand .brandtxt{display:none}}

.ctrl{background:var(--panel);border:1px solid var(--grid);border-radius:var(--radius);padding:6px 10px;cursor:pointer;display:flex;align-items:center;gap:6px}
.ctrl:hover{border-color:#3a3f4c}
#symbollabel{font-weight:600;letter-spacing:.3px}
.caret{color:var(--dim);font-size:10px}
select.ctrl{appearance:none;padding-right:22px;background-image:linear-gradient(45deg,transparent 50%,var(--dim) 50%),linear-gradient(135deg,var(--dim) 50%,transparent 50%);background-position:calc(100% - 12px) 15px,calc(100% - 8px) 15px;background-size:4px 4px;background-repeat:no-repeat}

.seg{display:inline-flex;background:var(--panel);border:1px solid var(--grid);border-radius:var(--radius);overflow:hidden}
.seg button{background:transparent;border:0;color:var(--dim);padding:6px 11px;cursor:pointer}
.seg button.on{background:var(--accent);color:#fff}
.seg button:not(.on):hover{color:var(--text)}
.seg .i{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border:1px solid currentColor;border-radius:50%;font-size:9px;font-style:italic;margin-left:5px;opacity:.7}

.sizewrap{position:relative}
.sizepop{top:38px;left:0;width:230px;max-height:60vh}
.sizelist{overflow-y:auto;padding:4px;flex:1 1 auto}
.sizelist .row{display:flex;justify-content:space-between;align-items:center;padding:7px 6px 7px 10px;border-radius:var(--radius);cursor:pointer}
.sizelist .row:hover{background:var(--bg)}
.sizelist .row.on .nm{color:var(--accent);font-weight:600}
.sizelist .del{background:transparent;border:0;color:transparent;font-size:14px;cursor:pointer;padding:0 6px;border-radius:4px;line-height:1}
.sizelist .row:hover .del{color:var(--dim)}
.sizelist .del:hover{color:var(--down)}
.sizeadd{display:flex;gap:6px;padding:8px;border-top:1px solid var(--grid)}
.sizeadd input{flex:1;background:var(--bg);border:1px solid var(--grid);border-radius:var(--radius);padding:6px 9px;outline:none;min-width:0}
.sizeadd input:focus{border-color:var(--accent)}
.sizeadd button{background:var(--accent);border:0;color:#fff;border-radius:var(--radius);padding:6px 12px;cursor:pointer;font-weight:500}
.sizeadd button:hover{filter:brightness(1.1)}
.sizehint{padding:0 10px 9px;color:var(--dim);font-size:11px}

/* indicators modal */
.toolswrap{position:relative}
.modal{position:fixed;inset:0;background:rgba(0,0,0,.55);display:flex;align-items:center;justify-content:center;z-index:60}
.modal[hidden]{display:none}
.mbox{background:var(--panel);border:1px solid var(--grid);border-radius:10px;width:min(760px,94vw);max-height:84vh;display:flex;flex-direction:column;box-shadow:0 20px 60px rgba(0,0,0,.6);overflow:hidden}
.mbox.small{width:min(540px,92vw)}
.mhead{display:flex;align-items:center;justify-content:space-between;padding:13px 18px;font-size:16px;font-weight:600;border-bottom:1px solid var(--grid)}
.msearch{margin:12px 16px 10px;background:var(--bg);border:1px solid var(--grid);border-radius:8px;padding:10px 14px;outline:none;font-size:13.5px}
.msearch:focus{border-color:var(--accent)}
.mbody{display:flex;min-height:0;flex:1}
#indnav{width:172px;border-right:1px solid var(--grid);padding:8px;display:flex;flex-direction:column;gap:2px;flex-shrink:0}
#indnav button{background:transparent;border:0;color:var(--dim);text-align:left;padding:9px 12px;border-radius:6px;cursor:pointer;font-size:13.5px}
#indnav button:hover{color:var(--text);background:var(--bg)}
#indnav button.on{color:var(--text);background:var(--bg);font-weight:600}
.indlist{flex:1;overflow-y:auto;padding:6px 10px 12px}
.indlist .grp{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.08em;padding:10px 10px 4px}
.indlist .row{display:flex;align-items:center;gap:10px;padding:10px;border-radius:6px;cursor:pointer;font-size:13.5px}
.indlist .row:hover{background:var(--bg)}
.indlist .row .nm{flex:1}
.indlist .row.on .nm{color:var(--accent);font-weight:600}
.onchk{color:var(--accent);font-weight:700}
.indlist .tdesc{color:var(--dim);font-size:11.5px;font-weight:400}
.cfgbox{display:flex;flex-direction:column;gap:11px;margin:16px 0 6px}
.cfgrow{display:flex;align-items:center;justify-content:space-between;gap:12px}
.cfgrow span{color:var(--text);font-size:13.5px}
.cfgin{background:var(--bg);border:1px solid var(--grid);border-radius:6px;color:var(--text);padding:8px 10px;width:130px;outline:none}
.cfgin:focus{border-color:var(--accent)}
.cfgin[type=color]{padding:2px;width:46px;height:32px;cursor:pointer}
select.cfgin{width:auto;min-width:160px;max-width:230px;cursor:pointer;font-size:13px}
/* Reference-line bounds. Styled like a parameter box but deliberately NOT class `cfgin`: the
   parameter reader picks up `.cfgin[data-k]`, and these are presentation, not parameters. */
.cfgbound{background:var(--bg);border:1px solid var(--grid);border-radius:6px;color:var(--text);padding:8px 10px;width:130px;outline:none}
.cfgbound:focus{border-color:var(--accent)}
.cfgbound::placeholder{color:var(--dim)}
.cfghint{color:var(--dim);font-size:13px;margin:0}
.kind{color:var(--dim);font-size:11px;border:1px solid var(--grid);border-radius:4px;padding:1px 6px;white-space:nowrap}
.ibtn{background:transparent;border:1px solid var(--grid);color:var(--dim);cursor:pointer;width:20px;height:20px;border-radius:50%;font-size:11px;font-style:italic;line-height:1;flex-shrink:0}
.ibtn:hover{color:var(--accent);border-color:var(--accent)}
.star{background:transparent;border:0;color:var(--dim);cursor:pointer;font-size:16px;padding:0 2px;line-height:1}
.star:hover,.star.fav{color:#F0B429}
.infobody{padding:4px 18px 18px;overflow-y:auto}
.infobody h4{margin:14px 0 4px;font-size:11.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--dim)}
.infobody p{margin:0;font-size:13.5px;line-height:1.6;color:var(--text)}
.ibfoot{display:flex;align-items:center;justify-content:space-between;margin-top:18px}
.mbtn{background:var(--accent);border:0;color:#fff;border-radius:6px;padding:8px 16px;cursor:pointer;font-weight:500}
.mbtn:hover{filter:brightness(1.12)}
@media(max-width:640px){#indnav{width:120px}}

/* processor & memory chips — live load on the server, polled every few seconds. Same three heat
   bands as the Server info panel, so a colour means the same thing in both places. */
.loadchips{display:flex;gap:6px}
.loadchips[hidden]{display:none}
.loadchip{display:flex;align-items:center;gap:6px;line-height:1;padding:5px 8px;cursor:pointer;
  background:var(--panel);border:1px solid var(--grid);border-radius:var(--radius)}
.loadchip:hover{border-color:#3a3f4c}
.loadchip .lc-k{color:var(--dim);font-size:10px;font-weight:600;letter-spacing:.06em}
.loadchip .lc-v{font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;min-width:31px;text-align:right}
.loadchip .lc-bar{width:34px;height:4px;border-radius:2px;background:var(--grid);overflow:hidden}
.loadchip .lc-bar i{display:block;height:100%;width:0;border-radius:2px;background:var(--up);transition:width .3s linear}
.loadchip.warn .lc-v{color:#FFA726}
.loadchip.warn .lc-bar i{background:#FFA726}
.loadchip.bad .lc-v{color:var(--down)}
.loadchip.bad .lc-bar i{background:var(--down)}
/* Reading stopped coming back: dim it rather than leave a stale number looking live. */
.loadchips.stale{opacity:.4}
@media(max-width:1180px){.loadchip .lc-bar{display:none}}
@media(max-width:1040px){.loadchips{display:none}}

.spacer{flex:1 1 auto;min-width:8px}
.pricechip{display:flex;align-items:baseline;gap:8px;padding:0 6px;font-variant-numeric:tabular-nums}
#px{font-size:15px;font-weight:600}
.chg{font-size:12px;color:var(--dim)}
.chg.up{color:var(--up)} .chg.down{color:var(--down)}
@media(max-width:900px){.pricechip{display:none}}

.iconbtn{background:transparent;border:0;color:var(--dim);cursor:pointer;font-size:15px;padding:6px 8px;border-radius:var(--radius)}
.iconbtn:hover{color:var(--text);background:var(--panel)}
@media(max-width:900px){#style{display:none}}

/* account: avatar, profile dropdown, auth gates, admin */
.avatar{position:relative;width:28px;height:28px;border-radius:50%;background:var(--accent);color:#fff;border:0;cursor:pointer;font-weight:700;font-size:12px;margin-left:4px}
.avatar:hover{filter:brightness(1.12)}
.pdot{position:absolute;top:-3px;right:-3px;min-width:15px;height:15px;padding:0 3px;border-radius:8px;background:var(--down);color:#fff;font-size:9px;font-weight:700;display:flex;align-items:center;justify-content:center;border:1px solid var(--bg)}
.popover.profilepop{top:44px;right:10px;left:auto;width:260px;padding:12px}
.pp-id{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
#pp-name{font-weight:600;font-size:15px}
.rolebadge{font-size:11px;text-transform:uppercase;letter-spacing:.05em;padding:2px 8px;border-radius:10px;background:var(--grid);color:var(--text)}
.rolebadge.role-owner{background:#2962FF;color:#fff}
.rolebadge.role-editor{background:#26A69A;color:#04241f}
.rolebadge.role-viewer{background:#3a3f4c;color:var(--text)}
.rolebadge.role-pending{background:#F0B429;color:#3a2a00}
.pp-desc{font-size:12.5px;color:var(--dim);line-height:1.5;margin-bottom:10px}
.pp-item{display:flex;justify-content:space-between;align-items:center;width:100%;background:transparent;border:0;color:var(--text);text-align:left;padding:9px 10px;border-radius:6px;cursor:pointer;font-size:13.5px}
.pp-item:hover{background:var(--bg)}
.pp-item .cnt{color:#F0B429;font-size:11px}

.fullscreen{position:fixed;inset:0;z-index:80;background:var(--bg);display:flex;align-items:center;justify-content:center}
.fullscreen[hidden]{display:none}
.authcard{display:flex;flex-direction:column;gap:12px;width:340px;max-width:90vw;padding:28px;background:var(--panel);border:1px solid var(--grid);border-radius:14px}
.brand.big{font-size:20px;justify-content:center;margin-bottom:6px}
.brand.big .mark{width:30px;height:30px;font-size:14px}
.authtabs{width:100%}
.authtabs button{flex:1}
.authinput{background:var(--bg);border:1px solid var(--grid);border-radius:8px;padding:11px 14px;font-size:14px;outline:none}
.authinput:focus{border-color:var(--accent)}
.authbtn{background:var(--accent);border:0;color:#fff;border-radius:8px;padding:12px;font-size:14px;font-weight:600;cursor:pointer}
.authbtn:hover{filter:brightness(1.12)}
.authbtn.ghost{background:transparent;border:1px solid var(--grid);color:var(--dim)}
.authbtn.ghost:hover{color:var(--text);filter:none;background:var(--bg)}
.authmsg{color:var(--down);font-size:12.5px;min-height:16px;text-align:center}
.authhint{color:var(--dim);font-size:12px;text-align:center;line-height:1.5}

.admincreate{display:flex;gap:8px;padding:14px 16px 6px;align-items:center;flex-wrap:wrap;border-bottom:1px solid var(--grid)}
.admincreate input{flex:1;min-width:120px;background:var(--bg);border:1px solid var(--grid);border-radius:6px;padding:8px 11px;color:var(--text);outline:none}
.admincreate input:focus{border-color:var(--accent)}
.admincreate select{background:var(--bg);border:1px solid var(--grid);border-radius:6px;color:var(--text);padding:8px;cursor:pointer}
.adminfilter{display:flex;gap:4px;padding:10px 16px 4px;flex-wrap:wrap}
.adminfilter button{background:transparent;border:1px solid var(--grid);color:var(--dim);padding:5px 12px;border-radius:14px;cursor:pointer;font-size:12.5px}
.adminfilter button:hover{color:var(--text)}
.adminfilter button.on{background:var(--accent);border-color:var(--accent);color:#fff}
.delbtn{background:transparent;border:1px solid var(--grid);color:var(--dim);border-radius:6px;padding:5px 9px;cursor:pointer;font-size:12px}
.delbtn:hover{color:var(--down);border-color:var(--down)}
.admintable{overflow:auto;padding:6px 6px 14px}
.admintable table{width:100%;border-collapse:collapse;font-size:13.5px}
.admintable th{text-align:left;color:var(--dim);font-weight:500;padding:10px 12px;border-bottom:1px solid var(--grid);position:sticky;top:0;background:var(--panel)}
.admintable td{padding:9px 12px;border-bottom:1px solid var(--grid)}
.admintable tr.pend td{background:rgba(240,180,41,.07)}
.admintable .muted{color:var(--dim);font-size:12px}
.newtag{background:#F0B429;color:#3a2a00;font-size:9px;font-weight:700;padding:1px 5px;border-radius:4px;margin-left:6px;vertical-align:middle}
.rolesel{background:var(--bg);border:1px solid var(--grid);border-radius:6px;color:var(--text);padding:5px 8px;cursor:pointer}
.rolesel:focus{border-color:var(--accent);outline:none}

/* memory & documents modal (owner) */
#memnav{width:172px;border-right:1px solid var(--grid);padding:8px;display:flex;flex-direction:column;gap:2px;flex-shrink:0}
#memnav button{background:transparent;border:0;color:var(--dim);text-align:left;padding:9px 12px;border-radius:6px;cursor:pointer;font-size:13.5px}
#memnav button:hover{color:var(--text);background:var(--bg)}
#memnav button.on{color:var(--text);background:var(--bg);font-weight:600}
.mempanel{flex:1;min-width:0;overflow:auto;padding:14px 16px}
.memintro{color:var(--dim);font-size:12.5px;line-height:1.5;margin:0 0 12px}
.memintro code{background:var(--bg);border:1px solid var(--grid);border-radius:4px;padding:1px 5px;font-size:11.5px}
/* notes */
.notecard{border:1px solid var(--grid);border-radius:8px;margin-bottom:10px;overflow:hidden;background:var(--bg)}
.notecard>summary{list-style:none;cursor:pointer;padding:11px 14px;display:flex;flex-direction:column;gap:2px}
.notecard>summary::-webkit-details-marker{display:none}
.notecard>summary:hover{background:var(--panel)}
.notecard .nt{font-weight:600;font-size:13.5px;display:flex;align-items:center;gap:8px}
.notecard .nt .fn{color:var(--dim);font-weight:400;font-size:11.5px;font-family:ui-monospace,Menlo,Consolas,monospace}
.notecard .nmeta{color:var(--dim);font-size:11.5px}
.notecard pre{margin:0;padding:12px 14px;border-top:1px solid var(--grid);background:var(--panel);white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.55;color:var(--text);max-height:46vh;overflow:auto}
/* upload dropzone */
.dropzone{border:1.5px dashed var(--grid);border-radius:10px;padding:22px 16px;text-align:center;color:var(--dim);cursor:pointer;transition:border-color .15s,background .15s;margin-bottom:14px}
.dropzone:hover,.dropzone.drag{border-color:var(--accent);background:rgba(41,98,255,.06);color:var(--text)}
.dropzone .big{font-size:13.5px;color:var(--text);margin-bottom:3px}
.dropzone .sub{font-size:11.5px}
.dropzone .accent{color:var(--accent);font-weight:600}
/* document list */
.doclist{display:flex;flex-direction:column;gap:6px}
.docrow{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--grid);border-radius:8px;background:var(--bg)}
.docrow .dname{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.docrow .dmeta{color:var(--dim);font-size:11.5px;white-space:nowrap;font-variant-numeric:tabular-nums}
.docrow .dbtn{background:transparent;border:1px solid var(--grid);color:var(--dim);border-radius:6px;padding:5px 10px;cursor:pointer;font-size:12px}
.docrow .dbtn:hover{color:var(--text);border-color:var(--accent)}
.docrow .dbtn.del:hover{color:var(--down);border-color:var(--down)}
.memempty{color:var(--dim);font-size:12.5px;text-align:center;padding:26px 10px}
/* storage & retention */
/* Embedded Grafana. Fills the modal panel and scrolls internally, so the dashboard's own
   height never pushes the surrounding modal into a page-level scroll. */
.gframe{border:1px solid var(--grid);border-radius:8px;overflow:hidden;background:var(--bg);height:min(72vh,820px)}
.gframe iframe{width:100%;height:100%;border:0;display:block}
.stblock{margin-bottom:22px}
.sthead{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:8px}
.sthead .stt{font-weight:600;font-size:13.5px}
.sthead .sts{color:var(--dim);font-size:12px;font-variant-numeric:tabular-nums}
.usagebar{position:relative;height:26px;border-radius:7px;overflow:hidden;display:flex;background:var(--bg);border:1px solid var(--grid)}
/* The system disk's reserve line: where "used" is not allowed to reach. Drawn over the bar
   rather than as a segment, because it marks a limit, not an allocation. */
.usagebar .resvmark{position:absolute;top:0;bottom:0;width:0;border-left:2px dashed #FFA726;pointer-events:none}
.usagebar .resvmark.breach{border-left-color:#ef5350;box-shadow:0 0 0 1px rgba(239,83,80,.35)}
.stlegend .sw.resv{background:transparent;border-left:2px dashed #FFA726;border-radius:0;width:6px}
.usagebar .seg{height:100%;transition:width .3s}
.usagebar .seg.snap{background:var(--accent)}
.usagebar .seg.other{background:#4a5163}
.usagebar .seg.proj{background:repeating-linear-gradient(45deg,rgba(41,98,255,.5),rgba(41,98,255,.5) 6px,rgba(41,98,255,.28) 6px,rgba(41,98,255,.28) 12px)}
.usagebar .seg.free{background:transparent}
.stlegend{display:flex;gap:16px;flex-wrap:wrap;margin-top:8px;font-size:12px;color:var(--dim)}
.stlegend .lg{display:flex;align-items:center;gap:6px}
.stlegend .sw{width:11px;height:11px;border-radius:3px;display:inline-block}
.stlegend .sw.snap{background:var(--accent)}
.stlegend .sw.other{background:#4a5163}
.stlegend .sw.free{background:var(--bg);border:1px solid var(--grid)}
.stlegend .sw.proj{background:repeating-linear-gradient(45deg,rgba(41,98,255,.6),rgba(41,98,255,.6) 4px,rgba(41,98,255,.3) 4px,rgba(41,98,255,.3) 8px)}
.stlegend b{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums}
.sttable{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:6px}
.sttable td{padding:6px 8px;border-bottom:1px solid var(--grid);font-variant-numeric:tabular-nums}
.sttable td:first-child{color:var(--dim)}
.sttable td:last-child{text-align:right}
/* retention control */
.retrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:4px 0 10px}
.retrow input{width:88px;background:var(--bg);border:1px solid var(--grid);border-radius:6px;padding:8px 11px;color:var(--text);outline:none;font-variant-numeric:tabular-nums}
.retrow input:focus{border-color:var(--accent)}
.retrow select{background:var(--bg);border:1px solid var(--grid);border-radius:6px;color:var(--text);padding:8px 10px;cursor:pointer}
.retrow .cur{color:var(--dim);font-size:12.5px}
/* One retention control per table. The table name leads each group so it is never ambiguous
   which object an Apply button is about to change. */
.retgroup{border:1px solid var(--grid);border-radius:8px;padding:10px 12px;margin:10px 0;background:var(--bg)}
.rethead{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.rethead code{font-size:12.5px;color:var(--text);font-weight:600}
.rethead .retrole{font-size:11.5px;color:var(--dim);text-transform:uppercase;letter-spacing:.04em}
.rethead .retcur{margin-left:auto;font-size:12px;color:var(--dim);font-variant-numeric:tabular-nums}
.retnote{font-size:12.5px;line-height:1.5;border-radius:8px;padding:9px 12px;margin:8px 0}
.retnote.warn{background:rgba(239,83,80,.1);border:1px solid rgba(239,83,80,.4);color:#ffb3b0}
.retnote.info{background:rgba(41,98,255,.08);border:1px solid rgba(41,98,255,.3);color:var(--text)}
.retnote.ok{background:rgba(38,166,154,.1);border:1px solid rgba(38,166,154,.4);color:#8fe0d6}

/* clocks (top-right): UTC with ms + SG/NY secondary */
#clocks{display:flex;flex-direction:column;align-items:flex-end;justify-content:center;line-height:1.25;padding:0 6px;font-variant-numeric:tabular-nums;white-space:nowrap}
#clock-utc{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;font-weight:600;color:var(--text)}
#clock-alt{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dim)}
@media(max-width:760px){#clock-alt{display:none}#clock-utc{font-size:11px}}

/* body */
#body{display:flex;min-height:0;min-width:0}
#rail{width:52px;background:var(--bg);border-right:1px solid var(--grid);display:flex;flex-direction:column;align-items:center;padding:6px 0;gap:2px;overflow-y:auto}
#rail .tool{position:relative;width:38px;height:38px;border:0;background:transparent;color:var(--dim);cursor:pointer;border-radius:var(--radius);display:flex;align-items:center;justify-content:center}
#rail .tool svg{width:20px;height:20px}
#rail .tool:hover{color:var(--text);background:var(--panel)}
#rail .tool.on{color:var(--accent)}
#rail .tool.on::before{content:"";position:absolute;left:0;top:7px;bottom:7px;width:2px;background:var(--accent);border-radius:2px}
#rail .tool .soon{position:absolute;top:6px;right:6px;width:5px;height:5px;border-radius:50%;background:var(--accent);opacity:.8}
#rail .divider{width:24px;height:1px;background:var(--grid);margin:4px 0}
@media(max-width:760px){#rail{width:44px}#rail .tool{width:34px;height:34px}}

/* Pane grid. The host window's own chart is the first cell; extra cells are iframes, each an
   independent instance of the app. min-width/height:0 lets the cells actually shrink. */
#panes{flex:1 1 auto;min-width:0;min-height:0;display:grid;gap:1px;background:var(--grid)}
#panes.l1{grid-template-columns:1fr}
#panes.l2c{grid-template-columns:1fr 1fr}
#panes.l2r{grid-template-rows:1fr 1fr}
#panes.l4{grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr}
#panes > *{min-width:0;min-height:0;overflow:hidden}
#panes iframe{border:0;width:100%;height:100%;display:block;background:var(--bg)}
#layout button{font-size:13px;line-height:1;padding:5px 7px}

/* Embedded pane: drop the host-only chrome, keep the series controls and the chart. */
body.embed #topbar .brand,
body.embed #topbar #clocks,
body.embed #topbar #fsbtn,
body.embed #topbar #helpbtn,
body.embed #topbar #profilebtn,
body.embed #topbar #layout,
body.embed #topbar #loadchips,
body.embed #rail{display:none!important}
body.embed #topbar{padding:0 6px;gap:6px}
body.embed #status{font-size:11px}

#chartwrap{position:relative;flex:1 1 auto;min-width:0}
#chart{position:absolute;inset:0}
#overlay{position:absolute;inset:0;z-index:2;pointer-events:none}
/* Per-bar tooltip. Follows the crosshair, so it is a floating card rather than a corner
   legend; `pointer-events:none` keeps it from ever eating a click meant for the chart. */
.bartip{position:absolute;z-index:6;pointer-events:none;font-variant-numeric:tabular-nums;
  background:rgba(19,23,34,.94);border:1px solid var(--grid);border-radius:8px;
  padding:9px 11px;min-width:210px;max-width:290px;
  box-shadow:0 6px 22px rgba(0,0,0,.5);font-size:11.5px;line-height:1.45}
.bartip .bt-h{font-weight:600;font-size:12px;letter-spacing:.2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bartip .bt-sep{color:var(--grid)}
/* The two metadata lines: dim, small, and allowed to wrap rather than widen the card. */
.bartip .bt-m{color:var(--dim);font-size:10.5px;line-height:1.4;margin-top:1px}
.bartip .bt-px{font-size:16px;font-weight:600;margin:6px 0 2px;letter-spacing:.2px}
.bartip .bt-ohlc{display:grid;grid-template-columns:auto 1fr auto 1fr;gap:0 6px;font-size:11px}
.bartip .bt-ohlc i{color:var(--dim);font-style:normal}
/* Buy/sell/total share one grid so the dollar figures line up in a column. */
.bartip .bt-flow{display:grid;grid-template-columns:auto 1fr auto;gap:1px 8px;margin-top:6px;
  padding-top:6px;border-top:1px solid var(--grid)}
.bartip .bt-flow .bt-lbl{color:var(--dim)}
.bartip .bt-flow .bt-amt{text-align:right;font-weight:600}
.bartip .bt-flow .bt-pct{color:var(--dim);text-align:right;min-width:34px}
.bartip .bt-buy .bt-amt,.bartip .bt-buy .bt-lbl{color:var(--up)}
.bartip .bt-sell .bt-amt,.bartip .bt-sell .bt-lbl{color:var(--down)}
.bartip .bt-tot .bt-amt{color:var(--text)}
/* A split bar under the flow rows: the buy/sell ratio as one glance, no numbers needed. */
.bartip .bt-bar{grid-column:1/-1;height:3px;border-radius:2px;background:var(--down);margin-top:4px;overflow:hidden}
.bartip .bt-bar span{display:block;height:100%;background:var(--up)}
/* Indicator breakdowns appended to the card: label on the left, figure right-aligned, so a point
   total and its parts read as one column you can add up by eye. Tabular figures keep the decimal
   points in line — a breakdown you cannot check at a glance is not a breakdown. */
.bartip .bt-ind{display:grid;grid-template-columns:auto 1fr;gap:1px 10px;margin-top:6px;
  padding-top:6px;border-top:1px solid var(--grid);font-size:11px}
.bartip .bt-ind .bt-ih{grid-column:1/-1;font-weight:600;margin-bottom:2px}
.bartip .bt-ind i{color:var(--dim);font-style:normal;white-space:nowrap}
.bartip .bt-ind b{font-weight:600}
.bartip .bt-ind span{text-align:right;font-variant-numeric:tabular-nums}
.bartip .bt-ind .bt-rule{grid-column:1/-1;height:1px;background:var(--grid);margin:3px 0}
.bartip .bt-l1{color:var(--dim);margin-top:5px;font-size:10.5px}
.bartip .up{color:var(--up)}
.bartip .down{color:var(--down)}
/* active-indicator legend (hover to reveal ✕ remove) */
#indlegend{position:absolute;top:52px;left:12px;z-index:4;display:flex;flex-direction:column;gap:3px;pointer-events:none;max-width:min(60vw,360px)}
.indchip{display:inline-flex;align-items:center;gap:6px;pointer-events:auto;font-size:11.5px;line-height:1.4;background:rgba(30,34,45,.5);border:1px solid transparent;border-radius:5px;padding:2px 3px 2px 6px;width:max-content;max-width:min(60vw,360px);text-shadow:0 1px 2px rgba(0,0,0,.6)}
.indchip.panechip{position:absolute;left:12px;z-index:4}
.indchip:hover{background:rgba(30,34,45,.96);border-color:var(--grid)}
.indchip .isw{width:9px;height:9px;border-radius:2px;flex-shrink:0}
.indchip .ilbl{color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A note the server attached to this indicator's values (an adaptive threshold, an empty bucket, a
   capped read). Dim and truncated so it never competes with the label; full text on hover. */
.indchip .iverdict{font-size:10.5px;font-weight:600;letter-spacing:.02em;white-space:nowrap;flex-shrink:0}
.indchip .inote{color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:min(40vw,260px);font-size:10.5px;border-left:1px solid var(--grid);padding-left:6px}
.indchip .ix{visibility:hidden;border:0;background:transparent;color:var(--dim);cursor:pointer;font-size:12px;line-height:1;padding:1px 3px;border-radius:3px;flex-shrink:0}
.indchip:hover .ix{visibility:visible}
.indchip .ix:hover{color:var(--down);background:rgba(239,83,80,.15)}
/* settings gear — same hover-reveal as the ✕, sits just before it */
.indchip .icfg{visibility:hidden;border:0;background:transparent;color:var(--dim);cursor:pointer;line-height:1;padding:1px 2px;border-radius:3px;flex-shrink:0;display:inline-flex;align-items:center}
.indchip:hover .icfg{visibility:visible}
.indchip .icfg svg{width:12px;height:12px}
.indchip .icfg:hover{color:var(--text);background:rgba(255,255,255,.10)}
/* hide/show eye — hover-revealed like the gear, but STAYS visible while the indicator is hidden,
   since the crossed eye is the only sign left that the indicator is still there */
.indchip .ieye{visibility:hidden;border:0;background:transparent;color:var(--dim);cursor:pointer;line-height:1;padding:1px 2px;border-radius:3px;flex-shrink:0;display:inline-flex;align-items:center}
.indchip:hover .ieye,.indchip.off .ieye{visibility:visible}
.indchip .ieye svg{width:12px;height:12px}
.indchip .ieye:hover{color:var(--text);background:rgba(255,255,255,.10)}
/* a hidden indicator's chip stays put but reads as inactive */
.indchip.off{background:rgba(30,34,45,.35)}
.indchip.off:hover{background:rgba(30,34,45,.96)}
.indchip.off .ilbl{color:var(--dim);text-decoration:line-through;text-decoration-color:rgba(255,255,255,.25)}
.indchip.off .isw{opacity:.35}
/* per-pane hide + delete controls (top-right of a sub-pane, revealed on pane hover) */
.panectl{position:absolute;z-index:5;opacity:0;transition:opacity .12s;pointer-events:none;display:inline-flex;gap:4px}
.panectl.hot{opacity:1}
.panectl .pdel,.panectl .pcfg,.panectl .peye{pointer-events:none;display:inline-flex;align-items:center;justify-content:center;width:26px;height:22px;border:1px solid var(--grid);background:rgba(30,34,45,.92);color:var(--dim);border-radius:5px;cursor:pointer;padding:0}
.panectl.hot .pdel,.panectl.hot .pcfg,.panectl.hot .peye{pointer-events:auto}
.panectl .pdel:hover{color:var(--down);border-color:var(--down);background:rgba(239,83,80,.12)}
.panectl .pcfg:hover,.panectl .peye:hover{color:var(--text);border-color:var(--dim);background:rgba(255,255,255,.08)}
.panectl .pdel svg,.panectl .pcfg svg,.panectl .peye svg{width:14px;height:14px}
/* hide/show in the indicator menu's "on chart" list — same box as Remove, minus the red hover */
.hidebtn{background:transparent;border:1px solid var(--grid);color:var(--dim);border-radius:6px;padding:5px 9px;cursor:pointer;font-size:12px}
.hidebtn:hover{color:var(--text);border-color:var(--dim)}

.toast{position:absolute;bottom:16px;left:50%;transform:translateX(-50%);background:var(--panel);border:1px solid var(--grid);color:var(--text);padding:8px 14px;border-radius:8px;opacity:0;transition:opacity .2s;pointer-events:none;z-index:5}
.toast.show{opacity:1}

/* ---------- Bar Replay ---------- */
/* The topbar button reads "armed" while a replay session is live, so a pane showing withheld
   history can never be mistaken for one showing the market. */
#replaybtn svg{width:14px;height:14px}
#replaybtn.on{background:var(--accent);border-color:var(--accent);color:#fff}
#replaybtn.picking{border-color:var(--accent);color:var(--accent)}
.dot.replay{background:var(--accent)}

/* Transport bar, floating over the bottom of the chart (it may overlap the time axis, which is
   dead space while replaying anyway). Toast sits at bottom:16px, so this clears it. */
#replaybar{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);z-index:6;
  background:rgba(30,34,45,.96);border:1px solid var(--grid);border-radius:10px;
  box-shadow:0 8px 26px rgba(0,0,0,.5);font-size:12px;white-space:nowrap;max-width:calc(100% - 24px)}
#replaybar[hidden]{display:none}
#replaybar .rp-pick,#replaybar .rp-ctrl{display:flex;align-items:center;gap:8px;padding:6px 8px}
#replaybar .rp-pick[hidden],#replaybar .rp-ctrl[hidden]{display:none}
#replaybar .rp-pick{color:var(--text);padding-left:12px}
#replaybar .rp-dot{width:7px;height:7px;border-radius:50%;background:var(--accent);animation:pulse 2s infinite;flex:none}
#replaybar .rp-cancel{background:transparent;border:1px solid var(--grid);border-radius:var(--radius);
  color:var(--dim);padding:4px 10px;cursor:pointer}
#replaybar .rp-cancel:hover{color:var(--text);border-color:#3a3f4c}
#replaybar .rp-ctrl>button{background:transparent;border:0;color:var(--text);cursor:pointer;
  width:30px;height:28px;border-radius:var(--radius);display:flex;align-items:center;justify-content:center;flex:none}
#replaybar .rp-ctrl>button:hover{background:var(--bg)}
#replaybar .rp-ctrl>button:disabled{color:#4a4e5a;cursor:default;background:transparent}
#replaybar .rp-ctrl>button svg{width:17px;height:17px}
#replaybar .rp-play{color:var(--accent)!important}
#replaybar .rp-play:disabled{color:#4a4e5a!important}
/* Play/pause is one button with two glyphs; `hidden` is not honoured on inline SVG, so the
   swap goes through a class on the button. */
#replaybar .rp-play .rp-i-pause{display:none}
#replaybar .rp-play.playing .rp-i-play{display:none}
#replaybar .rp-play.playing .rp-i-pause{display:block}
#replaybar .rp-sep{width:1px;height:18px;background:var(--grid);flex:none}
#replaybar .rp-speed{display:inline-flex;background:var(--bg);border:1px solid var(--grid);border-radius:var(--radius);overflow:hidden;flex:none}
#replaybar .rp-speed button{background:transparent;border:0;color:var(--dim);padding:4px 9px;cursor:pointer;font-variant-numeric:tabular-nums}
#replaybar .rp-speed button.on{background:var(--accent);color:#fff}
#replaybar .rp-speed button:not(.on):hover{color:var(--text)}
#replaybar .rp-at{color:var(--text);font-variant-numeric:tabular-nums;padding-left:2px}
#replaybar .rp-left{color:var(--dim);font-variant-numeric:tabular-nums}
#replaybar .rp-wait{color:#F0B429;cursor:help}
#replaybar .rp-wait[hidden]{display:none}
#replaybar .rp-exit{color:var(--dim)!important;font-size:14px}
#replaybar .rp-exit:hover{color:var(--text)!important}
/* A narrow pane (4-way split) drops the labels rather than overflowing the chart. */
@media (max-width:560px){#replaybar .rp-at,#replaybar .rp-left,#replaybar .rp-sep{display:none}}

/* status strip */
#status{display:flex;align-items:center;gap:8px;padding:0 12px;background:var(--bg);border-top:1px solid var(--grid);color:var(--dim);font-size:12px;font-variant-numeric:tabular-nums}
#status .sep{opacity:.4}
#status .muted{color:var(--dim)}
/* Bar Count trend HUD — top-right of the chart */
#bchud{position:absolute;top:8px;right:78px;z-index:6;display:none;min-width:112px;
  background:rgba(19,23,34,.86);border:1px solid var(--grid);border-radius:6px;padding:6px 8px;
  font-size:11px;line-height:1.35;text-align:right;pointer-events:auto;
  font-family:ui-monospace,Menlo,monospace;font-variant-numeric:tabular-nums}
#bchud .bctitle{color:var(--text);font-weight:600;letter-spacing:.02em;margin-bottom:2px;
  padding-bottom:3px;border-bottom:1px solid var(--grid);text-align:left}
#bchud .bcarrow{font-size:22px;line-height:1.05;font-weight:600;display:flex;align-items:baseline;justify-content:flex-end;gap:5px}
#bchud .bcnow{font-size:16px}
#bchud .bcprev{color:var(--dim)}
#bchud .bcbias{font-weight:700;font-size:13px;letter-spacing:.06em;margin-top:2px}
#bchud .bcscope{color:var(--dim);opacity:.75;margin-top:2px;white-space:nowrap}
#bchud select{margin-top:5px;width:100%;background:var(--panel);color:var(--text);border:1px solid var(--grid);
  border-radius:4px;font-size:10.5px;padding:2px 3px;cursor:pointer;font-family:inherit}
#bchud select:hover{border-color:var(--dim)}

/* horizontal squeeze/stretch control */
.hzoom{display:inline-flex;align-items:center;gap:4px}
.hzoom button{border:1px solid transparent;background:transparent;color:var(--dim);cursor:pointer;font-size:12px;line-height:1;padding:2px 4px;border-radius:3px}
.hzoom button:hover{color:var(--text);background:rgba(255,255,255,.08);border-color:var(--grid)}
.hzoom input[type=range]{-webkit-appearance:none;appearance:none;width:88px;height:14px;background:transparent;cursor:ew-resize}
.hzoom input[type=range]::-webkit-slider-runnable-track{height:3px;background:var(--grid);border-radius:2px}
.hzoom input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:11px;height:11px;margin-top:-4px;border-radius:50%;background:var(--dim);border:0}
.hzoom input[type=range]:hover::-webkit-slider-thumb{background:var(--text)}
.hzoom input[type=range]::-moz-range-track{height:3px;background:var(--grid);border-radius:2px}
.hzoom input[type=range]::-moz-range-thumb{width:11px;height:11px;border-radius:50%;background:var(--dim);border:0}
.hzoom input[type=range]:hover::-moz-range-thumb{background:var(--text)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--dim)}
.dot.live{background:var(--up);box-shadow:0 0 0 0 rgba(38,166,154,.5);animation:pulse 2s infinite}
.dot.warn{background:#F0B429}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(38,166,154,.5)}70%{box-shadow:0 0 0 6px rgba(38,166,154,0)}100%{box-shadow:0 0 0 0 rgba(38,166,154,0)}}

/* popover */
.popover{position:absolute;top:44px;left:140px;z-index:20;background:var(--panel);border:1px solid var(--grid);border-radius:8px;box-shadow:0 8px 28px rgba(0,0,0,.5);width:300px;max-height:70vh;display:flex;flex-direction:column;overflow:hidden}
.popover[hidden]{display:none}
/* belt-and-suspenders: hide any TradingView attribution anchor */
#chart a[href*="tradingview"]{display:none!important}
.search{background:var(--bg);border:0;border-bottom:1px solid var(--grid);padding:10px 12px;outline:none}
.symlist{overflow-y:auto;padding:4px}
.symlist .grp{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.08em;padding:8px 10px 4px}
.symlist .row{display:flex;justify-content:space-between;align-items:center;padding:7px 10px;border-radius:var(--radius);cursor:pointer}
.symlist .row:hover,.symlist .row.hl{background:var(--bg)}
.symlist .row .nm{font-weight:600}
.symlist .row .meta{color:var(--dim);font-size:11px}
.symlist .row.on .nm{color:var(--accent)}

/* ---------- server info panel (owner) ---------- */
/* Reuses the storage panel's blocks (.stblock/.usagebar/.sttable) so the two owner panels read as
   one system; everything below is only what the live view adds. */
.srvbody{flex:1;min-width:0;overflow:auto;padding:14px 16px}
.srvage{color:var(--dim);font-size:11.5px;font-weight:400;margin-left:8px}
/* headline tiles: one per resource, colour-banded at 70% / 90% */
.srvtiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-bottom:20px}
.tile{background:var(--bg);border:1px solid var(--grid);border-left-width:3px;border-radius:8px;padding:9px 11px}
.tile .tk{color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.4px}
.tile .tv{font-size:22px;font-weight:600;font-variant-numeric:tabular-nums;line-height:1.25}
.tile .ts{color:var(--dim);font-size:11.5px;font-variant-numeric:tabular-nums}
.tile.ok{border-left-color:var(--up)}
.tile.warn{border-left-color:#FFA726}
.tile.bad{border-left-color:var(--down)}
/* scoped to the panel: .ok/.warn/.bad are generic enough to collide anywhere else */
.srvbody .ok{color:var(--up)}
.srvbody .warn{color:#FFA726}
.srvbody .bad{color:var(--down)}
/* numbers left, sparkline right — collapses to one column on a phone */
.srvsplit{display:grid;grid-template-columns:1fr 140px;gap:14px;align-items:start}
@media(max-width:640px){.srvsplit{grid-template-columns:1fr}}
.corerow{display:flex;align-items:center;gap:8px;margin-bottom:5px;font-size:12px}
.corerow .cl{color:var(--dim);width:34px;font-variant-numeric:tabular-nums}
.corerow .cv{width:38px;text-align:right;font-variant-numeric:tabular-nums}
.cbar{flex:1;height:9px;background:var(--bg);border:1px solid var(--grid);border-radius:5px;overflow:hidden}
.cfill{height:100%;transition:width .3s}
.cfill.ok{background:var(--up)}
.cfill.warn{background:#FFA726}
.cfill.bad{background:var(--down)}
.sparkbox{background:var(--bg);border:1px solid var(--grid);border-radius:8px;padding:8px}
.spklbl{color:var(--dim);font-size:11px;margin-bottom:4px;line-height:1.3}
.spkax{display:flex;justify-content:space-between;color:var(--dim);font-size:10px;font-variant-numeric:tabular-nums}
.spark{width:100%;height:26px;display:block}
.spark polyline{fill:none;stroke:var(--accent);stroke-width:1.5;vector-effect:non-scaling-stroke}
.spark polyline.fill{fill:rgba(41,98,255,.16);stroke:none}
.spark.rows polyline{stroke:var(--up)}
.spark.rows polyline.fill{fill:rgba(38,166,154,.16)}
/* the write path, one row per stage */
.pipeline{display:flex;flex-direction:column;gap:1px}
.pstage{display:flex;align-items:center;gap:10px;background:var(--bg);border:1px solid var(--grid);border-radius:7px;padding:7px 10px}
.pstage .pn{width:19px;height:19px;flex-shrink:0;border-radius:50%;background:var(--grid);color:var(--dim);display:flex;align-items:center;justify-content:center;font-size:11px;font-variant-numeric:tabular-nums}
.pstage .pd{flex:1;min-width:0}
.pstage .pname{font-weight:600;font-size:12.5px}
.pstage .pdet{color:var(--dim);font-size:11.5px;line-height:1.4}
.pstage .pval{text-align:right;font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.pstage.warn{border-color:#FFA726}
.pstage.warn .pval{color:#FFA726}
.pstage.bad{border-color:var(--down)}
.pstage.bad .pval{color:var(--down)}
.pill{font-size:10.5px;padding:1px 6px;border-radius:10px;border:1px solid var(--grid);color:var(--dim);margin-left:6px}
.pill.cold{border-color:rgba(41,98,255,.5);color:#7d9dff}
.pill.hot{border-color:rgba(255,167,38,.5);color:#FFA726}
.usagebar .seg.hot{background:#FFA726}
.stlegend .sw.hot{background:#FFA726}
.sthead.sub{margin-top:16px}
/* service health rows */
.svcrow{display:grid;grid-template-columns:10px 1fr auto auto;gap:10px;align-items:center;padding:7px 2px;border-bottom:1px solid var(--grid);font-size:12.5px}
.svcrow .dot{width:8px;height:8px;border-radius:50%}
.svcrow .dot.ok{background:var(--up)}
.svcrow .dot.bad{background:var(--down)}
.svcrow .sstate,.svcrow .swhen{color:var(--dim);font-size:11.5px;font-variant-numeric:tabular-nums}
@media(max-width:560px){.svcrow{grid-template-columns:10px 1fr;row-gap:2px}.svcrow .sstate,.svcrow .swhen{grid-column:2}}

/* ---------- per-column recording audit (bottom of the storage panel) ---------- */
.colbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:10px 0 4px}
.colbar .spacer{flex:1 1 auto;min-width:0}
.cchip{font-size:11.5px;padding:3px 9px;border-radius:11px;border:1px solid var(--grid);color:var(--dim);white-space:nowrap}
.cchip.v-recording{border-color:rgba(38,166,154,.45);color:var(--up)}
.cchip.v-partial,.cchip.v-constant{border-color:rgba(255,167,38,.45);color:#FFA726}
.cchip.v-empty{border-color:rgba(239,83,80,.45);color:var(--down)}
.seg.colseg button{padding:5px 9px;font-size:12px}
.colsearch{background:var(--bg);border:1px solid var(--grid);border-radius:var(--radius);padding:5px 9px;outline:none;width:130px}
.colsearch:focus{border-color:var(--accent)}
#col-window{background:var(--bg);border:1px solid var(--grid);border-radius:var(--radius);padding:5px 8px;cursor:pointer;font-size:12px}
/* 212 rows: keep the list inside its own scroller so the panel's own scroll stays usable */
#colrows{max-height:340px;overflow-y:auto;border:1px solid var(--grid);border-radius:8px;margin-top:6px}
.coltable{margin:0}
.coltable td{padding:5px 8px;vertical-align:middle}
.coltable tr:last-child td{border-bottom:0}
.coltable td.cn{color:var(--text);font-family:ui-monospace,Menlo,monospace;font-size:11.5px;white-space:nowrap}
.coltable td.cn .ct{color:var(--dim);font-family:var(--font);font-size:10.5px;margin-left:7px}
.coltable td:nth-child(2){color:var(--dim);font-size:11.5px}
.coltable td.cf{width:120px;white-space:nowrap;text-align:right}
.fbar{display:inline-block;width:56px;height:7px;background:var(--bg);border:1px solid var(--grid);border-radius:4px;overflow:hidden;vertical-align:middle}
.ffill{display:block;height:100%}
.ffill.v-recording{background:var(--up)}
.ffill.v-partial{background:#FFA726}
.ffill.v-constant{background:#8a6d3b}
.ffill.v-empty{background:transparent}
.fpct{display:inline-block;width:46px;text-align:right;font-size:11px;color:var(--dim)}
.vpill{font-size:10.5px;padding:1px 7px;border-radius:10px;border:1px solid var(--grid);color:var(--dim);white-space:nowrap}
.vpill.v-recording{border-color:rgba(38,166,154,.4);color:var(--up)}
.vpill.v-partial,.vpill.v-constant{border-color:rgba(255,167,38,.45);color:#FFA726}
.vpill.v-empty{border-color:rgba(239,83,80,.45);color:var(--down)}
