/* P.A.T.S. — design tokens ported from the WebTech / MarkerVision console
   so the two systems read as one family. No animations in the shell. */
:root{
  --sw:236px;--sc:64px;
  --sbg:#0f172a;--shv:#1e293b;--sac:#334155;--stx:#94a3b8;
  --acc:#3b82f6;--acc2:#8b5cf6;--acc3:#06b6d4;
  --bg:#eef2f7;--card:#ffffff;--ink:#1e293b;--ink2:#475569;--muted:#94a3b8;
  --line:#e2e8f0;--line2:#f1f5f9;--head:#f8fafc;--topbar:#ffffff;
  --shadow:0 1px 4px rgba(15,23,42,.07);--shadow-lg:0 10px 26px rgba(15,23,42,.12);
  --glow:rgba(59,130,246,.18);
  --ok:#16a34a;--warn:#ca8a04;--bad:#dc2626;
}
html[data-theme=dark]{
  --sbg:#080c17;--shv:#141c30;--sac:#243149;--stx:#8091ab;
  --bg:#0a0f1c;--card:#121a2e;--ink:#e8eefc;--ink2:#b6c2da;--muted:#6b7a97;
  --line:#22304d;--line2:#1a2338;--head:#161f36;--topbar:#0e1424;
  --shadow:0 1px 4px rgba(0,0,0,.5);--shadow-lg:0 12px 28px rgba(0,0,0,.5);
  --glow:rgba(99,102,241,.25);
  --ok:#4ade80;--warn:#fbbf24;--bad:#fb7185;
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
     background:var(--bg);color:var(--ink);overflow-x:hidden}
a{text-decoration:none;color:var(--acc)}
.hidden{display:none!important}
.muted{color:var(--muted)}
.mono{font-family:'Cascadia Mono',Consolas,'Courier New',monospace}

/* ===== Sidebar ===== */
.sidebar{position:fixed;top:0;left:0;width:var(--sw);height:100vh;background:var(--sbg);
  color:var(--stx);display:flex;flex-direction:column;z-index:1040;overflow-x:hidden;overflow-y:auto}
.sidebar.collapsed{width:var(--sc)}
.sidebar.collapsed .sb-brand-text,.sidebar.collapsed .sb-section,
.sidebar.collapsed .sb-link span:last-child,.sidebar.collapsed .sb-status-card{display:none}
.sb-brand{display:flex;align-items:center;gap:12px;padding:18px 16px;
  border-bottom:1px solid rgba(148,163,184,.12);min-height:68px}
.sb-brand-icon{width:34px;height:34px;min-width:34px;background:linear-gradient(135deg,#3b82f6,#8b5cf6);
  border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff}
.sb-brand-text h5{margin:0;font-size:15px;font-weight:800;color:#fff;letter-spacing:.02em}
.sb-brand-text small{font-size:11px;color:#64748b}
.sb-section{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.09em;
  color:#64748b;padding:14px 18px 6px}
.sb-link{display:flex;align-items:center;gap:11px;padding:9px 18px;color:var(--stx);
  font-size:13.5px;font-weight:500;margin:2px 8px;border-radius:10px;position:relative;
  cursor:pointer;border:0;background:0;width:calc(100% - 16px);text-align:left;font-family:inherit}
.sb-link:hover{color:#fff;background:var(--shv)}
.sb-link.active{color:#fff;background:linear-gradient(100deg,var(--sac),rgba(59,130,246,.16))}
.sb-link.active::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:3px;height:22px;background:linear-gradient(var(--acc),var(--acc2));border-radius:0 3px 3px 0}
.sb-link .ic{display:flex;align-items:center;justify-content:center;min-width:22px}
.sb-link .cnt{margin-left:auto;background:var(--bad);color:#fff;border-radius:9px;
  padding:0 6px;font-size:10.5px;font-weight:800}
.sb-status-card{margin:6px 10px 14px;padding:12px;background:var(--shv);border-radius:12px;
  border:1px solid rgba(148,163,184,.16)}
.sb-status-card .mc-label{font-size:10px;font-weight:700;text-transform:uppercase;
  letter-spacing:.06em;color:#64748b;margin-bottom:8px}
.sb-status-card .mc-name{font-size:12.5px;font-weight:600;color:#e2e8f0;display:flex;
  align-items:center;gap:8px}
.dot-green{width:8px;height:8px;border-radius:50%;background:#22c55e;display:inline-block;flex:none}
.dot-red{width:8px;height:8px;border-radius:50%;background:#ef4444;display:inline-block;flex:none}
.dot-amber{width:8px;height:8px;border-radius:50%;background:#f59e0b;display:inline-block;flex:none}

/* ===== Main / topbar ===== */
.main{margin-left:var(--sw);min-height:100vh;display:flex;flex-direction:column;position:relative;z-index:1}
.sidebar.collapsed~.main{margin-left:var(--sc)}
.topbar{background:var(--topbar);border-bottom:1px solid var(--line);padding:11px 24px;
  display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:1020;gap:14px}
.topbar-heading h4{margin:0;font-size:18px;font-weight:800;color:var(--ink);letter-spacing:-.02em}
.topbar-heading p{margin:0;font-size:12px;color:var(--muted)}
.page-body{flex:1;padding:22px}
.main-footer{background:var(--card);border-top:1px solid var(--line);padding:14px 24px;
  text-align:center;font-size:12px;color:var(--muted)}

/* ===== Cards ===== */
.card{background:var(--card);border-radius:16px;box-shadow:var(--shadow);border:1px solid var(--line);
  margin-bottom:20px;overflow:hidden}
.card-header-mv{padding:16px 20px;border-bottom:1px solid var(--line2);display:flex;
  justify-content:space-between;align-items:center;gap:12px}
.card-header-mv h3{font-size:14.5px;font-weight:800;color:var(--ink);margin:0;letter-spacing:-.01em}
.card-header-mv p{font-size:12px;color:var(--muted);margin:2px 0 0}
.card-body-mv{padding:18px 20px}

.verdict-banner{border-radius:16px;padding:16px 20px;display:flex;align-items:center;gap:14px;margin-bottom:18px}
.verdict-banner.warning{background:#fef9c3;border-left:5px solid #f59e0b;color:#854d0e}
.verdict-banner.fail{background:#fee2e2;border-left:5px solid #ef4444;color:#991b1b}
html[data-theme=dark] .verdict-banner.warning{background:#2c2408;color:#fbbf24}
html[data-theme=dark] .verdict-banner.fail{background:#331014;color:#fca5a5}
.verdict-label{font-size:1.02rem;font-weight:800;letter-spacing:-.01em}
.verdict-msg{font-size:12.5px;margin-top:2px;opacity:.9}

.meta-chip{display:inline-flex;align-items:center;gap:6px;background:var(--line2);
  border:1px solid var(--line);border-radius:20px;padding:4px 12px;font-size:12px;
  font-weight:500;color:var(--ink2);margin:3px 4px 3px 0}
.meta-chip svg{color:var(--acc)}
.badge-mv{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:20px;
  font-size:11px;font-weight:700}
.badge-pass{background:#dcfce7;color:#166534}.badge-fail{background:#fee2e2;color:#991b1b}
.badge-warning{background:#fef9c3;color:#854d0e}.badge-pending{background:#e0e7ff;color:#3730a3}
.badge-muted{background:var(--line2);color:var(--muted)}
html[data-theme=dark] .badge-pass{background:#0f3323;color:#4ade80}
html[data-theme=dark] .badge-fail{background:#3a1220;color:#fb7185}
html[data-theme=dark] .badge-warning{background:#2a2207;color:#fbbf24}
html[data-theme=dark] .badge-pending{background:#1c1740;color:#a5b4fc}

/* ===== Stat cards ===== */
.stat-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;margin-bottom:20px}
.stat-card{background:var(--card);border-radius:16px;padding:16px 18px;box-shadow:var(--shadow);
  border:1px solid var(--line);display:flex;align-items:center;gap:14px}
.stat-icon{width:44px;height:44px;border-radius:13px;display:flex;align-items:center;
  justify-content:center;flex-shrink:0}
.stat-value{font-size:1.5rem;font-weight:800;line-height:1.1;letter-spacing:-.02em}
.stat-label{font-size:11px;color:var(--muted);margin-top:2px}

/* ===== Tables ===== */
.results-table{width:100%;border-collapse:collapse;font-size:13px}
.results-table thead th{background:var(--head);padding:9px 13px;text-align:left;font-weight:700;
  color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.3px;
  border-bottom:2px solid var(--line)}
.results-table tbody tr{border-bottom:1px solid var(--line2)}
.results-table tbody tr:hover{background:var(--head)}
.results-table tbody td{padding:9px 13px;color:var(--ink2);vertical-align:middle}
.results-table tbody tr.clickable{cursor:pointer}

/* ===== Forms ===== */
label.fl{font-size:13px;font-weight:600;color:var(--ink2);display:block;margin-bottom:5px}
.form-control-mv{width:100%;padding:9px 12px;border:1px solid var(--line);border-radius:10px;
  font-size:13px;background:var(--card);color:var(--ink);font-family:inherit}
textarea.form-control-mv{resize:vertical;min-height:70px}
select.form-control-mv{cursor:pointer}
.form-control-mv:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--glow)}
.field{margin-bottom:14px}

/* ===== Buttons ===== */
.btn-primary-mv{padding:9px 18px;background:linear-gradient(135deg,var(--acc),#4f46e5);color:#fff;
  border:none;border-radius:11px;font-size:13px;font-weight:700;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;font-family:inherit}
.btn-primary-mv:hover{filter:brightness(1.06)}
.btn-outline-mv{padding:9px 15px;background:var(--card);color:var(--ink2);border:1px solid var(--line);
  border-radius:11px;font-size:13px;font-weight:600;cursor:pointer;display:inline-flex;
  align-items:center;gap:7px;font-family:inherit}
.btn-outline-mv:hover{background:var(--line2);color:var(--ink);border-color:var(--acc)}
.btn-danger-mv{padding:8px 14px;background:#fee2e2;color:#b91c1c;border:1px solid #fecaca;
  border-radius:11px;font-size:12.5px;font-weight:700;cursor:pointer;font-family:inherit}
html[data-theme=dark] .btn-danger-mv{background:#3a1220;color:#fb7185;border-color:#4a1524}
.btn-sm{padding:5px 10px;font-size:12px;border-radius:9px}

/* ===== Alerts ===== */
.alert-mv{padding:12px 16px;border-radius:12px;font-size:13px;margin-bottom:14px;
  display:flex;align-items:center;gap:10px}
.alert-error{background:#fee2e2;color:#991b1b;border:1px solid #fecaca}
.alert-info{background:#dbeafe;color:#1e40af;border:1px solid #bfdbfe}
html[data-theme=dark] .alert-error{background:#3a1220;color:#fca5a5;border-color:#4a1524}
html[data-theme=dark] .alert-info{background:#0f2544;color:#93c5fd;border-color:#1e3a5f}

.network-chip{display:inline-flex;align-items:center;gap:8px;background:var(--sbg);color:#e2e8f0;
  border-radius:10px;padding:6px 12px;font-size:12px;font-family:monospace}
.network-chip svg{color:#60a5fa}
.user-chip{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink2);font-weight:700}
.user-chip svg{color:var(--muted)}

/* ===== Location board ===== */
.board{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:16px}
.loc-card{background:var(--card);border:1px solid var(--line);border-radius:16px;
  box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column}
.loc-head{padding:12px 16px;border-bottom:1px solid var(--line2);display:flex;
  align-items:center;justify-content:space-between;gap:8px;background:var(--head)}
.loc-head h3{font-size:13px;font-weight:800;color:var(--ink);display:flex;align-items:center;gap:8px}
.loc-head h3 svg{color:var(--acc)}
.loc-head .cnt{font-size:11px;font-weight:700;color:var(--muted);background:var(--card);
  border:1px solid var(--line);border-radius:20px;padding:2px 9px}

.mach{display:flex;gap:12px;padding:12px 16px;border-top:1px solid var(--line2);cursor:pointer;align-items:flex-start}
.mach:first-of-type{border-top:0}
.mach:hover{background:var(--head)}
.thumb{width:74px;height:56px;border-radius:10px;background:var(--line2);border:1px solid var(--line);
  flex:none;overflow:hidden;display:flex;align-items:center;justify-content:center}
.thumb img,.thumb svg{width:100%;height:100%;object-fit:cover;display:block}
.thumb.art svg,.thumb.art img{object-fit:contain;padding:2px}
.mach-body{flex:1;min-width:0}
.mach-title{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.mach-tag{font-size:14.5px;font-weight:800;color:var(--ink);letter-spacing:-.01em}
.mach-model{font-size:11.5px;color:var(--muted);margin-top:1px}
.att-list{margin-top:6px;display:flex;flex-wrap:wrap;gap:4px}
.att-pill{font-size:10.5px;font-weight:600;background:var(--line2);border:1px solid var(--line);
  color:var(--ink2);border-radius:20px;padding:2px 8px}
.att-none{font-size:11px;color:var(--muted);font-style:italic;margin-top:6px}

/* ===== Asset detail ===== */
.hero{display:flex;gap:18px;align-items:flex-start;flex-wrap:wrap}
.hero-img{width:210px;height:158px;border-radius:14px;background:var(--line2);
  border:1px solid var(--line);overflow:hidden;flex:none;display:flex;align-items:center;justify-content:center}
.hero-img img{width:100%;height:100%;object-fit:cover}
.hero-img svg{width:100%;height:100%;object-fit:contain;padding:6px}
.photo-strip{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.photo-thumb{width:72px;height:54px;border-radius:8px;overflow:hidden;border:1px solid var(--line);
  position:relative;cursor:pointer}
.photo-thumb img{width:100%;height:100%;object-fit:cover}
.photo-thumb.is-primary{outline:2px solid var(--acc);outline-offset:1px}
/* the photo you are about to make main or remove, shown at a size you can
   actually recognise it at */
.photo-big{border-radius:12px;overflow:hidden;border:1px solid var(--line);background:var(--head)}
.photo-big img{display:block;width:100%;max-height:44vh;object-fit:contain}

dl.kv{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;margin:0;font-size:12.5px}
dl.kv dt{color:var(--muted);white-space:nowrap;font-weight:600}
dl.kv dd{margin:0;word-break:break-word;color:var(--ink2)}

/* ===== Modal ===== */
.modal{position:fixed;inset:0;background:rgba(6,12,18,.6);display:flex;align-items:flex-start;
  justify-content:center;padding:2.5rem 1rem;z-index:1500;overflow:auto}
.modal-box{background:var(--bg);border-radius:18px;max-width:1000px;width:100%;
  box-shadow:var(--shadow-lg);position:relative}
.modal-head{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
  padding:18px 22px;border-bottom:1px solid var(--line);background:var(--card);
  border-radius:18px 18px 0 0}
.modal-head h2{font-size:17px;font-weight:800;letter-spacing:-.02em}
.modal-body{padding:20px 22px}
.modal-x{background:0;border:0;color:var(--muted);cursor:pointer;padding:4px;line-height:0}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.grid-auto{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px}

.loading{padding:3rem;text-align:center;color:var(--muted)}

/* A screen being built. In the document so getElementById works while it is
   drawn, invisible so nothing is seen until it is finished. visibility rather
   than display:none, because a hidden-by-display element has no layout and
   anything measuring itself as it renders would read zero. */
.view-staging{visibility:hidden;position:absolute;left:0;right:0;top:0}

/* Shown only if the wait is long enough to notice - see the timer in go(). */
.view-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;padding:4rem 1rem;color:var(--muted)}
.view-loading-label{font-size:13px;font-weight:600;letter-spacing:.02em}
.spinner{width:34px;height:34px;border-radius:50%;
  border:3px solid var(--line,#e2e8f0);border-top-color:var(--acc3,#4f46e5);
  animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){
  .spinner{animation-duration:2s}
}

/* The end-of-term handover prompt. Only drawn in the final week of a quarter -
   nothing on this system sends mail by itself, and on a shared host nothing
   could, so the honest thing is to ask at the right moment rather than to
   promise a send that would never happen. */
.handover-due{display:flex;align-items:center;gap:16px;margin-bottom:1.1rem;
  padding:16px 18px;border-radius:14px;
  border:1px solid var(--acc3,#4f46e5);
  background:color-mix(in srgb, var(--acc3,#4f46e5) 8%, transparent)}
.handover-due .hd-icon{flex:none;width:42px;height:42px;border-radius:12px;
  display:flex;align-items:center;justify-content:center;color:#fff;
  background:var(--acc3,#4f46e5)}
.handover-due .hd-main{flex:1;min-width:0}
.handover-due h3{font-size:15px;color:var(--ink);margin-bottom:3px}
.handover-due p{font-size:13px;line-height:1.55;color:var(--muted)}
.handover-due button{flex:none}
@media(max-width:640px){
  .handover-due{flex-direction:column;align-items:flex-start}
  .handover-due button{width:100%}
}

/* A screen that failed to load. It used to be an eternal "Loading…". */
.view-error{max-width:520px;margin:3rem auto;padding:1.6rem 1.8rem;text-align:center;
  border:1px solid var(--line,#e2e8f0);border-radius:16px;background:var(--card,#fff)}
.view-error h3{display:flex;align-items:center;justify-content:center;gap:9px;
  font-size:16px;color:var(--ink);margin-bottom:.7rem}
.view-error h3 svg{color:#f59e0b}
.view-error p{font-size:13.5px;line-height:1.6;margin-bottom:.6rem}
.view-error .muted{color:var(--muted);font-size:12.5px}
.view-error button{margin-top:.9rem}

@media(max-width:900px){
  .sidebar{transform:translateX(-100%);width:var(--sw)!important}
  .sidebar.open{transform:none}
  .main{margin-left:0!important}
  .grid-2{grid-template-columns:1fr}
}

/* ===== filter bar ===== */
.filters{display:flex;gap:9px;flex-wrap:wrap;align-items:flex-end}
.filters .fgroup{display:flex;flex-direction:column;gap:3px}
.filters .fgroup label{font-size:10.5px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted)}
.filters select,.filters input{min-width:130px}
.chipbar{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.fchip{font-size:11.5px;font-weight:600;background:var(--info-bg);color:var(--info);
  border:1px solid var(--line);border-radius:20px;padding:3px 10px;cursor:pointer}
.fchip:hover{filter:brightness(.97)}
.fchip .x{margin-left:5px;opacity:.6;font-weight:800}

/* ===== overflow containment =================================================
   Grid and flex items default to min-width:auto, so a wide table refuses to
   shrink; combined with .card{overflow:hidden} the surplus is silently CLIPPED
   rather than spilling, which is why C5B's attached-items column vanished off
   the right edge. Let items shrink, and let genuinely wide tables scroll. */
.grid-auto > *, .grid-2 > *, .hero > *, .board > *{min-width:0}
.table-wrap{overflow-x:auto;max-width:100%}
.results-table td, .results-table th{overflow-wrap:anywhere}
.results-table td.nowrap{white-space:nowrap;overflow-wrap:normal}
dl.kv dd{overflow-wrap:anywhere}

/* ===== unified detail panels ===== */
.panel{background:var(--card);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;display:flex;flex-direction:column}
.panel-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 14px;border-bottom:1px solid var(--line2);background:var(--head)}
.panel-head h4{font-size:12.5px;font-weight:800;color:var(--ink);letter-spacing:-.01em;
  display:flex;align-items:center;gap:7px;margin:0}
.panel-head h4 svg{color:var(--acc)}
.panel-head .n{font-size:10.5px;font-weight:700;color:var(--muted);background:var(--card);
  border:1px solid var(--line);border-radius:20px;padding:1px 8px}
.panel-body{padding:12px 14px;flex:1}
.panel-body.tight{padding:0}
.panel-empty{padding:16px 14px;text-align:center;color:var(--muted);font-size:12px}
.panel-empty p{margin:0 0 10px;line-height:1.5}

/* the buttons at the end of a row - Edit / Delete on a section */
.item-acts{display:flex;gap:5px;flex:none}

/* segmented control — makes the list/calendar choice obvious rather than
   two buttons that look like unrelated actions */
.seg{display:inline-flex;border:1px solid var(--line);border-radius:11px;overflow:hidden;
  background:var(--card)}
.seg button{border:0;background:transparent;color:var(--ink2);font:inherit;font-size:12.5px;
  font-weight:700;padding:8px 14px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.seg button + button{border-left:1px solid var(--line)}
.seg button:hover{background:var(--line2)}
.seg button.on{background:linear-gradient(135deg,var(--acc),#4f46e5);color:#fff}
#bulkTable input[type=date]{min-width:130px}

/* ===== walk-round ===== */
.round-bar{height:4px;background:var(--line2)}
.round-bar>div{height:100%;background:linear-gradient(90deg,var(--acc),var(--acc2));
  transition:width .25s ease}

/* ===== undo toast ===== */
.toast{position:fixed;left:50%;bottom:-90px;transform:translateX(-50%);z-index:3000;
  display:flex;align-items:center;gap:11px;background:var(--sbg);color:#e2e8f0;
  padding:11px 14px;border-radius:12px;box-shadow:0 12px 30px rgba(0,0,0,.4);
  font-size:12.5px;transition:bottom .22s ease;max-width:92vw}
.toast.show{bottom:22px}
.toast button{background:rgba(255,255,255,.14);border:0;color:#fff;font:inherit;
  font-weight:700;border-radius:8px;padding:5px 12px;cursor:pointer}
.toast button:hover{background:rgba(255,255,255,.24)}
.toast button.x{background:0;padding:4px 6px;opacity:.6}

/* ===== command palette ===== */
.palette{position:fixed;inset:0;background:rgba(6,12,18,.55);z-index:3500;
  display:none;align-items:flex-start;justify-content:center;padding:12vh 1rem}
.palette.show{display:flex}
.palette-box{background:var(--card);border:1px solid var(--line);border-radius:16px;
  width:640px;max-width:96vw;box-shadow:var(--shadow-lg);overflow:hidden}
.palette-input{display:flex;align-items:center;gap:10px;padding:14px 16px;
  border-bottom:1px solid var(--line);color:var(--muted)}
.palette-input input{border:0;background:0;flex:1;font:inherit;font-size:15px;
  color:var(--ink);outline:none;padding:0}
.palette-input kbd{font-size:10px;border:1px solid var(--line);border-radius:5px;
  padding:2px 6px;color:var(--muted)}
.palette-results{max-height:52vh;overflow-y:auto}
.palette-row{display:flex;align-items:center;gap:10px;padding:9px 16px;cursor:pointer;
  border-top:1px solid var(--line2)}
.palette-row.sel,.palette-row:hover{background:var(--info-bg)}
.palette-row .pk{font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);background:var(--line2);border-radius:20px;padding:2px 7px;flex:none;width:64px;
  text-align:center}
.palette-row .pt{font-weight:800;color:var(--ink);flex:none;min-width:64px}
.palette-row .ps{color:var(--muted);font-size:12px;flex:1;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.palette-row .pe{color:var(--muted);font-size:11px;flex:none}
.palette-hint{padding:22px 16px;text-align:center;color:var(--muted);font-size:12.5px}

.due{font-size:10px;font-weight:700;color:var(--muted);background:var(--line2);
  border-radius:20px;padding:1px 7px}
.due.soon{background:#fef9c3;color:#854d0e}
.due.over{background:#fee2e2;color:#991b1b}
html[data-theme=dark] .due.soon{background:#2a2207;color:#fbbf24}
html[data-theme=dark] .due.over{background:#3a1220;color:#fb7185}
.vchip{font-size:10.5px;font-weight:700;border-radius:20px;padding:3px 9px;flex:none}
.vchip.fuji{background:#dbeafe;color:#1e40af}
.vchip.canon{background:#dcfce7;color:#166534}
.vchip.siemens{background:#ede9fe;color:#5b21b6}
.vchip.other{background:var(--line2);color:var(--muted)}
html[data-theme=dark] .vchip.fuji{background:#132a4a;color:#93c5fd}
html[data-theme=dark] .vchip.canon{background:#0f3323;color:#86efac}
html[data-theme=dark] .vchip.siemens{background:#241a45;color:#c4b5fd}
.ok-tick{color:var(--ok);display:inline-flex}

/* ===== Keeper — names first ===== */
.keeper-hero{background:linear-gradient(135deg,var(--sbg),#1e293b);color:#fff;
  border-radius:18px;padding:22px 24px;margin-bottom:20px;box-shadow:var(--shadow)}
.kh-period{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;
  color:#94a3b8;margin-bottom:14px}
.kh-period span{letter-spacing:.04em;opacity:.85}
.kh-people{display:flex;gap:34px;align-items:center;flex-wrap:wrap}
.kh-person{display:flex;align-items:center;gap:13px}
.kh-av{width:52px;height:52px;border-radius:15px;flex:none;display:flex;align-items:center;
  justify-content:center;font-size:22px;font-weight:800;color:#fff;
  background:linear-gradient(135deg,var(--acc),var(--acc2))}
.kh-person.alt .kh-av{background:linear-gradient(135deg,#475569,#334155);
  width:44px;height:44px;font-size:18px;border-radius:13px}
.kh-name{font-size:23px;font-weight:800;letter-spacing:-.02em;line-height:1.15}
.kh-person.alt .kh-name{font-size:17px;color:#cbd5e1}
.kh-role{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  color:#94a3b8;margin-top:2px}
.kh-prog{margin-left:auto;min-width:150px}
.kh-count{font-size:26px;font-weight:800;letter-spacing:-.02em}
.kh-count span{font-size:15px;color:#94a3b8;font-weight:700}
.kh-bar{height:5px;border-radius:99px;background:rgba(255,255,255,.16);margin:6px 0 4px}
.kh-bar>div{height:100%;border-radius:99px;background:linear-gradient(90deg,#22c55e,#4ade80);
  transition:width .4s cubic-bezier(.22,1,.36,1)}

.duty{display:flex;gap:14px;align-items:flex-start;padding:12px 20px;
  border-top:1px solid var(--line2)}
.duty:hover{background:var(--head)}
/* A finished duty stays in the list and goes green — the term's record is the
   point, so it must be visibly done rather than gone. */
.duty.done,.duty.done:hover{background:color-mix(in srgb,var(--ok) 10%,transparent)}
.duty-mark{display:flex;flex-direction:column;align-items:flex-start;gap:5px;
  flex:none;min-width:96px}
.duty-main{flex:1;min-width:0}
.duty-title{font-size:13.5px;font-weight:700;color:var(--ink)}
.duty.done .duty-title{color:var(--ink2);text-decoration:line-through}
.duty-detail{font-size:11.5px;color:var(--muted);margin-top:2px}
.duty-by{font-size:10.5px;color:var(--ok);font-weight:700;flex:none;white-space:nowrap}
@media (max-width:640px){.duty{flex-wrap:wrap}.duty-mark{min-width:0}}

/* ---- "done" marks, shared by the keeper duties and the PM completion sheet ---- */
/* Same button as everywhere else, given a fuller tap target: this one gets
   pressed at the machine on a phone, or on a shared ward PC with a stiff
   mouse, and a 26px-high btn-sm is a poor target for the main action. */
.mark-done{white-space:nowrap;padding:8px 15px;font-size:12.5px}

.roster{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;padding:16px 20px}
.rq{border:1px solid var(--line);border-radius:12px;padding:11px 13px;background:var(--card)}
.rq.now{border-color:var(--acc);box-shadow:0 0 0 3px var(--glow)}
.rq-q{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.rq-p{font-size:15px;font-weight:800;color:var(--ink);margin-top:3px}
.rq-s{font-size:11.5px;color:var(--muted)}

/* ===== custom sections ===== */
.sec-row{display:flex;gap:14px;align-items:flex-start;padding:13px 20px;
  border-top:1px solid var(--line2)}
.sec-name{font-size:14px;font-weight:800;color:var(--ink)}
.sec-sub{font-size:11.5px;color:var(--muted);margin-top:1px}
.sec-fields{display:flex;gap:4px;flex-wrap:wrap;margin-top:7px}
.fv-row{display:flex;align-items:center;gap:10px;padding:5px 0;
  border-bottom:1px solid var(--line2);font-size:12.5px}
.fv-row:last-child{border-bottom:0}
.fv-label{color:var(--muted);flex:none;min-width:38%}
.fv-val{flex:1;color:var(--ink2);overflow-wrap:anywhere}
.fv-val.empty{color:var(--muted);font-style:italic}
.fv-tick{flex:none;width:24px;height:24px;border-radius:7px;border:1px solid var(--line);
  background:var(--card);color:var(--muted);cursor:pointer;display:inline-flex;
  align-items:center;justify-content:center;padding:0}
.fv-tick:hover{border-color:var(--ok);color:var(--ok)}
.fv-tick.on{background:var(--ok);border-color:var(--ok);color:#fff}

/* ===== settings tab bar ===== */
.tabbar{display:flex;gap:4px;flex-wrap:wrap;background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:5px;margin-bottom:18px;box-shadow:var(--shadow)}
.tabbar button{border:0;background:transparent;color:var(--ink2);font:inherit;font-size:12.5px;
  font-weight:700;padding:8px 14px;border-radius:10px;cursor:pointer;display:inline-flex;
  align-items:center;gap:7px}
.tabbar button:hover{background:var(--line2);color:var(--ink)}
.tabbar button.on{background:linear-gradient(135deg,var(--acc),#4f46e5);color:#fff}
.tabbar .tb-n{background:var(--bad);color:#fff;border-radius:9px;padding:0 6px;
  font-size:10px;font-weight:800}
.tabbar button.on .tb-n{background:rgba(255,255,255,.25)}
.sb-sep{height:1px;background:rgba(148,163,184,.16);margin:12px 16px 6px}

/* ===== Locations board ===== */
.board-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:16px}
.mach-where{color:var(--acc)}
.att-pill.has{background:var(--line2);border-color:var(--line);color:var(--ink2)}
/* kit items that SHOULD be there but are not — deliberately a different colour
   from the neutral pills used for things that actually are attached */
.att-pill.missing{background:#fee2e2;border-color:#fca5a5;color:#991b1b}
.att-pill.opt{background:#fff4dc;border-color:#fcd34d;color:#854d0e}
html[data-theme=dark] .att-pill.missing{background:#3a1220;border-color:#7f1d1d;color:#fca5a5}
html[data-theme=dark] .att-pill.opt{background:#2c2408;border-color:#78350f;color:#fbbf24}

/* ===== machine record: one panel per row ===== */
.prows{display:flex;flex-direction:column;gap:14px}
.prow{background:var(--card);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.prow-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 16px;background:var(--sbg)}
.prow-head h4{font-size:13px;font-weight:800;color:#fff;display:flex;align-items:center;
  gap:8px;margin:0;letter-spacing:-.01em}
.prow-head h4 svg{color:#8ab4ff}
.prow-head .n{font-size:10.5px;font-weight:800;color:#cbd5e1;background:rgba(255,255,255,.14);
  border-radius:20px;padding:1px 8px}
.prow-acts{display:flex;gap:6px}
.prow-body{padding:14px 16px}

/* header buttons: outlined on the dark heading */
.btn-head{background:transparent;border:1px solid rgba(255,255,255,.35);color:#fff;
  font:inherit;font-size:11.5px;font-weight:700;border-radius:8px;padding:5px 11px;
  cursor:pointer;display:inline-flex;align-items:center;gap:5px}
.btn-head:hover{background:rgba(255,255,255,.16);border-color:#fff}
/* content buttons: filled, a different hue from the header entirely */
.btn-body{background:var(--acc2);border:0;color:#fff;font:inherit;font-size:11.5px;
  font-weight:700;border-radius:8px;padding:6px 12px;cursor:pointer;
  display:inline-flex;align-items:center;gap:5px;margin-right:6px;margin-top:2px}
.btn-body:hover{filter:brightness(1.1)}

.mi{display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start}
.mi-img{width:150px;height:114px;border-radius:12px;background:var(--line2);
  border:1px solid var(--line);overflow:hidden;flex:none;display:flex;
  align-items:center;justify-content:center}
.mi-img img{width:100%;height:100%;object-fit:cover}
.mi-img.art img{object-fit:contain;padding:5px}
.kv.net{grid-template-columns:auto 1fr auto 1fr}
.kitline,.faults{margin-top:12px;padding-top:11px;border-top:1px solid var(--line2)}
.kitline-t{display:block;font-size:10px;font-weight:800;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted);margin-bottom:6px}
.kitline .att-pill{margin:0 4px 4px 0}
.fault-row{display:flex;gap:10px;font-size:12px;padding:3px 0}
.pempty{font-size:12.5px;color:var(--muted);line-height:1.5;margin:0 0 8px}

/* ---- the links graph: holders on the left, this record, what it holds ----
   Drawn by lgSvg() in app.js. Colours are classes, not attributes, so the
   dark theme and the hover state can reach them. The graph keeps its size and
   scrolls sideways inside its panel on a phone rather than shrinking the
   writing to nothing. */
.lg{overflow-x:auto;padding:2px 0 6px}
.lg-svg{display:block;max-width:none;font-family:inherit}
.lg-h{font-size:9.5px;font-weight:800;letter-spacing:.08em;fill:var(--muted)}
.lg-h.me{fill:var(--acc)}
.lg-e{fill:none;stroke:var(--muted);stroke-width:1.5}
.lg-e.dash{stroke-dasharray:5 4}
.lg-node rect{fill:var(--head);stroke:var(--line);stroke-width:1.2;transition:stroke .12s}
.lg-node.holder rect{fill:rgba(59,130,246,.07);stroke:rgba(59,130,246,.5)}
.lg-node.this rect{fill:rgba(59,130,246,.15);stroke:var(--acc);stroke-width:2.5}
.lg-node[role=button]{cursor:pointer;outline:none}
.lg-node[role=button]:hover rect,.lg-node[role=button]:focus-visible rect{stroke:var(--acc);stroke-width:2}
.lg-t{font-size:12.5px;font-weight:800;fill:var(--ink)}
.lg-node.this .lg-t{font-size:13px}
.lg-t.none{fill:var(--warn);font-style:italic}
.lg-n{fill:var(--acc)}
.lg-s{font-size:10.5px;font-weight:600;fill:var(--muted)}
.lg-foot{display:flex;gap:2px;align-items:center;flex-wrap:wrap;margin-top:10px}
.lg-key{margin-left:auto;font-size:11.5px;color:var(--muted);display:flex;align-items:center;
  gap:4px 10px;flex-wrap:wrap}
.lg-key > span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.lg-key i{display:inline-block;width:22px;border-top:1.5px dashed var(--muted)}
.lg-key i.solid{border-top-style:solid}
/* a box's options - on <body>, above the record (the modal is 1500) */
.lg-pop{position:fixed;z-index:1600;background:var(--card);border:1px solid var(--line);
  border-radius:12px;box-shadow:var(--shadow-lg);padding:6px;min-width:220px;max-width:300px;
  display:none}
.lg-pop.on{display:block}
.lg-pop h5{font-size:12.5px;font-weight:800;color:var(--ink);padding:6px 10px 2px;margin:0;
  overflow-wrap:anywhere}
.lg-pop p{font-size:11.5px;color:var(--muted);padding:0 10px 6px;margin:0}
.lg-pop button{display:flex;align-items:center;gap:8px;width:100%;background:0;border:0;
  font:inherit;font-size:12.5px;color:var(--ink2);padding:7px 10px;border-radius:8px;
  cursor:pointer;text-align:left}
.lg-pop button:hover,.lg-pop button:focus-visible{background:var(--line2);color:var(--ink);outline:none}
.lg-pop button.bad{color:var(--bad)}

/* ===== grouped add-asset form ===== */
.fgroup-box{border:1px solid var(--line);border-radius:14px;overflow:hidden;margin-bottom:14px}
.fgroup-head{display:flex;gap:11px;align-items:flex-start;padding:11px 15px;
  background:var(--head);border-bottom:1px solid var(--line2)}
.fgroup-n{width:23px;height:23px;border-radius:8px;flex:none;display:flex;align-items:center;
  justify-content:center;font-size:12px;font-weight:800;color:#fff;
  background:linear-gradient(135deg,var(--acc),#4f46e5)}
.fgroup-head h4{font-size:13px;font-weight:800;color:var(--ink);margin:0;letter-spacing:-.01em}
.fgroup-head p{font-size:11.5px;color:var(--muted);margin:1px 0 0}
.fgroup-body{padding:14px 15px 4px}
.fgroup-body .field:last-child{margin-bottom:10px}

/* ===== inline tag rename on the location card ===== */
.tag-edit{border:0;background:transparent;color:var(--muted);cursor:pointer;padding:2px 3px;
  border-radius:6px;line-height:0;opacity:0;transition:opacity .12s}
.mach:hover .tag-edit{opacity:1}
.tag-edit:hover{background:var(--line2);color:var(--acc)}
.tag-input{width:104px;font:inherit;font-size:14.5px;font-weight:800;color:var(--ink);
  padding:1px 6px;border:1px solid var(--acc);border-radius:7px;background:var(--card);
  box-shadow:0 0 0 3px var(--glow);letter-spacing:-.01em}

/* ==============================================================
   Edge-ribbon collapse control, ported from the AccessPlain /
   RosterHub console: a thin stripe on the sidebar's outer edge
   that widens on hover, with a chevron disc and a tooltip.

   Adapted in one way — .sidebar has overflow-x:hidden for its own
   scrolling, which would CLIP an absolutely-positioned child at
   right:-8px. So the tab is position:fixed and tracks the sidebar
   width instead of living inside it.
   ============================================================== */
#sidebar-collapse-tab{
  position:fixed;top:0;bottom:0;left:var(--sw);width:9px;
  background:transparent;border:0;padding:0;cursor:pointer;z-index:1045;
  display:flex;align-items:center;justify-content:center;
  /* width animates on hover; `left` does NOT, for the same reason the sidebar
     width does not — transitioning it left the tab stranded at the expanded
     position while the sidebar had already snapped narrow. */
  transition:width .18s cubic-bezier(.2,.6,.3,1);
}
body.sb-collapsed #sidebar-collapse-tab{left:var(--sc)}

#sidebar-collapse-tab .sb-cr-grip{
  position:absolute;inset:20% 1px;background:var(--shv);border-radius:0 4px 4px 0;
  transition:background .18s cubic-bezier(.2,.6,.3,1), inset .18s cubic-bezier(.2,.6,.3,1);
}
#sidebar-collapse-tab .sb-cr-chevron{
  position:relative;z-index:2;width:28px;height:28px;border-radius:50%;
  background:var(--sbg);border:2px solid var(--shv);color:var(--stx);
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 8px rgba(0,0,0,.22);
  transition:background .18s cubic-bezier(.2,.6,.3,1),
             border-color .18s cubic-bezier(.2,.6,.3,1),
             color .18s cubic-bezier(.2,.6,.3,1),
             transform .18s cubic-bezier(.2,.6,.3,1);
}
#sidebar-collapse-tab .sb-cr-chevron svg{width:14px;height:14px;transition:transform .2s}
#sidebar-collapse-tab:hover{width:15px}
#sidebar-collapse-tab:hover .sb-cr-grip{background:var(--acc);inset:12% 1px}
#sidebar-collapse-tab:hover .sb-cr-chevron{
  background:var(--acc);border-color:#4f46e5;color:#fff;transform:scale(1.1)}
#sidebar-collapse-tab:active .sb-cr-chevron{transform:scale(.95)}

#sidebar-collapse-tab::after{
  content:attr(data-label-collapse);position:absolute;left:100%;top:50%;
  transform:translateY(-50%) translateX(8px);margin-left:8px;padding:6px 12px;
  background:var(--sbg);color:#fff;font-size:12px;font-weight:600;border-radius:6px;
  white-space:nowrap;opacity:0;pointer-events:none;
  box-shadow:0 4px 14px rgba(0,0,0,.25);
  transition:opacity .18s ease, transform .18s ease;
}
#sidebar-collapse-tab:hover::after{opacity:1;transform:translateY(-50%) translateX(0)}
body.sb-collapsed #sidebar-collapse-tab::after{content:attr(data-label-expand)}
body.sb-collapsed #sidebar-collapse-tab .sb-cr-chevron svg{transform:rotate(180deg)}

/* No width transition on the sidebar. It was an embellishment I added on top
   of the ported design, and animating width here left the panel stuck at its
   expanded size on a real click while the labels correctly hid — a half
   collapsed sidebar. The original console does not animate it either. */
@media(max-width:900px){#sidebar-collapse-tab{display:none}}


/* ===== Locations — building view =====================================
   Drawn the way the workgroup's own hospital diagram draws it: flat blocks
   against a blue sky, planted roofs, a dark slab cap and a white name board,
   with each floor a labelled band down the elevation.

   The only rule underneath the illustration: a floor band exists because
   something is standing on it. Runs of empty storeys fold into a strip of
   glazing whose height grows with the number of floors inside, so an 11-storey
   block still reads 11 storeys tall without costing 11 rows. Nothing here
   knows which floors the workgroup "uses" — the data decides. */
:root{
  --sky1:#8ecbe9;--sky2:#c9e7f6;--sky3:#eaf6fc;--cloud:rgba(255,255,255,.92);
  --leaf:#57a75b;--leaf2:#3f8a45;--slabcap:#5b6b7f;--slabcap2:#46566a;
  --fac:#f4f7fb;--facline:#c6d4e4;--glass:#b9d3ea;--mull:#e8f0f8;
  --core:#5b6b7f;--coreink:#eaf1f8;--podium:#8595a9;--street:#6a7a8e;
  --plate:#ffffff;--plateink:#1d4ed8}
html[data-theme=dark]{
  --sky1:#0b1a2e;--sky2:#0d2138;--sky3:#0a1424;--cloud:rgba(148,180,214,.10);
  --leaf:#2f6b40;--leaf2:#245334;--slabcap:#1c2942;--slabcap2:#151f33;
  --fac:#121a2e;--facline:#25324c;--glass:#f3c96b;--mull:#141d31;
  --core:#1b2740;--coreink:#b6c2da;--podium:#1a2438;--street:#141c2c;
  --plate:#16203a;--plateink:#8ab4ff}

.bl-plan{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:26px;
  align-items:end;padding:26px 22px 0;border-radius:16px;overflow:hidden;
  background:linear-gradient(180deg,var(--sky1) 0%,var(--sky2) 45%,var(--sky3) 100%)}
.bl-plan::before{content:'';position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(42px 19px at 14% 46px,var(--cloud),transparent 72%),
    radial-gradient(30px 14px at 20% 38px,var(--cloud),transparent 72%),
    radial-gradient(50px 21px at 78% 74px,var(--cloud),transparent 72%),
    radial-gradient(34px 15px at 86% 62px,var(--cloud),transparent 72%),
    radial-gradient(26px 12px at 50% 30px,var(--cloud),transparent 72%)}
@media (max-width:1000px){.bl-plan{grid-template-columns:1fr}}

.bl-tower{position:relative;display:flex;flex-direction:column;
  filter:drop-shadow(0 8px 16px rgba(21,45,71,.20))}
html[data-theme=dark] .bl-tower{filter:drop-shadow(0 8px 20px rgba(0,0,0,.55))}

/* planted roof — the green tops on the hospital diagram */
.bl-garden{display:flex;align-items:flex-end;justify-content:center;gap:4px;height:17px;
  padding:0 12px}
.bl-garden i{flex:1;max-width:34px;height:12px;border-radius:9px 9px 0 0;
  background:linear-gradient(180deg,var(--leaf),var(--leaf2))}
.bl-garden i:nth-child(2){height:17px}
.bl-garden i:nth-child(4){height:15px}

/* dark slab cap, with the tank and AC deck every block here has */
.bl-roofslab{position:relative;height:15px;margin:0 -6px;border-radius:4px 4px 0 0;
  background:linear-gradient(180deg,var(--slabcap),var(--slabcap2))}
.bl-roofslab b{position:absolute;bottom:15px;background:var(--slabcap);
  border-radius:3px 3px 0 0}
.bl-tank{left:16%;width:15px;height:13px;border-radius:8px 8px 0 0}
.bl-ac{right:20%;width:30px;height:8px}

/* the building's name board */
.bl-sign{display:flex;align-items:center;gap:11px;padding:11px 14px;background:var(--plate);
  border-left:3px solid var(--slabcap);border-right:3px solid var(--slabcap)}
.bl-badge{font-size:19px;font-weight:900;letter-spacing:.08em;color:var(--plateink);
  background:color-mix(in srgb,var(--plateink) 12%,transparent);
  border-radius:9px;padding:3px 12px;line-height:1.2;flex:none}
.bl-signtext{display:flex;flex-direction:column;min-width:0}
.bl-signtext b{font-size:13px;font-weight:800;color:var(--ink)}
.bl-signtext em{font-style:normal;font-size:11px;color:var(--muted);font-weight:600}

.bl-floors{border-left:3px solid var(--slabcap);border-right:3px solid var(--slabcap);
  overflow:hidden;background:var(--fac)}
.bl-floor{display:grid;grid-template-columns:52px 1fr;border-top:3px solid var(--slabcap)}

/* lift core, carrying the storey numbers up the elevation */
.bl-fnum{display:flex;align-items:center;justify-content:center;color:var(--coreink);
  background:var(--core);font-family:'Cascadia Mono',Consolas,monospace;font-size:12.5px;
  font-weight:800;letter-spacing:.02em;padding:10px 0}
.bl-fbody{padding:9px;display:flex;flex-wrap:wrap;gap:8px;background:var(--fac)}

/* a room reads as a name plate on the facade */
.bl-room{background:var(--plate);border:1px solid var(--facline);border-radius:7px;
  padding:7px 9px 8px;min-width:168px;flex:1 1 188px;
  box-shadow:0 1px 2px rgba(21,45,71,.10)}
.bl-rname{font-size:12px;font-weight:800;color:var(--plateink);margin-bottom:5px;
  line-height:1.3;letter-spacing:.01em;overflow-wrap:anywhere}

/* One machine per row, and the row WRAPS. A status like "pending condemn" is
   112px on its own; with everything flex:none the badge got pushed outside the
   card once the category had shrunk to nothing. Wrapping drops the status and
   the attachment count onto a second line instead of out of the box. */
.bl-mach{display:flex;flex-wrap:wrap;align-items:center;gap:3px 7px;padding:3px 6px;
  border-radius:6px;cursor:pointer;font-size:12px;min-width:0;max-width:100%}
.bl-mach:hover{background:color-mix(in srgb,var(--plateink) 8%,transparent)}
.bl-mach > *{flex:none;max-width:100%}
.bl-tag{font-family:'Cascadia Mono',Consolas,monospace;font-weight:800;font-size:12px}
.bl-cat{flex:1 1 auto;min-width:0;color:var(--muted);font-size:10.5px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bl-att{margin-left:auto;font-size:10px;font-weight:700;color:var(--ink2);
  background:color-mix(in srgb,var(--plateink) 10%,transparent);border-radius:20px;
  padding:1px 6px}

/* folded storeys — glazing. --n scales the height with how many are inside.
   In dark mode the windows are lit, which is both prettier and truer. */
.bl-brk{--n:1;width:100%;display:flex;align-items:center;justify-content:center;
  height:calc(22px + var(--n) * 13px);padding:0 12px;cursor:pointer;font-family:inherit;
  border:0;border-top:3px solid var(--slabcap);
  background-image:
    repeating-linear-gradient(180deg,transparent 0 11px,var(--mull) 11px 14px),
    repeating-linear-gradient(90deg,var(--mull) 0 6px,var(--glass) 6px 18px)}
html[data-theme=dark] .bl-brk{opacity:.72}
.bl-brk:hover{filter:brightness(1.06)}
.bl-brk:focus-visible{outline:2px solid var(--acc);outline-offset:-4px}
.bl-plate{display:flex;align-items:center;gap:9px;padding:4px 12px;border-radius:20px;
  background:var(--plate);border:1px solid var(--facline);
  box-shadow:0 1px 3px rgba(21,45,71,.18)}
.bl-rng{font-family:'Cascadia Mono',Consolas,monospace;font-size:11.5px;font-weight:800;
  color:var(--plateink);white-space:nowrap}
.bl-cap{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);white-space:nowrap}
.bl-gap .bl-gapfloors{display:none}
.bl-gap.open .bl-gapfloors{display:block}
.bl-gap.open .bl-cap::after{content:' — click to fold'}
.bl-void .bl-fbody{padding:6px 12px;align-items:center;display:flex}
.bl-void .bl-fnum{padding:6px 0}
.bl-empty{font-size:10.5px;color:var(--muted);font-weight:600;font-style:italic}

/* podium and street */
.bl-podium{height:16px;margin:0 -6px;border-radius:0 0 3px 3px;
  background:linear-gradient(180deg,var(--podium),var(--street))}
.bl-street{height:7px;margin:0 -18px;background:var(--street);opacity:.55;border-radius:3px}

.bl-legend{display:flex;flex-wrap:wrap;gap:15px;align-items:center;margin-bottom:14px;
  padding:10px 14px;background:var(--card);border:1px solid var(--line);
  border-radius:11px;box-shadow:var(--shadow)}
.bl-lg{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink2);font-weight:600}
.bl-lg i{width:11px;height:11px;border-radius:3px;flex:none}

.bl-sec{display:flex;align-items:center;gap:8px;margin:26px 0 4px;font-size:14px;font-weight:800}
.bl-sec .cnt{background:var(--line2);color:var(--ink2);border-radius:20px;padding:1px 8px;
  font-size:11px;font-weight:700}
.bl-note{font-size:12.5px;color:var(--ink2);margin-bottom:10px;max-width:74ch}
.bl-sites{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.bl-site{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:12px;
  box-shadow:var(--shadow)}
.bl-site .bl-room{border:0;box-shadow:none;padding:4px 0;background:0;min-width:0}
.bl-shead{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;
  padding-bottom:7px;margin-bottom:4px;border-bottom:1px solid var(--line)}
.bl-shead .cnt{margin-left:auto;background:var(--line2);color:var(--ink2);border-radius:20px;
  padding:1px 8px;font-size:11px;font-weight:700}

/* Tag-family colours. Derived from the three existing accents so the building
   view reads as part of P.A.T.S. rather than a visitor; Canon gets the one new
   hue because four families need four separations and there are only three
   accents. Semantic colours (--ok/--warn/--bad) stay reserved for state. */
:root{--fam-f:#2563eb;--fam-c:#b45309;--fam-r:#0e7490;--fam-s:#7c3aed;--fam-x:#94a3b8}
html[data-theme=dark]{--fam-f:#60a5fa;--fam-c:#fbbf24;--fam-r:#22d3ee;--fam-s:#a78bfa;
  --fam-x:#6b7a97}

.bl-mach{border-left:3px solid transparent;padding-left:7px}
.bl-mach.fam-F{border-left-color:var(--fam-f)} .bl-mach.fam-F .bl-tag{color:var(--fam-f)}
.bl-mach.fam-C{border-left-color:var(--fam-c)} .bl-mach.fam-C .bl-tag{color:var(--fam-c)}
.bl-mach.fam-R{border-left-color:var(--fam-r)} .bl-mach.fam-R .bl-tag{color:var(--fam-r)}
.bl-mach.fam-S{border-left-color:var(--fam-s)} .bl-mach.fam-S .bl-tag{color:var(--fam-s)}
.bl-mach.fam-x{border-left-color:var(--fam-x)} .bl-mach.fam-x .bl-tag{color:var(--muted)}
.bl-st{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  color:var(--warn);background:var(--line2);border-radius:20px;padding:1px 6px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}

.bl-legend{display:flex;flex-wrap:wrap;gap:15px;align-items:center;margin-bottom:14px;
  padding:10px 14px;background:var(--card);border:1px solid var(--line);
  border-radius:11px;box-shadow:var(--shadow)}
.bl-lg{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink2);font-weight:600}
.bl-lg i{width:11px;height:11px;border-radius:3px;flex:none}
.bl-lg i.fam-F{background:var(--fam-f)} .bl-lg i.fam-C{background:var(--fam-c)}
.bl-lg i.fam-R{background:var(--fam-r)} .bl-lg i.fam-S{background:var(--fam-s)}
.bl-lg i.fam-x{background:var(--fam-x)}

/* ---- machine notes ---- */
.notebox{display:flex;gap:8px;align-items:flex-start}
.notebox textarea{flex:1;min-width:0;resize:vertical;font-family:inherit;font-size:13px}
.notebox .btn-primary-mv{flex:none;white-space:nowrap}
.notelist{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
.notelist li{background:var(--head);border:1px solid var(--line);border-left:3px solid var(--acc);
  border-radius:0 9px 9px 0;padding:8px 11px 9px}
.note-meta{display:flex;align-items:center;gap:9px;margin-bottom:4px}
.note-meta strong{font-size:11.5px;color:var(--ink)}
.note-meta span{font-size:10.5px;color:var(--muted);font-family:'Cascadia Mono',Consolas,monospace}
.note-del{margin-left:auto;background:0;border:0;color:var(--muted);cursor:pointer;
  padding:2px 4px;border-radius:5px;display:flex}
.note-del:hover{color:var(--bad);background:var(--line2)}
.notelist p{margin:0;font-size:13px;color:var(--ink2);white-space:pre-wrap;overflow-wrap:anywhere}

/* ---- messages under a form, and a list of files (the licence forms) ---- */
.js-msg{font-size:12px;color:var(--ink2);margin-top:8px;min-height:16px}
.js-msg.bad{color:var(--bad);font-weight:600}
.js-list{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.js-list li{display:flex;align-items:center;gap:9px;padding:8px 11px;background:var(--head);
  border:1px solid var(--line);border-radius:9px;font-size:13px}
.js-list a{font-weight:700;color:var(--acc);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;min-width:0}
.js-meta{margin-left:auto;font-size:10.5px;color:var(--muted);white-space:nowrap;flex:none}

/* ---- the asset editor, as a page rather than a dialog -------------------
   The same fields used to be crushed into two narrow modal columns, which read
   as one jumbled list. Here each group gets a heading and the page width, the
   boxes inside a group flow into as many columns as the screen allows, and the
   Save / Cancel / Delete row is always the last thing on the page. */
.edit-page{display:flex;flex-direction:column;gap:16px;max-width:1080px}
.edit-group{background:var(--card);border:1px solid var(--line);border-radius:16px;
  box-shadow:var(--shadow);overflow:hidden}
.edit-group-head{padding:15px 22px;border-bottom:1px solid var(--line2);background:var(--head)}
.edit-group-head h4{margin:0;font-size:14px;font-weight:800;color:var(--ink);letter-spacing:-.01em}
.edit-group-head p{margin:3px 0 0;font-size:12px;color:var(--muted)}
.edit-group-body{padding:20px 22px}
.edit-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:6px 22px}
.edit-fields > *{min-width:0}
.edit-fields .field{margin-bottom:16px}
.edit-foot{display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);border-radius:16px;
  box-shadow:var(--shadow);padding:14px 22px}

/* ---- public board controls on the asset editor ---- */
.pubbox{background:var(--head);border:1px solid var(--line);border-left:3px solid var(--acc2);
  border-radius:0 11px 11px 0;padding:13px 15px;margin:0}
.pubtick{display:flex;gap:10px;align-items:flex-start;cursor:pointer}
.pubtick input{width:17px;height:17px;margin-top:2px;flex:none;accent-color:var(--acc2)}
.pubtick strong{display:block;font-size:13px;color:var(--ink)}
.pubtick em{display:block;font-style:normal;font-size:11.5px;color:var(--muted);
  margin-top:3px;line-height:1.5}

/* ---- Where is it? — the one screen a signed-out visitor sees ---- */
.guest-hello{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:18px;
  padding:16px 18px;background:var(--card);border:1px solid var(--line);
  border-left:3px solid var(--acc);border-radius:0 12px 12px 0;box-shadow:var(--shadow)}
.guest-hello h3{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:800;margin:0}
.guest-hello p{font-size:12.5px;color:var(--ink2);margin:4px 0 0;max-width:62ch}
.guest-hello a{margin-left:auto;text-decoration:none;white-space:nowrap}

.where-find{position:relative;display:flex;align-items:center}
.where-find svg{position:absolute;left:14px;color:var(--muted);pointer-events:none}
.where-find input{width:100%;padding:13px 15px 13px 42px;font-size:15px;font-family:inherit;
  border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--ink);
  box-shadow:var(--shadow)}
.where-find input:focus{outline:2px solid var(--acc);outline-offset:1px;border-color:transparent}
.where-stamp{font-family:'Cascadia Mono',Consolas,monospace;font-size:11.5px;
  color:var(--muted);margin:9px 2px 18px}

.where-group{display:flex;align-items:center;gap:9px;margin:24px 0 11px;font-size:12.5px;
  font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.where-group .n{background:var(--line2);color:var(--ink2);border-radius:20px;padding:1px 9px;
  font-size:11px;letter-spacing:0}
.where-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));gap:12px}
.where-card{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--fam-x);
  border-radius:12px;padding:14px 15px;box-shadow:var(--shadow)}
.where-card.fam-F{border-left-color:var(--fam-f)}
.where-card.fam-C{border-left-color:var(--fam-c)}
.where-card.fam-R{border-left-color:var(--fam-r)}
.where-card.fam-S{border-left-color:var(--fam-s)}
.wc-name{font-size:17px;font-weight:800;letter-spacing:-.01em;overflow-wrap:anywhere}
.wc-kind{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--muted);margin-top:2px}
.wc-where{display:flex;align-items:flex-start;gap:8px;font-size:14px;font-weight:600;
  color:var(--ink2);margin-top:11px;padding-top:11px;border-top:1px solid var(--line)}
.wc-where svg{flex:none;margin-top:2px;color:var(--acc)}
.wc-tag{font-size:11px;color:var(--muted);margin-top:8px}

/* ---- Where card: photo bleeds to the edge, everything else sits in a padded
   body. The body is what makes the edit form behave — an earlier version had
   no wrapper and injected the form into .wc-head, which is a flex row, so the
   name was squeezed to one character per line beside it. ---- */
.where-card{padding:0;overflow:hidden;display:flex;flex-direction:column}
.wc-photo{aspect-ratio:5/4;background:var(--head);overflow:hidden;
  border-bottom:1px solid var(--line);flex:none}
.wc-photo img{width:100%;height:100%;object-fit:cover;display:block}
.wc-body{padding:14px 15px;display:flex;flex-direction:column;flex:1;min-width:0}

.wc-head{display:flex;align-items:flex-start;gap:8px;min-width:0}
.wc-head .wc-name{flex:1;min-width:0}

/* The card's controls: pencil and map at the top right, the cross at the
   bottom right. Out of sight until the pointer is over the card, so the board
   reads as a board; always shown where there is no hover to reveal them. */
.wc-tools{display:flex;gap:2px;flex:none;margin:-3px -5px 0 0}
.wc-tool,.wc-off{background:0;border:0;color:var(--muted);cursor:pointer;padding:5px;
  border-radius:7px;display:flex;opacity:0;transition:opacity .15s,color .15s,background .15s}
.wc-tool:hover{color:var(--acc);background:var(--line2)}
.wc-off:hover{color:var(--bad);background:color-mix(in srgb,var(--bad) 10%,transparent)}
.where-card:hover .wc-tool,.where-card:hover .wc-off,
.wc-tool:focus-visible,.wc-off:focus-visible{opacity:1}
@media (hover:none){.wc-tool,.wc-off{opacity:1}}
.where-card.busy{opacity:.55;pointer-events:none}

/* The last row sits on the card's floor, so the cross lands in the same corner
   on every card in a row however much text is above it. */
.wc-foot{display:flex;align-items:flex-end;gap:8px;margin-top:auto;padding-top:8px}
.wc-foot .wc-upd{margin-top:0;flex:1;min-width:0}
.wc-off{margin:0 -6px -6px auto;flex:none}

/* ---- report a problem: the note, the flag, the form, and the staff list ----
   Red throughout, the one colour the board does not otherwise use for anything
   but a fault. See reportForm() in app.js and php/lib/reports.php. */
.btn-report{display:inline-flex;align-items:center;gap:7px;padding:8px 14px;border-radius:10px;font:inherit;
  font-size:13px;font-weight:700;cursor:pointer;background:#fff1f2;color:#be123c;border:1px solid #fecdd3;
  white-space:nowrap}
.btn-report:hover{background:#ffe4e6;border-color:#fda4af}
html[data-theme=dark] .btn-report{background:#3a1220;color:#fda4af;border-color:#5b1a2e}
/* in the top bar only once the board says reports are taken, and never on a
   phone, where the note under it is the way in */
.rp-top{display:none!important}
body.can-report .rp-top{display:inline-flex!important}
@media (max-width:700px){body.can-report .rp-top{display:none!important}}
.rp-note,.rp-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 14px;padding:12px 14px;
  border-radius:14px;border:1px solid var(--line);border-left:4px solid #e11d48}
.rp-note{background:var(--card);box-shadow:var(--shadow)}
.rp-banner{background:#fff1f2;border-color:#fecdd3;border-left-color:#e11d48}
html[data-theme=dark] .rp-banner{background:#2a0f19;border-color:#5b1a2e;border-left-color:#e11d48}
.rp-ic{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:#fff1f2;color:#e11d48;flex:none}
html[data-theme=dark] .rp-ic{background:#3a1220;color:#fda4af}
.rp-say{flex:1;min-width:210px;display:flex;flex-direction:column;gap:1px}
.rp-say b{font-size:14px;color:var(--ink)}
.rp-say span{font-size:12.5px;color:var(--ink2)}
.rp-banner .rp-say b{color:#881337}
.rp-banner .rp-say span{color:#9f1239}
html[data-theme=dark] .rp-banner .rp-say b{color:#fecdd3}
html[data-theme=dark] .rp-banner .rp-say span{color:#fda4af}
.rp-chip{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;color:#be123c;
  background:#fff1f2;border:1px solid #fecdd3;border-radius:20px;padding:2px 8px;white-space:nowrap}
html[data-theme=dark] .rp-chip{background:#3a1220;color:#fda4af;border-color:#5b1a2e}
.wc-tool.rp-flag:hover{color:#e11d48}
.modal-box.rp-narrow{max-width:620px}
.modal-box.rp-mid{max-width:820px}
.rp-lead{font-size:13px;color:var(--ink2);margin:0 0 14px;line-height:1.5}
.rp-me{font-size:13px;color:var(--ink2);margin:-4px 0 14px}
.rp-me .mono{margin-left:6px;color:var(--muted)}
.rp-two{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media (max-width:520px){.rp-two{grid-template-columns:1fr;gap:0}}
.rp-kind{display:grid;gap:7px}
.rp-kind label{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--line);
  border-radius:11px;cursor:pointer;background:var(--card)}
.rp-kind label:has(input:checked){border-color:var(--acc);box-shadow:0 0 0 3px var(--glow)}
.rp-kind input{margin-top:3px;accent-color:var(--acc)}
.rp-kind b{display:block;font-size:13px;color:var(--ink)}
.rp-kind em{display:block;font-style:normal;font-size:12px;color:var(--muted)}
.rp-already{margin-top:7px;font-size:12px;line-height:1.45;color:#9a3412;background:#fff7ed;
  border:1px solid #fed7aa;border-radius:10px;padding:8px 10px}
html[data-theme=dark] .rp-already{background:#2a1a07;color:#fdba74;border-color:#5a3410}
/* the field a person never sees; a robot filling in every box fills this one too */
.rp-hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.rp-form .js-msg{margin:-4px 0 10px}
.rp-acts{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.rp-small{font-size:11.5px;color:var(--muted);margin-top:12px;line-height:1.5}
.rp-ok{text-align:center;padding:14px 6px 4px}
.rp-ok .big{width:56px;height:56px;border-radius:50%;background:#dcfce7;color:#16a34a;display:grid;
  place-items:center;margin:0 auto 12px}
.rp-ok h3{font-size:18px;color:var(--ink)}
.rp-ok p{font-size:13px;color:var(--ink2);margin:6px auto 0;max-width:46ch;line-height:1.5}
.rp-ok .rp-acts{justify-content:center;margin-top:16px}
.rp-item{border:1px solid var(--line);border-left:4px solid #e11d48;border-radius:12px;padding:12px 14px;
  margin-bottom:10px;background:var(--card)}
.rp-item.done{border-left-color:var(--ok)}
.rp-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rp-head b{font-size:14px;color:var(--ink)}
.rp-head .mono{font-size:11px;color:var(--muted)}
.rp-when{margin-left:auto;font-size:11.5px;color:var(--muted);white-space:nowrap}
.rp-k{font-size:10.5px;font-weight:800;border-radius:20px;padding:2px 8px}
.rp-k.fix{background:#fff1f2;color:#be123c;border:1px solid #fecdd3}
.rp-k.update{background:#eff6ff;color:#1d4ed8;border:1px solid #bfdbfe}
html[data-theme=dark] .rp-k.fix{background:#3a1220;color:#fda4af;border-color:#5b1a2e}
html[data-theme=dark] .rp-k.update{background:#0f2544;color:#93c5fd;border-color:#1e3a66}
.rp-text{font-size:13.5px;color:var(--ink);margin:7px 0 5px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
.rp-who{font-size:12px;color:var(--ink2);margin-bottom:9px}
.rp-outcome{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--ok);font-weight:600}
.rp-donebox{display:flex;gap:8px;margin-top:9px}
.rp-donebox input{flex:1;min-width:0}
.rp-list details{margin-top:6px}
.rp-list summary{cursor:pointer;font-size:12.5px;font-weight:700;color:var(--ink2);padding:6px 0}

/* ---- PM job sheets, per machine ---- */
.docs{display:flex;flex-direction:column;gap:10px;margin-top:14px}

/* ---- keeper reminders (were tick-off duties) ---- */
.duty.reminder{display:flex;align-items:flex-start;gap:13px}
.duty-n{flex:none;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;background:var(--line2);color:var(--ink2);font-size:12px;
  font-weight:800;margin-top:1px}

/* ---- handover email preview ---- */
.ho-preview{max-height:46vh;overflow:auto;margin-top:12px;padding:16px 18px;
  background:#fff;color:#1e293b;border:1px solid var(--line);border-radius:10px}
html[data-theme=dark] .ho-preview{background:#f8fafc}
.ho-preview table{max-width:100%}
.js-msg.ok{color:var(--ok);font-weight:600}

.seg button[disabled]{opacity:.42;cursor:not-allowed}

/* ---- who last touched a machine, on the Where board ---- */
.wc-upd{display:flex;align-items:center;gap:5px;margin-top:8px;font-size:10.5px;
  color:var(--muted);font-weight:600}
.wc-upd svg{flex:none}

/* ---- bigger handover button ---- */
.ho-btn{font-size:14px;padding:11px 18px;gap:9px}

/* ---- removing a keeper reminder ---- */
.duty-del{margin-left:auto;background:0;border:0;color:var(--muted);cursor:pointer;
  padding:5px;border-radius:7px;display:flex;opacity:0;transition:opacity .15s}
.duty.reminder:hover .duty-del,.duty-del:focus-visible{opacity:1}
.duty-del:hover{color:var(--bad);background:var(--line2)}
@media (hover:none){.duty-del{opacity:1}}

/* ---- badges: the dot or short label after a machine's name ---- */
.bdg-row{display:inline-flex;align-items:center;gap:5px;margin-left:7px;vertical-align:middle}
.bdg-dot{width:12px;height:12px;border-radius:50%;display:inline-block;flex:none;
  box-shadow:0 0 0 2px color-mix(in srgb,var(--card) 70%,transparent)}
.bdg-label{display:inline-flex;align-items:center;font-size:10px;font-weight:800;
  text-transform:uppercase;letter-spacing:.06em;border:1px solid;border-radius:20px;
  padding:1px 7px;white-space:nowrap;line-height:1.5}
.bdg-list{display:flex;flex-direction:column;gap:6px;margin:12px 0}
.bdg-item{display:flex;align-items:center;gap:11px;padding:8px 11px;background:var(--head);
  border:1px solid var(--line);border-radius:9px}
.bdg-prev{display:flex;align-items:center;min-width:38px}
.bdg-desc{font-size:12.5px;color:var(--ink2)}
.bdg-x{margin-left:auto;background:0;border:0;color:var(--muted);cursor:pointer;padding:4px;
  border-radius:6px;display:flex}
.bdg-x:hover{color:var(--bad);background:var(--line2)}
.bdg-form{border-top:1px solid var(--line);padding-top:14px;margin-top:4px}
.bdg-live{display:flex;align-items:center;gap:10px;margin-top:6px;padding:10px 12px;
  background:var(--head);border:1px dashed var(--line);border-radius:9px;
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}

/* ---- ordering the board ---- */
.where-tools{display:flex;gap:8px;margin:10px 0 0}
.ord-head{display:flex;align-items:center;gap:9px;margin:16px 0 8px;font-size:11px;
  font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.ord-head span{background:var(--line2);color:var(--ink2);border-radius:20px;padding:1px 8px;
  font-size:10.5px;letter-spacing:0}
.ord-list{display:flex;flex-direction:column;gap:5px;max-height:30vh;overflow-y:auto;
  padding-right:2px}
.ord-rest{max-height:22vh}
.ord-row{display:flex;align-items:center;gap:10px;padding:7px 11px;background:var(--head);
  border:1px solid var(--line);border-radius:9px}
.ord-n{font-family:'Cascadia Mono',Consolas,monospace;font-size:12px;font-weight:800;
  color:var(--muted);min-width:16px;text-align:center;flex:none}
.ord-name{flex:1;min-width:0;font-size:13px;font-weight:700;color:var(--ink);
  display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.ord-name em{font-style:normal;font-size:11px;font-weight:600;color:var(--muted)}
.ord-btn{flex:none;background:var(--card);border:1px solid var(--line);border-radius:7px;
  padding:3px 8px;font-size:11px;font-family:inherit;color:var(--ink2);cursor:pointer;
  display:inline-flex;align-items:center;gap:4px;line-height:1.6}
.ord-btn:hover:not(:disabled){border-color:var(--acc);color:var(--acc)}
.ord-btn:disabled{opacity:.35;cursor:default}
.ord-btn.drop:hover{border-color:var(--bad);color:var(--bad)}
.ord-btn.add:hover{border-color:var(--ok);color:var(--ok)}

/* ---- status on a board card ---- */
.wc-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:5px}
.wc-status{display:inline-flex;align-items:center;padding:2px 9px;
  font-size:10.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  border:1px solid transparent;border-radius:999px;font-family:inherit;line-height:1.75;
  white-space:nowrap}
button.wc-status{cursor:pointer}
button.wc-status:hover{filter:brightness(1.08);box-shadow:0 0 0 2px var(--card),0 0 0 3px currentColor}
.st-swatch{display:inline-flex;align-items:center;padding:3px 10px;font-size:11px;
  font-weight:800;letter-spacing:.04em;text-transform:uppercase;border-radius:999px}
.st-list{display:flex;flex-direction:column;gap:6px;margin-top:12px}
.st-opt{display:flex;align-items:center;gap:9px;width:100%;padding:10px 12px;
  font-size:13.5px;font-family:inherit;color:var(--fg);background:var(--card);
  border:1px solid var(--line);border-radius:10px;cursor:pointer;text-align:left}
.st-opt:hover{border-color:var(--acc)}
.st-opt.on{border-color:var(--acc);background:var(--head)}
.st-lab{font-weight:600}
.st-now{margin-left:auto;display:inline-flex;align-items:center;gap:4px;
  font-size:10.5px;font-weight:800;text-transform:uppercase;color:var(--acc)}
.wc-meta .wc-kind{margin-top:0}

/* ---- the stand-in shown while a machine is in maintenance ---- */
.wc-maint{background:#fde68a}
.wc-maint svg{width:100%;height:100%;display:block}

/* ---- square frames for everything that is not a wheeled machine ----
   Height is kept and the width comes in to match, so rows keep their
   heights and the table columns line up as before. */
.thumb.sq{width:56px}
.hero-img.sq{width:158px}
.mi-img.sq{width:114px}
.photo-thumb.sq{width:54px}

/* ---- small inline edit affordance next to a value ---- */
.lnk-edit{display:inline-flex;align-items:center;gap:3px;margin-left:6px;padding:1px 6px;
  font-size:10.5px;font-weight:700;font-family:inherit;color:var(--acc);background:transparent;
  border:1px solid var(--line);border-radius:6px;cursor:pointer;vertical-align:middle}
.lnk-edit:hover{border-color:var(--acc);background:var(--head)}
.mi-tied{display:flex;align-items:center;gap:4px;margin-top:3px;font-size:10.5px;
  color:var(--muted)}

/* ---- picking a photo while adding an asset ---- */
.addph{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap}
.addph-prev{width:150px;height:114px;flex:none;border:1px solid var(--line);border-radius:11px;
  background:var(--head);display:flex;align-items:center;justify-content:center;
  overflow:hidden;font-size:11.5px}
.addph-prev img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- managing the kinds of thing tracked ---- */
.cat-yes{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;
  text-transform:uppercase;letter-spacing:.04em;color:var(--ok)}
.cat-chk{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;margin-bottom:8px;
  border:1px solid var(--line);border-radius:10px;cursor:pointer;background:var(--card)}
.cat-chk:hover{border-color:var(--acc)}
.cat-chk input{width:16px;height:16px;margin-top:2px;flex:none}
.cat-chk b{display:block;font-size:13px;color:var(--ink)}
.cat-chk em{display:block;font-style:normal;font-size:11.5px;color:var(--muted);margin-top:2px}

/* ---- note in the move dialog when an item is tied to a machine ---- */
.mv-tied{display:flex;gap:9px;align-items:flex-start;margin-top:12px;padding:11px 13px;
  font-size:12.5px;line-height:1.5;color:var(--ink2);background:var(--head);
  border:1px solid var(--line);border-left:3px solid var(--warn);border-radius:9px}
.mv-tied svg{flex:none;margin-top:2px;color:var(--warn)}

/* ---- photos on the edit screen ---- */
.edph{display:flex;gap:12px;flex-wrap:wrap;align-items:stretch}
.edph-item{width:172px;border:1px solid var(--line);border-radius:11px;overflow:hidden;
  background:var(--head)}
.edph-item.is-main{border-color:var(--ok);box-shadow:0 0 0 1px var(--ok)}
.edph-item img{width:100%;aspect-ratio:5/4;object-fit:cover;display:block}
.edph-meta{font-size:10.5px;color:var(--muted);padding:7px 10px 0}
.edph-acts{display:flex;gap:6px;align-items:center;padding:7px 10px 9px}
.edph-main{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;
  text-transform:uppercase;letter-spacing:.05em;color:var(--ok)}
.edph-add{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  width:172px;min-height:150px;font-family:inherit;font-size:12.5px;font-weight:600;
  color:var(--muted);background:transparent;border:2px dashed var(--line);border-radius:11px;
  cursor:pointer}
.edph-add:hover{border-color:var(--acc);color:var(--acc)}

/* ---- picking something from the inventory to attach ---- */
.atk-find{position:relative;display:flex;align-items:center;margin:12px 0 10px}
.atk-find svg{position:absolute;left:11px;color:var(--muted);pointer-events:none}
.atk-find input{width:100%;padding:9px 12px 9px 34px;font-size:13px;font-family:inherit;
  color:var(--fg);background:var(--card);border:1px solid var(--line);border-radius:9px}
.atk-find input:focus{outline:2px solid var(--acc);outline-offset:1px;border-color:transparent}
.atk-list{max-height:38vh;overflow-y:auto;display:flex;flex-direction:column;gap:6px}
.atk-item{display:flex;gap:11px;align-items:center;width:100%;padding:8px 11px;text-align:left;
  font-family:inherit;background:var(--card);border:1px solid var(--line);border-radius:10px;
  cursor:pointer}
.atk-item:hover{border-color:var(--acc)}
.atk-item.on{border-color:var(--acc);background:var(--head);box-shadow:0 0 0 1px var(--acc)}
.atk-thumb{width:46px;height:46px;flex:none;border-radius:8px;overflow:hidden;
  background:var(--line2);border:1px solid var(--line)}
.atk-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.atk-thumb img.art{object-fit:contain;padding:3px}
.atk-main{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.atk-main b{font-size:13.5px;color:var(--ink)}
.atk-main em{font-style:normal;font-size:11px;color:var(--muted);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.atk-where{display:flex;align-items:center;gap:4px}
.atk-tick{color:var(--acc);flex:none}

/* ---- this tab is running JavaScript from before an update ---- */
#staleBar{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:9999;
  display:flex;align-items:center;gap:14px;max-width:calc(100vw - 32px);
  padding:12px 16px;font-size:13px;color:#fff;background:#1e293b;
  border-radius:11px;box-shadow:0 10px 30px rgba(15,23,42,.35)}
#staleBar button{padding:6px 13px;font-size:12.5px;font-weight:700;font-family:inherit;
  color:#0f172a;background:#fde68a;border:0;border-radius:8px;cursor:pointer}

/* Queued writes waiting for signal. Sits above the stale-build bar so the two
   stack rather than cover each other, and low enough on the screen to be
   reachable with a thumb — this is read while standing next to a machine. */
#queueBar{position:fixed;left:50%;bottom:78px;transform:translateX(-50%);z-index:9998;
  display:flex;align-items:center;gap:14px;max-width:calc(100vw - 32px);
  padding:12px 16px;font-size:13px;color:#fff;background:#b45309;
  border-radius:11px;box-shadow:0 10px 30px rgba(15,23,42,.35)}
#queueBar.has-failed{background:#991b1b}
#queueBar button{padding:6px 13px;font-size:12.5px;font-weight:700;font-family:inherit;
  color:#7c2d12;background:#fed7aa;border:0;border-radius:8px;cursor:pointer}
#queueBar.has-failed button{color:#7f1d1d;background:#fecaca}

/* ---- barcode scanner setup sheets ----
   Deliberately large. These are scanned off the screen, and a barcode shrunk
   into a thumbnail will not read. One per row at full width, never cropped. */
/* Two across on a desk screen, one on a tablet. Full width per sheet was
   bigger than anyone needs to line a scanner up, and pushed the second sheet
   off the bottom — the point is to see both and pick one. Clicking still opens
   a sheet full width, which is where the scanning actually happens. */
.ss-list{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:18px}
@media (max-width: 1000px){ .ss-list{grid-template-columns:1fr} }
.ss-item{margin:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;
  background:var(--head)}
.ss-item figcaption{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:11px 14px;border-bottom:1px solid var(--line);background:var(--card)}
.ss-item figcaption strong{font-size:13.5px;color:var(--ink)}
.ss-item figcaption .muted{font-size:11px}
.ss-acts{margin-left:auto;display:flex;gap:6px}
.ss-item img{display:block;width:100%;height:auto;background:#fff;cursor:zoom-in}
.ss-pdf{display:flex;align-items:center;justify-content:center;gap:9px;padding:34px;
  font-size:14px;font-weight:700;color:var(--acc);text-decoration:none}
.ss-pdf:hover{background:var(--card)}

/* Full window, plain white behind it: the biggest, cleanest target the monitor
   can give the scanner.

   Width, not height. Capping the height fits the sheet on screen, which is the
   wrong goal — these pages are portrait, and fitting one to a 720px-tall
   monitor left the barcodes about a third of the width they could have been.
   It fills the width and scrolls instead. */
.ss-zoom{position:fixed;inset:0;z-index:10000;overflow:auto;padding:0 0 20px;
  background:#fff;cursor:zoom-out}
.ss-zoom-bar{position:sticky;top:0;display:flex;align-items:baseline;gap:12px;
  flex-wrap:wrap;padding:10px 16px;color:#0f172a;font-size:13px;background:#fff;
  border-bottom:1px solid #e2e8f0}
.ss-zoom-bar .muted{color:#64748b;font-size:11.5px}
.ss-zoom img{display:block;width:100%;height:auto;margin:0 auto}

/* A roster quarter is clickable for anyone who may change it. */
.roster .rq[onclick]{cursor:pointer}
.roster .rq[onclick]:hover{border-color:var(--acc)}

/* ==== on-site support email (PM) =======================================
   Two columns: what goes in the email on the left, the email itself on the
   right. The right column has to be wide enough for the real thing — IT's
   form table is 537pt, about 716px — so this dialog asks for a wider modal
   than the rest of the app (.modal-box.modal-xl) instead of scrolling the
   preview sideways, which is what it did before and which made the preview
   useless for checking anything.

   Below 1180px the columns stack and the picker comes first: on a phone you
   are choosing machines on a walk-round, not proofreading an email. */
.modal-box.modal-xl{max-width:min(1480px,96vw)}

/* The dialog is a fixed-height thing, not a growing page.
   It used to size to its content and cap the picker at a fraction of the
   viewport, so the equipment list was short no matter how much room there was
   — the modal scrolled instead, which meant scrolling the whole dialog to see
   more machines while the preview beside it scrolled away too. Now the body
   takes the height it can have, and the picker and the preview each flex into
   what is left and scroll inside themselves. */
.modal-box.modal-xl .modal-body{display:flex;flex-direction:column;
  max-height:calc(100vh - 10rem);overflow:auto}

/* The preview column is sized to the email — IT's form table is 537pt, about
   716px — and the picker takes everything else. Widening the picker at the
   preview's expense would put the horizontal scrollbar back. */
.pe-wrap{display:grid;grid-template-columns:minmax(400px,1fr) minmax(720px,760px);
  gap:16px;align-items:stretch;flex:1 1 auto;min-height:0}
.pe-col{display:flex;flex-direction:column;gap:12px;min-width:0;min-height:0}

.pe-panel{border:1px solid var(--line);border-radius:14px;background:var(--card);
  overflow:hidden;display:flex;flex-direction:column;min-height:0}
.pe-panel-head{display:flex;align-items:center;gap:8px;padding:10px 13px;
  background:var(--head);border-bottom:1px solid var(--line);
  font-size:12px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;
  color:var(--ink2)}
.pe-panel-head svg{color:var(--acc)}
.pe-count{margin-left:auto;font-size:11px;font-weight:600;text-transform:none;
  letter-spacing:0;color:var(--muted);white-space:nowrap}
.pe-count.ok{color:var(--ok)}
.pe-count.bad{color:var(--bad)}
.pe-panel-head .pe-acts{display:flex;gap:6px;margin-left:10px}

.pe-fields{display:grid;grid-template-columns:1fr 1fr;gap:10px 12px;padding:13px}
.pe-fields .field{margin:0}

/* The visit folds away. <details> gives the behaviour for free; the marker is
   replaced by a chevron so the summary can carry a one-line recap of what is
   inside it when shut. */
.pe-visit{display:block;flex:none}
.pe-visit summary{cursor:pointer;list-style:none;user-select:none}
.pe-visit summary::-webkit-details-marker{display:none}
.pe-visit summary::after{content:'';flex:none;width:7px;height:7px;margin-left:2px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .15s}
.pe-visit[open] summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.pe-visit summary:hover::after{border-color:var(--acc)}
.pe-visit[open] summary{border-bottom:1px solid var(--line)}
.pe-visit:not([open]) summary{border-bottom:0}

/* ---- the picker ---- */
/* Fills whatever the dialog has left, rather than a slice of the viewport. */
.pe-pick{flex:1 1 auto;min-height:220px}
.pe-list{overflow:auto;flex:1 1 auto;min-height:0}
/* The room filter and the bulk buttons, above the grid. */
.pe-bar{display:flex;align-items:center;gap:7px;padding:9px 13px;
  border-bottom:1px solid var(--line);background:var(--card);flex:none}
.pe-bar select{flex:1 1 auto;min-width:0;padding:6px 10px;font-size:12px}
.pe-bar .btn-sm{flex:none;white-space:nowrap}

.pe-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));
  gap:7px;padding:7px 13px 9px}

/* The whole card is the control. Nothing to aim at but the thing itself. */
.pe-card{position:relative;display:flex;flex-direction:column;gap:1px;
  text-align:left;font:inherit;cursor:pointer;padding:7px 10px 7px;
  border:1.5px solid var(--line);border-radius:11px;background:var(--card);
  transition:border-color .13s,background .13s,box-shadow .13s,transform .13s}
.pe-card:hover{border-color:var(--acc);transform:translateY(-1px);
  box-shadow:0 3px 10px rgba(15,23,42,.10)}
.pe-card:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.pe-card.on{border-color:var(--acc);background:var(--glow);
  box-shadow:0 0 0 3px var(--glow)}

.pe-card-tick{position:absolute;top:7px;right:7px;width:17px;height:17px;
  border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--line2);color:transparent;transition:.13s}
.pe-card.on .pe-card-tick{background:var(--acc);color:#fff}

.pe-card-tag{font-family:Consolas,ui-monospace,monospace;font-size:13.5px;
  font-weight:800;color:var(--ink);padding-right:20px;line-height:1.2}
.pe-card-name{font-size:11px;color:var(--ink2);line-height:1.3;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
/* The room, on the card. It used to be a heading band over a group of cards,
   which cost more height than the cards themselves — see pmEmailPick(). */
.pe-card-room{font-size:10px;color:var(--muted);font-weight:600;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pe-card-foot{display:flex;align-items:center;gap:6px;margin-top:3px;
  flex-wrap:wrap}
.pe-chip{font-size:10px;font-weight:800;padding:2px 6px;border-radius:20px;
  background:var(--line2);color:var(--ink2);font-variant-numeric:tabular-nums}
.pe-chip.now{background:var(--acc);color:#fff}
.pe-chip.none{background:transparent;color:var(--muted);font-weight:600;
  padding-left:0}
.pe-parts{font-size:10px;color:var(--muted);font-weight:600}

/* ---- the preview ---- */
.pe-col-prev{min-height:0}
.pe-prevpanel{flex:1 1 auto;min-height:0}
.pe-prevpanel .ho-preview{margin:0;border:0;border-radius:0;
  flex:1 1 auto;min-height:0;max-height:none}
.pe-head{font-size:12px;color:#475569;border-bottom:1px solid #e2e8f0;
  padding-bottom:9px;margin-bottom:12px;line-height:1.6;word-break:break-word}
.pe-head b{color:#0f172a}
.pe-buttons{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

@media(max-width:1180px){
  /* Stacked: the dialog scrolls as one again, because two panes each scrolling
     inside a phone-height screen is worse than one honest scroll. */
  .modal-box.modal-xl .modal-body{max-height:none;overflow:visible}
  .pe-wrap{grid-template-columns:1fr;min-height:0}
  .pe-list{max-height:56vh}
  .pe-pick{flex:none}
  /* Both columns carry .pe-col, so .pe-col-prev needs the extra specificity or
     the later rule wins and the preview stays on top — which puts the email
     above the picker on a phone, where choosing machines is the job. */
  .pe-col{order:1}
  .pe-wrap .pe-col-prev{position:static;order:2}
  .pe-prevpanel .ho-preview{max-height:52vh}
}
@media(max-width:560px){
  .pe-fields{grid-template-columns:1fr}
  .pe-grid{grid-template-columns:repeat(auto-fill,minmax(135px,1fr))}
}

/* ---- curating the PM email's equipment list (superadmin) ----
   Edit mode turns each card from a tick box into a row with two controls. The
   card stops being clickable-to-select on purpose: one surface that both
   selects and renames is one that renames something when you meant to pick it. */
.pe-bar .btn-sm.on{background:var(--acc);color:#fff;border-color:var(--acc)}
.pe-card-edit{cursor:default}
.pe-card-edit:hover{transform:none;border-color:var(--line);
  box-shadow:none;background:var(--card)}
.pe-card-edit.added{border-color:var(--acc)}
.pe-edit-acts{display:flex;gap:4px;margin-left:auto}
.pe-mini{border:1px solid var(--line);background:var(--card);color:var(--ink2);
  font:inherit;font-size:10px;font-weight:700;padding:2px 7px;border-radius:7px;
  cursor:pointer;display:inline-flex;align-items:center;gap:3px;white-space:nowrap}
.pe-mini:hover{border-color:var(--acc);color:var(--acc)}
.pe-mini.danger:hover{border-color:var(--bad);color:var(--bad)}
.pe-mini.add{border-color:var(--acc);color:var(--acc)}
.pe-mini.add:hover{background:var(--acc);color:#fff}
.pe-chip.added{background:var(--acc);color:#fff}

.pe-cand{border-top:2px solid var(--line);margin-top:6px;background:var(--head)}
.pe-cand-head{display:flex;align-items:center;gap:8px;padding:8px 13px;
  font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink2)}
.pe-cand-head svg{color:var(--acc)}
.pe-cand-head .muted{text-transform:none;letter-spacing:0;font-weight:600;
  font-size:10.5px}
.pe-bar .pe-needs-upgrade{border-color:var(--warn);color:var(--warn)}
.pe-bar .pe-needs-upgrade:hover{background:var(--warn);color:#fff}

/* Which of the two emails is on screen. Both are built from the one selection,
   so this only swaps what is rendered — nothing is re-chosen. */
.pe-seg{flex:none}
.pe-seg button{padding:5px 10px;font-size:11.5px;font-weight:700;
  display:inline-flex;align-items:center;gap:5px;text-transform:none;
  letter-spacing:0}
.pe-seg button svg{width:14px;height:14px}
.pe-seg button.on svg{color:#fff}

/* ==== PM progress: one page of visit cards ================================
   A visit is one vendor, one date, one machine or several. Tags are the
   biggest thing on a card because they are what people scan for. */
.topbar-heading p:empty{display:none}

.pmx-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:16px}
.pmx-today{display:flex;align-items:center;gap:8px;font-size:13.5px;font-weight:700;
  color:var(--ink2)}
.pmx-bar-acts{margin-left:auto;display:flex;align-items:center;gap:8px}
.pmx-email{font-size:14px;padding:10px 18px;gap:8px;
  box-shadow:0 4px 14px color-mix(in srgb,var(--acc) 35%,transparent)}
.pmx-more{position:relative}
.pmx-dots{padding:8px 10px}
.pmx-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:40;min-width:250px;
  background:var(--card);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow-lg);padding:6px}
.pmx-menu button{display:flex;align-items:flex-start;gap:10px;width:100%;padding:9px 10px;
  border:0;background:0;font:inherit;color:var(--ink);cursor:pointer;border-radius:8px;
  text-align:left}
.pmx-menu button:hover{background:var(--head)}
.pmx-menu button svg{margin-top:2px;color:var(--acc)}
.pmx-menu b{display:block;font-size:13px}
.pmx-menu em{display:block;font-style:normal;font-size:11.5px;color:var(--muted)}

.pmx-none{display:flex;align-items:center;gap:10px;padding:18px 20px;margin-bottom:18px;
  background:var(--card);border:1px dashed var(--line);border-radius:14px;
  color:var(--ink2);font-size:13.5px}

/* the next visit */
.pmx-hero{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-bottom:22px;
  padding:18px 22px;background:var(--card);border:2px solid var(--acc);border-radius:16px;
  box-shadow:var(--shadow)}
.pmx-hdate{display:flex;flex-direction:column;align-items:center;min-width:72px;
  font-size:12.5px;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em}
.pmx-hdate b{font-size:42px;line-height:1;color:var(--ink);letter-spacing:-.03em;
  text-transform:none}
.pmx-hmain{flex:1;min-width:240px;display:flex;flex-direction:column;gap:9px}
.pmx-hlab{font-size:13px;font-weight:800;color:var(--acc)}
.pmx-hero .pmx-tag{font-size:17px;padding:5px 12px}
.pmx-acts.big{flex-direction:column;align-items:stretch;margin:0}
.pmx-acts.big .btn-outline-mv{justify-content:flex-start}

/* months, and the sections under them */
.pmx-month{margin-bottom:14px}
.pmx-month>summary{display:flex;align-items:center;gap:9px;cursor:pointer;list-style:none;
  margin:18px 0 11px;font-size:12.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted)}
.pmx-month>summary::-webkit-details-marker{display:none}
.pmx-month>summary::before{content:'';width:7px;height:7px;flex:none;margin-right:2px;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(-45deg);transition:transform .15s}
.pmx-month[open]>summary::before{transform:rotate(45deg)}
.pmx-month>summary .n{background:var(--line2);color:var(--ink2);border-radius:20px;
  padding:1px 9px;font-size:11px;letter-spacing:0}

/* the cards */
.pmx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(255px,1fr));gap:12px}
.pmx-grid>*{min-width:0}
.pmx-card{display:flex;flex-direction:column;gap:10px;padding:14px 15px;
  background:var(--card);border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--shadow)}
.pmx-chead{display:flex;align-items:flex-start;gap:10px}
.pmx-chead .vchip{margin-left:auto}
.pmx-day{display:flex;align-items:center;gap:9px}
.pmx-day b{font-size:28px;line-height:1;color:var(--ink);letter-spacing:-.02em}
.pmx-day span{font-size:11.5px;font-weight:700;line-height:1.3;color:var(--muted)}
.pmx-tags{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.pmx-tag{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;
  font-family:'Cascadia Mono',Consolas,monospace;font-size:15px;font-weight:800;
  color:var(--ink);background:var(--head);border:1.5px solid var(--line);border-radius:9px;
  cursor:pointer;line-height:1.35}
.pmx-tag:hover{border-color:var(--acc);color:var(--acc)}
.pmx-rooms{display:flex;align-items:flex-start;gap:6px;font-size:12.5px;font-weight:600;
  color:var(--ink2)}
.pmx-rooms svg{flex:none;margin-top:1px;color:var(--acc)}
.pmx-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto;padding-top:2px}

/* changing a date, inside the card */
.pmx-cd:empty{display:none}
.pmx-cdbox{display:flex;flex-direction:column;gap:8px;padding-top:10px;
  border-top:1px solid var(--line2)}
.pmx-cdbox .fl{margin:0}
.pmx-cdwho{display:flex;flex-wrap:wrap;gap:6px 12px;font-size:13px;font-weight:700}
.pmx-cdwho label{display:inline-flex;align-items:center;gap:5px;cursor:pointer}
.pmx-cdbtns{display:flex;gap:6px}

/* ---- the licence form, inside a mobile unit's Machine info ---- */
.lic-list{margin-top:4px}
