  :root{
    /* ── APQ Design System tokens ── */
    --navy:#0E1C2E;
    --navy-hover:#1e293b;
    --navy-active:#243044;
    --brand-navy:#0E1C2E;
    --brand-blue:#1A3F6A;
    --gold:#F5A623;
    --gold-hover:#e0951c;
    --gold-bg:rgba(245,166,35,0.1);
    --gold-tint:rgba(245,166,35,0.15);
    --blue:#0071e3;
    --blue-bg:#eff6ff;
    --blue-ink:#1d4ed8;
    --green:#16a34a;
    --green-bg:#f0fdf4;
    --red:#dc2626;
    --red-bg:#fef2f2;
    --amber:#d97706;
    --amber-bg:#fffbeb;
    --purple:#7c3aed;
    --purple-bg:#f5f3ff;
    --bg:#f5f5f7;
    --white:#ffffff;
    --t1:#111827;
    --t2:#374151;
    --t3:#6b7280;
    --t4:#9ca3af;
    --border:#e5e7eb;
    --border2:#d1d5db;
    --r:8px;
    --r2:12px;
    --r3:16px;
    --r4:20px;
    --shadow:0 1px 3px rgba(0,0,0,0.08),0 1px 2px rgba(0,0,0,0.04);
    --shadow2:0 4px 16px rgba(0,0,0,0.08);
    --shadow3:0 20px 60px rgba(0,0,0,0.15);

    /* ── Legacy aliases so existing class rules keep working ── */
    --card:var(--white);
    --ink:var(--t1);
    --ink-soft:var(--t2);
    --muted:var(--t3);
    --line:var(--border);
    --line-2:var(--border);
    --brand:var(--blue);
    --brand-dk:#005ac0;
    --ok:var(--green);
    --warn:var(--amber);
    --bad:var(--red);
    --surface:var(--bg);
  }
  *{box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
  html,body{margin:0;height:100%;
    font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;
    color:var(--t1);background:var(--bg);font-size:14px;line-height:1.5}
  a{color:var(--blue);text-decoration:none}
  a:hover{text-decoration:underline}
  button{font:inherit;cursor:pointer}
  input,select,textarea{font:inherit}

  /* Layout — sidebar + main */
  .app{display:flex;flex-direction:row;min-height:100vh}
  .topbar{flex:0 0 248px;width:248px;background:var(--navy);color:rgba(255,255,255,0.7);
    position:sticky;top:0;align-self:flex-start;height:100vh;overflow-y:auto;z-index:30}
  /* Topbar layout — matches APQ Recruitment portal exactly:
     padding 22px 14px 0, brand uses margin-bottom:14px to gap to nav, no flex gap. */
  .topbar-inner{max-width:none;margin:0;padding:22px 14px 0;height:100%;display:flex;flex-direction:column;align-items:stretch;gap:0}
  .brand{display:flex;align-items:center;gap:12px;color:#fff;padding:4px 8px 22px;margin-bottom:14px;white-space:nowrap;border-bottom:1px solid rgba(255,255,255,0.08)}
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .brand .mark{width:30px;height:36px;background:transparent;color:#fff;display:grid;place-items:center;flex:0 0 30px}
  .brand .mark svg{width:30px;height:36px;display:block}
  /* Match APQ Accounts: brand-text shrinks to content (flex:0 1 auto)
     instead of stretching to fill — keeps "AP Quantum" sized identically
     across all sibling portals. */
  .brand .brand-text{flex:0 1 auto;min-width:0}
  .brand .brand-name{font-size:15px;font-weight:700;color:#fff;letter-spacing:0.1px}
  .brand .brand-sub{font-size:10px;font-weight:500;color:rgba(255,255,255,0.45);text-transform:uppercase;letter-spacing:1.4px;margin-top:2px}
  .brand small{font-weight:400;color:rgba(255,255,255,0.5);font-size:11px;display:block;margin-top:2px}
  /* Nav — matches APQ Accounts exactly */
  .topnav{display:flex;flex-direction:column;gap:1px;flex:1;overflow-y:auto;scrollbar-width:thin;padding:0}
  .topnav::-webkit-scrollbar{width:6px}
  .topnav::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.08);border-radius:4px}
  .topnav button{background:transparent;border:0;padding:9px 12px;font-size:13px;font-weight:500;color:rgba(255,255,255,0.5);text-align:left;white-space:nowrap;transition:all .15s;border-radius:8px;display:flex;align-items:center;gap:11px;position:relative}
  .topnav button .nav-ic{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;flex:0 0 17px;color:inherit;opacity:0.85}
  .topnav button .nav-ic svg{width:17px;height:17px}
  .topnav button .nav-lbl{flex:1;min-width:0}
  .topnav button .nav-badge{flex:0 0 auto;background:rgba(245,166,35,0.18);color:var(--gold);font-size:11px;font-weight:600;padding:2px 7px;border-radius:10px;line-height:1.4;min-width:22px;text-align:center}
  .topnav button .nav-badge.amber{background:rgba(217,119,6,0.2);color:#fbbf24}
  /* Section labels — matches APQ Accounts exactly */
  .topnav .nav-section{font-size:11px;font-weight:700;color:rgba(255,255,255,0.30);letter-spacing:0.12em;padding:18px 8px 6px;margin:0;text-transform:uppercase;pointer-events:none}
  /* In rail (collapsed) mode, replace section labels with a thin divider line */
  body.sb-rail .topnav .nav-section{font-size:0;padding:8px 0;border-top:1px solid rgba(255,255,255,0.08);margin:4px 6px 0}
  .topnav button:hover{background:#1e293b;color:rgba(255,255,255,0.95)}
  .topnav button:hover .nav-ic{opacity:1;color:var(--gold)}
  /* Active state — matches APQ Accounts exactly: inset box-shadow, no padding shift */
  .topnav button.active{background:rgba(245,166,35,0.10);color:#fff;font-weight:500;box-shadow:inset 3px 0 0 var(--gold)}
  .topnav button.active .nav-ic{opacity:1;color:var(--gold)}
  .topnav button.active:hover{background:rgba(245,166,35,0.14)}
  /* Icon-rail collapsed mode */
  body.sb-rail .topbar{flex:0 0 64px;width:64px}
  body.sb-rail .topbar-inner{padding:16px 8px;gap:10px}
  body.sb-rail .brand{justify-content:center;padding:0 0 12px;gap:0}
  body.sb-rail .brand > div:not(.mark){display:none}
  /* sb-collapse rules removed — element no longer exists */
  body.sb-rail .topnav button{justify-content:center;padding:10px 0;border-left:0;border-radius:8px;margin:0 2px}
  body.sb-rail .topnav button.active{border-left:0;background:var(--gold-bg);box-shadow:inset 0 0 0 1px rgba(245,166,35,0.3)}
  body.sb-rail .topnav button .nav-lbl{display:none}
  body.sb-rail .topnav button .nav-badge{position:absolute;top:2px;right:2px;padding:1px 5px;font-size:9.5px;min-width:0}
  body.sb-rail .global-search{display:none}
  body.sb-rail #cloud-badge{padding:8px 4px !important;font-size:10px !important}
  body.sb-rail #cloud-text{display:none}
  body.sb-rail #cloud-dot{margin-right:0}
  .global-search{position:relative;flex:0 0 auto;width:100%;margin-top:auto}
  .global-search input{width:100%;height:auto;border-radius:var(--r);border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.05);padding:10px 40px 10px 14px;font-size:13px;font-weight:500;color:#fff;outline:none;transition:border-color .15s,box-shadow .15s}
  /* Scan (camera) button — sits inside the search field on the right. */
  #gs-scan-btn{position:absolute;right:4px;top:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:6px;background:transparent;color:rgba(255,255,255,0.55);cursor:pointer;transition:background .15s,color .15s}
  #gs-scan-btn:hover{background:rgba(255,255,255,0.1);color:#fff}
  #gs-scan-btn svg{width:18px;height:18px}
  /* Barcode scanner overlay — fullscreen on mobile, modal-ish on desktop */
  #bc-scan-overlay{position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.85);display:none;align-items:center;justify-content:center;padding:16px}
  #bc-scan-overlay.on{display:flex}
  #bc-scan-frame{position:relative;width:100%;max-width:520px;background:#000;border-radius:12px;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,0.5)}
  #bc-scan-frame video{width:100%;height:auto;max-height:70vh;object-fit:cover;display:block;background:#000}
  #bc-scan-reticle{position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;justify-content:center}
  #bc-scan-reticle-inner{width:78%;height:30%;border:3px solid rgba(255,255,255,0.7);border-radius:10px;box-shadow:0 0 0 9999px rgba(0,0,0,0.35)}
  #bc-scan-status{position:absolute;left:0;right:0;bottom:0;padding:10px 14px;background:linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0));color:#fff;font-size:13px;text-align:center;font-weight:500}
  #bc-scan-header{position:absolute;top:0;left:0;right:0;padding:10px 14px;display:flex;justify-content:space-between;align-items:center;background:linear-gradient(to bottom, rgba(0,0,0,0.7), rgba(0,0,0,0));color:#fff;font-weight:600;font-size:14px;z-index:2}
  #bc-scan-close{background:rgba(255,255,255,0.15);border:0;color:#fff;width:32px;height:32px;border-radius:50%;cursor:pointer;font-size:18px;line-height:1;display:flex;align-items:center;justify-content:center}
  #bc-scan-close:hover{background:rgba(255,255,255,0.25)}
  #bc-scan-manual-toggle{background:rgba(255,255,255,0.15);border:0;color:#fff;height:32px;padding:0 12px;border-radius:16px;cursor:pointer;font-size:12px;font-weight:600;margin-right:8px}
  #bc-scan-manual-toggle:hover{background:rgba(255,255,255,0.25)}
  #bc-scan-manual{position:absolute;left:0;right:0;bottom:0;padding:14px;background:rgba(0,0,0,0.92);display:none;flex-direction:column;gap:8px;z-index:3}
  #bc-scan-manual.on{display:flex}
  #bc-scan-manual label{color:#fff;font-size:12px;font-weight:600;letter-spacing:.02em}
  #bc-scan-manual .row{display:flex;gap:8px}
  #bc-scan-manual input{flex:1;height:40px;border-radius:8px;border:1px solid rgba(255,255,255,0.25);background:#fff;color:#111;padding:0 12px;font-size:15px;font-family:inherit;text-transform:uppercase;letter-spacing:.04em}
  #bc-scan-manual input:focus{outline:2px solid #2563eb;border-color:#2563eb}
  #bc-scan-manual button.go{background:#2563eb;border:0;color:#fff;height:40px;padding:0 16px;border-radius:8px;cursor:pointer;font-size:14px;font-weight:600}
  #bc-scan-manual button.go:hover{background:#1d4ed8}
  #bc-scan-manual .hint{color:#cbd5e1;font-size:11.5px}

  /* ===== Scan card ===== */
  #scanCard{position:fixed;inset:0;z-index:9000;display:none;align-items:flex-end;justify-content:center;background:rgba(0,0,0,0.55);padding:0}
  #scanCard.on{display:flex}
  @media(min-width:600px){#scanCard{align-items:center;padding:16px}}
  #scanCard-inner{background:var(--white);width:100%;max-width:480px;border-radius:20px 20px 0 0;padding:0;overflow:hidden;box-shadow:0 -4px 40px rgba(0,0,0,0.18);animation:scSlideUp .22s ease}
  @media(min-width:600px){#scanCard-inner{border-radius:16px;animation:scFadeIn .18s ease}}
  @keyframes scSlideUp{from{transform:translateY(40px);opacity:0}to{transform:translateY(0);opacity:1}}
  @keyframes scFadeIn{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}
  #scanCard-drag{width:36px;height:4px;border-radius:2px;background:#d1d5db;margin:10px auto 0}
  #scanCard-status-bar{display:flex;align-items:center;gap:10px;padding:16px 20px 0}
  #scanCard-status-dot{width:10px;height:10px;border-radius:50%;flex:0 0 10px}
  #scanCard-status-dot.ok{background:#22c55e}
  #scanCard-status-dot.use{background:#3b82f6}
  #scanCard-status-dot.warn{background:#f59e0b}
  #scanCard-status-dot.bad{background:#ef4444}
  #scanCard-status-dot.muted{background:#94a3b8}
  #scanCard-status-dot.gold{background:#eab308}
  #scanCard-status-label{font-size:13px;font-weight:600;color:var(--t2)}
  #scanCard-close-x{margin-left:auto;background:none;border:none;cursor:pointer;color:var(--t3);font-size:20px;line-height:1;padding:0 0 0 8px}
  #scanCard-title{padding:6px 20px 2px;font-size:19px;font-weight:700;color:var(--t1);line-height:1.25}
  #scanCard-sub{padding:0 20px 12px;font-size:13px;color:var(--t2)}
  #scanCard-holder{margin:0 20px 14px;padding:10px 14px;background:#eff6ff;border-radius:10px;font-size:13.5px;color:#1e40af;display:none}
  #scanCard-holder b{display:block;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:#3b82f6;margin-bottom:2px}
  #scanCard-action{padding:0 20px 4px;display:flex;gap:8px;flex-wrap:wrap;align-items:flex-end}
  #scanCard-action .sc-label{font-size:11.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--t3);margin-bottom:4px}
  #scanCard-action .sc-field{display:flex;flex-direction:column;flex:1;min-width:140px}
  #scanCard-action input,#scanCard-action select{height:38px;border:1px solid var(--border);border-radius:8px;padding:0 10px;font-size:14px;font-family:inherit;background:var(--white);color:var(--t1);width:100%}
  #scanCard-action input:focus,#scanCard-action select:focus{outline:2px solid #2563eb;border-color:#2563eb}
  #scanCard-meta{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:14px 20px;border-top:1px solid var(--border);margin-top:4px}
  #scanCard-meta .sc-meta-item{display:flex;flex-direction:column;gap:2px}
  #scanCard-meta .sc-meta-lbl{font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--t3)}
  #scanCard-meta .sc-meta-val{font-size:13.5px;color:var(--t1);font-weight:500}
  #scanCard-foot{display:flex;gap:8px;padding:10px 20px 20px;border-top:1px solid var(--border)}
  #scanCard-foot .btn{flex:1}

  /* ===== View-only mode ===== */
  #vo-banner{display:none;position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:9999;background:#1e293b;color:#f1f5f9;font-size:12.5px;font-weight:600;padding:8px 18px;border-radius:999px;pointer-events:none;white-space:nowrap;box-shadow:0 4px 16px rgba(0,0,0,.3);letter-spacing:.02em}
  body.view-only #vo-banner{display:block}
  /* Hide write-only nav items */
  body.view-only [data-view="bulk"],
  body.view-only [data-view="checkout"],
  body.view-only [data-view="stocktake"],
  body.view-only [data-view="labels"],
  body.view-only [data-view="settings"]{display:none}
  /* Hide write buttons throughout */
  body.view-only .m-scan,
  body.view-only #gs-scan-btn,
  body.view-only #scanCard-edit-btn,
  body.view-only #assetDeleteBtn,
  body.view-only #assetTransferBtn,
  body.view-only #assetModal .foot .btn-primary,
  body.view-only #locationModal .foot .btn-primary,
  body.view-only #locationModal .foot .btn-danger,
  body.view-only #ownerModal .foot .btn-primary,
  body.view-only #ownerModal .foot .btn-danger,
  body.view-only #staffModal .foot .btn-primary,
  body.view-only #staffModal .foot .btn-danger,
  body.view-only #staffCardDeleteBtn,
  body.view-only button[onclick="openAssetModal()"],
  body.view-only button[onclick="openOwnerModal()"],
  body.view-only button[onclick="openLocationModal()"],
  body.view-only button[onclick="openLeadModal()"],
  body.view-only button[onclick="openVoipModal()"]{display:none !important}

  /* ===== Stock-take view ===== */
  .st-counters{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
  .st-counter{display:flex;flex-direction:column;align-items:center;justify-content:center;background:var(--card,#fff);border:1px solid var(--border);border-radius:10px;padding:12px 8px;text-align:center}
  .st-counter .st-num{font-size:24px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
  .st-counter .st-lbl{font-size:11.5px;color:var(--muted,#6b7280);margin-top:2px;font-weight:500;text-transform:uppercase;letter-spacing:.04em}
  .st-counter.ok .st-num{color:#059669}
  .st-counter.pending .st-num{color:#dc2626}
  .st-counter.warn .st-num{color:#d97706}
  .st-counter.total .st-num{color:#111827}
  .st-recent{display:flex;flex-direction:column;gap:6px;max-height:240px;overflow:auto;padding:4px}
  .st-recent .st-row{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;background:#f8fafc;border:1px solid #eef2f7;font-size:13px}
  .st-recent .st-row .st-tag{font-weight:600;font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:12px;padding:2px 7px;border-radius:6px}
  .st-recent .st-row.found .st-tag{background:#dcfce7;color:#166534}
  .st-recent .st-row.foreign .st-tag{background:#fef3c7;color:#92400e}
  .st-recent .st-row.dup .st-tag{background:#e0e7ff;color:#3730a3}
  .st-recent .st-row.unknown .st-tag{background:#fee2e2;color:#991b1b}
  .st-recent .st-row .st-id{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-weight:600;color:#111827}
  .st-recent .st-row .st-meta{color:#6b7280;font-size:12px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .st-tabs{display:flex;gap:4px;border-bottom:1px solid var(--border);padding:0}
  .st-tab{background:transparent;border:0;border-bottom:2px solid transparent;padding:10px 14px;font-size:14px;font-weight:600;color:#6b7280;cursor:pointer}
  .st-tab.active{color:#111827;border-bottom-color:#2563eb}
  .st-tab:hover{color:#111827}
  .st-tab-body{margin-top:14px;max-height:420px;overflow:auto}
  .st-tab-body .st-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;border:1px solid #eef2f7;margin-bottom:6px;font-size:13.5px;background:#fff}
  .st-tab-body .st-row .st-id{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-weight:600;color:#2563eb;cursor:pointer;min-width:90px}
  .st-tab-body .st-row .st-name{flex:1;color:#374151;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .st-tab-body .st-row .st-where{color:#6b7280;font-size:12.5px;flex-shrink:0}
  .st-tab-body .st-empty{padding:24px;text-align:center;color:#6b7280;font-size:13.5px}
  /* Compact counters on narrow screens */
  @media (max-width:600px){
    .st-counters{grid-template-columns:repeat(2,1fr)}
    .st-counter .st-num{font-size:22px}
  }
  /* Quick-flash on successful stock-take scan to confirm without leaving the camera */
  #bc-scan-overlay.st-flash #bc-scan-frame{animation:stFlash 0.35s ease-out}
  @keyframes stFlash{
    0%   { box-shadow: 0 0 0 0 rgba(5,150,105,0); }
    30%  { box-shadow: 0 0 0 8px rgba(5,150,105,.55); }
    100% { box-shadow: 0 20px 60px rgba(0,0,0,0.5); }
  }
  #bc-scan-overlay.st-flash-warn #bc-scan-frame{animation:stFlashWarn 0.35s ease-out}
  @keyframes stFlashWarn{
    0%   { box-shadow: 0 0 0 0 rgba(217,119,6,0); }
    30%  { box-shadow: 0 0 0 8px rgba(217,119,6,.55); }
    100% { box-shadow: 0 20px 60px rgba(0,0,0,0.5); }
  }
  .global-search input::placeholder{color:rgba(255,255,255,0.35)}
  .global-search input:focus{background:rgba(255,255,255,0.08);border-color:rgba(245,166,35,0.5);box-shadow:0 0 0 3px rgba(245,166,35,0.1)}
  .gs-dropdown{position:absolute;bottom:calc(100% + 6px);left:0;width:100%;max-height:360px;overflow-y:auto;background:#fff;border:1px solid var(--border);border-radius:var(--r2);box-shadow:var(--shadow3);z-index:40;padding:6px}
  .gs-item{display:block;width:100%;text-align:left;background:transparent;border:0;padding:10px 12px;border-radius:var(--r);font-size:13px;color:var(--t1);cursor:pointer}
  .gs-item:hover,.gs-item.hi{background:var(--bg)}
  .gs-item .gs-meta{color:var(--t3);font-size:11.5px;margin-top:2px}
  .gs-item .gs-tag{display:inline-block;background:var(--bg);border-radius:var(--r);padding:1px 8px;font-size:10.5px;margin-right:6px;color:var(--t2);font-weight:500}
  .gs-empty{padding:14px;color:var(--t3);font-size:13px;text-align:center}
  /* Sidebar footer card — mirrors APQ Accounts layout */
  /* sidebar-footer is now nested inside .sb-action-group which carries the
     slate panel background. Keeping just layout rules here so we don't get a
     card-in-card visual. */
  .sidebar-footer{display:flex;flex-direction:column;gap:10px;flex:0 0 auto}
  .sidebar-footer .user-row{display:flex;align-items:center;gap:10px;padding:0;width:100%}
  .sidebar-footer .avatar{width:34px;height:34px;border-radius:50%;background-image:linear-gradient(135deg, #F5A623, #C47D0A);color:#0E1C2E;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:12px;flex:0 0 34px;letter-spacing:0.3px}
  .sidebar-footer .user-meta{flex:1;min-width:0;line-height:1.25}
  .sidebar-footer .user-name{font-size:13px;font-weight:600;color:#fff;letter-spacing:0.1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .sidebar-footer .user-role{font-size:11px;font-weight:400;color:rgba(255,255,255,0.5);display:flex;align-items:center;gap:5px}
  .sidebar-footer .user-role .dot{width:6px;height:6px;border-radius:50%;background:#22c55e;flex:0 0 6px}
  .sidebar-footer .icon-btn{width:32px;height:32px;border-radius:8px;background:transparent;border:0;color:rgba(255,255,255,0.7);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;flex:0 0 32px;transition:background .15s,color .15s}
  .sidebar-footer .icon-btn:hover{background:rgba(255,255,255,0.08);color:#fff}
  .sidebar-footer .icon-btn svg{width:16px;height:16px}
  .sidebar-footer .switch-btn{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.85);border:1px solid rgba(255,255,255,0.15);border-radius:8px;padding:8px 10px;font-size:12px;font-weight:500;cursor:pointer;width:100%;transition:background .15s,border-color .15s,color .15s;display:flex;align-items:center;justify-content:center;gap:6px}
  .sidebar-footer .switch-btn:hover{background:rgba(245,166,35,0.15);color:var(--gold);border-color:rgba(245,166,35,0.4)}
  .sidebar-status{display:flex;align-items:center;gap:6px;justify-content:center;padding:6px 10px;border-radius:999px;background:rgba(255,255,255,0.10);border:1px solid rgba(255,255,255,0.16);font-size:11px;font-weight:600;color:#fff;letter-spacing:0.2px;cursor:pointer;width:100%;transition:background .15s,border-color .15s,color .15s}
  .sidebar-status:hover{background:rgba(255,255,255,0.16);border-color:rgba(255,255,255,0.24)}
  .sidebar-status .dot{width:7px;height:7px;border-radius:50%;background:#9ca3af;flex:0 0 7px;box-shadow:0 0 0 2px rgba(255,255,255,0.04)}
  .sidebar-status.live{background:rgba(34,197,94,0.22);border-color:rgba(34,197,94,0.40);color:#bbf7d0}
  .sidebar-status.live .dot{background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,0.18);animation:livepulse 2s ease-in-out infinite}
  .sidebar-status.syncing{background:rgba(245,158,11,0.22);border-color:rgba(245,158,11,0.40);color:#fde68a}
  .sidebar-status.syncing .dot{background:#f59e0b;box-shadow:0 0 0 3px rgba(245,158,11,0.18);animation:livepulse 1.2s ease-in-out infinite}
  .sidebar-status.error,.sidebar-status.offline{background:rgba(239,68,68,0.22);border-color:rgba(239,68,68,0.40);color:#fecaca}
  .sidebar-status.error .dot,.sidebar-status.offline .dot{background:#ef4444;box-shadow:0 0 0 3px rgba(239,68,68,0.18)}
  .sidebar-status.stale{background:rgba(245,158,11,0.18);border-color:rgba(245,158,11,0.32);color:#fde68a}
  .sidebar-status.stale .dot{background:#f59e0b;box-shadow:0 0 0 3px rgba(245,158,11,0.18)}
  @keyframes livepulse{0%,100%{opacity:1}50%{opacity:0.55}}

  /* Layout — matches APQ Accounts. The page-head becomes a real sticky top
     bar on desktop (white background, bottom border, breaks out of .main's
     horizontal padding so it spans edge-to-edge of the content area). */
  /* Horizontal padding on desktop — 2rem (32px) to match APQ Accounts'
     .content wrapper. Top stays at 0 so the sticky .page-head sits flush
     against the top of the main column (no body-background strip showing
     above the white header). The page-head's negative margins follow so it
     spans edge-to-edge of the content area. */
  .main{width:100%;padding:0 32px 40px;flex:1;min-width:0}
  .page-head{
    position:sticky;top:0;z-index:10;
    display:flex;align-items:center;justify-content:space-between;
    background:var(--white);
    margin:0 -32px 16px;
    padding:14px 32px;
    border-bottom:1px solid var(--border);
    flex-wrap:wrap;gap:12px
  }
  .page-head h2{margin:0;font-size:20px;font-weight:700;color:var(--t1);line-height:30px;letter-spacing:-0.2px}
  .page-head .btn{height:34px;padding-top:0;padding-bottom:0;box-sizing:border-box}
  .page-head p{margin:2px 0 0;color:var(--t3);font-size:13px}

  /* Bulk Add page-specific toolbar — sits below the sticky page-head and
     scrolls with content. Used for pages with many page-specific actions
     (8+ buttons) that would crowd the top bar. */
  .bulk-toolbar{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 16px;padding:0}
  .bulk-toolbar .btn{flex:0 0 auto}
  @media (max-width:768px){
    .bulk-toolbar{margin:0 0 12px;padding:0 4px;overflow-x:auto;flex-wrap:nowrap;-webkit-overflow-scrolling:touch}
    .bulk-toolbar::-webkit-scrollbar{display:none}
    .bulk-toolbar{scrollbar-width:none}
  }

  /* QR engine readiness chip — shown next to the Labels page title.
     Loading = amber spinner, Ready = green check, Failed = red.
     vertical-align tuned to optically center against the h2 cap-height. */
  .qr-status{display:inline-flex;align-items:center;gap:5px;vertical-align:middle;margin-left:8px;position:relative;top:-2px;padding:1px 8px;border-radius:999px;font-size:10px;font-weight:600;border:1px solid transparent;letter-spacing:0.02em;background:#fff7ed;color:#9a3412;border-color:#fed7aa;line-height:1.5}
  .qr-status::before{content:"";width:6px;height:6px;border-radius:50%;background:#f59e0b;animation:qrpulse 1.2s ease-in-out infinite;flex:0 0 6px}
  .qr-status.ready{background:#dcfce7;color:#166534;border-color:#bbf7d0}
  .qr-status.ready::before{background:#16a34a;animation:none}
  .qr-status.ready::after{content:"";width:8px;height:8px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23166534' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");background-size:contain;background-repeat:no-repeat;background-position:center}
  .qr-status.fail{background:#fee2e2;color:#991b1b;border-color:#fecaca}
  .qr-status.fail::before{background:#dc2626;animation:none}
  @keyframes qrpulse{0%,100%{opacity:1}50%{opacity:0.35}}

  /* Hide the in-page title block on mobile — the m-header already shows it.
     Action buttons get teleported to a sticky bottom bar (see below). */
  @media (max-width:768px){
    .page-head > div:first-child:not(.btn-row){display:none}
    .page-head{margin:0;padding:0;min-height:0}

    /* Sticky bottom action bar — every page's .page-head .btn-row gets pinned
       to the viewport bottom so primary actions (Add Asset, Save as PNG,
       Print Labels, Export CSV, etc.) are always one tap away regardless of
       scroll position. Mirrors the modal's sticky-foot pattern. */
    .page-head .btn-row{
      position:fixed;bottom:0;left:0;right:0;z-index:40;
      background:#fff;
      border-top:1px solid var(--border);
      padding:10px 12px;
      padding-bottom:max(10px, env(safe-area-inset-bottom));
      gap:8px;display:flex;margin:0;
      box-shadow:0 -2px 12px rgba(0,0,0,0.06)
    }
    .page-head .btn-row > .btn{flex:1 1 auto;min-width:0}

    /* Reserve room at the bottom of the scroll container so the last bit of
       content isn't hidden behind the sticky bar. */
    .main{padding-bottom:calc(86px + env(safe-area-inset-bottom)) !important}

    /* FAB sits ABOVE the sticky action bar so they don't overlap. */
    .fab{bottom:calc(86px + env(safe-area-inset-bottom)) !important}

    /* Hide the "X rows in template" counter on mobile — purely informational and
       takes up valuable horizontal space on a narrow screen. */
    #bulk-count{display:none}
  }

  /* Mobile header — hamburger + brand, always visible on mobile.
     gap:12px controls the spacing between hamburger ↔ title ↔ scan-icon. */
  .m-header{display:none;align-items:center;gap:12px;padding:10px 12px;background:#fff;color:#111827;position:sticky;top:0;z-index:55;border-bottom:1px solid #e5e7eb;justify-content:space-between}
  .m-header .m-title{margin-left:0}
  .m-header .hamburger{background:transparent;border:1px solid #d1d5db;color:#374151;width:38px;height:38px;border-radius:8px;cursor:pointer;display:grid;place-items:center;padding:0;flex:0 0 38px}
  .m-header .hamburger svg{width:20px;height:20px}
  .m-header .hamburger:active,.m-header .hamburger:hover{background:#f3f4f6}
  .m-header .m-title{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}
  .m-header .m-title h1{margin:0;font-size:16px;font-weight:600;line-height:24px;color:#111827;letter-spacing:normal;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-header .m-title p{margin:2px 0 0;font-size:12.5px;font-weight:400;line-height:1.35;color:#6b7280;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-header .m-scan{background:transparent;border:1px solid #d1d5db;color:#374151;width:38px;height:38px;border-radius:8px;cursor:pointer;display:grid;place-items:center;padding:0;flex:0 0 38px}
  .m-header .m-scan:active,.m-header .m-scan:hover{background:#f3f4f6}
  .m-header .m-scan svg{width:20px;height:20px}

  /* Sidebar drawer backdrop (mobile only) */
  .sb-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.45);opacity:0;pointer-events:none;transition:opacity .25s ease;z-index:70}
  body.sb-open .sb-backdrop{opacity:1;pointer-events:auto}
  /* sb-close-btn removed — drawer closes via backdrop tap or selecting a nav item. */

  /* mobile: sidebar becomes a left drawer triggered by hamburger */
  @media (max-width:768px){
    .app{flex-direction:column}
    .m-header{display:flex}
    /* Scan icon hidden on mobile — barcode scanner is reachable via the
       hamburger then sidebar's "Scan or search" input, so the m-header stays
       lean (just hamburger + title) at 768px and 480px. */
    .m-header .m-scan{display:none !important}

    /* Mobile sidebar — matches APQ Accounts visually but with a higher
       z-index than the .sb-backdrop (70) so taps on nav items aren't
       intercepted. Stacking: content < m-header (55) < backdrop (70) <
       sidebar (100) < modal (120). */
    .topbar{position:fixed !important;top:0;bottom:0;width:248px !important;max-width:248px;height:100dvh !important;flex:none !important;left:-260px;transform:none;transition:left .2s ease;z-index:100;overflow-y:auto;padding-bottom:max(14px, env(safe-area-inset-bottom));box-shadow:2px 0 20px rgba(0,0,0,0.25)}
    .topbar-inner{height:auto !important;min-height:100%;padding:22px 14px 0;overflow:visible;display:flex;flex-direction:column;gap:0}
    .topbar-inner > .topnav,
    .topbar-inner > #nav{flex:1 1 auto;overflow-y:visible}
    .topbar-inner > .sidebar-footer{margin-top:auto;flex:0 0 auto}
    body.sb-open .topbar{left:0}

    /* Section labels stay readable on mobile. The desktop rail rule
       (body.sb-rail .topnav .nav-section{font-size:0...}) was leaking into
       the mobile drawer when the rail class persisted, hiding labels and
       leaving only the border-top showing as a thin line. */
    body.sb-rail .topnav .nav-section,
    .topnav .nav-section{font-size:11px !important;padding:12px 8px 6px !important;border-top:0 !important;margin:0 !important;color:rgba(255,255,255,0.40) !important;letter-spacing:0.12em !important;font-weight:700 !important;text-transform:uppercase !important}

    /* Restore the brand on mobile — was getting flattened by the rail rules
       leaking into mobile context. */
    body.sb-rail .brand,
    .brand{padding:4px 8px 22px !important;justify-content:flex-start !important;gap:12px !important}
    body.sb-rail .brand > div:not(.mark),
    .brand > div:not(.mark){display:block !important}
    body.sb-rail .brand .brand-text .brand-name,
    .brand .brand-name{font-size:15px !important}

    /* Restore the sidebar footer's Admin / Administration text + Synced label
       on mobile. The desktop rail-mode rule
       (body.sb-rail .sidebar-footer .user-meta { display:none }) was leaking
       into the mobile drawer, leaving only the avatar and an empty status pill. */
    body.sb-rail .sidebar-footer .user-meta,
    .sidebar-footer .user-meta{display:block !important}
    body.sb-rail .sidebar-status #cloud-text,
    .sidebar-status #cloud-text{display:inline !important}

    /* Ensure drawer content is vertical (override any horizontal mobile rules) */
    .topbar-inner{flex-direction:column !important;padding:22px 12px 16px;gap:10px;align-items:stretch;overflow-y:auto;height:100%}

    /* Nav stays vertical inside drawer */
    .topnav{flex-direction:column !important;flex:1 1 auto !important;overflow-y:auto;gap:1px;overflow-x:visible !important}
    .topnav button{border-left:3px solid transparent !important;border-bottom:0 !important;padding:12px 14px !important;font-size:14px !important;width:100%;justify-content:flex-start !important;white-space:normal}
    .topnav button.active{border-left-color:var(--gold) !important;border-bottom-color:transparent !important}

    /* Mobile-only sidebar slimming — keep "Scan or search" input (it's the
       primary search/scan entry point now that the FAB is gone). Hide only
       the Print view button (Cmd+P / Dashboard Print covers it). */
    .topbar .sidebar-footer .switch-btn{display:none !important}
    /* iOS Safari auto-zooms inputs whose font-size is below 16px when focused.
       Force 16px on the sidebar search to suppress that zoom-on-tap. */
    .topbar .global-search input{font-size:16px !important}
    #cloud-badge{width:100% !important}
    .gs-dropdown{bottom:calc(100% + 6px);top:auto}

    /* Undo any sb-rail (desktop collapsed) styling while on mobile */
    body.sb-rail .topbar{width:min(86vw, 320px) !important;flex:none !important;padding:0}
    body.sb-rail .topbar-inner{padding:22px 12px 16px !important;gap:10px !important;flex-direction:column !important}
    body.sb-rail .brand{padding:0 10px 14px !important;justify-content:flex-start !important;border-bottom:1px solid rgba(255,255,255,0.08) !important}
    body.sb-rail .brand > div:not(.mark){display:block !important}
    body.sb-rail .topnav button{justify-content:flex-start !important;padding:12px 14px !important;border-left:3px solid transparent !important;border-radius:0 !important;margin:0 !important}
    body.sb-rail .topnav button.active{border-left-color:var(--gold) !important;background:var(--gold-bg) !important;box-shadow:none !important}
    body.sb-rail .topnav button .nav-lbl{display:inline-block !important}
    body.sb-rail .topnav button .nav-badge{position:static !important;padding:2px 7px !important;font-size:11px !important;min-width:22px !important}
    body.sb-rail .global-search{display:flex !important}
    body.sb-rail #cloud-badge{padding:10px 14px !important;font-size:13px !important}
    body.sb-rail #cloud-text{display:inline !important}
    /* sb-collapse rules removed — element no longer exists */

    .main{padding:6px 10px 12px}

    /* Modal head — avoid Print+Delete+× fighting for space with a long title.
       Let the button-row wrap to a second line; title keeps the full first line. */
    /* Header layout: title on the left, × close on the right (single row).
       Long button-rows (Print + Delete + Cancel + Save) still wrap to a
       second line — they're inside .btn-row which is flex:0 0 100%. */
    .modal .head{flex-wrap:wrap;padding:14px 16px;gap:10px;align-items:center;justify-content:space-between}
    .modal .head h3{flex:1 1 auto;min-width:0;font-size:16px;line-height:1.3;word-break:break-word;margin:0}
    .modal .head > .btn-ghost{margin-left:auto}
    .modal .head .btn-row{flex:0 0 100%;justify-content:flex-end}
    .modal .body{padding:14px 16px}
    .modal .foot{padding:12px 14px;flex-wrap:wrap;gap:8px}

    /* Staff handover card — stack header and table for mobile readability */
    .staff-card{padding:0}
    .staff-card .hdr{flex-direction:column;align-items:flex-start;gap:10px;padding-bottom:12px;margin-bottom:14px}
    .staff-card .who h2{font-size:22px}
    .staff-card .meta{text-align:left;font-size:12px;line-height:1.6}
    .staff-card table{display:block;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch;font-size:12px}
    .staff-card th,.staff-card td{padding:8px 10px;white-space:nowrap}
    .staff-card .sig{grid-template-columns:1fr;gap:28px;margin-top:28px}
    .staff-card .sig .line{text-align:left}

    /* ── Mobile readability — bump tiny labels so users don't reach for pinch-zoom ──
       Desktop keeps the original compact density; phones get a +1-2px nudge on
       small text. WCAG SC 1.4.4 + Apple HIG suggest 12-14px minimum body text
       on touch devices held at arm's length. */
    .kpi-col .kpi-label,
    .pill, .chip, .status,
    .nav-badge, .ms-count,
    .qr-status, .sidebar-status, .sidebar-footer .user-role,
    .cmdk-item .k-group, .cmdk-hint,
    .staff-tile .tag, .staff-tile .contact .ico,
    .chip-filter .n,
    .staff-card th, .staff-card .badge,
    h3.section-title,
    table.loc-tbl td .loc-auto-tag,
    table.own-tbl td.id-cell .own-unreg{font-size:12px !important}
    th{font-size:12px !important}
    .brand .brand-sub{font-size:11px !important}
    .brand small{font-size:12px !important}

    /* Hamburger / scan buttons stay at the base 38×38 size to match APQ
       Accounts visually. Touch target compliance for asset links is still
       handled by the .mono a tap-padding rule below. */
    /* Asset ID links and inline action anchors get a tap-padding so the row
       click area meets the 44px minimum even though the visible text stays
       compact. */
    .mono a, td.mono a, td a.mono{display:inline-block;padding:10px 4px;margin:-10px -4px;min-height:44px;line-height:24px;box-sizing:border-box}
  }

  /* Cards */
  .card{background:var(--white);border:1px solid var(--border);border-radius:var(--r3);overflow:hidden;box-shadow:var(--shadow);transition:box-shadow .2s,border-color .2s}
  .card .head{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;border-bottom:1px solid var(--border)}
  .card .head h3{margin:0;font-size:13px;font-weight:600;color:var(--t2)}
  .card .body{padding:1.5rem}
  .card .body.pad0{padding:0}

  .grid{display:grid;gap:14px}
  .grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}
  .grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  @media (max-width:900px){
    .grid-4{grid-template-columns:repeat(2,1fr)}
    .grid-3,.grid-2{grid-template-columns:1fr}
    .topbar-inner{gap:14px}
    .page-head h2{font-size:26px}
  }

  /* KPI — clean summary strip */
  .kpi-strip{display:flex;align-items:stretch;background:var(--white);border:1px solid var(--border);border-radius:var(--r2);overflow:hidden;transition:box-shadow .2s ease}
  .kpi-col{flex:1;padding:20px 24px;position:relative;display:flex;flex-direction:column;justify-content:center;min-width:0;transition:background .18s ease}
  .kpi-col + .kpi-col{border-left:1px solid var(--border)}
  .kpi-col:hover{background:var(--bg)}
  .kpi-col .kpi-label{color:var(--t3);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.06em}
  .kpi-col .kpi-value{font-size:30px;font-weight:600;margin-top:6px;line-height:1.1;color:var(--t1);letter-spacing:-0.02em;font-variant-numeric:tabular-nums}
  .kpi-col .kpi-sub{color:var(--t3);font-size:12px;margin-top:6px;display:flex;align-items:center;gap:6px}
  .kpi-col .delta{font-weight:600;font-size:11.5px}
  .kpi-col .delta.up{color:#166534}
  .kpi-col .delta.down{color:#991b1b}
  .kpi-col .delta.flat{color:var(--t3)}
  /* Inverted polarity for "negative" KPIs (e.g. Unaccounted) where going UP
     is bad news, not good. Used on tiles where the desired direction is down. */
  .kpi-col .delta.inverse.up{color:#991b1b}
  .kpi-col .delta.inverse.down{color:#166534}
  .kpi-col .delta.inverse.flat{color:var(--t3)}
  .kpi-col .accent{position:absolute;top:0;left:0;right:0;height:2px}
  .kpi-col.blue .accent{background:var(--blue)}
  .kpi-col.green .accent{background:var(--green)}
  .kpi-col.amber .accent{background:var(--amber)}
  .kpi-col.red .accent{background:var(--red)}
  .skel{background:linear-gradient(90deg,var(--border) 25%,var(--bg) 50%,var(--border) 75%);background-size:200% 100%;animation:skel-shimmer 1.4s infinite;display:block}
  @keyframes skel-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}
  .kpi-col .spark{position:absolute;right:14px;top:14px;opacity:.55;pointer-events:none}
  .kpi-col .spark path{fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
  .kpi-col.blue  .spark path{stroke:var(--blue)}
  .kpi-col.green .spark path{stroke:#166534}
  .kpi-col.amber .spark path{stroke:#a16207}
  .kpi-col.red   .spark path{stroke:#991b1b}

  /* Status breakdown strip — reconciles Total = Available + In Use + everything else */
  .status-strip{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
  .status-chip{display:inline-flex;align-items:center;gap:8px;background:var(--white);border:1px solid var(--border);border-radius:999px;padding:6px 12px;font-size:12.5px;color:var(--t2);cursor:pointer;transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease}
  .status-chip:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,.06);border-color:#c7ccd3}
  .status-chip b{color:var(--t1);font-weight:600;font-variant-numeric:tabular-nums}
  .status-chip .dot{width:8px;height:8px;border-radius:50%;flex:0 0 8px}
  .status-chip .dot.pulse{animation:statusPulse 2.2s ease-in-out infinite}
  @keyframes statusPulse{0%,100%{box-shadow:0 0 0 0 rgba(0,0,0,0)}50%{box-shadow:0 0 0 5px rgba(0,0,0,.05)}}
  .status-chip.ok .dot{background:#22c55e}
  .status-chip.use .dot{background:#3b82f6}
  .status-chip.warn .dot{background:#f59e0b}
  .status-chip.bad .dot{background:#ef4444}
  .status-chip.muted .dot{background:#94a3b8}
  .status-chip.gold .dot{background:#eab308}

  /* "Back to staff card" trail — only shown after navigating from a staff click.
     [hidden] !important is required because the pill uses display:flex and the
     bare `hidden` attribute would otherwise lose specificity. */
  .back-trail{margin:0 0 12px;padding:10px 14px;background:#fef3c7;border:1px solid #fde68a;border-radius:8px;display:flex;align-items:center;gap:10px;font-size:13px}
  .back-trail[hidden]{display:none !important}

  /* Skeleton loader */
  .skeleton{background:linear-gradient(90deg,#eef0f3 0%,#f7f8fa 50%,#eef0f3 100%);background-size:200% 100%;animation:skelShine 1.3s linear infinite;border-radius:6px;color:transparent !important}
  @keyframes skelShine{0%{background-position:200% 0}100%{background-position:-200% 0}}
  .skel-row{height:12px;margin:8px 0}
  .skel-box{height:60px}

  /* Respect users who prefer reduced motion — disable non-essential animations */
  @media (prefers-reduced-motion: reduce){
    *, *::before, *::after{
      animation-duration:0.01ms !important;
      animation-iteration-count:1 !important;
      transition-duration:0.01ms !important;
      scroll-behavior:auto !important;
    }
    .skeleton{animation:none !important;background:#eef0f3 !important}
  }

  /* Command palette */
  .cmdk-bg{position:fixed;inset:0;background:rgba(17,24,39,.35);backdrop-filter:blur(2px);z-index:9998;display:flex;align-items:flex-start;justify-content:center;padding-top:12vh;opacity:0;transition:opacity .18s ease}
  .cmdk-bg[hidden]{display:none !important} /* CRITICAL: HTML `hidden` attr must win over display:flex, otherwise a transparent overlay blocks clicks on the Dashboard */
  .cmdk-bg.show{opacity:1}
  .cmdk{width:min(640px,92vw);background:var(--white);border:1px solid var(--border);border-radius:14px;box-shadow:0 25px 60px rgba(0,0,0,.25);overflow:hidden;transform:translateY(-8px);transition:transform .22s ease}
  .cmdk-bg.show .cmdk{transform:translateY(0)}
  .cmdk input{width:100%;padding:16px 18px;font-size:15px;border:0;outline:0;border-bottom:1px solid var(--border);background:transparent;color:var(--t1)}
  .cmdk input::placeholder{color:var(--t4)}
  .cmdk-list{max-height:56vh;overflow-y:auto}
  .cmdk-item{display:flex;align-items:center;gap:10px;padding:10px 16px;font-size:13.5px;color:var(--t2);cursor:pointer;border-left:2px solid transparent}
  .cmdk-item .k-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .cmdk-item .k-group{font-size:11px;color:var(--t4);text-transform:uppercase;letter-spacing:.06em;font-weight:600}
  .cmdk-item.active{background:var(--bg);border-left-color:var(--blue);color:var(--t1)}
  .cmdk-item:hover{background:var(--bg)}
  .cmdk-empty{padding:22px 16px;color:var(--t4);font-size:13px;text-align:center}
  .cmdk-hint{padding:8px 16px;font-size:11px;color:var(--t4);border-top:1px solid var(--border);background:var(--bg);display:flex;gap:14px;justify-content:space-between}
  .cmdk-hint kbd{background:var(--white);border:1px solid var(--border);border-radius:4px;padding:1px 6px;font-family:"SF Mono","Menlo",monospace;font-size:10.5px}

  /* Subtle pulse on Available status dot — signals "ready to deploy" */
  .status.available::before{animation:statusPulse 2.4s ease-in-out infinite}

  /* Page fade transition */
  .view{animation:viewFade .22s ease}
  @keyframes viewFade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}

  /* Button/tile hover lift */
  .btn{transition:transform .12s ease, box-shadow .18s ease, background-color .18s ease}
  .btn:hover{transform:translateY(-1px);box-shadow:0 3px 8px rgba(0,0,0,.06)}
  .btn:active{transform:translateY(0);box-shadow:none}
  .card{transition:box-shadow .18s ease, border-color .18s ease}
  .card:hover{box-shadow:0 4px 12px rgba(0,0,0,.04)}

  /* Empty state */
  .empty-state{padding:48px 20px;text-align:center;color:var(--t3)}
  .empty-state svg{width:72px;height:72px;opacity:.45;margin-bottom:14px}
  .empty-state h4{font-size:15px;color:var(--t2);margin:0 0 4px 0;font-weight:600}
  .empty-state p{margin:0;font-size:13px;color:var(--t4)}

  /* Floating action button (mobile only) */
  .fab{display:none;position:fixed;right:18px;bottom:18px;z-index:900}
  .fab-main{width:56px;height:56px;border-radius:50%;background:var(--blue);color:#fff;border:0;box-shadow:0 10px 24px rgba(30,64,175,.35);font-size:28px;line-height:0;cursor:pointer;transition:transform .15s ease}
  .fab-main:active{transform:scale(.94)}
  .fab-menu{position:absolute;right:4px;bottom:64px;display:flex;flex-direction:column;gap:10px;align-items:flex-end;opacity:0;transform:translateY(8px) scale(.95);pointer-events:none;transition:opacity .18s ease, transform .18s ease}
  .fab.open .fab-menu{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}
  .fab-item{display:inline-flex;align-items:center;gap:10px;background:var(--white);border:1px solid var(--border);padding:10px 14px;border-radius:999px;font-size:13px;color:var(--t1);box-shadow:0 6px 14px rgba(0,0,0,.1);cursor:pointer;white-space:nowrap}
  .fab-item:active{background:var(--bg)}
  @media (max-width:768px){
    input,select,textarea,.global-search input{font-size:16px !important}
    .kpi-strip{flex-direction:column}
    .kpi-col + .kpi-col{border-left:0;border-top:1px solid var(--border)}
    /* Bump tap targets on mobile — desktop-density controls are too small for fingers */
    #tbl-assets .qa-btn{width:38px;height:38px}
    #tbl-assets .qa-btn svg{width:16px;height:16px}
    #gs-scan-btn{width:38px;height:38px;top:4px}
    #gs-scan-btn svg{width:20px;height:20px}

    /* Patch 5 — universal mobile tap-target bump for icon buttons in tables/cards */
    .row-actions button,
    .row-actions a.btn,
    table button[title]:not(.btn):not(.btn-primary):not(.btn-secondary),
    .icon-btn,
    .qa-btn{
      min-width:38px;min-height:38px;
      display:inline-grid;place-items:center;
      padding:0;
    }
    .row-actions button svg,
    .icon-btn svg,
    .qa-btn svg{ width:18px;height:18px }

    /* Patch 8 — pin first column on wide tables so context never disappears during horizontal scroll */
    #tbl-bulk th:first-child, #tbl-bulk td:first-child,
    #tbl-owners th:first-child, #tbl-owners td:first-child,
    #tbl-locations th:first-child, #tbl-locations td:first-child{
      position:sticky; left:0; z-index:2;
      background:var(--white);
      box-shadow:1px 0 0 var(--border);
    }
    #tbl-bulk thead th:first-child,
    #tbl-owners thead th:first-child,
    #tbl-locations thead th:first-child{
      background:var(--bg);
      z-index:3;
    }

    /* Patch 9 — on mobile the hamburger toggles the drawer; the brand logo no longer needs to */
    .brand .mark[onclick]{ pointer-events:none }

    /* Main content padding on mobile — 16px top to match APQ Accounts'
       .content padding: 1rem on mobile. */
    .main{padding:16px 10px 12px}
    /* Hide .page-head entirely on mobile — the .m-header already shows the
       title (and FAB / sidebar handle add actions). Leaving page-head visible
       collapsed it to a 1px-tall element whose border-bottom rendered as an
       orphan horizontal line that overlapped the toolbar / pills below. */
    .page-head{display:none !important}
    .page-head h2{font-size:22px}
    .card .body{padding:14px}
    .card .head{padding:12px 14px}

    /* Assets table — hide low-priority columns so what's left fits comfortably.
       Visible on mobile: Asset ID, Device Name, Staff, Status, Actions.
       Hidden on mobile: checkbox, Owner, Category, Brand, Model, Serial, AnyDesk, Location, Sold Price, Sold Date. */
    #tbl-assets th:nth-child(1),  #tbl-assets td:nth-child(1),  /* checkbox */
    #tbl-assets th:nth-child(3),  #tbl-assets td:nth-child(3),  /* Owner */
    #tbl-assets th:nth-child(4),  #tbl-assets td:nth-child(4),  /* Category */
    #tbl-assets th:nth-child(5),  #tbl-assets td:nth-child(5),  /* Brand */
    #tbl-assets th:nth-child(6),  #tbl-assets td:nth-child(6),  /* Model */
    #tbl-assets th:nth-child(8),  #tbl-assets td:nth-child(8),  /* Serial */
    #tbl-assets th:nth-child(9),  #tbl-assets td:nth-child(9),  /* AnyDesk */
    #tbl-assets th:nth-child(10), #tbl-assets td:nth-child(10), /* Location */
    #tbl-assets th:nth-child(13), #tbl-assets td:nth-child(13), /* Sold Price */
    #tbl-assets th:nth-child(14), #tbl-assets td:nth-child(14)  /* Sold Date */
    { display:none }
    #tbl-assets{font-size:13px}
    #tbl-assets th, #tbl-assets td{padding:8px 6px}

    /* History table — hide Owner + Notes; keep Date, Action, Asset, Staff */
    #tbl-history th:nth-child(4), #tbl-history td:nth-child(4), /* Owner */
    #tbl-history th:nth-child(6), #tbl-history td:nth-child(6)  /* Notes */
    { display:none }
    #tbl-history{font-size:13px}
    #tbl-history th, #tbl-history td{padding:8px 6px}

    /* Warranty table — hide Owner + Days Left (keep date) */
    #tbl-warr th:nth-child(4), #tbl-warr td:nth-child(4), /* Owner */
    #tbl-warr th:nth-child(7), #tbl-warr td:nth-child(7)  /* Days left */
    { display:none }

    /* Filter toolbar on mobile — tighter, tidier grid. Scoped to toolbars
       that contain a search input (Assets / History) so the Bulk Add tip
       panel (which is also a .toolbar but contains no input, just the
       "Tip:" text) keeps its natural left-aligned flex layout. */
    .toolbar:has(input){padding:8px 10px !important;gap:6px !important;display:grid !important;grid-template-columns:1fr 1fr !important;align-items:stretch !important}
    .toolbar:has(input) > *{min-width:0}
    .toolbar:has(input) > input,
    .toolbar:has(input) > .global-search,
    .toolbar:has(input) > .filter-count{grid-column:1 / -1 !important}
    .toolbar:has(input) > .spacer{display:none !important}
    .toolbar:has(input) > .multisel{flex:none !important;min-width:0 !important;width:100% !important;grid-column:auto !important}
    .toolbar:has(input) > select{grid-column:1 / 2 !important}
    .toolbar:has(input) > #assets-clear-filters{grid-column:1 / 2 !important;justify-self:start;align-self:center;padding:4px 0 !important;height:auto !important}
    .toolbar:has(input) > #assets-count,
    .toolbar:has(input) > #history-count{grid-column:2 / -1 !important;justify-self:end;align-self:center;text-align:right;font-size:12px}
    .multisel{min-width:0}

    /* Bulk Add tip panel — make sure it stays left-aligned and wraps cleanly
       on narrow screens (Tip: + muted text on one wrapping line). */
    .toolbar:not(:has(input)){padding:10px 12px !important;gap:6px !important;align-items:flex-start !important}
    .toolbar:not(:has(input)) > .spacer{display:none !important}

    /* Bulk Add table on mobile — let it scroll horizontally INSIDE its
       container (.table-wrap has overflow:auto). The container is what
       scrolls, NOT the page. Make sure the table-wrap explicitly handles
       its own horizontal scroll and doesn't push the page wide. */
    .card:has(#tbl-bulk){overflow:hidden}
    .card:has(#tbl-bulk) .table-wrap{overflow-x:auto;overflow-y:visible;max-width:100%;-webkit-overflow-scrolling:touch}
    /* Fixed column widths so width:100% on inputs resolves to the cell
       width, not the table width (Safari Mobile percentage bug fix).
       All cells use the same horizontal padding (8px) so the visible
       gap between every input box is identical — including the gap
       between the sticky #-column and the first input. */
    #tbl-bulk{table-layout:fixed}
    table.bulk th,table.bulk td{padding:5px 8px !important;box-sizing:border-box;width:96px;max-width:96px}
    table.bulk input,table.bulk select,table.bulk textarea{width:100% !important;min-width:0 !important;box-sizing:border-box !important;font-size:12px !important}
    /* First column (row number) — wider so it gets the same 8px
       horizontal padding as every other cell. 40px = 8 + 24 (room for
       "10") + 8. */
    #tbl-bulk th:first-child,#tbl-bulk td:first-child{width:40px !important;max-width:40px !important;padding:5px 8px !important}
    /* Second column gets an extra 8px of left padding so the gap from
       the (input-less) # column to the first input box equals the
       16px gap between every other consecutive input pair. Cell width
       is bumped to 104px to compensate, keeping the input itself the
       same 80px width as every other column's input. */
    #tbl-bulk th:nth-child(2),#tbl-bulk td:nth-child(2){padding-left:16px !important;width:104px !important;max-width:104px !important}

    /* Group tabs on mobile — give the pills breathing room above (so they
       don't touch the m-header's sticky border) and below (so the bottom of
       the pill doesn't visually overlap the toolbar/card top border). */
    .grp-tabs{margin-top:8px;margin-bottom:12px !important;padding:0 2px}

    /* Global search — full-width under the brand on mobile */
    .global-search{width:100% !important;order:10;margin-top:8px}

    /* Modals — never exceed viewport, internal body scrolls. The .head and
       .foot stay sticky at the top/bottom of the modal so the close button
       (×), Cancel and Save are always reachable no matter how long the form
       gets — this is the biggest mobile UX win. */
    .modal-bg{padding:0}
    .modal{max-height:100vh;max-height:100dvh;height:100vh;height:100dvh;border-radius:0;display:flex;flex-direction:column;width:100%}
    .modal > .head{position:sticky;top:0;z-index:2;background:var(--white);border-bottom:1px solid var(--border);padding:14px 16px;flex:0 0 auto}
    .modal > .head h3{font-size:16px}
    .modal > .body{overflow-y:auto;-webkit-overflow-scrolling:touch;flex:1 1 auto;padding:16px}
    .modal > .foot{position:sticky;bottom:0;z-index:2;background:var(--white);border-top:1px solid var(--border);padding:12px 16px;flex:0 0 auto;display:flex;gap:8px;flex-wrap:wrap;padding-bottom:max(12px, env(safe-area-inset-bottom))}
    .modal > .foot > .btn{flex:1 1 auto;min-width:0}
    /* Make the × close button a comfortable tap target on mobile */
    .modal > .head .btn-ghost{width:40px;height:40px;font-size:24px;line-height:1;display:flex;align-items:center;justify-content:center;flex:0 0 40px}

    /* Staff grid — allow narrower tiles on small phones */
    .staff-grid{grid-template-columns:1fr !important}

    /* Dashboard Data Health grid — single column */
    #dh-grid{grid-template-columns:1fr !important}

    /* Labels setup grid — stack single column on mobile */
    .lbl-setup-grid{grid-template-columns:1fr !important}
    /* Show floating action button on mobile only */
    .fab{display:block}

    /* Toast reposition so it isn't hidden behind FAB */
    #toast{right:10px !important;bottom:84px !important}

    /* ===== Mobile declutter — hide non-essentials so the core flow breathes ===== */
    /* Hide page subtitles on every view (reclaims ~20px per page) */
    .page-head p{display:none}
    /* Hide the trailing button row on page heads (+Add Asset, Print, Export CSV, etc.) — FAB covers the primary actions */
    .page-head .btn-row{display:none}
    /* Exception: Labels tab needs Save as PNG / Print accessible on mobile (not covered by FAB). */
    section[data-view="labels"] .page-head .btn-row{display:flex !important;width:100%;gap:8px;flex-wrap:wrap}
    section[data-view="labels"] .page-head .btn-row .btn{flex:1 1 140px;min-height:40px}

    /* Hide KPI sparklines — too small to read on a phone and adds visual noise */
    .kpi-col .spark{display:none !important}
    /* On mobile, show the FULL subtitle (delta number + descriptive text) so
       users see "0 added this week · 724 records" instead of either the
       cryptic "— 0" alone or the orphaned "added this week" alone.
       Strip the leading symbol (▲/▼/—) by hiding only the first character via
       font-size 0 on the delta but keeping the number visible. */
    .kpi-col .kpi-sub{display:flex;flex-wrap:nowrap;align-items:baseline;gap:4px;font-size:11.5px}
    .kpi-col .kpi-sub .delta{font-size:11.5px;font-weight:600}
    .kpi-col .kpi-sub .kpi-sub-tail{display:inline;color:var(--t3);font-size:11.5px;white-space:normal;flex:1;min-width:0}

    /* Remove the whole bottom grid (Assets by Owner / Category) on mobile — duplicated in Assets view */
    #dash-breakdown-grid{display:none}

    /* Cap Recent Activity at 4 items on mobile — long scrolls hurt on phones */
    #activity-feed .af-item:nth-child(n+5){display:none}

    /* Pull Cloud-sync badge and Dark-mode toggle out of the sidebar entirely on mobile.
       Status/theme can be set from desktop; keeping the drawer minimal.
       Boost specificity with `body` so this beats the later `#sb-theme{display:flex !important}` rule. */
    body #cloud-badge, body #sb-theme{display:none !important}
    /* Force the slate panel to keep its full 12px padding on mobile even when
       body.sb-rail is present (the desktop "rail" class can persist into mobile
       and would otherwise shrink the panel to padding:8px, pushing the Admin
       row right up to the top edge). */
    body.sb-rail .sb-action-group,
    .sb-action-group{padding:12px !important;gap:10px !important}

    /* Hide the command-palette hint footer — no kbd keys on mobile */
    .cmdk-hint{display:none}

    /* Hide subtitle on very small phones — matches APQ Accounts behaviour, h1 alone reads cleaner */
    .m-header .m-title p{display:none}

    /* Make the dashboard status strip horizontally scrollable instead of wrapping.
       Cleaner than truncating, and users get a natural swipe affordance. */
    .status-strip{flex-wrap:nowrap !important;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
    .status-strip::-webkit-scrollbar{display:none}
    .status-strip .status-chip{flex:0 0 auto}

    /* Forms — collapse 2-column grid to single column on mobile */
    .form-grid{grid-template-columns:1fr !important}

    /* Checkout table — hide Owner + Location; keep Asset, Staff, Date, Actions */
    #tbl-out th:nth-child(2), #tbl-out td:nth-child(2),  /* Owner */
    #tbl-out th:nth-child(5), #tbl-out td:nth-child(5)   /* Location */
    { display:none }

    /* Confiscate table — hide Owner + Held at; keep Asset, Taken from, Reason, Date, Actions */
    #tbl-cf th:nth-child(2), #tbl-cf td:nth-child(2),    /* Owner */
    #tbl-cf th:nth-child(6), #tbl-cf td:nth-child(6)     /* Held at */
    { display:none }

    /* Owners & Locations tables on mobile — show all columns but scroll
       horizontally so users can swipe to the data they need. The first column
       (Owner ID / Location) is sticky-pinned and capped at 92 px so it doesn't
       hog the viewport; long IDs like "JAM001 (BO Sunway)" truncate with an
       ellipsis (full text in tooltip, colour pill still identifies the owner). */
    #tbl-owners,
    #tbl-loc{font-size:12.5px}
    #tbl-owners th, #tbl-owners td,
    #tbl-loc th, #tbl-loc td{padding:8px 10px;white-space:nowrap}
    #tbl-owners th:first-child, #tbl-owners td:first-child,
    #tbl-loc th:first-child, #tbl-loc td:first-child{
      width:92px;max-width:92px;min-width:92px;
      padding-left:10px;padding-right:8px;
      overflow:hidden;
    }
    /* Compact pills with ellipsis for the rare long Owner ID */
    #tbl-owners .own-id-pill,
    #tbl-loc .loc-pill{
      font-size:11px;padding:2px 8px;letter-spacing:0;line-height:1.3;
      max-width:100%;overflow:hidden;text-overflow:ellipsis;display:inline-block;vertical-align:middle
    }
    #tbl-owners .own-unreg{display:none}
    #tbl-loc .loc-auto-tag{display:none}
    /* Hide the map-pin icon on mobile — pill colour + name already convey
       the location, the icon just adds visual noise on narrow screens.
       !important to defeat the desktop display:block rule on
       table.loc-tbl td .loc-pill .loc-pin (line ~994). */
    .loc-pin{display:none !important}

    /* Status chips — taller touch target on mobile */
    .status-chip{min-height:36px;padding:8px 14px}

    /* FAB — respect iPhone notch / home-indicator safe areas */
    .fab{right:max(18px, env(safe-area-inset-right, 0px));bottom:max(18px, env(safe-area-inset-bottom, 0px))}
    #toast{bottom:max(84px, calc(74px + env(safe-area-inset-bottom, 0px))) !important}

    /* Barcode scanner close button — 44px tap target */
    #bc-scan-close{width:44px;height:44px;border-radius:50%;font-size:20px}
    #bc-scan-manual-toggle{height:40px;padding:0 14px}
  }
  /* Extra-small phones — even tighter */
  @media (max-width:420px){
    .main{padding:4px 8px 10px}
    .card .body{padding:12px 10px}
    #tbl-assets th, #tbl-assets td{padding:6px 4px;font-size:12.5px}
    .page-head h2{font-size:20px}
  }
  /* Stacked horizontal bar — assets by owner */
  .stacked-bar{padding:16px 20px}
  .stacked-bar .sb-row{display:flex;align-items:center;gap:10px;margin-bottom:8px;font-size:12.5px}
  .stacked-bar .sb-row:last-child{margin-bottom:0}
  /* Owner ID labels — Inter to match the rest of the app and APQ Accounts.
     Slight letter-spacing keeps codes scannable without the 'terminal' feel. */
  .stacked-bar .sb-label{flex:0 0 72px;font-weight:600;color:var(--t2);font-size:12px;letter-spacing:0.02em;font-variant-numeric:tabular-nums}
  .stacked-bar .sb-track{flex:1;height:18px;background:var(--bg);border-radius:8px;overflow:hidden;display:flex}
  .stacked-bar .sb-seg{height:100%;transition:width .3s}
  .stacked-bar .sb-seg.avail{background:#86efac}
  .stacked-bar .sb-seg.inuse{background:#93c5fd}
  .stacked-bar .sb-seg.other{background:#fcd34d}
  .stacked-bar .sb-total{flex:0 0 auto;color:var(--t2);font-weight:600;min-width:32px;text-align:right}
  .stacked-bar .sb-legend{display:flex;gap:14px;margin-top:10px;font-size:11.5px;color:var(--t3);padding-top:10px;border-top:1px dashed var(--border)}
  .stacked-bar .sb-legend span{display:inline-flex;align-items:center;gap:5px}
  .stacked-bar .sb-legend i{width:10px;height:10px;border-radius:3px;display:inline-block}
  /* Activity feed widget */
  .activity-feed{padding:6px 0}
  .activity-feed .af-item{display:flex;gap:12px;padding:10px 20px;border-bottom:1px solid var(--border);align-items:flex-start}
  .activity-feed .af-item:last-child{border-bottom:0}
  .activity-feed .af-avatar{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;font-size:14px;font-weight:600;color:#fff;flex:0 0 32px}
  .activity-feed .af-body{flex:1;font-size:13px;color:var(--t2);line-height:1.5}
  .activity-feed .af-body b{color:var(--t1);font-weight:600}
  .activity-feed .af-time{color:var(--t4);font-size:11.5px;margin-top:2px}
  .activity-feed .af-tag{display:inline-block;background:var(--bg);color:var(--t2);font-size:10.5px;padding:1px 6px;border-radius:4px;font-weight:600;margin-right:4px}
  .activity-feed .af-tag.add{background:#dcfce7;color:#166534}
  .activity-feed .af-tag.co{background:#dbeafe;color:#1e40af}
  .activity-feed .af-tag.ci{background:#fef3c7;color:#92400e}
  .activity-feed .af-tag.del{background:#fee2e2;color:#991b1b}

  /* History log action chips — 5 semantic groups
     create=green / edit=blue / del=red / custody=amber / terminal=muted */
  #tbl-history .chip{font-size:11px;padding:2px 8px;border-radius:999px;font-weight:600;background:#f1f5f9;color:#475569;display:inline-block;letter-spacing:0.01em}
  #tbl-history .chip.act-create{background:#dcfce7;color:#166534}
  #tbl-history .chip.act-edit{background:#dbeafe;color:#1e40af}
  #tbl-history .chip.act-del{background:#fee2e2;color:#991b1b}
  #tbl-history .chip.act-custody{background:#fef3c7;color:#92400e}
  #tbl-history .chip.act-terminal{background:#f1f5f9;color:#475569}
  .kpi.green .value{color:var(--green)}
  .kpi.blue .value{color:var(--blue)}
  .kpi.amber .value{color:var(--amber)}
  .kpi.red .value{color:var(--red)}

  /* Data Health tiles */
  .dh-tile{padding:16px 18px;border:1px solid var(--border);border-radius:var(--r2);background:var(--white)}
  .dh-tile.dh-ok{border-color:#bbf7d0;background:var(--green-bg)}
  .dh-tile.dh-amber{border-color:#fed7aa;background:var(--amber-bg)}
  .dh-tile.dh-red{border-color:#fecaca;background:var(--red-bg)}
  .dh-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
  .dh-title{font-weight:600;font-size:13px;color:var(--t2)}
  .dh-count{font-size:24px;font-weight:700;line-height:1}
  .dh-ok .dh-count{color:var(--green)}
  .dh-amber .dh-count{color:var(--amber)}
  .dh-red .dh-count{color:var(--red)}
  .dh-help{color:var(--t3);font-size:12px;margin-top:4px}
  .dh-list{margin-top:10px;font-size:12px;line-height:1.9}
  .dh-clean{margin-top:10px;font-size:13px;color:var(--green);font-weight:600}

  /* Buttons */
  .btn{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--border2);background:var(--white);color:var(--t1);padding:8px 14px;border-radius:var(--r);font-size:13px;font-weight:500;transition:transform .12s,border-color .15s,background .15s,box-shadow .15s}
  .btn:hover{border-color:var(--blue);transform:translateY(-1px);box-shadow:var(--shadow)}
  .btn:active{transform:translateY(0)}
  .btn-primary{background:var(--gold);border-color:var(--gold);color:var(--brand-navy);font-weight:700}
  .btn-primary:hover{background:var(--gold-hover);border-color:var(--gold-hover);color:var(--brand-navy)}
  .btn-ghost{border-color:transparent;background:transparent;color:var(--t2)}
  .btn-ghost:hover{background:var(--bg);border-color:transparent;transform:none;box-shadow:none}
  /* .btn-link — semantic <button> rendered as an inline text link. Used for
     in-table actions like "open asset modal" so we don't ship href="#" or
     javascript:void(0) (both pollute browser history and confuse AT). */
  .btn-link{background:transparent;border:0;padding:0;margin:0;color:inherit;font:inherit;cursor:pointer;text-align:inherit;display:inline;line-height:inherit}
  .btn-link:hover{text-decoration:underline}
  .btn-link:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:2px}
  .btn-danger{background:var(--white);border-color:var(--border2);color:var(--red)}
  .btn-danger:hover{background:var(--red-bg);border-color:var(--red);color:var(--red)}
  .btn-warn{background:#fff8e1;border-color:#f4c430;color:#8a6a00;font-weight:600}
  .btn-warn:hover{background:#fff1b8;border-color:#d9a800;color:#6a5000}
  .btn-sm{padding:5px 12px;font-size:12px}
  .btn-row{display:flex;gap:8px;flex-wrap:wrap}

  /* Form */
  .form-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
  .form-grid.full{grid-template-columns:1fr}
  .field{display:flex;flex-direction:column;gap:5px}
  .field label{font-size:12px;color:var(--t3);font-weight:600}
  .field input:not([type="checkbox"]):not([type="radio"]),.field select,.field textarea{padding:8px 11px;border:1px solid var(--border2);border-radius:var(--r);background:var(--white);outline:none;color:var(--t1);font-size:13px;box-sizing:border-box;line-height:1.2;transition:border-color .15s,box-shadow .15s;width:100%}
  .field input:not([type="checkbox"]):not([type="radio"]),.field select{height:36px}
  .field input[type="checkbox"],.field input[type="radio"]{width:auto;height:auto;accent-color:var(--blue)}
  .field select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='1,1 6,6 11,1'/></svg>");background-repeat:no-repeat;background-position:right 10px center;background-size:10px 6px;padding-right:28px}
  .field input:focus,.field select:focus,.field textarea:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,113,227,0.1)}
  .field textarea{min-height:76px;resize:vertical;height:auto}

  /* Table */
  .table-wrap{overflow:auto}
  table{width:100%;border-collapse:collapse;font-size:13px}
  th,td{padding:11px 14px;text-align:left;vertical-align:top}
  /* Dashboard: Assets by Category — Category column left-aligned, numeric cols centered */
  #tbl-by-cat th, #tbl-by-cat td{text-align:center;vertical-align:middle}
  #tbl-by-cat th:first-child, #tbl-by-cat td:first-child{text-align:left;padding-left:18px}
  /* Check In/Out + Confiscated tables — center-align the ACTIONS column header
     and cell content (Check In button) so they sit centered above each other. */
  #tbl-out th:last-child, #tbl-out td:last-child,
  #tbl-cf  th:last-child, #tbl-cf  td:last-child{text-align:center}
  /* Center Owner, Staff, Check Out Date, Location columns so headers
     sit directly above their (centered) cell content. */
  #tbl-out th:nth-child(2), #tbl-out td:nth-child(2),
  #tbl-out th:nth-child(3), #tbl-out td:nth-child(3),
  #tbl-out th:nth-child(4), #tbl-out td:nth-child(4),
  #tbl-out th:nth-child(5), #tbl-out td:nth-child(5){text-align:center}
  #tbl-by-cat td:first-child .chip{margin:0}
  #tbl-by-cat td .chip{margin:0 auto}
  th{background:var(--bg);font-size:11px;color:var(--t2);font-weight:700;text-transform:uppercase;letter-spacing:0.7px;position:sticky;top:0;z-index:1;border-bottom:1px solid var(--border)}
  /* Sticky headers must NOT be sticky during print — sticky elements
     anchor to the print viewport top and overlap the first body row.
     This applies globally so any printable table (borrow form, asset
     list, history, etc.) renders row 1 correctly. */
  @media print{
    th{position:static !important}
  }
  body.print-borrow th,body.print-card th,body.print-labels th{position:static !important}

  /* Performance — defer layout/paint for off-screen rows on the three long tables.
     Browsers skip layout for any tr that isn't intersecting the viewport (or near it).
     The contain-intrinsic-size keeps scrollbars accurate before each row is measured. */
  #tbl-assets tbody tr,
  #tbl-history tbody tr,
  #tbl-out tbody tr{
    content-visibility:auto;
    contain-intrinsic-size:auto 44px;
  }
  td{border-bottom:1px solid var(--border);color:var(--t2)}
  tbody tr:hover{background:var(--bg)}
  tbody tr:last-child td{border-bottom:0}
  td.actions{white-space:nowrap}

  /* Locations table — centered */
  table.loc-tbl th, table.loc-tbl td{text-align:center;vertical-align:middle;white-space:nowrap;padding:10px 12px}
  table.loc-tbl th{font-size:10.5px}
  /* First column: Location name — left-aligned with pill treatment */
  table.loc-tbl th:first-child,
  table.loc-tbl td:first-child{text-align:left;padding-left:18px}
  table.loc-tbl td .loc-pill{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;background:var(--pill-bg,var(--bg));border:1px solid var(--pill-bd,var(--border2));border-radius:999px;font-size:12.5px;font-weight:600;color:var(--pill-fg,var(--t1));line-height:1;transition:filter .15s,box-shadow .15s,transform .15s}
  table.loc-tbl td .loc-pill .loc-pin{opacity:0.7;flex:0 0 auto;display:block;vertical-align:middle;position:relative;top:0.5px}
  table.loc-tbl tr:hover td .loc-pill{filter:brightness(0.96);box-shadow:0 1px 4px rgba(0,0,0,0.06);transform:translateY(-0.5px)}
  table.loc-tbl tr:hover td .loc-pill .loc-pin{opacity:1}
  table.loc-tbl td .loc-auto-tag{font-size:10px;font-weight:600;color:var(--t3);background:var(--bg);border:1px solid var(--border2);padding:2px 7px;border-radius:999px;margin-left:6px;letter-spacing:0.04em;text-transform:uppercase}
  table.loc-tbl td.zero{color:var(--t3);opacity:0.35}
  table.loc-tbl td.total{font-weight:700;color:var(--t1)}
  table.loc-tbl td.actions{white-space:nowrap}

  /* Owners table — numeric cells centered, Owner ID column left-aligned */
  table.own-tbl{table-layout:auto;width:100%}
  table.own-tbl th, table.own-tbl td{text-align:center;vertical-align:middle;white-space:nowrap;padding:10px 12px}
  table.own-tbl th{font-size:10.5px}
  /* First column: Owner ID — left-aligned with pill treatment */
  table.own-tbl th:first-child,
  table.own-tbl td.id-cell{text-align:left;padding-left:18px}
  /* Owner ID column — Inter to match the rest of the app. tabular-nums keeps
     codes vertically aligned without the 'developer terminal' feel. */
  table.own-tbl td.id-cell{font-weight:600;color:var(--t1);letter-spacing:0.02em;font-variant-numeric:tabular-nums}
  table.own-tbl td.id-cell .own-id-pill{display:inline-flex;align-items:center;padding:4px 12px;background:var(--pill-bg,var(--bg));border:1px solid var(--pill-bd,var(--border2));border-radius:999px;font-size:12.5px;line-height:1;color:var(--pill-fg,var(--t1));font-weight:600;letter-spacing:.04em;transition:filter .15s,box-shadow .15s,transform .15s}
  table.own-tbl tr:hover td.id-cell .own-id-pill{filter:brightness(0.96);box-shadow:0 1px 4px rgba(0,0,0,0.06);transform:translateY(-0.5px)}
  table.own-tbl td.id-cell .own-unreg{font-size:10px;font-weight:600;color:var(--t3);background:var(--bg);border:1px solid var(--border2);padding:2px 7px;border-radius:999px;margin-left:6px;letter-spacing:0.04em;text-transform:uppercase;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
  table.own-tbl td.zero{color:var(--t3);opacity:0.35}
  table.own-tbl td.total{font-weight:700;color:var(--t1)}
  table.own-tbl td.value{font-variant-numeric:tabular-nums;color:var(--t2)}
  table.own-tbl td.actions{white-space:nowrap}

  /* Labels Sheet Setup row — align all dropdowns to a common baseline */
  .lbl-setup-grid .field{display:flex;flex-direction:column}
  .lbl-setup-grid .field > select{margin-top:auto}
  .lbl-setup-grid .field > label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  /* Labels picker toolbar — uniform 36px row */
  .lbl-pick-toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:8px}
  .lbl-pick-toolbar > input,
  .lbl-pick-toolbar > select{height:36px;box-sizing:border-box;padding:0 12px;border:1px solid var(--border2);border-radius:var(--r);background:var(--white);color:var(--t1);font-size:13px;outline:none}
  .lbl-pick-toolbar > input{flex:1;min-width:260px}
  .lbl-pick-toolbar > input:focus,
  .lbl-pick-toolbar > select:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,113,227,0.1)}
  .lbl-pick-toolbar > .btn{height:36px;box-sizing:border-box;padding-top:0;padding-bottom:0}

  /* Group tabs */
  .grp-tabs{display:flex;gap:6px;flex-wrap:wrap;padding:0;margin-bottom:12px;background:transparent}
  .grp-tab{background:transparent;border:1px solid var(--border2);border-radius:20px;padding:5px 16px;font-size:13px;font-weight:500;color:var(--t2);cursor:pointer;transition:all .15s;white-space:nowrap}
  .grp-tab:hover{border-color:var(--gold);color:var(--t1)}
  .grp-tab.active{background:var(--gold);border-color:var(--gold);color:#0E1C2E;font-weight:700}

  /* Toolbar — sits at the top of its card. It's intentionally NOT sticky:
     when sticky was set with top:78 (to clear the sticky page-head), Chrome
     reserved a 78 px offset inside the card's overflow:hidden context even
     at scroll=0, causing a white gap at the top of Assets / Bulk Add /
     History. The page-head alone stays pinned during scroll. */
  .toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:14px 20px;border-bottom:1px solid var(--border);background:var(--bg);backdrop-filter:saturate(180%) blur(8px);-webkit-backdrop-filter:saturate(180%) blur(8px)}
  .bulkbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:12px 20px;border-bottom:1px solid var(--border);background:var(--gold-bg)}
  /* The HTML `hidden` attribute must beat `display:flex` above. Without this
     override the bulkbar always shows, leaving an empty amber strip between
     the tabs and the toolbar even when no rows are selected. */
  .bulkbar[hidden]{display:none !important}
  .bulkbar-count{font-size:13px;color:var(--t1);margin-right:4px;font-weight:500}
  .bulkbar .btn{font-size:12.5px;height:36px;box-sizing:border-box;padding-top:0;padding-bottom:0}
  .toolbar .btn{height:36px;box-sizing:border-box;padding-top:0;padding-bottom:0}
  /* Checkbox column — wider, more professional column with proper breathing
     room around an 18px checkbox. Symmetric padding so text-align:center
     actually centers the checkbox horizontally within the cell. */
  th.cb,td.cb{width:56px;min-width:56px;padding-left:8px;padding-right:8px;text-align:center}
  input[type="checkbox"].row-sel{cursor:pointer;width:18px;height:18px;accent-color:var(--blue);border-radius:4px;vertical-align:middle}
  /* Unified filter controls — same padding, height, and border across .toolbar and .bulkbar */
  .toolbar input,.toolbar select,.bulkbar input,.bulkbar select{padding:8px 11px;border:1px solid var(--border2);border-radius:var(--r);background:var(--white);font-size:13px;height:36px;box-sizing:border-box;line-height:1.2;color:var(--t1)}
  .toolbar select,.bulkbar select{width:170px;min-width:170px;flex:0 0 170px;appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='1,1 6,6 11,1'/></svg>");background-repeat:no-repeat;background-position:right 10px center;background-size:10px 6px;padding-right:28px}
  .toolbar input,.bulkbar input{flex:1 1 260px;min-width:220px}
  .toolbar input:focus,.toolbar select:focus,.bulkbar input:focus,.bulkbar select:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,113,227,0.1);outline:none}
  .toolbar .spacer,.bulkbar .spacer{flex:1}

  /* Multi-select filter */
  .multisel{position:relative;flex:0 0 170px;width:170px}
  .ms-btn{display:flex;align-items:center;gap:6px;width:100%;height:36px;padding:8px 28px 8px 11px;border:1px solid var(--border2);border-radius:var(--r);background:var(--white);font-size:13px;color:var(--t1);line-height:1.2;box-sizing:border-box;text-align:left;cursor:pointer;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='1,1 6,6 11,1'/></svg>");background-repeat:no-repeat;background-position:right 10px center;background-size:10px 6px}
  .ms-btn:hover{border-color:var(--t3)}
  .multisel.on .ms-btn{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,113,227,0.1);outline:none}
  .ms-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ms-label.placeholder{color:var(--t3)}
  .ms-count{flex:0 0 auto;background:var(--blue);color:#fff;font-size:11px;font-weight:600;padding:1px 7px;border-radius:10px}
  .ms-panel{position:absolute;top:calc(100% + 4px);left:0;width:240px;max-width:90vw;background:#fff;border:1px solid var(--border);border-radius:var(--r2);box-shadow:var(--shadow3);z-index:40;padding:6px;flex-direction:column;display:none}
  .multisel.on .ms-panel{display:flex}
  .ms-list{flex:1;overflow-y:auto;max-height:260px}
  .ms-opt{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;font-size:13px;cursor:pointer;color:var(--t1)}
  .ms-opt:hover{background:var(--bg)}
  .ms-opt input{margin:0;accent-color:var(--blue);flex:0 0 14px !important;width:14px !important;min-width:0 !important;max-width:14px !important;height:14px}
  .ms-opt span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ms-empty{padding:12px;color:var(--t3);font-size:12.5px;text-align:center}
  .ms-foot{display:flex;justify-content:flex-end;padding:6px 4px 2px;border-top:1px solid var(--border);margin-top:4px}
  .ms-clear{background:transparent;border:0;color:var(--t2);font-size:12px;cursor:pointer;padding:4px 8px;border-radius:4px}
  .ms-clear:hover{background:var(--bg);color:var(--t1)}

  /* Row hover quick actions */
  #tbl-assets tbody tr{transition:background .12s}
  #tbl-assets tbody tr:hover{background:#fafbfc}
  #tbl-assets .qa-row{display:flex !important;justify-content:center !important;align-items:center;gap:4px;opacity:0;transition:opacity .12s;white-space:nowrap;width:100%}
  /* Reveal triggers — desktop hover, plus mobile-friendly fallbacks. iOS Safari
     fires :hover on first tap and keeps it sticky until another element is
     tapped; :active covers the tap-down moment on Android; :focus-within
     covers keyboard navigation and any tap that lands on a focusable element
     inside the row. */
  #tbl-assets tbody tr:hover .qa-row,
  #tbl-assets tbody tr:active .qa-row,
  #tbl-assets tbody tr:focus-within .qa-row{opacity:1}
  #tbl-assets .qa-btn{border:1px solid var(--border);background:var(--white);color:var(--t2);width:26px;height:26px;border-radius:6px;display:inline-grid;place-items:center;cursor:pointer;padding:0;transition:background .12s,color .12s,border-color .12s}
  #tbl-assets .qa-btn:hover{background:var(--bg);color:var(--t1);border-color:var(--border2)}
  #tbl-assets .qa-btn.danger:hover{background:#fee2e2;color:#991b1b;border-color:#fecaca}
  #tbl-assets .qa-btn svg{width:13px;height:13px}
  /* Single-line rows — prevent wrapping, truncate long values, horizontal scroll via .table-wrap */
  #tbl-assets th,#tbl-assets td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:260px;vertical-align:middle;text-align:center}
  #tbl-assets th{text-align:center}
  /* Faded column dividers — very subtle inset hairline on right edge of every cell */
  #tbl-assets th:not(:last-child),#tbl-assets td:not(:last-child){border-right:1px solid rgba(15,23,42,0.05)}
  /* Zebra striping for easier horizontal scanning */
  #tbl-assets tbody tr:nth-child(even){background:#fafbfc}
  #tbl-assets tbody tr:nth-child(even):hover,#tbl-assets tbody tr:hover{background:#f1f5f9}
  #tbl-assets th.cb,#tbl-assets td.cb{max-width:none;text-align:center}
  #tbl-assets td.actions{max-width:none;overflow:visible;text-align:center}
  #tbl-assets td .label-cell{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;text-align:center}
  /* Asset ID column — Inter (standardized across portals). tabular-nums keeps
     IDs vertically aligned in the table; tint stays for visual hierarchy. */
  #tbl-assets td:nth-child(2){font-size:12px;color:var(--t2);letter-spacing:0.02em;font-variant-numeric:tabular-nums;font-weight:600}
  /* Serial # column — wider so full serial fits; AnyDesk similar */
  #tbl-assets th:nth-child(8),#tbl-assets td:nth-child(8){max-width:320px;min-width:180px;font-variant-numeric:tabular-nums}
  #tbl-assets th:nth-child(9),#tbl-assets td:nth-child(9){max-width:180px;min-width:120px}
  /* Device Name a bit wider too */
  #tbl-assets th:nth-child(7),#tbl-assets td:nth-child(7){max-width:220px;min-width:140px}
  /* Empty state */
  .empty-state{padding:48px 24px;text-align:center;color:var(--t3)}
  .empty-state .empty-ic{font-size:40px;margin-bottom:10px;opacity:0.7}
  .empty-state h4{margin:0 0 4px;color:var(--t1);font-weight:600;font-size:15px}
  .empty-state p{margin:0 0 14px;font-size:13px;color:var(--t3)}
  .empty-state .btn{margin-top:4px}
  /* Chips */
  .chip{display:inline-flex;align-items:center;padding:2px 8px;border-radius:6px;font-size:11px;background:var(--bg);color:var(--t2);font-weight:600}
  .chip.owner{background:var(--chip-bg,var(--purple-bg));color:var(--chip-fg,var(--purple));border:1px solid transparent}
  .chip.cat{background:var(--blue-bg);color:var(--blue-ink)}
  .chip.loc{background:var(--bg);color:var(--t2)}
  .status{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:999px;font-size:11px;font-weight:600;background:var(--bg);color:var(--t2);border:1px solid transparent;line-height:1.4;white-space:nowrap}
  .status::before{content:"";width:6px;height:6px;border-radius:999px;background:currentColor;flex:0 0 6px}
  .status.available{color:#166534;background:#dcfce7;border-color:#bbf7d0}
  .status.inuse{color:#1e40af;background:#dbeafe;border-color:#bfdbfe}
  .status.confiscated{color:#9a3412;background:#ffedd5;border-color:#fed7aa}
  .status.maintenance{color:#92400e;background:#fef3c7;border-color:#fde68a}
  .status.faulty{color:#c2410c;background:#ffedd5;border-color:#fdba74}

  /* Empty date inputs — hide native dd/mm/yyyy placeholder until focused or filled */
  input[type="date"].is-empty-date:not(:focus)::-webkit-datetime-edit{color:transparent}
  input[type="date"].is-empty-date:not(:focus){color:transparent}

  /* iOS Safari overflow fix — native date inputs centre their value and the
     ::-webkit-date-and-time-value pseudo doesn't shrink to fit. Force flex
     children to allow shrink, left-align the value, and lock dimensions so
     dates don't render taller/wider than text inputs and selects in the same
     grid (iOS Safari otherwise gives <input type="date"> its own intrinsic
     height regardless of CSS height). Padding matches .field input on line
     947 so all input types are visually identical. */
  .field input[type="date"]{min-width:0;text-align:left;-webkit-appearance:none;appearance:none;padding:8px 11px !important;height:36px !important;line-height:1.2;box-sizing:border-box;width:100%}
  .field input[type="date"]::-webkit-date-and-time-value{text-align:left;min-width:0;width:100%;margin:0;line-height:1.2}
  .field input[type="date"]::-webkit-calendar-picker-indicator{margin-left:auto;opacity:0.6;width:14px;height:14px;padding:0}
  .status.retired{color:#475569;background:#f1f5f9;border-color:#e2e8f0}
  .status.pendingtosell{color:#78350f;background:#f5f5f4;border-color:#d6d3d1}
  .status.sold{color:#6b21a8;background:#f3e8ff;border-color:#e9d5ff}
  .status.lost{color:#991b1b;background:#fee2e2;border-color:#fecaca}
  .status.staffnoreturn{color:#7c2d12;background:#fef2f2;border-color:#fecaca}

  /* Modal */
  @keyframes modalSlideUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
  .modal-bg{position:fixed;inset:0;background:rgba(0,0,0,0.35);display:none;align-items:center;justify-content:center;z-index:120;padding:20px;
    -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
  .modal-bg.on{display:flex}
  /* When any modal is open, hide the mobile sticky header, FAB, and sidebar
     drawer backdrop so the modal can use the full viewport. */
  body:has(.modal-bg.on) .m-header,
  body:has(.modal-bg.on) .fab,
  body:has(.modal-bg.on) .sb-backdrop{display:none !important}
  body:has(.modal-bg.on){overflow:hidden}
  .modal{background:var(--white);border-radius:var(--r4);max-width:720px;width:100%;max-height:90vh;overflow:auto;box-shadow:var(--shadow3);animation:modalSlideUp .22s ease-out}
  .modal .head{display:flex;justify-content:space-between;align-items:center;padding:1.25rem 1.75rem;border-bottom:1px solid var(--border)}
  .modal .head h3{margin:0;font-size:16px;font-weight:700;color:var(--t1)}
  .modal .body{padding:1.75rem}
  .modal .foot{display:flex;justify-content:flex-end;gap:8px;padding:1.25rem 1.75rem;border-top:1px solid var(--border);background:var(--bg)}

  /* Toast */
  .toast{position:fixed;bottom:24px;right:24px;background:var(--navy);color:#fff;padding:10px 18px;border-radius:var(--r);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;transform:translateY(10px);z-index:100;font-size:13px;font-weight:500;box-shadow:var(--shadow2)}
  .toast.on{opacity:1;transform:translateY(0)}
  .toast.ok{background:var(--green)}
  .toast.err{background:var(--red)}

  /* .mono utility — was monospace; now Inter with tabular-nums so digits/IDs
     stay vertically aligned in tables without the 'developer terminal' look.
     Used for serials, AnyDesk codes, prices, dates, and asset IDs in lists. */
  .mono{font-size:12.5px;font-variant-numeric:tabular-nums;letter-spacing:0.01em}
  .muted{color:var(--t3)}
  .right{text-align:right}
  .nowrap{white-space:nowrap}
  /* Divider gap tightened from 1.75rem (28px) to 0.75rem (12px) — Check In/Out
     and similar pages were spending too much vertical space between sections. */
  .divider{height:1px;background:var(--border);margin:0.75rem 0}
  .empty{padding:60px 20px;text-align:center;color:var(--t3);font-size:14px}
  .pill{display:inline-block;padding:2px 8px;border-radius:6px;background:var(--bg);color:var(--t3);font-size:11px;font-weight:600}
  h3.section-title{margin:1.25rem 0 14px;font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:0.7px;font-weight:700}
  .actions button{margin-right:4px}

  /* Bulk add grid */
  /* Bulk Add — uniform spreadsheet-style data entry. Every input,
     select, and textarea is forced to the same 32px height with the
     same border, radius, and 13px type so the grid reads cleanly. */
  table.bulk th{padding:7px 6px;text-align:center;font-size:12px;font-weight:600;color:var(--muted);letter-spacing:.01em}
  table.bulk th small.muted{font-size:10.5px;font-weight:400}
  table.bulk td{padding:3px;vertical-align:middle;border-bottom:1px solid var(--line-2);text-align:center}
  table.bulk input,table.bulk select,table.bulk textarea{
    width:100%;
    height:32px;
    box-sizing:border-box;
    border:1px solid var(--border2);
    border-radius:6px;
    padding:0 8px;
    background:#fff;
    font:inherit;
    font-size:13px;
    line-height:1.4;
    min-width:80px;
    transition:background .15s,border-color .15s,box-shadow .15s;
    text-align:center;
    text-align-last:center;
  }
  table.bulk textarea{height:auto;min-height:32px;padding:6px 8px;resize:vertical}
  /* Strip iOS native rendering and align internal padding with text/select
     inputs so date/number boxes look identical to all other bulk inputs */
  table.bulk input[type="date"],table.bulk input[type="number"]{
    padding:0 8px;
    -webkit-appearance:none;appearance:none;
  }
  table.bulk input[type="number"]::-webkit-outer-spin-button,
  table.bulk input[type="number"]::-webkit-inner-spin-button{
    -webkit-appearance:none;margin:0;
  }
  table.bulk input:hover,table.bulk select:hover,table.bulk textarea:hover{background:var(--surface);border-color:var(--border)}
  table.bulk input:focus,table.bulk select:focus,table.bulk textarea:focus{background:#fff;border-color:var(--brand);box-shadow:0 0 0 2px rgba(0,113,227,0.18);outline:none}
  table.bulk tr.req-missing input.req-missing{background:#fff5f3;border-color:rgba(199,52,30,0.5)}
  table.bulk tr.inuse{background:rgba(0,113,227,0.04)}
  table.bulk tr.inuse td:first-child{box-shadow:inset 3px 0 0 var(--brand)}
  table.bulk .rowdel{background:transparent;border:0;color:var(--muted);cursor:pointer;font-size:16px;padding:4px 6px;border-radius:6px;transition:background .15s,color .15s;height:32px;width:32px;line-height:1}
  table.bulk .rowdel:hover{background:rgba(199,52,30,0.08);color:var(--bad)}
  table.bulk .rownum{color:var(--muted);text-align:center;font-size:12px;padding-top:10px;font-weight:500}

  /* Staff tab cards */
  .staff-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
  .staff-section-head{display:flex;align-items:center;gap:12px;margin:16px 0 12px;padding:0 2px}
  .staff-section-head h3{margin:0;font-size:13px;font-weight:700;color:var(--t2);letter-spacing:0.08em;text-transform:uppercase}
  .staff-section-head .muted{font-size:12px}
  /* Staff tile — minimalist */
  .staff-tile{background:var(--white);border:1px solid var(--border);border-radius:var(--r2);padding:22px 18px 18px;position:relative;transition:border-color .15s,box-shadow .15s;overflow:hidden}
  /* Fat left-edge stripe (saturated team color) — makes teams obvious in the grid. */
  /* Team color bar — horizontal strip at the top of the card. Minimalist accent
     that identifies the team at a glance without overwhelming the card. */
  .staff-tile .team-stripe{position:absolute;top:0;left:0;right:0;height:4px;border-radius:var(--r2) var(--r2) 0 0}
  .staff-tile:hover{border-color:var(--t3);box-shadow:0 2px 8px rgba(0,0,0,0.04)}
  .staff-tile.inactive{opacity:0.6}
  .staff-tile .st-head{display:flex;align-items:center;gap:12px}
  /* Avatar uses saturated team fg as background, white text — "pops" per card. */
  .staff-tile .avatar{width:40px;height:40px;border-radius:999px;display:grid;place-items:center;font-weight:700;font-size:14px;flex:0 0 40px;background:var(--bg);color:var(--t1);border:1px solid var(--border);letter-spacing:0.02em}
  .staff-tile .st-info{flex:1;min-width:0}
  .staff-tile .st-info h4{margin:0;font-size:14.5px;font-weight:600;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-0.01em}
  .staff-tile .st-info .ic-sub{margin-top:2px;font-size:11.5px;color:var(--t3);font-family:"SF Mono","Menlo","Consolas",monospace;letter-spacing:0.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .staff-tile .meta-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px;align-items:center}
  .staff-tile .tag{display:inline-block;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;border:1px solid var(--border);color:var(--t2);background:var(--white);letter-spacing:0.03em}
  /* Team tag: inline style sets bg + readable text per palette entry.
     Don't force a hardcoded color here or pastel entries become unreadable. */
  .staff-tile .tag.team{border-color:transparent;text-transform:uppercase}
  .staff-tile .tag.inactive-tag{color:#991b1b;border-color:#fecaca;background:#fef2f2}
  /* Unaccounted: Lost / Staff No Return items attributed to this staff member.
     Saturated red so it stands out against the team color. Clickable to filter. */
  .staff-tile .tag.unaccounted-tag{color:#fff;background:#dc2626;border-color:#dc2626;cursor:pointer;font-weight:700}
  .staff-tile .tag.unaccounted-tag:hover{background:#b91c1c;border-color:#b91c1c}
  .staff-tile .divider{height:1px;background:var(--border);margin:14px 0}
  .staff-tile .contact{font-size:12.5px;color:var(--t2);line-height:1.6}
  .staff-tile .contact div{display:flex;align-items:center;gap:6px}
  .staff-tile .contact .ico{width:12px;font-size:11px;opacity:0.55;flex:0 0 12px}
  .staff-tile .contact .telco{font-size:10.5px;color:var(--t3);text-transform:uppercase;letter-spacing:0.04em;margin-right:2px}
  .staff-tile .contact a{color:var(--t1);font-weight:500;text-decoration:none}
  .staff-tile .contact a:hover{color:var(--blue)}
  .staff-tile .items-line{display:flex;align-items:baseline;gap:8px;font-size:12.5px;color:var(--t2)}
  .staff-tile .items-line .n{font-size:18px;font-weight:600;color:var(--t1);line-height:1}
  .staff-tile .items-line .lbl{font-size:11.5px;color:var(--t3)}
  .staff-tile .breakdown{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
  .staff-tile .bitem{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--t2);padding:2px 8px;border-radius:4px;background:var(--bg)}
  .staff-tile .bitem b{font-weight:600;color:var(--t1)}
  .staff-tile .no-items{color:var(--t3);font-size:12px}
  .staff-tile .actions-row{display:flex;gap:6px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border)}
  .staff-tile .actions-row button{flex:1;padding:7px 10px;font-size:12.5px;font-weight:500;border-radius:6px;border:1px solid var(--border);cursor:pointer;background:var(--white);color:var(--t1);transition:border-color .15s,color .15s,background .15s}
  .staff-tile .actions-row button:hover{border-color:var(--t2);color:var(--t1);background:var(--bg)}

  .chip-filter{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--border2);background:var(--white);color:var(--t2);padding:5px 12px;border-radius:6px;font-size:12px;font-weight:500;cursor:pointer;transition:background .15s,color .15s,border-color .15s}
  .chip-filter .n{background:var(--bg);color:var(--t3);border-radius:4px;padding:0 6px;font-size:11px;font-weight:700}
  .chip-filter:hover{background:var(--bg);border-color:var(--blue)}
  .chip-filter.active{background:var(--navy);color:#fff;border-color:var(--navy)}
  .chip-filter.active .n{background:rgba(255,255,255,0.18);color:#fff}

  /* Staff handover card (printable) */
  .staff-card{color:var(--ink);padding:8px 4px}
  .staff-card .hdr{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:18px}
  .staff-card .who h2{margin:0;font-size:26px;font-weight:600;letter-spacing:-0.02em}
  .staff-card .who p{margin:4px 0;color:var(--muted)}
  .staff-card .meta{text-align:right;font-size:12.5px;color:var(--muted);line-height:1.7}
  .staff-card .meta b{color:var(--ink)}
  .staff-card table{width:100%;border-collapse:collapse;margin-top:6px}
  .staff-card th,.staff-card td{border-bottom:1px solid var(--line-2);padding:10px 12px;font-size:12.5px;text-align:left;vertical-align:top}
  .staff-card th{background:transparent;color:var(--muted);font-weight:500;text-transform:uppercase;letter-spacing:0.04em;font-size:11px;border-bottom:1px solid var(--line)}
  .staff-card .sig{display:grid;grid-template-columns:1fr 1fr;gap:40px;margin-top:40px}
  .staff-card .sig .line{border-top:1px solid var(--ink);padding-top:6px;font-size:12px;color:var(--muted);text-align:center}
  .staff-card .note{font-size:12px;color:var(--muted);margin-top:20px;line-height:1.6}
  .staff-card .sc-actions{white-space:nowrap}
  .staff-card .sc-actions .btn{margin-right:4px}
  body.print-card .sc-actions{display:none !important}
  .staff-card .badge{display:inline-block;padding:3px 10px;border-radius:980px;background:var(--ink);color:#fff;font-size:11px;letter-spacing:0.04em;text-transform:uppercase;font-weight:500}

  /* print */
  @media print{
    .topbar,#sb-show,.toolbar,.page-head .btn-row,.actions{display:none !important}
    .app{flex-direction:column}
    .main{padding:0;max-width:none;width:100%}
    .card{border:0;box-shadow:none}
    body{background:#fff}
  }
  body.print-card *{visibility:hidden}
  body.print-card #staffCardModal,
  body.print-card #staffCardModal *{visibility:visible}
  body.print-card #staffCardModal{position:absolute;inset:0;background:#fff;display:block;padding:0}
  body.print-card #staffCardModal .modal{box-shadow:none;border:0;max-width:100%;max-height:none;overflow:visible;border-radius:0}
  body.print-card #staffCardModal .head,
  body.print-card #staffCardModal .head *{visibility:hidden}
  body.print-card .staff-card .badge{background:var(--ink) !important;color:#fff !important;-webkit-print-color-adjust:exact;print-color-adjust:exact}

  /* ===== Equipment Borrowing Form (printable) =====
     Matches the AP Quantum paper template: logo, title, 10-row item
     table, terms & conditions, and four signature blocks. Hidden on
     screen — only rendered into the DOM when the user clicks
     "Borrowing Form" and only made visible during print.

     Print isolation uses display:none on every body child *except* the
     print area. visibility:hidden was leaving the rest of the app in
     the layout, which inflated body height and produced 8+ blank pages
     after the form. display:none collapses the body cleanly. */
  #borrowFormPrintArea{display:none}
  body.print-borrow{background:#fff;margin:0;padding:0}
  body.print-borrow > *{display:none !important}
  body.print-borrow > #borrowFormPrintArea{display:block !important}
  /* Pure-document print layout. Position at top-left only (NO inset/bottom)
     so the element's height grows from its own content, not from the
     (invisible but still-laid-out) rest of the app body. @page handles
     top/bottom margins on EVERY printed page including overflow. */
  body.print-borrow #borrowFormPrintArea{display:block;position:absolute;top:0;left:0;width:100%;background:#fff;font-family:"Times New Roman",Times,serif;color:#000;font-size:11pt;line-height:1.5;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .borrow-form .bf-head{display:flex;align-items:center;gap:10px;margin-bottom:4mm}
  .borrow-form .bf-logo{width:13mm;height:auto;flex:0 0 auto}
  .borrow-form .bf-title{text-align:center;font-size:18pt;font-weight:700;margin:0 0 8mm;letter-spacing:0.01em}
  /* Borrower header row at the top of page 1 — Name / IC filled in
     from the borrowed-by signature meta so the form is identifiable
     even before the signature pages */
  .borrow-form .bf-borrower{width:100%;border-collapse:collapse;margin-bottom:5mm}
  .borrow-form .bf-borrower td{padding:3px 4px;font-size:10.5pt;vertical-align:bottom}
  .borrow-form .bf-borrower-lbl{font-weight:700;white-space:nowrap;width:1%}
  .borrow-form .bf-borrower-val{border-bottom:1px solid #000;padding-left:6px;padding-right:10px;min-width:30mm}
  /* Use border-spacing model instead of collapse — collapse mode lets the
     browser drop the rightmost border on print render. With separate
     borders + zero spacing we get a guaranteed right edge that prints
     consistently across browsers/PDF engines. */
  .borrow-form .bf-table{width:99%;border-collapse:separate;border-spacing:0;margin:0 0 8mm}
  .borrow-form .bf-table th,.borrow-form .bf-table td{border-right:1px solid #444;border-bottom:1px solid #444;padding:5px 8px;font-size:10.5pt;vertical-align:top;word-wrap:break-word;overflow-wrap:break-word;
    /* Override the global "th{position:sticky;top:0}" rule (line ~1004)
       which was making the form's header row stick to the print viewport
       top and overlap row 1 */
    position:static !important}
  .borrow-form .bf-table th:first-child,.borrow-form .bf-table td:first-child{border-left:1px solid #444}
  .borrow-form .bf-table thead th{border-top:1px solid #444}
  /* Light grey header reads as a professional document instead of a
     heavy near-black bar. Bold dark text gives the same emphasis. */
  .borrow-form .bf-table thead th{background:#F2F2F7;color:#0E1C2E;font-weight:700;text-align:left;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .borrow-form .bf-table th.bf-num,.borrow-form .bf-table td.bf-num{width:10mm;text-align:center;font-weight:700;white-space:nowrap}
  .borrow-form .bf-table th.bf-qty,.borrow-form .bf-table td.bf-qty{width:14mm;text-align:center}
  .borrow-form .bf-table th.bf-date,.borrow-form .bf-table td.bf-date{width:24mm}
  .borrow-form .bf-table tbody td{height:8mm}
  /* Keep each row + each T&C item intact across page breaks so things
     like row 10 or a clause never get sliced in half */
  .borrow-form .bf-table tr,.borrow-form .bf-tc li{break-inside:avoid;page-break-inside:avoid}
  .borrow-form .bf-table thead{display:table-header-group}
  .borrow-form .bf-intro{margin:0 0 4mm;text-align:justify}
  .borrow-form .bf-tc{margin:0 0 6mm;padding-left:7mm}
  .borrow-form .bf-tc li{margin-bottom:2.5mm;text-align:justify}
  /* Section header for each acknowledgement block — matches the visual
     weight of the form's main title at a slightly smaller size, so the
     two signature sections read as proper contractual sections rather
     than a stray sentence above signature lines */
  .borrow-form .bf-sig-section-title{font-size:13pt;font-weight:700;margin:0 0 3mm;letter-spacing:0.01em;color:#0E1C2E}
  .borrow-form .bf-sig-intro{margin:0 0 6mm;text-align:justify;font-size:10.5pt}
  .borrow-form .bf-sig-grid{display:grid;grid-template-columns:1fr 1fr;gap:18mm;margin-top:8mm;break-inside:avoid;page-break-inside:avoid}
  .borrow-form .bf-sig-block{font-size:10.5pt;break-inside:avoid;page-break-inside:avoid}
  .borrow-form .bf-sig-title{font-weight:600;margin-bottom:18mm}
  .borrow-form .bf-sig-line{border-top:1px solid #000;width:55mm;margin-bottom:2mm}
  .borrow-form .bf-sig-block .bf-sig-row{margin:1.2mm 0}
  .borrow-form .bf-sep{border:0;border-top:1px solid #000;margin:8mm 0 4mm}
  .borrow-form .bf-receipt{font-size:9.5pt;margin:0 0 4mm;text-align:justify}
  /* Keep the return-signature section (separator + receipt + 2 sig pads)
     together as one unit so we never orphan the headings on a half-empty
     page above the actual signature lines */
  .borrow-form .bf-return-block{break-inside:avoid;page-break-inside:avoid}
  /* Forced page breaks — pin the layout to a clean 3-page structure:
     page 1 = items table, page 2 = T&Cs, page 3 = signatures */
  .borrow-form .bf-page-break{break-before:page;page-break-before:always;height:0}
  @media print{
    /* @page margins apply to EVERY printed page (including overflow),
       unlike padding on an absolute-positioned element which only
       offsets page 1. Margins kept comfortably inside the printable
       area of common office printers (most can't print to edge): 18mm
       top/bottom, 20mm sides on A4 = safe for HP/Brother/Canon. */
    @page{size:A4;margin:18mm 20mm}
    /* Hard cap content width but DO NOT clip — overflow:hidden was
       chopping the table's right border off by ~1px because the border
       sits at the edge of the content box */
    body.print-borrow #borrowFormPrintArea{max-width:100%}
    body.print-borrow .borrow-form .bf-table,
    body.print-borrow .borrow-form .bf-borrower,
    body.print-borrow .borrow-form .bf-sig-grid{max-width:100%}
  }

  /* ===== Borrow form ON-SCREEN view (lives inside #staffCardBody) =====
     Editable form with signature canvases. Distinct from the print-only
     #borrowFormPrintArea above — that one renders the same data into a
     paper-style layout for window.print(). */
  .bv{font-size:13px;color:var(--ink)}
  .bv-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:12px;border-bottom:1px solid var(--line);margin-bottom:14px;flex-wrap:wrap}
  .bv-head .who h2{margin:0;font-size:18px;font-weight:600;letter-spacing:-0.01em}
  .bv-head .who p{margin:3px 0 0;font-size:12px;color:var(--muted)}
  .bv-status{display:inline-block;padding:3px 10px;border-radius:980px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.04em}
  .bv-status.draft{background:#f3f4f6;color:#374151}
  .bv-status.active{background:#dbeafe;color:#1e3a8a}
  .bv-status.returned{background:#dcfce7;color:#166534}
  .bv-section{margin:0 0 18px}
  .bv-section h3{margin:0 0 8px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:0.06em;color:var(--muted)}
  .bv-table{width:100%;border-collapse:collapse}
  .bv-table th,.bv-table td{border:1px solid var(--line);padding:6px 8px;font-size:12.5px;text-align:left;vertical-align:middle}
  /* Override the app-wide "last row has no bottom border" rule so the
     fixed 10-row form table closes cleanly at the bottom */
  .bv-table tbody tr:last-child td{border-bottom:1px solid var(--line)}
  .bv-table thead th{background:var(--surface);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:0.04em;color:var(--muted)}
  .bv-table th.bv-num,.bv-table td.bv-num{width:32px;text-align:center;color:var(--muted)}
  .bv-table th.bv-qty,.bv-table td.bv-qty{width:54px}
  .bv-table th.bv-date,.bv-table td.bv-date{width:120px}
  .bv-table th.bv-action,.bv-table td.bv-action{width:88px;text-align:center;white-space:nowrap}
  .bv-table tr.returned td{background:#f3f4f6;color:var(--muted)}
  .bv-table tr.returned input{color:var(--muted)}
  .bv-row-return{padding:3px 10px !important;font-size:11.5px !important;height:auto !important;min-height:0 !important}
  .bv-returned-badge{display:inline-block;padding:2px 8px;border-radius:980px;background:#dcfce7;color:#166534;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.05em}
  .bv-table input{width:100%;border:0;background:transparent;font:inherit;font-size:12.5px;padding:4px 2px;color:var(--ink);outline:none}
  .bv-table input:focus{background:rgba(0,113,227,0.06);border-radius:3px}
  .bv-table tr.prefilled td{background:rgba(0,113,227,0.03)}
  /* padding-left needs to accommodate two-digit markers (10.-14.) so the
     leading digit isn't clipped by the list-marker box */
  .bv-tc{margin:0 0 10px;padding-left:28px;font-size:12px;color:var(--ink-soft);line-height:1.55}
  .bv-tc li{margin:4px 0 8px;padding-left:2px}
  .bv-tc li:last-child{margin-bottom:4px}
  .bv-tc-toggle{background:none;border:0;color:var(--brand);font-size:12px;cursor:pointer;padding:4px 0;font-weight:500}
  .bv-tc-wrap{max-height:0;overflow:hidden;transition:max-height .25s ease}
  .bv-tc-wrap.open{max-height:1200px}
  .bv-sig-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
  .bv-sig-card{border:1px solid var(--line);border-radius:8px;padding:10px;background:#fff}
  .bv-sig-card .bv-sig-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--muted);margin-bottom:8px}
  .bv-sig-pad{position:relative;width:100%;aspect-ratio:5/2;background:#fafafa;border:1px dashed var(--border2);border-radius:6px;touch-action:none;cursor:crosshair;overflow:hidden}
  .bv-sig-pad canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
  .bv-sig-pad.signed{background:#fff;border-style:solid;border-color:var(--line)}
  .bv-sig-pad .bv-sig-hint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:11px;pointer-events:none}
  .bv-sig-pad.signed .bv-sig-hint{display:none}
  .bv-sig-meta{margin-top:8px;display:grid;grid-template-columns:1fr 1fr;gap:6px}
  .bv-sig-meta input{font:inherit;font-size:12px;padding:5px 8px;border:1px solid var(--border2);border-radius:5px;background:#fff;outline:none;width:100%;box-sizing:border-box}
  .bv-sig-meta input:focus{border-color:var(--brand)}
  .bv-sig-actions{display:flex;justify-content:space-between;align-items:center;margin-top:6px;font-size:11px;color:var(--muted)}
  .bv-sig-actions button{background:none;border:0;color:var(--brand);font-size:11px;cursor:pointer;padding:2px 0}
  .bv-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;padding-top:14px;border-top:1px solid var(--line);margin-top:14px}
  .bv-history{margin-top:18px}
  .bv-history-row{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--line);border-radius:8px;margin-bottom:6px;background:#fff;font-size:12.5px}
  .bv-history-row .bv-h-date{font-weight:600;color:var(--ink)}
  .bv-history-row .bv-h-meta{color:var(--muted);font-size:11.5px}
  .bv-history-row .bv-h-actions{display:flex;gap:6px}
  .bv-empty{padding:24px;text-align:center;color:var(--muted);font-size:13px;border:1px dashed var(--border2);border-radius:8px}
  @media (max-width:640px){
    .bv-sig-grid{grid-template-columns:1fr}
    .bv-table th.bv-date,.bv-table td.bv-date{width:90px}
    .bv-actions{justify-content:stretch}
    .bv-actions .btn{flex:1 1 auto;min-width:0}
  }

  /* (legacy fully-hidden sidebar removed — rail mode is now the collapsed state) */

  /* ===== Labels — simple, clean, centred ===== */
  .label-hero{display:flex;gap:32px;align-items:center;flex-wrap:wrap}
  .hero-key{font-size:13px;line-height:1.8;color:var(--ink-soft);max-width:520px}
  .hero-key .dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:8px;vertical-align:middle}
  .hero-key b{color:var(--ink)}
  .chk{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--ink-soft);padding:4px 0}
  .chk input{margin:0}
  .lbl-grid{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(60mm,max-content));justify-content:center}
  .label{background:#fff;border:1px dashed rgba(0,0,0,0.2);box-sizing:border-box;overflow:hidden;color:#000;font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Helvetica,Arial,sans-serif;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}
  .label.showgrid{border:1px dashed rgba(0,113,227,0.35)}
  .label-50x30{width:50mm;height:30mm;padding:1.6mm 2mm}
  .label-50x40{width:50mm;height:40mm;padding:2mm 2mm}
  .label-50x80{width:50mm;height:80mm;padding:3mm 2mm}
  .label-40x30{width:40mm;height:30mm;padding:1.4mm 1.6mm}
  .label-60x40{width:60mm;height:40mm;padding:2mm 2.5mm}
  .label-30x20{width:30mm;height:20mm;padding:0.8mm 1mm}
  .label .code-box{width:100%;display:flex;align-items:center;justify-content:center;flex:0 0 auto}
  .label .code-box svg,.label .code-box img{display:block;max-width:100%;height:auto}
  .label-50x30 .code-box{height:11mm}
  .label-50x40 .code-box{height:16mm}
  .label-50x80 .code-box{height:30mm}
  .label-40x30 .code-box{height:10.5mm}
  .label-60x40 .code-box{height:16mm}
  .label-30x20 .code-box{height:8mm}
  .label .code-box img{height:100%;width:auto;image-rendering:pixelated}
  .label .code-box.qr img{height:100%;width:auto}
  .label .asset-id{font-weight:700;letter-spacing:0.04em;font-family:"SF Mono","Menlo","Consolas",monospace;margin-top:0.8mm;line-height:1}
  .label-50x30 .asset-id{font-size:12pt}
  .label-50x40 .asset-id{font-size:14pt}
  .label-50x80 .asset-id{font-size:16pt}
  .label-40x30 .asset-id{font-size:10pt}
  .label-60x40 .asset-id{font-size:15pt}
  .label-30x20 .asset-id{font-size:8.5pt;margin-top:0.4mm}
  .label .sub{color:#000;margin-top:0.5mm;line-height:1.15;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}
  .label-50x30 .sub{font-size:8pt}
  .label-50x40 .sub{font-size:9pt}
  .label-50x80 .sub{font-size:10pt}
  .label-40x30 .sub{font-size:7pt}
  .label-60x40 .sub{font-size:9pt}
  .label-30x20 .sub{display:none}
  .label .sub.strong{color:#000;font-weight:500;line-height:1.1}
  .label .sub.strong.bracket{margin-top:0.2mm;font-weight:500;color:#000;line-height:1.1}
  /* bracket inherits .sub font-size per label — keep as one visual unit */
  .label-30x20 .sub.strong.bracket{display:none}
  .label .owner-tag{margin-top:0.5mm;font-weight:600;letter-spacing:0.06em;color:#000}
  .label-50x30 .owner-tag{font-size:7pt}
  .label-50x40 .owner-tag{font-size:8pt}
  .label-50x80 .owner-tag{font-size:9pt}
  .label-40x30 .owner-tag{font-size:6.5pt}
  .label-60x40 .owner-tag{font-size:8pt}
  .label-30x20 .owner-tag{display:none}

  /* QR-only layout centres a square code */
  .label.qr-only .code-box{aspect-ratio:1/1;height:auto}
  .label-50x30.qr-only .code-box{width:18mm;height:18mm}
  .label-50x40.qr-only .code-box{width:26mm;height:26mm}
  .label-50x80.qr-only .code-box{width:36mm;height:36mm}
  .label-40x30.qr-only .code-box{width:16mm;height:16mm}
  .label-60x40.qr-only .code-box{width:22mm;height:22mm}
  .label-30x20.qr-only .code-box{width:10mm;height:10mm}

  /* Print-only rules: when body has .print-labels, only the label grid prints */
  body.print-labels{background:#fff}
  body.print-labels *{visibility:hidden}
  body.print-labels #lbl-grid,
  body.print-labels #lbl-grid *{visibility:visible}
  body.print-labels #lbl-grid{position:absolute;inset:0;padding:6mm;margin:0}
  body.print-labels .label{border:0 !important}
  @media print{
    body.print-labels .label{break-inside:avoid;page-break-inside:avoid}
  }

  /* Dark mode removed — app is light-only. */
  .ms-panel[hidden]{display:none !important}
  body #sb-theme{display:none !important}

  /* ===== Sidebar bottom action group — slate panel containing the Scan or
     search input PLUS the user/cloud-status footer. Background colour matches
     APQ Accounts' .sidebar-footer card so the bottom of the sidebar reads as
     one cohesive zone, visually separated from the dark-navy nav above. */
  .sb-action-group{background:rgb(30,41,59);border-radius:12px;padding:12px;display:flex;flex-direction:column;gap:10px;margin-top:auto}
  .global-search input{
    width:100% !important;
    height:44px !important;
    box-sizing:border-box !important;
    padding:0 44px 0 14px !important;
    display:flex !important;
    align-items:center !important;
    background:rgba(255,255,255,0.12) !important;
    border:1px solid rgba(255,255,255,0.18) !important;
    border-radius:10px !important;
    color:#fff !important;
    font-size:13px !important;
    font-weight:500 !important;
    line-height:1 !important;
    transition:background .15s, border-color .15s, box-shadow .15s;
  }
  .global-search input:hover{
    background:rgba(255,255,255,0.18) !important;
    border-color:rgba(255,255,255,0.28) !important;
  }
  .global-search input:focus{
    background:rgba(255,255,255,0.20) !important;
    border-color:rgba(245,166,35,0.6) !important;
    box-shadow:0 0 0 3px rgba(245,166,35,0.15) !important;
    outline:none !important;
  }
  .global-search input::placeholder{color:rgba(255,255,255,0.6) !important}
  /* The scan camera button sits inside .global-search as a right-pinned icon */
  #gs-scan-btn{right:6px !important;top:6px !important;width:32px !important;height:32px !important}
  /* Rail (collapsed desktop) overrides — hide footer card text in rail mode */
  body.sb-rail .sidebar-footer{padding:8px;gap:6px}
  body.sb-rail .sidebar-footer .user-meta,
  body.sb-rail .sidebar-footer .switch-btn span,
  body.sb-rail .sidebar-status #cloud-text{display:none}
  body.sb-rail .sidebar-footer .switch-btn{padding:8px;justify-content:center;gap:0}
  body.sb-rail .sidebar-footer .user-row{justify-content:center}
  body.sb-rail .sb-action-group{padding:8px;gap:6px}
