/* Installed Base - shared stylesheet.
   Extracted from index.html when the single page was split into units,
   customers, edit and settings.  One file so a rule changed here changes
   every page, which is the whole reason the pages were split rather than
   copied. */
:root{
  --ground:#E9EEEF; --surface:#FFFFFF; --surface-2:#F5F8F9; --surface-3:#EDF2F3;
  --ink:#0F1719; --ink-2:#33474D; --muted:#61757B;
  --rule:#D2DCDF; --rule-2:#BCC9CD;
  --accent:#0B6068; --accent-ink:#FFFFFF; --accent-soft:#DFEDEE;
  --band-red:#FFC7CE; --band-amber:#FFE699; --band-blue:#BDD7EE; --band-ink:#20272A;
  --band-green:#C6EFCE; --band-green-2:#9BC98C;
  --stripe-red:#D1495B; --stripe-amber:#C98A16; --stripe-blue:#3E7CB1; --stripe-ok:#9FB0B5;
  --shadow:0 1px 2px rgba(15,23,25,.06), 0 10px 28px -22px rgba(15,23,25,.5);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ground:#080D0F; --surface:#101819; --surface-2:#162125; --surface-3:#1C292E;
    --ink:#E4EDEF; --ink-2:#B6C7CB; --muted:#87999E;
    --rule:#213036; --rule-2:#2E4148;
    --accent:#5FBAC3; --accent-ink:#04191C; --accent-soft:#12292D;
    --band-red:#5E2A31; --band-amber:#5A4515; --band-blue:#1E3C52; --band-ink:#E4EDEF;
    --band-green:#254A2E; --band-green-2:#356B3B;
    --stripe-red:#E2707F; --stripe-amber:#E0B14B; --stripe-blue:#6FA8D6; --stripe-ok:#4A5C62;
    --shadow:0 1px 2px rgba(0,0,0,.5), 0 12px 32px -24px rgba(0,0,0,.9);
  }
}
:root[data-theme="dark"]{
  --ground:#080D0F; --surface:#101819; --surface-2:#162125; --surface-3:#1C292E;
  --ink:#E4EDEF; --ink-2:#B6C7CB; --muted:#87999E;
  --rule:#213036; --rule-2:#2E4148;
  --accent:#5FBAC3; --accent-ink:#04191C; --accent-soft:#12292D;
  --band-red:#5E2A31; --band-amber:#5A4515; --band-blue:#1E3C52; --band-ink:#E4EDEF;
  --band-green:#254A2E; --band-green-2:#356B3B;
  --stripe-red:#E2707F; --stripe-amber:#E0B14B; --stripe-blue:#6FA8D6; --stripe-ok:#4A5C62;
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 12px 32px -24px rgba(0,0,0,.9);
}
*{box-sizing:border-box}
/* .controls and .stats set display:flex, which outranks the hidden attribute's
   display:none - without this the two toolbars render on top of each other. */
[hidden]{display:none !important;}
html,body{height:100%}
/* The whole interface renders at 80%.
   zoom rather than transform:scale - the drawer and the scrim are position:fixed
   and the table header is position:sticky, and a transform makes an element the
   containing block for its fixed descendants, which would strand all three.

   The height is 125vh, not 125%, and the difference is the whole layout.
   Under body{zoom} a percentage height is resolved against a containing block
   that has already been scaled up, and is then scaled down again - so 125%
   computed to 1,406px and drew 1,125px tall in a 900px window.  The bottom fifth
   of every page sat below the window, and with the body set not to scroll there
   was no way to reach it: the last rows of every table and the last cards of the
   dashboard were simply unreachable.  vh is not rescaled that way; 125vh draws at
   exactly the window's height.  Same cause, same fix, as the overlays further
   down. */
body{ zoom:0.8; height:125vh; }
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:14px; -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; overflow:hidden;
}
header{
  background:var(--surface); border-bottom:1px solid var(--rule);
  padding:14px clamp(12px,2vw,22px) 0; flex:none;
}
.top{display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-bottom:12px;}
.top .sub{flex:1 1 auto; min-width:0;}
.top .dash{margin-left:auto; margin-bottom:0; flex:none;}
h1{font-size:17px; font-weight:700; margin:0; letter-spacing:-.01em;}
.sub{font-size:12px; color:var(--muted);}
.sub b{font-family:"IBM Plex Mono",monospace; color:var(--ink-2); font-weight:600;}
.stats{display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px;}
.chip{
  display:flex; align-items:center; gap:8px; cursor:pointer; user-select:none;
  background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:6px 11px 6px 8px; font:inherit; font-size:12px; font-weight:500; color:var(--ink-2);
  transition:border-color .12s, background .12s;
}
.chip:hover{border-color:var(--rule-2);}
.chip[aria-pressed="true"]{background:var(--accent-soft); border-color:var(--accent); color:var(--ink);}
.chip .sw{width:11px; height:11px; border-radius:2px; flex:none; border:1px solid rgba(0,0,0,.12);}
.chip .ct{font-family:"IBM Plex Mono",monospace; font-weight:600; font-variant-numeric:tabular-nums; color:var(--ink);}
.chip .pc{font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--muted);}
.controls{display:flex; gap:8px; flex-wrap:wrap; align-items:center; padding-bottom:12px;}
.search{position:relative; flex:1 1 260px; min-width:200px; max-width:420px;}
.search input{
  width:100%; background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:7px 10px 7px 30px; font:inherit; font-size:13px; color:var(--ink);
}
.search input:focus{outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent;}
.search svg{position:absolute; left:9px; top:50%; transform:translateY(-50%); opacity:.5;}
select{
  background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:7px 9px; font:inherit; font-size:12.5px; color:var(--ink); max-width:190px;
}
select:focus{outline:2px solid var(--accent); outline-offset:-1px;}
.reset{
  background:none; border:1px solid var(--rule); border-radius:3px; padding:7px 11px;
  font:inherit; font-size:12.5px; color:var(--muted); cursor:pointer;
}
.reset:hover{color:var(--ink); border-color:var(--rule-2);}
.count{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--muted); white-space:nowrap;}
.count b{color:var(--ink); font-weight:600;}
.wrap{flex:1; overflow:auto; position:relative; background:var(--surface);}
table{border-collapse:separate; border-spacing:0; width:100%; min-width:1500px;}
thead th{
  position:sticky; top:0; z-index:3; background:var(--accent); color:var(--accent-ink);
  font-size:10.5px; font-weight:600; letter-spacing:.07em; text-transform:uppercase;
  text-align:left; padding:0 10px; height:38px; white-space:nowrap; cursor:pointer;
  user-select:none; border-right:1px solid rgba(255,255,255,.12);
}
thead th .ar{opacity:.35; margin-left:5px; font-size:9px;}
thead th[aria-sort] .ar{opacity:1;}
thead th.num{text-align:right;}
tbody td{
  padding:0 10px; height:32px; border-bottom:1px solid var(--rule);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:280px;
  font-size:12.5px; color:var(--ink-2);
}
tbody td.k{color:var(--ink); font-weight:500;}
tbody td.m{font-family:"IBM Plex Mono",monospace; font-size:11.5px;}
tbody td.num{text-align:right; font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;}
tbody tr:hover td{background:var(--surface-3);}
tbody tr{cursor:pointer;}
td.st{position:relative; padding-left:16px;}
td.st::before{content:""; position:absolute; left:4px; top:6px; bottom:6px; width:3px; border-radius:2px;}
tr[data-s="N"] td.st::before{background:var(--stripe-red);}
tr[data-s="P"] td.st::before{background:var(--stripe-amber);}
tr[data-s="C"] td.st::before{background:var(--stripe-blue);}
tr[data-s="O"] td.st::before{background:var(--stripe-ok);}
tr[data-s="N"] td.st{background:var(--band-red); color:var(--band-ink); font-weight:600;}
tr[data-s="P"] td.st{background:var(--band-amber); color:var(--band-ink); font-weight:600;}
tr[data-s="C"] td.st{background:var(--band-blue); color:var(--band-ink); font-weight:600;}
.pad td{padding:0; border:none; height:0;}
.drawer{
  /* Same 125vh compensation: right:0 under zoom lands at 80% of the window. */
  position:fixed; left:auto; right:0; top:0; height:125vh;
  width:min(430px,92vw); background:var(--surface);
  border-left:1px solid var(--rule); box-shadow:var(--shadow); z-index:20;
  transform:translateX(100%); transition:transform .18s ease; overflow-y:auto; padding:20px 22px 40px;
}
.drawer.open{transform:none;}
@media (prefers-reduced-motion:reduce){ .drawer{transition:none;} }
.drawer h2{font-size:15px; margin:0 0 3px; letter-spacing:-.01em;}
.drawer .sn{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--muted); margin-bottom:16px;}
.drawer dl{margin:0;}
.drawer .row{display:grid; grid-template-columns:132px 1fr; gap:10px; padding:8px 0; border-bottom:1px solid var(--rule);}
.drawer dt{font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); padding-top:2px;}
.drawer dd{margin:0; font-size:13px; color:var(--ink); word-break:break-word;}
.drawer dd.m{font-family:"IBM Plex Mono",monospace; font-size:12px;}
.close{position:absolute; top:14px; right:16px; background:none; border:1px solid var(--rule);
  border-radius:3px; width:26px; height:26px; color:var(--muted); cursor:pointer; font-size:15px; line-height:1;}
.close:hover{color:var(--ink);}
.badge{display:inline-block; padding:3px 9px; border-radius:3px; font-size:11.5px; font-weight:600;}
.scrim{position:fixed; top:0; left:0; width:125vw; height:125vh;
  background:rgba(8,13,15,.35); z-index:15; opacity:0; pointer-events:none; transition:opacity .18s;}
.scrim.on{opacity:1; pointer-events:auto;}
.empty{padding:60px 20px; text-align:center; color:var(--muted); font-size:13px;}
.dash{
  display:flex; flex-wrap:wrap; gap:1px; width:fit-content; max-width:100%;
  background:var(--rule); border:1px solid var(--rule); border-radius:3px;
  overflow:hidden; margin-bottom:12px;
}
.dash .t{background:var(--surface-2); padding:5px 15px 6px; min-width:104px;}
.dash .t b{
  display:block; font-family:"IBM Plex Mono",monospace; font-size:16px; font-weight:600;
  line-height:1.2; letter-spacing:-.015em; font-variant-numeric:tabular-nums; color:var(--ink);
}
.dash .t.r b{color:var(--stripe-red);}
.dash .t.a b{color:var(--stripe-amber);}
.dash .t span{
  display:block; font-size:9px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); margin-top:1px; white-space:nowrap;
}
.tabs{display:flex; gap:2px; margin-bottom:12px;}
.tab{
  background:none; border:none; border-bottom:2px solid transparent; cursor:pointer;
  font:inherit; font-size:13px; font-weight:600; color:var(--muted);
  padding:5px 12px 8px; letter-spacing:.01em;
}
.tab:hover{color:var(--ink-2);}
.tab[aria-selected="true"]{color:var(--accent); border-bottom-color:var(--accent);}
tr[data-f="1"] td.fleet{background:var(--band-green); color:var(--band-ink); font-weight:600;}
tr[data-f="2"] td.fleet{background:var(--band-green-2); color:var(--band-ink); font-weight:700;}
td.fleet{position:relative;}
.mail{color:var(--accent); text-decoration:none;}
.hist h3 .n{
  display:inline-block; margin-left:6px; padding:0 6px; border-radius:2px;
  background:var(--accent-soft); color:var(--accent); font-size:10px;
  font-family:"IBM Plex Mono",monospace;
}
.em{padding:7px 0; border-bottom:1px solid var(--rule);}
.em.cur{background:var(--surface-2); margin:0 -8px; padding-left:8px; padding-right:8px;}
.em .mail{font-family:"IBM Plex Mono",monospace; font-size:12px; word-break:break-all;}
.em .ph{
  display:inline-block; margin-left:8px; font-family:"IBM Plex Mono",monospace;
  font-size:11px; color:var(--ink-2);
}
.un{
  display:flex; align-items:baseline; gap:8px; padding:6px 0 6px 10px;
  border-bottom:1px solid var(--rule); position:relative; cursor:pointer;
  font-size:12px; color:var(--ink-2);
}
.un:hover{background:var(--surface-3);}
.un::before{
  content:""; position:absolute; left:0; top:6px; bottom:6px; width:3px;
  border-radius:2px; background:var(--stripe-ok);
}
.un[data-s="N"]::before{background:var(--stripe-red);}
.un[data-s="P"]::before{background:var(--stripe-amber);}
.un[data-s="C"]::before{background:var(--stripe-blue);}
.un .sn{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink);
  flex:none; min-width:92px;}
.un .md{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; color:var(--muted);}
.un .ag{font-family:"IBM Plex Mono",monospace; font-size:11px; flex:none;
  font-variant-numeric:tabular-nums;}
.un[data-s="N"] .ag{color:var(--stripe-red); font-weight:600;}
.un[data-s="P"] .ag{color:var(--stripe-amber); font-weight:600;}
.hist .load{
  display:block; width:100%; margin-top:8px; background:none; cursor:pointer;
  border:1px solid var(--rule); border-radius:2px; padding:6px;
  font:inherit; font-size:11.5px; color:var(--muted);
}
.hist .load:hover{color:var(--ink); border-color:var(--rule-2);}
.em .src{
  display:block; font-size:10px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--muted); margin-top:2px;
}
#ctb tr{cursor:pointer;}
.more{
  display:inline-block; margin-left:6px; padding:0 5px; border-radius:2px;
  background:var(--surface-3); color:var(--muted); font-size:10px;
  font-family:"IBM Plex Mono",monospace; vertical-align:1px;
}
.mail:hover{text-decoration:underline;}
.bar{display:inline-block; height:7px; border-radius:1px; background:var(--accent); opacity:.5; vertical-align:middle; margin-left:6px;}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
@media (max-width:720px){ header{padding-top:10px} h1{font-size:15px} .count{width:100%; margin:0} }

/* --- Phase 4 additions.  Everything above is the original file, untouched. --- */
tbody tr.loading td{ color:transparent; }
tbody tr.loading td::after{
  content:""; display:block; height:9px; width:70%; border-radius:2px;
  background:var(--surface-3); animation:pulse 1.1s ease-in-out infinite;
}
@keyframes pulse{ 0%,100%{opacity:.45} 50%{opacity:.9} }
@media (prefers-reduced-motion:reduce){ tbody tr.loading td::after{animation:none} }
.overlay{
  /* 125vw/vh = 1 / 0.8.  A position:fixed box under body{zoom} is sized against
     the unzoomed viewport and then scaled, so inset:0 covers only 80% of the
     window and leaves a strip of the table showing down the right-hand side.

     It must be vw/vh and NOT 125%.  Under zoom the two do not agree: a
     percentage resolves against the unzoomed viewport and is then scaled again,
     so width:125% rendered 2343px into a 1500px window - the right-hand column
     of the editor was clipped off the screen and the Save footer sat 200px
     below the fold, unreachable, with no scrollbar to reach it.  Viewport units
     are already in the zoomed space and land exactly on the window. */
  position:fixed; top:0; left:0; width:125vw; height:125vh; z-index:40;
  background:var(--ground);
  display:flex; align-items:center; justify-content:center; padding:20px;
}
.card{
  background:var(--surface); border:1px solid var(--rule); border-radius:4px;
  box-shadow:var(--shadow); padding:26px 28px; width:min(420px,100%);
}
.card h2{ margin:0 0 4px; font-size:16px; letter-spacing:-.01em; }
.card p{ margin:0 0 18px; font-size:12.5px; color:var(--muted); line-height:1.5; }
.card .f{display:flex; flex-direction:column; gap:4px;}
.card .f label{font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted);}
.card input{
  width:100%; background:var(--surface-2); border:1px solid var(--rule);
  border-radius:3px; padding:9px 11px; font:inherit; font-size:13px; color:var(--ink);
  font-family:"IBM Plex Mono",monospace;
}
.card input:focus{ outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent; }
.card button{
  margin-top:12px; width:100%; background:var(--accent); color:var(--accent-ink);
  border:none; border-radius:3px; padding:9px; font:inherit; font-size:13px;
  font-weight:600; cursor:pointer;
}
.card .msg{ margin:10px 0 0; color:var(--stripe-red); font-size:12px; min-height:1em; }
.card .msg.ok{ color:var(--accent); }
.card .hint{ margin:0; font-size:11.5px; color:var(--muted); line-height:1.5; }
.who{ font-size:11.5px; color:var(--muted); margin-left:8px; }
.who b{ color:var(--ink-2); font-weight:600; }
.linkish{
  background:none; border:1px solid var(--rule); border-radius:3px; padding:5px 10px;
  font:inherit; font-size:11.5px; color:var(--muted); cursor:pointer; margin-left:8px;
}
.linkish:hover{ color:var(--ink); border-color:var(--rule-2); }

/* --- Phase 5: add, edit, delete --- */
/* The editor uses the whole window.  At 860px with a customer holding 31
   addresses the card ran past the bottom of the screen and took Save with it. */
.overlay.full{padding:0; align-items:stretch;}
.sheet.full{
  width:100%; max-width:none; height:100%; max-height:none;
  border:none; border-radius:0; box-shadow:none; padding:0;
  display:flex; flex-direction:column; overflow:hidden;
}
.sheet.full .ehead{padding:18px 26px 14px; border-bottom:1px solid var(--rule); flex:none;}
.sheet.full .ehead h2{margin:0 0 3px;}
.sheet.full .ehead .hint{max-width:80ch;}
.sheet.full .ebody{
  flex:1; min-height:0; overflow-y:auto; padding:4px 26px 20px;
  display:grid; grid-template-columns:minmax(0,1fr) minmax(320px,400px); gap:0 34px;
  align-items:start;
}
.sheet.full .ecol{min-width:0;}
.sheet.full .eside{
  min-width:0; position:sticky; top:4px; align-self:start;
  border-left:1px solid var(--rule); padding-left:24px;
}
.sheet.full .eside .addrs{max-height:52vh; overflow-y:auto;}
/* The actions never scroll away - they are the reason the form is open. */
.sheet.full .actions{
  flex:none; margin:0; padding:12px 26px; border-top:1px solid var(--rule);
  background:var(--surface);
}
.sheet.full .actions .err{margin:0 14px; font-size:12px;}
@media (max-width:1100px){
  .sheet.full .ebody{grid-template-columns:minmax(0,1fr);}
  .sheet.full .eside{border-left:none; padding-left:0; position:static;
    border-top:1px solid var(--rule); margin-top:18px; padding-top:14px;}
  .sheet.full .eside .addrs{max-height:none;}
}
.sheet{
  background:var(--surface); border:1px solid var(--rule); border-radius:4px;
  box-shadow:var(--shadow); width:min(860px,100%); max-height:92vh; overflow-y:auto;
  padding:22px 24px 20px;
}
.sheet h2{margin:0 0 2px; font-size:16px; letter-spacing:-.01em;}
.sheet .hint{margin:0 0 16px; font-size:12px; color:var(--muted);}
.grp{
  font-size:10.5px; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); font-weight:600; margin:16px 0 8px;
  padding-bottom:5px; border-bottom:1px solid var(--rule);
}
.grp:first-of-type{margin-top:4px;}
.grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:11px 14px;}
.f{display:flex; flex-direction:column; gap:4px;}
.f label{font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted);}
.f input{
  background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:7px 9px; font:inherit; font-size:13px; color:var(--ink);
}
.f input:focus{outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent;}
.f input[type=date]{font-family:"IBM Plex Mono",monospace; font-size:12px;}
.f.mono input{font-family:"IBM Plex Mono",monospace; font-size:12.5px;}
.addrs{border-top:1px solid var(--rule);}
.addr{
  display:flex; align-items:center; gap:10px; padding:7px 0;
  border-bottom:1px solid var(--rule); font-size:12.5px;
}
.addr .e{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--ink);
  flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;}
.addr .p{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink-2); flex:none;}
.addr .s{
  font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; flex:none;
  color:var(--muted); background:var(--surface-2); border-radius:2px; padding:2px 6px;
}
.addr .x{
  flex:none; background:none; border:1px solid var(--rule); border-radius:2px;
  color:var(--muted); cursor:pointer; font:inherit; font-size:14px; line-height:1;
  width:24px; height:24px; padding:0;
}
.addr .x:hover{color:var(--stripe-red); border-color:var(--stripe-red);}
.addrs .none{padding:10px 0; color:var(--muted); font-size:12px;}
.addradd{display:flex; gap:8px; margin-top:10px;}
.addradd input{
  flex:1; min-width:0; background:var(--surface-2); border:1px solid var(--rule);
  border-radius:3px; padding:7px 9px; font:inherit; font-size:12.5px; color:var(--ink);
  font-family:"IBM Plex Mono",monospace;
}
.addradd input:focus{outline:2px solid var(--accent); outline-offset:-1px; border-color:transparent;}
.addradd .btn{flex:none;}
.grp .n{
  float:right; font-family:"IBM Plex Mono",monospace; font-size:10px;
  background:var(--accent-soft); color:var(--accent); border-radius:2px; padding:1px 6px;
}
.derived{
  margin-top:16px; background:var(--surface-2); border:1px solid var(--rule);
  border-radius:3px; padding:12px 14px;
}
.derived h3{
  margin:0 0 9px; font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:600;
}
.derived .dg{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px;}
.derived .d b{
  display:block; font-size:13px; color:var(--ink); font-weight:600; min-height:1.25em;
  font-family:"IBM Plex Mono",monospace;
}
.derived .d b.none{color:var(--muted); font-weight:400; font-style:italic;
  font-family:"IBM Plex Sans",sans-serif;}
.derived .d span{
  display:block; font-size:9.5px; text-transform:uppercase; letter-spacing:.07em;
  color:var(--muted); margin-top:2px;
}
.derived.busy{opacity:.55;}
.src{
  display:inline-block; margin-left:6px; padding:1px 6px; border-radius:2px;
  font-size:9.5px; letter-spacing:.05em; text-transform:uppercase;
  background:var(--accent-soft); color:var(--accent);
}
.actions{display:flex; gap:8px; align-items:center; margin-top:18px;}
.actions .spacer{flex:1;}
.btn{
  background:var(--accent); color:var(--accent-ink); border:none; border-radius:3px;
  padding:8px 16px; font:inherit; font-size:13px; font-weight:600; cursor:pointer;
}
.btn.ghost{background:none; border:1px solid var(--rule); color:var(--ink-2);}
.btn.ghost:hover{border-color:var(--rule-2); color:var(--ink);}
.btn.danger{background:none; border:1px solid var(--stripe-red); color:var(--stripe-red);}
.btn.danger:hover{background:var(--stripe-red); color:var(--surface);}
.btn:disabled{opacity:.5; cursor:not-allowed;}
.err{color:var(--stripe-red); font-size:12px; min-height:1em; margin:10px 0 0;}
.drawer .dact{display:flex; gap:7px; margin:14px 0 4px; flex-wrap:wrap;}
.drawer .dact .btn{padding:6px 12px; font-size:12px;}
.hist{margin-top:16px; border-top:1px solid var(--rule); padding-top:12px;}
.hist h3{font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); margin:0 0 8px;}
.hist .h{font-size:11.5px; color:var(--ink-2); padding:6px 0;
  border-bottom:1px solid var(--rule);}
.hist .h b{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--ink);}
.hist .h .w{color:var(--muted);}
.hist .d{font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--muted);
  margin-top:3px; word-break:break-word;}
.add{
  background:var(--accent); color:var(--accent-ink); border:none; border-radius:3px;
  padding:7px 13px; font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
}
.toast{
  position:fixed; left:50%; bottom:22px; transform:translateX(-50%);
  background:var(--ink); color:var(--surface); padding:9px 16px; border-radius:3px;
  font-size:12.5px; z-index:50; box-shadow:var(--shadow); opacity:0;
  transition:opacity .18s; pointer-events:none;
}
.toast.on{opacity:1;}
@media (prefers-reduced-motion:reduce){ .toast{transition:none;} }

/* --- multi-select filters --- */
.ms{position:relative; display:inline-block;}
.ms>button{
  background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:7px 26px 7px 9px; font:inherit; font-size:12.5px; color:var(--ink);
  cursor:pointer; max-width:210px; min-width:130px; text-align:left;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; position:relative;
}
.ms>button::after{
  content:""; position:absolute; right:9px; top:50%; width:0; height:0;
  border-left:3.5px solid transparent; border-right:3.5px solid transparent;
  border-top:4px solid var(--muted); transform:translateY(-1px);
}
.ms>button:hover{border-color:var(--rule-2);}
.ms>button:focus-visible{outline:2px solid var(--accent); outline-offset:-1px;}
.ms.on>button{border-color:var(--accent); background:var(--accent-soft);}
.ms .pop{
  position:absolute; z-index:30; top:calc(100% + 3px); left:0; min-width:290px;
  max-height:340px; overflow-y:auto; background:var(--surface);
  border:1px solid var(--rule-2); border-radius:3px; box-shadow:var(--shadow);
  padding:5px;
}
.ms .pop[hidden]{display:none;}
.ms .opt{
  display:flex; align-items:center; gap:8px; padding:5px 8px; border-radius:2px;
  font-size:12.5px; color:var(--ink-2); cursor:pointer; user-select:none;
  white-space:nowrap;
}
.ms .opt:hover{background:var(--surface-3);}
.ms .opt input{margin:0; accent-color:var(--accent); flex:none;}
.ms .opt .n{
  margin-left:auto; padding-left:12px; font-family:"IBM Plex Mono",monospace;
  font-size:10.5px; color:var(--muted); font-variant-numeric:tabular-nums;
}
.ms .opt.fam{font-weight:600; color:var(--ink);}
.ms .opt.mem{padding-left:26px;}
/* Not .bar: that class already belongs to the unit-count bar in the Top
   Customers table, which is 7px tall, accent-coloured and half transparent.
   Reusing the name inherited all three and painted a teal band across the top
   of every filter panel. */
.ms .tools{
  display:flex; gap:6px; padding:5px 8px 7px; border-bottom:1px solid var(--rule);
  margin-bottom:4px;
}
.ms .tools button{
  background:none; border:1px solid var(--rule); border-radius:2px; cursor:pointer;
  font:inherit; font-size:11px; color:var(--muted); padding:3px 8px;
}
.ms .tools button:hover{color:var(--ink); border-color:var(--rule-2);}
.ms .find{
  flex:1; min-width:0; background:var(--surface-2); border:1px solid var(--rule);
  border-radius:2px; padding:3px 7px; font:inherit; font-size:11.5px; color:var(--ink);
}
.ms .find:focus{outline:1px solid var(--accent); outline-offset:-1px;}
.ms .opt[hidden]{display:none;}
.ms .none{padding:10px 8px; font-size:11.5px; color:var(--muted);}

/* --- user menu --- */
.usr{position:relative; margin-left:10px; flex:none;}
.usr>button{
  width:44px; height:44px; border-radius:50%; border:1px solid var(--rule-2);
  background:var(--accent); color:var(--accent-ink); cursor:pointer;
  font:inherit; font-size:15px; font-weight:700; letter-spacing:.02em;
  display:flex; align-items:center; justify-content:center; padding:0;
}
.usr>button:hover{filter:brightness(1.1);}
.usr>button:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.usr .pop{
  position:absolute; right:0; top:calc(100% + 6px); z-index:35; min-width:230px;
  background:var(--surface); border:1px solid var(--rule-2); border-radius:3px;
  box-shadow:var(--shadow); padding:5px;
}
.usr .pop[hidden]{display:none;}
.usr .id{padding:9px 11px 10px; border-bottom:1px solid var(--rule); margin-bottom:4px;}
.usr .id b{display:block; font-size:13px; color:var(--ink);}
.usr .id span{
  display:block; font-size:10.5px; text-transform:uppercase; letter-spacing:.07em;
  color:var(--muted); margin-top:3px;
}
.usr .mi{
  display:block; width:100%; text-align:left; background:none; border:none;
  border-radius:2px; padding:8px 11px; font:inherit; font-size:12.5px;
  color:var(--ink-2); cursor:pointer;
}
.usr .mi:hover{background:var(--surface-3); color:var(--ink);}
.usr .mi.danger{color:var(--stripe-red);}

/* --- theme toggle --- */
.thm{
  /* 44px to match the outer height of the dashboard tiles beside it - 42px of
     tile plus the 1px border the .dash block carries on each side. */
  width:44px; height:44px; border-radius:50%; flex:none; cursor:pointer; padding:0;
  border:1px solid var(--rule); background:var(--surface-2); color:var(--ink-2);
  display:flex; align-items:center; justify-content:center; margin-left:10px;
}
.thm:hover{border-color:var(--rule-2); color:var(--ink);}
.thm:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.thm svg{width:19px; height:19px;}
.usr{margin-left:6px;}

/* --- brand --- */
.brand{display:flex; align-items:center; gap:12px; flex:none;}
.brand img{
  height:34px; width:auto; display:block;
  /* The wordmark is 98% darker than luminance 90, so the dark palette gets its
     own file rather than a filter - a CSS invert turns the navy muddy yellow. */
}
.brand .light{display:block;}
.brand .dark{display:none;}
:root[data-theme="dark"] .brand .light{display:none;}
:root[data-theme="dark"] .brand .dark{display:block;}
.brand .rule{width:1px; height:26px; background:var(--rule-2); flex:none;}
@media (max-width:720px){ .brand img{height:26px} .brand .rule{display:none} h1{font-size:14px} }

/* ------------------------------------------------- pages, not overlays ---
   Splitting the single page into units / customers / edit / settings turned
   two of the overlays into pages.  A .page is what .overlay was without the
   position:fixed - it is the document now, so it scrolls with the document and
   needs none of the 125vw/vh compensation that fixed boxes need under
   body{zoom}. */
.page{
  display:flex; align-items:center; justify-content:center; padding:20px;
  min-height:calc(100vh - 96px);
}
.page.full{padding:0; align-items:stretch; min-height:calc(100vh - 84px);}
.page.full .sheet.full{height:auto; min-height:calc(100vh - 84px);}

/* Tabs and some buttons are links now, because they navigate.  An <a> brings
   its own underline, its own colour and inline layout; these three lines make
   it sit where the <button> sat rather than restyling either from scratch. */
a.tab, a.btn{text-decoration:none; display:inline-block;}
a.tab{line-height:normal;}
a.btn{line-height:1.35;}
a.tab:visited, a.btn:visited{color:inherit;}
a.btn{color:var(--accent-ink);}
a.btn.ghost{color:var(--ink-2);}

/* Inside a .card the buttons are full-width stacked, so a link acting as one
   has to be too - otherwise Close sits as a small chip beside a full-width
   Change password and the pair looks like a mistake. */
.card .actions{display:flex; flex-direction:column; gap:8px;}
.card .actions .spacer{display:none;}
.card .actions a.btn{
  margin-top:12px; width:100%; padding:9px; text-align:center;
  border-radius:3px; font-size:13px; font-weight:600; box-sizing:border-box;
}

/* The age box and, beside it, what the dates would have said.  Styled to read
   as a caption rather than a second field: it is never editable, and a hint
   that looks like an input invites people to type in it. */
.agenote .lab{
  font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); display:block; margin-bottom:5px;
}
.agenote .hint{margin:0; font-size:12px; color:var(--ink-2); line-height:1.45;}
.agenote .hint b{font-variant-numeric:tabular-nums;}
.agenote .hint .none{color:var(--muted);}

/* An option the current search finds none of.  Dimmed rather than removed: a
   row reading zero answers "is there any Jubail oil-free?"; a row that is not
   there leaves the question open. */
.opt.zero, .chip.zero{opacity:.45;}
.opt.zero .n{font-variant-numeric:tabular-nums;}

/* --- Installed Base tab menu ---------------------------------------------
   Units and Customers are the same data - machines in the field - read by
   machine or by customer.  They sit behind one tab so the bar reads as the two
   things it really offers: what we have installed, and who we could sell to.
   The tab says which view you are on, so the menu is not the only place to
   find out.  position:absolute rather than fixed: fixed boxes under body{zoom}
   need the 125vw/vh compensation, and this one does not need to leave its tab. */
.tabmenu{position:relative; display:inline-block;}
.tabmenu > .tab{display:inline-flex; align-items:baseline;}
.tabsub{font-weight:600;}
.car{margin-left:6px; font-size:9px; opacity:.55; transform:translateY(-1px);}
.tabmenu > .tab[aria-expanded="true"] .car{opacity:.9;}
.tabpop{
  position:absolute; left:0; top:calc(100% + 2px); z-index:35; min-width:180px;
  background:var(--surface); border:1px solid var(--rule-2); border-radius:3px;
  box-shadow:var(--shadow); padding:5px;
}
.tabpop[hidden]{display:none;}
.tabpop .mi{
  display:block; padding:8px 11px; border-radius:2px; text-decoration:none;
  font-size:12.5px; font-weight:600; color:var(--ink-2);
}
.tabpop .mi:visited{color:var(--ink-2);}
.tabpop .mi:hover{background:var(--surface-3); color:var(--ink);}
.tabpop .mi[aria-current="page"]{color:var(--accent);}

/* --- dashboard -----------------------------------------------------------
   The page signing in opens on.  Built from the same tokens as everything
   else, so both themes come for free; the only colour of its own is the
   recessive grey for a folded "all other" bar, which must not be the OK band's
   grey - that one means something. */
:root{ --d-rest:#BCC9CD; }
:root[data-theme="dark"]{ --d-rest:#2E4148; }

.dashboard{
  flex:1; overflow:auto; background:var(--ground);
  padding:18px clamp(12px,2vw,22px) 48px;
}
.dashboard > .empty{margin-top:40px;}

/* headline: one hero figure, four tiles.  Proportional figures on both - equal-
   width digits look loose at this size. */
.dtop{display:flex; flex-wrap:wrap; align-items:stretch; gap:12px; margin-bottom:26px;}
.hero, .kpi{
  background:var(--surface); border:1px solid var(--rule); border-radius:4px;
  text-decoration:none; color:var(--ink);
}
.hero{display:flex; flex-direction:column; justify-content:center; padding:14px 24px 16px; min-width:220px;}
.hero b{font-size:52px; font-weight:600; line-height:1; letter-spacing:-.02em; color:var(--ink);}
.hero span{margin-top:8px; font-size:12px; color:var(--muted);}
.kpis{display:grid; grid-template-columns:repeat(4, minmax(150px, 1fr)); gap:12px; flex:1 1 640px;}
.kpi{display:flex; flex-direction:column; justify-content:center; gap:4px; padding:12px 16px;}
.kpi b{font-size:26px; font-weight:600; line-height:1.1; letter-spacing:-.015em; color:var(--ink);}
.klab{display:flex; align-items:center; gap:7px; font-size:12px; color:var(--ink-2);}
.kof{font-size:11px; color:var(--muted);}
.hero:hover, .kpi:hover{border-color:var(--rule-2);}
.hero:focus-visible, .kpi:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
@media (max-width:900px){ .kpis{grid-template-columns:repeat(2, minmax(0, 1fr));} }

/* groups and cards */
.dgroup{margin-bottom:26px;}
.dgroup > h2{
  margin:0 0 10px; font-size:11px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted);
}
.dgrid{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px;}
@media (max-width:1000px){ .dgrid{grid-template-columns:minmax(0, 1fr);} }
.dcard{
  position:relative; min-width:0; background:var(--surface);
  border:1px solid var(--rule); border-radius:4px; padding:14px 18px 16px;
}
.dhead{display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:14px;}
.dhead h3{margin:0; font-size:14px; font-weight:600; color:var(--ink);}
.dsub{margin:3px 0 0; font-size:12px; line-height:1.4; color:var(--muted);}
.dtog{
  flex:none; background:none; border:1px solid var(--rule); border-radius:3px;
  padding:4px 10px; font:inherit; font-size:11.5px; color:var(--ink-2); cursor:pointer;
}
.dtog:hover{border-color:var(--rule-2); color:var(--ink);}
.dtog[aria-pressed="true"]{background:var(--surface-3);}
.dnote{margin:12px 0 0; font-size:12px; color:var(--muted);}
.dnote a{color:var(--accent);}

/* fills: the bands keep the status colours the rest of the app gives them */
.b-n{background:var(--stripe-red);}
.b-p{background:var(--stripe-amber);}
.b-c{background:var(--stripe-blue);}
.b-o{background:var(--stripe-ok);}
.f-one{background:var(--accent);}
.f-rest{background:var(--d-rest);}

/* part-to-whole: a 2px surface gap between segments, not a stroke round each */
.stack{display:flex; gap:2px; height:22px; margin:4px 0 14px; background:var(--surface);}
.stack .seg{display:block; flex-basis:0; min-width:3px; text-decoration:none;}
.stack .seg:first-child{border-radius:4px 0 0 4px;}
.stack .seg:last-child{border-radius:0 4px 4px 0;}
.stack .seg.hot, .stack .seg:focus-visible{filter:brightness(1.12); outline:none;}

/* legend: the name and the number in text colours, the colour on a swatch */
.legend{display:flex; flex-wrap:wrap; gap:6px 18px;}
.legend .lg{display:inline-flex; align-items:baseline; gap:6px; font-size:12px; color:var(--ink-2); text-decoration:none;}
a.lg:hover .ln{color:var(--ink); text-decoration:underline;}
.legend .sw, .klab .sw{display:inline-block; width:10px; height:10px; border-radius:2px; flex:none; align-self:center;}
.legend b{font-weight:600; color:var(--ink); font-variant-numeric:tabular-nums;}
.legend .lp{font-size:11px; color:var(--muted);}

/* horizontal bars: <=24px thick (14), 4px rounded at the data end, square at
   the baseline, the value at the tip.  The whole row is the hover target. */
.hbars{display:flex; flex-direction:column; gap:2px;}
.hbar{
  display:grid; grid-template-columns:minmax(0, 13rem) minmax(0, 1fr); align-items:center;
  gap:12px; min-height:28px; padding:0 6px; margin:0 -6px; border-radius:3px;
  text-decoration:none; color:var(--ink-2);
}
a.hbar:hover, .hbar.hot, .hbar:focus-visible{background:var(--surface-3); color:var(--ink); outline:none;}
.hname{font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.hbar.rest .hname{color:var(--muted);}
.htrack{display:flex; align-items:center; gap:8px; min-width:0;}
.hfill{display:block; flex:none; height:14px; border-radius:0 4px 4px 0;}
.hbar.hot .hfill{filter:brightness(1.1);}
.hval{font-size:12px; color:var(--ink); font-variant-numeric:tabular-nums; white-space:nowrap;}

/* columns: the plot height is fixed and the labels sit below it, so the card
   grows to fit them rather than scrolling inside itself */
.cols{display:flex; align-items:flex-end; gap:8px; margin:6px 0 14px;}
.col{flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; border-radius:3px; outline:none;}
.col .plot{
  height:170px; width:100%; display:flex; flex-direction:column;
  justify-content:flex-end; align-items:center; border-bottom:1px solid var(--rule);
}
.cval{margin-bottom:4px; font-size:11.5px; color:var(--ink); font-variant-numeric:tabular-nums; white-space:nowrap;}
.cbar{display:block; width:min(24px, 70%); border-radius:4px 4px 0 0;}
.clab{margin-top:6px; font-size:11.5px; color:var(--muted); white-space:nowrap;}
.col.hot .cbar, .col:focus-visible .cbar{filter:brightness(1.12);}
.col:focus-visible .clab{color:var(--ink);}

/* readout: inverted, so it reads in either theme */
.dtip{
  position:absolute; z-index:5; pointer-events:none; white-space:nowrap;
  background:var(--ink); color:var(--surface); border-radius:3px;
  padding:6px 9px 7px; font-size:12px; line-height:1.3; box-shadow:var(--shadow);
}
.dtip[hidden]{display:none;}
.dtip b{display:block; font-weight:600; font-variant-numeric:tabular-nums;}
.dtip span{display:block; font-size:11.5px; opacity:.78;}

/* table twin.  The app's global table rules are for the 1,500px-wide data
   tables - sticky teal headers, fixed row heights - and all of it has to be
   undone here or a six-row table renders as a spreadsheet. */
.dcard table.dtable{min-width:0; width:100%; border-collapse:collapse;}
.dcard .dtable thead th{
  position:static; height:auto; background:none; color:var(--muted); cursor:default;
  border:none; border-bottom:1px solid var(--rule); padding:6px 8px;
  font-size:11px; letter-spacing:.06em; text-align:left;
}
.dcard .dtable td{
  height:auto; background:none; border:none; border-bottom:1px solid var(--rule);
  padding:6px 8px; font-size:12.5px; color:var(--ink-2); white-space:normal;
  max-width:none; overflow:visible; text-overflow:clip;
}
.dcard .dtable tr:hover td{background:none;}
/* The data tables' rows open a drawer, so they carry a pointer.  These rows open
   nothing, and a pointer on them promises a click that does nothing. */
.dcard .dtable tbody tr{cursor:default;}
.dcard .dtable .num{text-align:right; font-variant-numeric:tabular-nums;}

/* ------------------------------------------------------------- export ---
   The tick column, the button beside the filters, and the dialog.  All three
   are drawn by export.js, so a page that turns the export on gets them without
   any markup of its own - the same arrangement the filter counts use. */
th.pick, td.pick{
  width:32px; min-width:32px; max-width:32px; padding:0; text-align:center;
}
thead th.pick{cursor:pointer;}
th.pick input, td.pick input{
  width:13px; height:13px; margin:0; vertical-align:middle; cursor:pointer;
  accent-color:var(--accent);
}
/* On the header the boxes sit on the accent bar, where the accent fill would
   disappear into the background. */
thead th.pick input{accent-color:var(--surface);}

.xbtn{
  background:var(--accent-soft); border:1px solid transparent; border-radius:3px;
  padding:7px 11px; font:inherit; font-size:12.5px; font-weight:600;
  color:var(--accent); cursor:pointer;
}
.xbtn:hover{border-color:var(--accent);}
.xchip{
  display:inline-flex; align-items:center; gap:7px; font-size:12px; color:var(--ink-2);
  background:var(--surface-2); border:1px solid var(--rule); border-radius:3px;
  padding:6px 9px; white-space:nowrap;
}
.xchip b{font-family:"IBM Plex Mono",monospace; color:var(--ink);}
.xchip button{
  background:none; border:none; padding:0; font:inherit; font-size:11.5px;
  color:var(--muted); text-decoration:underline; cursor:pointer;
}
.xchip button:hover{color:var(--ink);}

.xsheet{width:min(880px,100%);}
.xgrid{
  display:grid; grid-template-columns:minmax(0,270px) minmax(0,1fr); gap:20px;
}
@media (max-width:760px){.xgrid{grid-template-columns:minmax(0,1fr);}}
.xgrid h3{
  margin:0 0 8px; font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:600; display:flex; align-items:center; gap:8px;
}
.xacts{margin-left:auto; display:flex; gap:4px;}
.xacts button{
  background:none; border:1px solid var(--rule); border-radius:3px; padding:2px 7px;
  font:inherit; font-size:10px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--muted); cursor:pointer;
}
.xacts button:hover{color:var(--ink); border-color:var(--rule-2);}
.xopt{
  display:flex; gap:9px; align-items:flex-start; padding:9px 11px; margin-bottom:7px;
  border:1px solid var(--rule); border-radius:4px; cursor:pointer;
  font-size:12.5px; color:var(--ink);
}
.xopt:hover{border-color:var(--rule-2);}
.xopt input{margin:2px 0 0; accent-color:var(--accent);}
.xopt small{display:block; color:var(--muted); font-size:11px; margin-top:2px;}
.xopt:has(input:checked){border-color:var(--accent); background:var(--accent-soft);}
.xlist{
  max-height:44vh; overflow:auto; border:1px solid var(--rule); border-radius:4px;
  padding:6px 4px; display:grid; align-content:start; gap:1px 8px;
  grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
}
.xgroup{
  grid-column:1/-1; padding:9px 8px 4px; font-size:10px; letter-spacing:.07em;
  text-transform:uppercase; color:var(--muted);
}
.xgroup:first-child{padding-top:2px;}
.xf{
  display:flex; gap:8px; align-items:center; padding:4px 8px; border-radius:3px;
  font-size:12.5px; color:var(--ink-2); cursor:pointer; min-width:0;
}
.xf span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.xf:hover{background:var(--surface-3); color:var(--ink);}
.xf input{accent-color:var(--accent); flex:none;}

/* ------------------------------------------- add and correct a customer ---
   The form is drawn by customer.js and shared by Add and Edit; the remove
   button belongs to the address list in the drawer, which edits one address at
   a time because that is how somebody fixes a wrong number. */
.csub{
  margin:18px 0 10px; font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:600;
}
.em{position:relative; padding-right:26px;}
.em .rm{
  position:absolute; right:0; top:5px; width:20px; height:20px; line-height:1;
  background:none; border:1px solid var(--rule); border-radius:3px;
  color:var(--muted); font-size:13px; cursor:pointer;
}
.em .rm:hover{border-color:var(--stripe-red); color:var(--stripe-red);}
.em .rm:disabled{opacity:.4; cursor:not-allowed;}
.em .mail.h{color:var(--muted); font-style:italic;}
.em{padding-right:52px;}
.em .ed{
  position:absolute; right:26px; top:5px; width:20px; height:20px; line-height:1;
  background:none; border:1px solid var(--rule); border-radius:3px;
  color:var(--muted); font-size:12px; cursor:pointer;
}
.em .ed:hover{border-color:var(--accent); color:var(--accent);}
.em .nm{display:block; font-size:12.5px; color:var(--ink); margin-bottom:1px;}
.em .addradd{margin-top:2px;}

/* ?account= on the Units page: which customer, and the way back to all. */
.acctonly{font-size:12px; color:var(--ink-2); margin-right:10px; white-space:nowrap;}
.acctonly a{color:var(--accent);}
