  :root{
    --bg:#0f172a; --panel:#1e293b; --panel2:#16213a; --border:#2f3d56;
    --text:#e6edf7; --muted:#94a3b8; --accent:#3b82f6; --accent2:#22c55e;
    --fail:#ef4444; --pass:#22c55e; --warn:#f59e0b;
  }
  body[data-theme="light"]{
    --bg:#f1f5f9; --panel:#ffffff; --panel2:#f8fafc; --border:#dbe2ea;
    --text:#0f172a; --muted:#64748b; --accent:#2563eb; --accent2:#16a34a;
    --fail:#dc2626; --pass:#16a34a; --warn:#d97706;
  }
  body[data-theme="light"] thead th{ color:#475569; }
  body[data-theme="light"] .pdf-modal-frame-wrap{ background:#e2e8f0; }
  *{box-sizing:border-box;}
  body{
    margin:0; font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
    background:var(--bg); color:var(--text); font-size:14px; transition:background .2s, color .2s;
  }
  header{
    padding:14px 24px; background:var(--panel);
    border-bottom:1px solid var(--border); display:flex; align-items:center; justify-content:space-between;
    flex-wrap:wrap; gap:12px;
    position:fixed; top:0; left:0; right:0; z-index:150;
  }
  /* Header is fixed, so everything below has to clear it. --header-h is measured at
     runtime because the toolbar wraps to two rows on narrower screens. */
  :root{ --header-h:64px; }
  header h1{ font-size:19px; margin:0; font-weight:700; letter-spacing:.3px; color:var(--text);}
  header .sub{ color:var(--muted); font-size:12px; margin-top:2px;}
  .toolbar{ display:flex; gap:8px; flex-wrap:wrap; align-items:center;}

  /* ---- Nav dropdowns ---- */
  .navgroup{ position:relative; }
  .nav-btn{
    background:var(--panel2); color:var(--text); border:1px solid var(--border);
    padding:9px 14px; border-radius:7px; font-size:13px; cursor:pointer; font-weight:600;
    display:inline-flex; align-items:center; gap:6px;
  }
  .nav-btn:hover{ border-color:var(--accent); }
  .nav-btn .caret{ font-size:10px; opacity:.7; }
  .nav-menu{
    position:absolute; top:calc(100% + 6px); left:0; min-width:220px; background:var(--panel);
    border:1px solid var(--border); border-radius:10px; padding:6px; box-shadow:0 10px 30px rgba(0,0,0,.35);
    display:none; flex-direction:column; gap:2px; z-index:150;
  }
  /* Menus belonging to groups near the right-hand end open leftwards, or they run off
     the edge of the window — Admin is the last item in the toolbar, so its menu had
     nowhere to go. Anchoring to the button's right edge keeps it on screen at any
     window width. Inert on mobile, where the menu is position:static. */
  .navgroup[data-align="right"] .nav-menu{ left:auto; right:0; }
  /* Last-resort guard for a very narrow window. */
  .nav-menu{ max-width:calc(100vw - 24px); }
  .navgroup.open .nav-menu{ display:flex; }
  .nav-menu button, .nav-menu .file-btn{
    background:transparent; color:var(--text); border:none; text-align:left; justify-content:flex-start;
    padding:9px 10px; border-radius:6px; font-weight:500; width:100%;
  }
  .nav-menu button:hover, .nav-menu .file-btn:hover{ background:var(--panel2); filter:none; }
  .nav-menu button.danger{ background:transparent; color:var(--fail); }
  .nav-menu button.danger:hover{ background:rgba(239,68,68,.12); }
  .nav-menu hr{ border:none; border-top:1px solid var(--border); margin:4px 2px; }

  /* ---- Theme toggle switch ---- */
  .theme-switch{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--muted); }
  .theme-switch-track{
    width:44px; height:24px; border-radius:20px; background:var(--panel2); border:1px solid var(--border);
    position:relative; cursor:pointer; flex-shrink:0;
  }
  .theme-switch-track .knob{
    position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%;
    background:var(--accent); transition:left .18s;
  }
  body[data-theme="light"] .theme-switch-track .knob{ left:23px; }

  .view-switch{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--muted); white-space:nowrap; }
  .view-switch-option{ transition:color .15s, font-weight .15s; }
  .view-switch-option.active{ color:var(--text); font-weight:700; }
  .view-switch-track{
    width:44px; height:24px; border-radius:20px; background:var(--panel2); border:1px solid var(--border);
    position:relative; cursor:pointer; flex-shrink:0;
  }
  .view-switch-track .knob{
    position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%;
    background:var(--accent); transition:left .18s;
  }
  .view-switch-track.on .knob{ left:23px; }

  .hamburger{
    display:none; background:var(--panel2); border:1px solid var(--border); color:var(--text);
    font-size:18px; padding:8px 12px; border-radius:7px; cursor:pointer;
  }

  /* ---- Barcode scanner modal ---- */
  .scanner-viewport{
    width:100%; max-width:420px; aspect-ratio:1/1; margin:0 auto; border-radius:10px; overflow:hidden;
    background:#000; position:relative;
  }
  .scanner-viewport video{ width:100%; height:100%; object-fit:cover; }
  .scanner-status{ text-align:center; font-size:13px; color:var(--muted); margin-top:14px; min-height:18px; }

  button, .file-btn{
    background:var(--accent); color:white; border:none; padding:9px 14px; border-radius:7px;
    font-size:13px; cursor:pointer; font-weight:600; display:inline-flex; align-items:center; gap:6px;
    transition:filter .15s;
  }
  button:hover, .file-btn:hover{ filter:brightness(1.12); }
  button.secondary{ background:#334155; color:#fff; }
  button.danger{ background:#7f1d1d; color:#fff; }
  button.ghost{ background:transparent; border:1px solid var(--border); color:var(--text);}
  button:disabled{ opacity:.4; cursor:not-allowed; }
  input[type=file]{ display:none; }
  /* Fill the available space on wide screens rather than capping at a fixed width;
     clamp keeps line lengths sane on very large monitors. */
  /* Top padding MUST clear the fixed header, and must live in this shorthand —
     a separate padding-top rule earlier in the file gets reset by this one. */
  main{ padding:calc(var(--header-h) + 20px) clamp(12px, 2vw, 40px) 20px;
    max-width:min(2200px, 100%); margin:0 auto; width:100%; }
  .stats{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:18px; }
  .stats-row{ display:flex; gap:12px; margin-bottom:18px; align-items:stretch; flex-wrap:wrap; }
  .stats-row .stats{ margin-bottom:0; flex:1 1 auto; min-width:0; }
  .stats-row .navgroup{ display:flex; align-items:center; flex:0 0 auto; }
  .inline-dropzone{
    flex:1; min-width:220px; border:2px dashed var(--border); border-radius:10px;
    display:flex; align-items:center; justify-content:center; text-align:center;
    color:var(--muted); font-size:13px; font-weight:600; cursor:pointer; padding:10px; transition:.15s;
  }
  .inline-dropzone small{ font-weight:500; color:var(--muted); }
  .inline-dropzone:hover, .inline-dropzone.drag{ border-color:var(--accent); background:rgba(59,130,246,.08); color:var(--text); }
  .stat{
    background:var(--panel); border:1px solid var(--border); border-radius:10px; padding:12px 18px; min-width:120px;
  }
  .stat .n{ font-size:22px; font-weight:800; }
  .stat .l{ color:var(--muted); font-size:11px; text-transform:uppercase; letter-spacing:.5px; margin-top:2px;}
  .stat.fail .n{ color:var(--fail); }
  .stat.pass .n{ color:var(--pass); }
  /* Deliberately its own colour, not pass-green and not fail-red: these assets are
     safe to use now, but the fact they failed and were repaired is information the
     client is entitled to see rather than have folded silently into the pass count. */
  .stat.fixed .n{ color:#c77d17; }
  .panel{ background:var(--panel); border:1px solid var(--border); border-radius:12px; padding:16px; margin-bottom:16px; }
  .filters{ display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end; }
  .filters-toggle{ display:none; width:100%; justify-content:space-between; align-items:center; margin-bottom:4px; }
  .filters-toggle .caret{ transition:transform .15s; }
  .filters-toggle.open .caret{ transform:rotate(180deg); }
  .field{ display:flex; flex-direction:column; gap:4px; min-width:0; }
  .field label{ font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.4px;}
  select, input[type=text], input[type=date]{
    background:var(--panel2); border:1px solid var(--border); color:var(--text);
    padding:8px 10px; border-radius:7px; font-size:13px; min-width:150px;
  }
  input[type=text]{ min-width:220px; }
  table{ width:100%; border-collapse:collapse; font-size:12.5px; }
  thead th{
    position:sticky; top:0; background:var(--panel2); text-align:left; padding:10px 8px;
    border-bottom:2px solid var(--border); cursor:pointer; white-space:nowrap; user-select:none;
    color:var(--muted); font-weight:700; font-size:11px; text-transform:uppercase; letter-spacing:.3px;
  }
  thead th:hover{ color:var(--text); }
  thead th .arrow{ opacity:.5; margin-left:3px; }
  tbody td{ padding:8px; border-bottom:1px solid var(--border); white-space:nowrap; }
  tbody tr:hover{ background:var(--panel2); }
  th.num, td.num{ text-align:right; }

  /* ---- Dashboard ---- */
  .dashboard-chart-svg{ width:100%; height:auto; display:block; }
  .dash-due-row{ display:flex; justify-content:space-between; align-items:center;
    padding:8px 0; border-bottom:1px solid var(--border); font-size:13.5px; }
  .dash-due-row:last-child{ border-bottom:none; }
  .dash-due-row b{ font-size:18px; }
  .dash-client-link{ display:flex; align-items:center; gap:8px; cursor:pointer; }
  .dash-client-link:hover{ color:var(--accent); }
  .dash-client-avatar{
    width:26px; height:26px; border-radius:6px; background:var(--panel2); border:1px solid var(--border);
    display:flex; align-items:center; justify-content:center; flex-shrink:0; overflow:hidden;
    font-size:10.5px; font-weight:700; color:var(--accent);
  }
  .dash-client-avatar img{ max-width:100%; max-height:100%; }
  .dash-compliance{ font-weight:700; }
  .dash-compliance.good{ color:var(--pass); }
  .dash-compliance.warn{ color:var(--warn); }
  .dash-compliance.bad{ color:var(--fail); }
  @media (max-width:900px){
    .dashboard-panels-row{ grid-template-columns:1fr !important; }
  }
  td.cell-link{ cursor:pointer; color:var(--accent); font-weight:600; }
  td.cell-link:hover{ text-decoration:underline; }

  /* ---- Manual entry wizard ---- */
  .wizard-progress{ display:flex; gap:6px; margin-bottom:16px; }
  .wizard-progress .step-dot{ flex:1; height:4px; border-radius:2px; background:var(--border); }
  .wizard-progress .step-dot.done, .wizard-progress .step-dot.active{ background:var(--accent); }
  .wizard-step-label{ font-size:11.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.4px; margin-bottom:16px; font-weight:700; }
  .wizard-nav{ display:flex; justify-content:space-between; align-items:center; padding-top:16px; margin-top:16px; border-top:1px solid var(--border); }
  .big-toggle{ display:flex; gap:10px; }
  .big-toggle button{
    flex:1; padding:16px; border-radius:10px; font-size:15px; font-weight:700;
    border:2px solid var(--border); background:var(--panel2); color:var(--text);
  }
  .big-toggle button.selected.pass{ border-color:var(--pass); background:rgba(34,197,94,.15); color:var(--pass); }
  .big-toggle button.selected.fail{ border-color:var(--fail); background:rgba(239,68,68,.15); color:var(--fail); }
  .test-card{ border:1px solid var(--border); border-radius:10px; padding:14px; margin-bottom:12px; transition:opacity .15s; }
  .test-card.disabled{ opacity:.45; }
  .test-card.disabled .test-card-body{ pointer-events:none; }
  .test-card-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:10px; }
  .test-card-head label{
    display:flex; align-items:center; gap:8px; font-weight:700; font-size:13.5px;
    color:var(--text); cursor:pointer; text-transform:none; letter-spacing:normal;
  }
  .test-card-head select{ width:auto; }
  .test-card-body{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  .test-card-body input, .test-card-body select{ width:100%; }
  .badge{ padding:2px 9px; border-radius:20px; font-size:11px; font-weight:700; }
  .badge.Pass{ background:rgba(34,197,94,.15); color:var(--pass); }
  .badge.Fail{ background:rgba(239,68,68,.15); color:var(--fail); }
  .badge.other{ background:rgba(245,158,11,.15); color:var(--warn); }
  .table-wrap{ max-height:60vh; overflow:auto; border:1px solid var(--border); border-radius:10px; }
  .empty{ text-align:center; padding:60px 20px; color:var(--muted); }
  .empty h2{ color:var(--text); margin-bottom:6px; }
  footer.bar{ display:flex; justify-content:space-between; align-items:center; margin-top:10px; flex-wrap:wrap; gap:8px; color:var(--muted); font-size:12px;}
  .drop{
    border:2px dashed var(--border); border-radius:12px; padding:40px; text-align:center; color:var(--muted);
    transition:.15s; cursor:pointer;
  }
  .drop.drag{ border-color:var(--accent); background:rgba(59,130,246,.08); color:var(--text); }
  .toast{
    position:fixed; bottom:20px; right:20px; background:var(--panel); border:1px solid var(--border);
    padding:12px 18px; border-radius:10px; box-shadow:0 8px 24px rgba(0,0,0,.4); z-index:100; font-size:13px;
    animation:in .25s ease;
  }
  @keyframes in{ from{transform:translateY(10px); opacity:0;} to{transform:translateY(0); opacity:1;} }
  .checkbox-cell{ width:34px; }
  .expand-cell{ width:26px; }
  .expand-toggle{
    background:none; border:none; color:var(--muted); cursor:pointer; font-size:12px;
    width:22px; height:22px; display:flex; align-items:center; justify-content:center;
    border-radius:4px; transition:transform .15s;
  }
  .expand-toggle:hover{ background:var(--panel2); color:var(--text); }
  .expand-toggle.open{ transform:rotate(90deg); }
  tr.test-subrow td{ background:var(--panel2); color:var(--muted); font-size:12px; }
  tr.test-subrow td:nth-child(3){ padding-left:26px; } /* indent under the asset ID column */
  .tests-count-badge{
    display:inline-block; background:var(--panel2); border:1px solid var(--border); border-radius:20px;
    padding:2px 9px; font-size:11.5px; font-weight:700; color:var(--text);
  }

  .combo-dropdown{
    position:absolute; top:100%; left:0; right:0; z-index:30; margin-top:4px;
    background:var(--panel); border:1px solid var(--border); border-radius:8px;
    max-height:180px; overflow-y:auto; box-shadow:0 10px 26px rgba(0,0,0,.35);
  }
  .combo-dropdown button{
    display:block; width:100%; text-align:left; background:none; border:none; color:var(--text);
    padding:9px 12px; font-size:13px; cursor:pointer; border-radius:0;
  }
  .combo-dropdown button:hover{ background:var(--panel2); }
  .context-menu{
    position:fixed; z-index:500; background:var(--panel); border:1px solid var(--border);
    border-radius:10px; padding:6px; min-width:200px; box-shadow:0 12px 30px rgba(0,0,0,.4);
    display:flex; flex-direction:column; gap:2px;
  }
  .context-menu button{
    background:transparent; color:var(--text); border:none; text-align:left; justify-content:flex-start;
    padding:9px 10px; border-radius:6px; font-weight:500; font-size:13px; width:100%;
  }
  .context-menu button:hover{ background:var(--panel2); filter:none; }
  .context-menu button.danger{ color:var(--fail); }
  .context-menu button.danger:hover{ background:rgba(239,68,68,.12); }
  .context-menu hr{ border:none; border-top:1px solid var(--border); margin:4px 2px; }
  a.linklike{ color:var(--accent); cursor:pointer; }
  .modal-bg{ position:fixed; inset:0; background:rgba(0,0,0,.55); display:flex;
    align-items:center; justify-content:center; z-index:200;
    overflow-y:auto; -webkit-overflow-scrolling:touch; padding:16px 0;}
  .modal{ background:var(--panel); border:1px solid var(--border); border-radius:12px;
    padding:20px; max-width:480px; width:90%; position:relative;
    max-height:calc(100dvh - 32px); overflow-y:auto; -webkit-overflow-scrolling:touch;
    margin:auto;}
  .modal-close-x{
    position:absolute; top:12px; right:12px; width:28px; height:28px; padding:0;
    display:flex; align-items:center; justify-content:center; border-radius:50%;
    background:var(--panel2); border:1px solid var(--border); color:var(--muted);
    font-size:14px; cursor:pointer; z-index:20;
  }
  .modal-close-x:hover{ background:rgba(239,68,68,.12); color:var(--fail); filter:none; }
  .import-spinner{
    width:36px; height:36px; border:4px solid var(--border); border-top-color:var(--accent);
    border-radius:50%; margin:10px auto 0 auto; animation:spin .8s linear infinite;
  }
  @keyframes spin{ to{ transform:rotate(360deg); } }
  .progress-bar-track{
    width:100%; height:10px; border-radius:6px; background:var(--panel2);
    border:1px solid var(--border); overflow:hidden;
  }
  .progress-bar-fill{
    height:100%; background:var(--accent); border-radius:6px 0 0 6px;
    transition:width .2s ease; min-width:2px;
  }
  .loading-state{ text-align:center; padding:60px 20px; color:var(--muted); }
  .loading-spinner{
    width:40px; height:40px; border:4px solid var(--border); border-top-color:var(--accent);
    border-radius:50%; margin:0 auto 16px auto; animation:spin .8s linear infinite;
  }
  #clientSelectLoadingText{ font-size:13.5px; font-weight:600; }
  .fail-note-box{
    background:rgba(245,158,11,.1); border:1px solid rgba(245,158,11,.4); color:var(--text);
    padding:10px 14px; border-radius:8px; font-size:13px; line-height:1.5;
  }
  .desc-change-badge{ cursor:help; font-size:12px; }
  .preview-client{ border:1px solid var(--border); border-radius:10px; padding:10px 14px; margin-bottom:8px; }
  .preview-client-head{ display:flex; align-items:center; gap:10px; cursor:pointer; font-size:14px; }
  .preview-status{ display:block; margin:4px 0 0 26px; font-size:12px; color:var(--muted); font-weight:600; }
  .preview-locations{ margin:8px 0 2px 26px; display:flex; flex-direction:column; gap:6px; }
  .preview-location-row{ display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--muted); cursor:pointer; }

  .selection-bar{
    display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:10px;
    background:rgba(59,130,246,.1); border:1px solid var(--accent); border-radius:10px;
    padding:12px 16px; margin-bottom:16px; font-size:13.5px; font-weight:600;
  }
  .modal h3{ margin-top:0;}
  .modal .row{ display:flex; gap:8px; justify-content:flex-end; margin-top:16px;}
  small.hint{ color:var(--muted); }
  .pdf-modal-bg{
    position:fixed; inset:0; background:rgba(0,0,0,.7); z-index:300;
    display:flex; flex-direction:column;
  }
  .pdf-modal-bar{
    display:flex; align-items:center; justify-content:space-between; padding:12px 20px;
    background:var(--panel); border-bottom:1px solid var(--border); gap:10px; flex-wrap:wrap;
  }
  .pdf-modal-bar .title{ font-weight:700; font-size:14px; }
  .pdf-modal-frame-wrap{ flex:1; padding:16px; background:#0b1220; }
  .pdf-modal-frame-wrap iframe{ width:100%; height:100%; border:none; border-radius:8px; background:white; }
  .dash-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(240px,1fr)); gap:12px; margin-top:12px; }
  .page-head{ margin-bottom:20px; }
  .page-head h2{ font-size:22px; margin-bottom:6px; }
  .page-head .hint{ color:var(--muted); font-size:13.5px; }
  .client-select-card{
    background:var(--panel); border:1px solid var(--border); border-radius:12px; padding:16px;
    cursor:pointer; transition:border-color .15s;
  }
  .client-select-card:hover{ border-color:var(--accent); }
  .client-select-card-head{ display:flex; align-items:center; gap:10px; margin-bottom:8px; }
  .client-select-card h4{ margin:0; font-size:15px; }
  .client-select-avatar{
    width:36px; height:36px; border-radius:8px; background:var(--panel2); border:1px solid var(--border);
    display:flex; align-items:center; justify-content:center; flex-shrink:0; overflow:hidden;
    font-size:12px; font-weight:700; color:var(--accent);
  }
  .client-select-avatar img{ max-width:100%; max-height:100%; }
  .client-select-card .meta{ font-size:12px; color:var(--muted); line-height:1.5; margin-bottom:10px; }
  .client-select-card .actions{ display:flex; gap:6px; flex-wrap:wrap; }
  .client-select-card .actions button{ font-size:11.5px; padding:6px 9px; }

  .client-header-card{
    display:flex; align-items:center; gap:16px; background:var(--panel); border:1px solid var(--border);
    border-radius:12px; padding:18px 20px; margin-bottom:16px; flex-wrap:wrap;
  }
  .client-header-logo{
    width:56px; height:56px; border-radius:10px; background:var(--panel2); border:1px solid var(--border);
    display:flex; align-items:center; justify-content:center; flex-shrink:0; overflow:hidden;
  }
  .client-header-logo img{ max-width:100%; max-height:100%; }
  .client-header-info{ flex:1; min-width:180px; }
  .client-header-info h2{ font-size:19px; margin-bottom:4px; }
  .client-header-actions{ display:flex; gap:8px; flex-wrap:wrap; }
  .dash-card{ background:var(--panel2); border:1px solid var(--border); border-radius:10px; padding:14px; }
  .dash-card h4{ margin:0 0 6px 0; font-size:14px; }
  .dash-card .meta{ font-size:12px; color:var(--muted); margin-bottom:10px; line-height:1.5; }
  .dash-card .actions{ display:flex; gap:6px; flex-wrap:wrap; }
  .dash-card .actions button{ font-size:11.5px; padding:6px 9px; }
  .client-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 0; border-bottom:1px solid var(--border); }
  .modal-actions-top{
    position:sticky; top:0; z-index:5; background:var(--panel);
    display:flex; gap:8px; justify-content:flex-end; flex-wrap:wrap;
    padding:10px 0 12px 0; margin-bottom:6px; border-bottom:1px solid var(--border);
  }
  .client-row:last-child{ border-bottom:none; }
  .client-row .name{ font-weight:700; }
  .client-row .count{ color:var(--muted); font-size:12px; }

  /* ---------------------------------------------------------------------
     Mobile layout — below this width, the nav collapses into a hamburger
     menu, filters/stats stack vertically, and everything gets touch-sized.
  --------------------------------------------------------------------- */
  /* ---- Auth screen ---- */
  body > header{ display:none; }
  body > main{ display:none; }
  body.authed > header{ display:flex; }
  body.authed > main{ display:block; }
  /* The sidebar (below) is the primary nav on desktop; the header is only ever
     the slim mobile bar. Same breakpoint as .client-rail, so exactly one of the
     two is visible at any width. */
  @media (min-width:900px){ body.authed > header{ display:none; } }
  #authScreen{ display:flex; }
  body.authed #authScreen{ display:none; }

  .auth-screen{
    min-height:100vh; align-items:center; justify-content:center; background:var(--bg); padding:20px;
  }
  .auth-card{
    background:var(--panel); border:1px solid var(--border); border-radius:14px; padding:28px;
    width:100%; max-width:380px; box-shadow:0 20px 50px rgba(0,0,0,.3);
  }
  .auth-card label{ font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.4px; }
  .auth-card input{
    background:var(--panel2); border:1px solid var(--border); color:var(--text);
    padding:9px 10px; border-radius:7px; font-size:13px; margin-top:4px;
  }
  .auth-error{
    background:rgba(239,68,68,.12); border:1px solid rgba(239,68,68,.4); color:var(--fail);
    border-radius:7px; padding:8px 10px; font-size:12.5px; margin-top:8px;
  }
  .sso-btn{
    width:100%; justify-content:center; background:var(--panel2); color:var(--text);
    border:1px solid var(--border); font-weight:600; font-size:13.5px; padding:10px 14px;
  }
  .sso-btn:hover{ border-color:var(--accent); filter:none; }
  .sso-icon{ font-weight:800; font-size:15px; width:18px; text-align:center; display:inline-block; }
  .sso-divider{
    display:flex; align-items:center; gap:10px; color:var(--muted); font-size:11.5px;
    text-transform:uppercase; letter-spacing:.05em; margin:4px 0 16px 0;
  }
  .sso-divider::before, .sso-divider::after{ content:''; flex:1; height:1px; background:var(--border); }

  @media (max-width: 760px){
    header{ padding:12px 16px; }
    header h1{ font-size:16px; }

    .filters-toggle{ display:flex; }
    .filters{ display:none; }
    .filters.open{ display:flex; margin-top:12px; }

    main{ padding:calc(var(--header-h) + 14px) 14px 14px; }
    /* .stats-row .stats was flex:0 0 auto, so the tile block refused to shrink, sized
       itself to its tiles and ran off the side of the screen — the flex-wrap on the
       tiles never fired because their container was already wider than the phone. */
    .stats-row{ flex-direction:column; align-items:stretch; gap:10px; }
    .stats{ display:grid; grid-template-columns:repeat(auto-fit, minmax(96px, 1fr)); gap:8px; width:100%; }
    .stats-row .navgroup{ width:100%; }
    .stats-row .navgroup .nav-btn{ width:100%; }
    .stat{ min-width:0; padding:10px 12px; }
    .stat .n{ font-size:18px; }

    .filters{ flex-direction:column; align-items:stretch; gap:10px; }
    .field{ width:100%; }
    .field select, .field input[type=text], .field input[type=date]{ width:100%; min-width:0; }

    table{ font-size:11.5px; }
    thead th{ padding:8px 6px; }
    tbody td{ padding:7px 6px; }

    .modal{ padding:16px; width:94%; }
    .dash-grid{ grid-template-columns:1fr; }
    .row{ flex-wrap:wrap; }
    .row button{ flex:1 1 auto; }

    .pdf-modal-bar{ padding:10px 12px; flex-wrap:wrap; }
    .pdf-modal-bar .title{ font-size:12.5px; width:100%; }
  }

  /* ---- Export wizard ---- */
  .export-scope{ display:flex; flex-direction:column; gap:8px; margin-bottom:14px; }
  .export-radio{ display:flex; gap:10px; align-items:flex-start; padding:10px 12px;
    border:1px solid var(--border); border-radius:8px; cursor:pointer; font-size:13.5px; }
  .export-radio:has(input:checked){ border-color:var(--accent, #2f6fed);
    background:rgba(47,111,237,.06); }
  .export-picker{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:14px; }
  .export-col{ border:1px solid var(--border); border-radius:8px; overflow:hidden; }
  .export-col-head{ display:flex; justify-content:space-between; align-items:center;
    gap:8px; padding:8px 10px; border-bottom:1px solid var(--border); font-size:12.5px; }
  .export-list{ max-height:190px; overflow-y:auto; padding:6px 10px; }
  .export-list label{ display:flex; gap:8px; align-items:center; padding:4px 0;
    font-size:13px; cursor:pointer; }
  .export-list label span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .export-latest{ display:flex; gap:10px; align-items:flex-start; padding:10px 12px;
    border:1px solid var(--border); border-radius:8px; cursor:pointer; font-size:13.5px; }
  .export-latest:has(input:checked){ border-color:var(--pass);
    background:rgba(22,163,74,.07); }
  .linkish{ background:none; border:0; padding:0; color:var(--accent, #2f6fed);
    cursor:pointer; font-size:12.5px; text-decoration:underline; }
  @media (max-width:560px){ .export-picker{ grid-template-columns:1fr; } }

  /* ---- Billing: Free vs Pro comparison ---- */
  .plan-compare{ border:1px solid var(--border); border-radius:10px; overflow:hidden; }
  .plan-compare table{ width:100%; border-collapse:collapse; font-size:13px; }
  .plan-compare th, .plan-compare td{ padding:9px 12px; border-bottom:1px solid var(--border);
    text-align:left; }
  .plan-compare thead th{ font-size:11px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--muted); }
  .plan-compare tbody th{ font-weight:400; }
  .plan-compare td{ text-align:center; width:96px; }
  .plan-compare thead th:not(:first-child){ text-align:center; }
  .plan-compare .pc-pro{ background:rgba(34,197,94,.08); }
  .pc-yes{ color:var(--pass, #16a34a); font-weight:800; }
  .pc-no{ color:var(--muted); opacity:.55; }
  .plan-compare-cta{ display:flex; align-items:center; justify-content:space-between;
    gap:12px; padding:12px; flex-wrap:wrap; background:rgba(34,197,94,.06); }

  /* ---- Retest calendar ---- */
  /* A real page within <main> now, not a full-screen overlay -- the sidebar stays
     visible. height (not min-height) keeps it a definite size so .cal-body's own
     flex:1 1 auto + overflow-y:auto still scrolls its content instead of growing
     the whole page, exactly as it did when position:fixed provided that bound. */
  .cal-full{ background:var(--bg); border:1px solid var(--border); border-radius:12px;
    height:calc(100dvh - 48px);
    display:flex; flex-direction:column; overflow:hidden; }
  @media (max-width:760px){
    .cal-full{ height:calc(100dvh - var(--header-h) - 42px); }
  }
  .cal-topbar{ display:flex; align-items:center; justify-content:space-between; gap:12px;
    padding:12px 18px; border-bottom:1px solid var(--border); background:var(--panel);
    flex:0 0 auto; flex-wrap:wrap; }
  .cal-controls{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
  .cal-tabs{ display:flex; border:1px solid var(--border); border-radius:8px; overflow:hidden; }
  .cal-tab{ background:transparent; border:0; border-radius:0; padding:7px 14px;
    font-size:13px; color:var(--muted); cursor:pointer; }
  .cal-tab.on{ background:var(--accent, #3b82f6); color:#fff; }
  .cal-body{ flex:1 1 auto; overflow-y:auto; padding:14px 18px 40px 18px; }
  .cal-nav{ display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
  .cal-nav strong{ min-width:170px; font-size:16px; }
  .cal-key{ margin-left:auto; display:flex; gap:14px; font-size:11.5px; color:var(--muted);
    flex-wrap:wrap; }
  .cal-key i.dot{ width:9px; height:9px; border-radius:50%; display:inline-block; margin-right:5px; }
  .dot.overdue{ background:var(--fail); } .dot.soon{ background:#f59e0b; } .dot.future{ background:var(--pass, #22c55e); }

  .cal-year{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }
  /* Tiles are <button>s, and the base button rule is inline-flex/row — override
     it explicitly or the contents lay out side by side. */
  .cal-ymonth{ display:flex; flex-direction:column; align-items:stretch; gap:0;
    width:100%; position:relative; text-align:left; min-height:170px; background:var(--panel);
    border:1px solid var(--border); border-radius:12px; padding:16px; cursor:pointer;
    color:var(--text); }
  .cal-ymonth.has{ border-color:var(--accent, #3b82f6); }
  .cal-ymonth .ym-count{ margin-top:2px; }
  .cal-ymonth .ym-clients{ margin-top:auto; }
  .ym-name{ font-size:13px; color:var(--muted); }
  .ym-count{ font-size:28px; font-weight:800; line-height:1.1; }
  .ym-sub{ font-size:11.5px; color:var(--muted); }
  .ym-flag{ position:absolute; top:12px; right:12px; font-size:10.5px; padding:2px 8px;
    border-radius:20px; font-weight:700; }
  .ym-flag.overdue{ background:rgba(239,68,68,.16); color:var(--fail); }
  .ym-flag.soon{ background:rgba(245,158,11,.16); color:#f59e0b; }
  .ym-clients{ list-style:none; margin:10px 0 0 0; padding:10px 0 0 0;
    border-top:1px solid var(--border); font-size:12px; }
  .ym-clients li{ display:flex; justify-content:space-between; gap:8px; padding:2px 0;
    color:var(--muted); }
  .ym-clients li.od .ymc-n{ color:var(--fail); font-weight:700; }
  .ymc-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ymc-n{ flex-shrink:0; font-family:'IBM Plex Mono',monospace; color:var(--text); }
  .ym-rest{ font-style:italic; opacity:.75; }
  .ym-empty{ margin-top:10px; padding-top:10px; border-top:1px solid var(--border);
    font-size:12px; color:var(--muted); }

  .cal-dow{ display:grid; grid-template-columns:repeat(7,1fr); gap:6px; margin-bottom:6px; }
  .cal-dow div{ font-size:11px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--muted); text-align:center; }
  .cal-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:6px; }
  .cal-week{ position:relative; margin-bottom:6px; }
  .cal-bars{ position:absolute; left:0; right:0; bottom:8px; display:grid;
    grid-template-columns:repeat(7,1fr); gap:6px; row-gap:4px; pointer-events:none;
    padding:0 1px; }
  .cal-bar{ pointer-events:auto; cursor:pointer; min-width:0; border-radius:6px;
    padding:4px 9px; font-size:11.5px; font-weight:600; line-height:1.3;
    background:rgba(34,197,94,.22); border:1px solid rgba(34,197,94,.5);
    color:var(--text); overflow:hidden; }
  .cal-bar span{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .cal-bar:hover{ filter:brightness(1.25); }
  .cal-bar.overdue{ background:rgba(239,68,68,.22); border-color:rgba(239,68,68,.55); }
  .cal-bar.soon{ background:rgba(245,158,11,.22); border-color:rgba(245,158,11,.55); }
  .cal-bar.cont-l{ border-top-left-radius:0; border-bottom-left-radius:0; border-left-style:dashed; }
  .cal-bar.cont-r{ border-top-right-radius:0; border-bottom-right-radius:0; border-right-style:dashed; }
  .cal-cell{ min-height:112px; padding-bottom:34px; border:1px solid var(--border); border-radius:9px; padding:6px;
    background:var(--panel); position:relative; }
  .cal-cell.empty{ background:transparent; border-color:transparent; }
  .cal-cell.has{ cursor:pointer; }
  .cal-cell.has:hover{ border-color:var(--accent, #3b82f6); }
  .cal-cell.today{ box-shadow:inset 0 0 0 2px var(--accent, #3b82f6); }
  .cal-daynum{ font-size:12px; color:var(--muted); }
  .cal-daycount{ position:absolute; top:5px; right:6px; font-size:10.5px; font-weight:800;
    padding:1px 7px; border-radius:20px; }
  .cal-daycount.overdue{ background:rgba(239,68,68,.18); color:var(--fail); }
  .cal-daycount.soon{ background:rgba(245,158,11,.18); color:#f59e0b; }
  .cal-daycount.future{ background:rgba(34,197,94,.18); color:var(--pass, #22c55e); }

  .cal-section{ background:var(--panel); border:1px solid var(--border); border-radius:12px;
    padding:14px; margin-top:14px; }
  .cal-section.overdue-section{ border-color:var(--fail); }
  .cal-crow{ border:1px solid var(--border); border-radius:9px; margin-bottom:7px;
    overflow:hidden; }
  .cal-crow.open{ border-color:var(--accent, #3b82f6); }
  .cal-crow-main{ display:flex; align-items:center; gap:12px; padding:10px 12px;
    cursor:pointer; }
  .cal-crow-main:hover{ background:rgba(148,163,184,.07); }
  .cal-crow-dot{ width:9px; height:9px; border-radius:50%; flex-shrink:0;
    background:var(--pass, #22c55e); }
  .cal-crow-dot.overdue{ background:var(--fail); }
  .cal-crow-dot.soon{ background:#f59e0b; }
  .cal-crow-name{ flex:1 1 auto; min-width:0; }
  .cal-crow-name b{ display:block; overflow:hidden; text-overflow:ellipsis;
    white-space:nowrap; }
  .cal-crow-count{ flex-shrink:0; font-size:13px; color:var(--muted); }
  .cal-crow-count b{ color:var(--text); font-size:15px; }
  .cal-crow-caret{ flex-shrink:0; color:var(--muted); font-size:12px;
    transition:transform .15s; }
  .cal-crow.open .cal-crow-caret{ transform:rotate(180deg); }
  .cal-crow-detail{ padding:0 12px 12px 12px; border-top:1px solid var(--border); }
  .cal-section-head{ display:flex; justify-content:space-between; align-items:center;
    gap:10px; margin-bottom:10px; }
  .cal-table-scroll{ overflow-x:auto; }
  table.cal-table{ width:100%; border-collapse:collapse; font-size:12.5px; }
  table.cal-table th, table.cal-table td{ padding:7px 9px; text-align:left;
    border-bottom:1px solid var(--border); vertical-align:top; }
  table.cal-table th{ color:var(--muted); font-size:11px; text-transform:uppercase;
    letter-spacing:.03em; }
  .cal-due{ font-weight:700; }
  .cal-due.overdue{ color:var(--fail); }
  .cal-due.soon{ color:#f59e0b; }
  .cal-rel{ font-size:11px; color:var(--muted); }
  @media (max-width:760px){
    /* minmax(0,1fr) not 1fr: grid items default to min-width:auto, so long client
       names force tracks wider than the viewport and the right column gets clipped. */
    .cal-year{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
    .cal-ymonth{ min-width:0; overflow:hidden; padding:12px; min-height:0; }
    .ym-count{ font-size:24px; }
    .ym-flag{ position:static; align-self:flex-start; margin-top:6px; display:inline-block; }
    .cal-body{ padding:12px 10px 40px 10px; }
  }

  @media (max-width:620px){
    .cal-year{ grid-template-columns:1fr; }
    /* The count badge was absolutely positioned and collided with the day number
       once cells got narrow. Stack them instead. */
    .cal-cell{ min-height:76px; padding:5px 4px 30px 4px; }
    .cal-daycount{ position:static; display:inline-block; margin-top:3px; }
    .cal-daynum{ font-size:11px; }
    .cal-bar{ font-size:9.5px; padding:2px 4px; }
    .cal-bars{ bottom:5px; gap:3px; }
    .cal-grid{ gap:3px; }
    .cal-dow{ gap:3px; }
    .cal-dow div{ font-size:9.5px; }
    .cal-topbar{ padding:10px 12px; }
    .cal-nav strong{ min-width:120px; font-size:15px; }
    .cal-key{ width:100%; margin-left:0; }
    .cal-crow-main{ padding:9px 10px; gap:9px; }
  }

  .cal-swipe-hint{ text-align:center; font-size:11.5px; color:var(--muted);
    margin:8px 0 2px; display:none; }
  @media (max-width:760px){ .cal-swipe-hint{ display:block; } }

  .subpanel{ border:1px solid var(--border); border-radius:10px; padding:12px; }
  .subpanel-head{ font-size:11.5px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--muted); font-weight:700; margin-bottom:10px; }
  .subpanel .field:last-child, .subpanel label:last-child{ margin-bottom:0 !important; }

  /* ---- Boot progress ---- */
  .boot-progress{ width:100%; max-width:420px; margin:0 auto; text-align:left; }
  .boot-title{ font-size:14.5px; font-weight:700; margin-bottom:10px; }
  .boot-bar{ height:8px; border-radius:20px; background:var(--border); overflow:hidden; }
  .boot-bar-fill{ height:100%; width:0%; border-radius:20px; background:var(--accent);
    transition:width .28s ease; }
  .boot-meta{ display:flex; justify-content:space-between; gap:10px; margin-top:7px;
    font-size:12px; color:var(--muted); }
  .boot-done{ margin-top:10px; font-size:11.5px; color:var(--muted); line-height:1.7;
    min-height:1.7em; }
  .boot-done span{ display:inline-block; margin-right:10px; }

  /* ---- Client rail (desktop) ---- */
  /* Fixed dark-navy palette, deliberately NOT the theme-reactive --panel/--text/
     etc: this is product chrome, not workspace content, and should read as one
     consistent frame regardless of the viewer's light/dark preference for their
     data — the same reasoning already used for the client portal's header
     (CHANGELOG v1.73.0, #0f1628, "stays dark in both themes"). Every rule below
     that colours something inside .client-rail uses --sb-* instead of the
     ordinary theme variables, on purpose. */
  .client-rail{
    --sb-bg:#0f1628; --sb-panel2:#16213a; --sb-border:#2f3d56;
    --sb-text:#e6edf7; --sb-muted:#94a3b8; --sb-accent:#3b82f6;
    position:fixed; left:0; top:0; bottom:0; width:236px; z-index:120;
    background:var(--sb-bg); border-right:1px solid var(--sb-border); color:var(--sb-text);
    display:none; flex-direction:column; padding-top:0;
  }
  /* Visible whenever signed in, not only while a client is open — it is the
     primary app nav now, not just a client switcher. */
  body.authed .client-rail.app-sidebar{ display:flex; }
  body.authed main{ padding-left:calc(236px + clamp(12px, 2vw, 40px)); }
  .client-rail button.ghost{ border-color:var(--sb-border); color:var(--sb-text); }
  .client-rail small.hint{ color:var(--sb-muted); }

  .rail-head{ display:flex; align-items:center; justify-content:space-between; gap:8px;
    padding:8px 10px 6px 12px; }
  .rail-title{ font-size:11.5px; text-transform:uppercase; letter-spacing:.06em;
    color:var(--sb-muted); font-weight:700; white-space:nowrap; overflow:hidden; }
  .rail-count{ opacity:.75; }
  .rail-search{ padding:0 10px 8px 12px; }
  .rail-search input{ width:100%; }
  .rail-list{ flex:1 1 auto; overflow-y:auto; padding:0 8px 8px 8px; }
  .rail-item{
    display:flex; align-items:center; gap:9px; width:100%; text-align:left;
    background:transparent; color:var(--sb-text); border:1px solid transparent;
    border-radius:8px; padding:7px 8px; margin-bottom:2px; cursor:pointer;
  }
  .rail-item:hover{ background:var(--sb-panel2); }
  .rail-item.on{ background:rgba(59,130,246,.14); border-color:var(--sb-accent); }
  .rail-initials{
    flex-shrink:0; width:28px; height:28px; border-radius:7px; display:grid;
    place-items:center; background:var(--sb-panel2); border:1px solid var(--sb-border);
    font-size:11px; font-weight:800; letter-spacing:.02em;
  }
  .rail-item.on .rail-initials{ background:var(--sb-accent); color:#fff; border-color:var(--sb-accent); }
  .rail-item-text{ min-width:0; display:flex; flex-direction:column; }
  .rail-item-name{ font-size:13px; font-weight:600; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; }
  .rail-item-count{ font-size:11px; color:var(--sb-muted); }
  .rail-foot{ border-top:1px solid var(--sb-border); padding:8px; }
  .rail-foot button{ width:100%; justify-content:flex-start; font-size:12.5px; }
  .rail-empty{ padding:10px 8px; }

  .rail-backdrop{ display:none; }

  /* ---- Mobile: bottom sheet instead of a rail ---- */
  @media (max-width:900px){
    body.authed .client-rail.app-sidebar{
      display:flex; left:0; right:0; width:auto; top:auto; bottom:0;
      max-height:min(84dvh, calc(100dvh - 20px));
      border-right:0; border-top:1px solid var(--sb-border);
      border-radius:16px 16px 0 0; box-shadow:0 -12px 34px rgba(0,0,0,.34);
      transform:translateY(102%); transition:transform .22s ease; padding-top:6px;
    }
    body.rail-sheet-open .client-rail.app-sidebar{ transform:translateY(0); }
    body.authed main{ padding-left:clamp(12px, 2vw, 40px); }
    /* Collapsing is meaningless on a sheet — always show full labels. */
    .rail-item{ padding:9px 8px; }
    .rail-list{ -webkit-overflow-scrolling:touch; }
    body.rail-sheet-open .rail-backdrop{
      display:block; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:119;
    }
  }

  /* ---- Sidebar primary nav ---- */
  .sidebar-brand{
    display:flex; align-items:center; gap:10px; padding:14px 14px 10px 14px; cursor:pointer; min-width:0;
  }
  .sidebar-brand img{ height:22px; width:auto; flex-shrink:0; }
  .sidebar-brand-text{ font-size:15px; font-weight:800; color:var(--sb-text); letter-spacing:.2px;
    white-space:nowrap; overflow:hidden; }
  @media (max-width:900px){
  }

  /* ---- Current client context (replaces the client list when one is open) ---- */
  .sidebar-client-context{ padding:6px 8px 10px 8px; margin-bottom:4px; border-bottom:1px solid var(--sb-border); }
  .sidebar-client-context-head{ display:flex; align-items:center; gap:9px; padding:6px 8px 10px 8px; cursor:pointer; }
  .sidebar-client-avatar{
    flex-shrink:0; width:28px; height:28px; border-radius:7px; display:grid; place-items:center;
    background:var(--sb-panel2); border:1px solid var(--sb-border); color:var(--sb-accent);
    font-size:11px; font-weight:800; overflow:hidden;
  }
  .sidebar-client-avatar img{ max-width:100%; max-height:100%; }
  .sidebar-client-context-name{ font-size:13.5px; font-weight:700; color:var(--sb-text); min-width:0;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  .sidebar-nav{ display:flex; flex-direction:column; gap:2px; padding:0 8px 8px 8px; }
  .sidebar-nav-item, .sidebar-nav-toggle{
    display:flex; align-items:center; gap:10px; width:100%; text-align:left;
    background:transparent; color:var(--sb-text); border:1px solid transparent;
    border-radius:8px; padding:8px; font-size:13.5px; font-weight:600;
  }
  .sidebar-nav-item:hover, .sidebar-nav-toggle:hover{ background:var(--sb-panel2); filter:none; }
  .sidebar-nav-item.on{ background:rgba(59,130,246,.16); border-color:var(--sb-accent); }
  .sidebar-nav-item.has-notifications{ border-color:#ef4444; }
  .sidebar-nav-icon{ flex-shrink:0; width:20px; text-align:center; font-size:15px; }
  .sidebar-nav-label{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1 1 auto; }
  .sidebar-nav-toggle .caret{ flex-shrink:0; font-size:10px; opacity:.7; transition:transform .15s; }
  .sidebar-nav-group.open .sidebar-nav-toggle .caret{ transform:rotate(180deg); }
  .sidebar-nav-submenu{ display:none; flex-direction:column; gap:1px; padding:2px 0 4px 30px; }
  .sidebar-nav-group.open .sidebar-nav-submenu{ display:flex; }
  .sidebar-nav-submenu button, .sidebar-nav-submenu .file-btn{
    background:transparent; color:var(--sb-text); border:none; text-align:left; justify-content:flex-start;
    padding:7px 8px; border-radius:6px; font-weight:500; font-size:13px; width:100%;
  }
  .sidebar-nav-submenu button:hover, .sidebar-nav-submenu .file-btn:hover{ background:var(--sb-panel2); filter:none; }
  .sidebar-nav-submenu button.danger{ background:transparent; color:#ef4444; }
  .sidebar-nav-submenu button.danger:hover{ background:rgba(239,68,68,.14); }
  .sidebar-nav-submenu hr{ border:none; border-top:1px solid var(--sb-border); margin:4px 2px; }
  .notif-badge{ flex-shrink:0; }

  @media (max-width:900px){
    .hamburger{ display:inline-flex; }
  }

  .pn-info{ font-size:12.5px; border-radius:8px; padding:8px 10px; }
  .pn-info.known{ background:rgba(34,197,94,.12); border:1px solid rgba(34,197,94,.35); }
  .pn-info.new{ background:rgba(245,158,11,.12); border:1px solid rgba(245,158,11,.35); }


  .data-toolbar{ display:flex; justify-content:flex-end; align-items:center; gap:12px;
    margin:0 0 8px 0; flex-wrap:wrap; }
  @media (max-width:620px){
    .data-toolbar{ justify-content:flex-start; }
    /* Drag-and-drop needs a mouse; the Data menu covers importing on a phone. */
    .inline-dropzone{ display:none !important; }
  }

  /* `.field label` styles form labels as small grey uppercase text — but the photo
     pickers are <label class="file-btn"> buttons living inside .field wrappers, so
     they were inheriting grey 11px uppercase over the accent fill. Restore button
     styling; placed late so it wins over .field label. */
  .field label.file-btn, label.file-btn{
    color:#fff; font-size:13px; font-weight:600; text-transform:none;
    letter-spacing:normal; padding:9px 14px;
  }
  .nav-menu .field label.file-btn, .nav-menu label.file-btn{
    color:var(--text); font-weight:500;
  }

  /* ---- Post-import note review ---- */
  .note-review-list{ max-height:46dvh; overflow-y:auto; margin-bottom:12px; }
  .note-review{ border:1px solid var(--border); border-radius:10px; padding:12px;
    margin-bottom:8px; opacity:.6; }
  .note-review.on{ opacity:1; border-color:var(--accent); }
  .note-review-head{ display:flex; gap:10px; align-items:flex-start; cursor:pointer; }
  .note-review-head input{ margin-top:3px; flex-shrink:0; }
  .note-review textarea{ background:var(--panel2); border:1px solid var(--border);
    color:var(--text); border-radius:7px; padding:8px 10px; font-family:inherit;
    font-size:13px; resize:vertical; }
  .note-review-photo{ margin-top:8px; display:flex; gap:10px; align-items:flex-start; }
  .note-review-photo img{ max-width:130px; max-height:130px; border-radius:8px;
    border:1px solid var(--border); transition:transform .18s ease; }
  .note-review-photo-tools{ display:flex; flex-direction:column; gap:6px; }
  .note-review-photo-tools button{ padding:5px 10px; font-size:12px; }

  .cal-view-client{ flex-shrink:0; padding:5px 10px; font-size:12px; }
  @media (max-width:620px){ .cal-view-client{ padding:5px 8px; font-size:11px; } }

  /* ---- Calendar client actions ---- */
  .cal-actions{ position:fixed; z-index:960; width:264px; background:var(--panel);
    border:1px solid var(--border); border-radius:12px; padding:10px;
    box-shadow:0 14px 40px rgba(0,0,0,.45); }
  .cal-actions-head{ padding:2px 4px 8px 4px; border-bottom:1px solid var(--border);
    margin-bottom:8px; }
  .cal-actions-head b{ display:block; overflow:hidden; text-overflow:ellipsis;
    white-space:nowrap; }
  .cal-action{ display:block; width:100%; text-align:left; background:transparent;
    color:var(--text); border:0; border-radius:7px; padding:9px 10px; font-size:13.5px;
    cursor:pointer; }
  .cal-action:hover{ background:var(--panel2); }
  .cal-action.danger{ color:var(--fail); }
  .cal-actions-sep{ height:1px; background:var(--border); margin:8px 0; }
  .cal-actions-label{ font-size:11px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--muted); font-weight:700; margin:6px 4px 5px 4px; }
  .cal-delay-row{ display:flex; gap:6px; align-items:center; margin-bottom:4px; }
  .cal-delay-row input, .cal-delay-row select{ min-width:0; }
  .cal-delay-row button{ flex-shrink:0; padding:7px 11px; font-size:12.5px; }
  .cal-due.moved{ text-decoration:underline dotted; }

  /* Swipe transitions need the panel to clip rather than show the neighbour bleeding
     out over the chrome. */
  #calContent{ will-change:transform, opacity; }
  .cal-body{ overflow-x:hidden; }
  @media (prefers-reduced-motion:reduce){
    #calContent{ transition:none !important; }
  }

  /* ---- Reschedule dialog: sits over the calendar, doesn't replace it ---- */
  .reschedule-layer{ position:fixed; inset:0; z-index:980; display:flex;
    align-items:center; justify-content:center; padding:16px;
    background:rgba(0,0,0,.45); overflow-y:auto; }
  .reschedule-box{ background:var(--panel); border:1px solid var(--border);
    border-radius:12px; padding:20px; width:100%; max-width:430px; position:relative;
    max-height:calc(100dvh - 32px); overflow-y:auto; box-shadow:0 20px 50px rgba(0,0,0,.45); }
  .reschedule-confirm{ background:var(--panel2); border:1px solid var(--border);
    border-radius:9px; padding:11px 13px; font-size:13.5px; margin-bottom:14px; }

  .cal-bar[draggable="true"]{ cursor:grab; }
  .cal-bar.dragging{ opacity:.4; cursor:grabbing; }
  .cal-cell.drop-target{ outline:2px dashed var(--accent, #3b82f6); outline-offset:-2px;
    background:rgba(59,130,246,.10); }

  /* ---- Background task panel ---- */
  .bg-task{ position:fixed; right:16px; bottom:16px; z-index:1200; width:280px;
    background:var(--panel); border:1px solid var(--border); border-radius:11px;
    padding:12px; box-shadow:0 12px 34px rgba(0,0,0,.4); }
  .bg-task.minimised{ width:190px; opacity:.9; }
  .bg-task.failed{ border-color:var(--fail); }
  .bg-task-head{ display:flex; justify-content:space-between; align-items:center;
    gap:8px; margin-bottom:7px; font-size:13px; }
  .bg-task-head button{ padding:2px 8px; font-size:12px; }
  .bg-task-step{ font-size:12px; color:var(--muted); margin-bottom:8px; }
  .bg-task-bar{ height:6px; border-radius:20px; background:var(--border); overflow:hidden; }
  .bg-task-fill{ height:100%; width:8%; background:var(--accent); border-radius:20px;
    transition:width .3s ease; }
  @media (max-width:620px){ .bg-task{ left:12px; right:12px; width:auto; bottom:12px; } }

  /* The admin page's simple labelled toggle, used here too. */
  /* The clear button sits inside the field rather than beside it, so it doesn't take
     width from an already-tight filter row on a phone. Hidden until there's something
     to clear — a permanently visible X invites a click that does nothing. */
  .search-wrap{ position:relative; flex:1 1 auto; min-width:0; display:flex; }
  .search-wrap input{ width:100%; padding-right:32px; }
  .search-clear{
    position:absolute; top:50%; right:6px; transform:translateY(-50%);
    width:22px; height:22px; padding:0; border-radius:50%;
    display:none; align-items:center; justify-content:center;
    background:transparent; border:none; color:var(--muted);
    font-size:12px; line-height:1; cursor:pointer;
  }
  .search-clear:hover{ background:var(--panel2); color:var(--text); }
  .search-wrap.has-text .search-clear{ display:flex; }
  .settings-drawer{ border:1px solid var(--border); border-radius:8px; margin:12px 0; }
  .settings-drawer summary{
    cursor:pointer; padding:10px 12px; font-size:13px; font-weight:600; list-style:none;
  }
  .settings-drawer summary::-webkit-details-marker{ display:none; }
  .settings-drawer summary::after{ content:'▾'; float:right; opacity:.55; }
  .settings-drawer[open] summary::after{ content:'▴'; }
  .settings-drawer > div{ padding:0 12px 12px 12px; }
  #themeToggleBtn{ gap:7px; }
  #themeToggleBtn #themeLabel{ font-weight:600; }

  .licence-box{ border:1px solid var(--border); border-radius:10px; padding:13px; }
  .licence-head{ display:flex; justify-content:space-between; align-items:baseline;
    gap:10px; margin-bottom:8px; font-size:14px; }
  .licence-bar{ height:8px; border-radius:20px; background:var(--border);
    overflow:hidden; margin-bottom:8px; }
  .licence-fill{ height:100%; background:var(--pass, #22c55e); border-radius:20px;
    transition:width .3s ease; }

  /* ---- Import mapping wizard ---- */
  .map-table-scroll{ max-height:52dvh; overflow:auto; border:1px solid var(--border);
    border-radius:9px; margin-bottom:14px; }
  table.map-table{ width:100%; border-collapse:collapse; font-size:13px; }
  table.map-table th, table.map-table td{ padding:8px 10px; text-align:left;
    border-bottom:1px solid var(--border); vertical-align:top; }
  table.map-table thead th{ position:sticky; top:0; background:var(--panel);
    font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); }
  table.map-table tr.mapped{ background:rgba(34,197,94,.06); }
  table.map-table select{ width:100%; min-width:150px; }
  .map-sample{ color:var(--muted); font-size:12px; max-width:220px; }
  .map-sample div{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  @media (max-width:620px){
    .map-sample{ display:none; }
    table.map-table th:nth-child(2){ display:none; }
  }

  /* ---- Notifications ---- */
  .notif-badge{ background:var(--fail); color:#fff; border-radius:20px; padding:1px 7px;
    font-size:11px; font-weight:800; margin-left:2px; }
  .nav-btn.has-notifications{ border-color:var(--fail); }
  .notif-card{ border:1px solid var(--border); border-radius:10px; padding:12px;
    margin-bottom:9px; font-size:13.5px; }
  .notif-card.pending{ border-color:var(--accent); }
  .notif-head{ display:flex; justify-content:space-between; align-items:center;
    gap:10px; margin-bottom:6px; }
  .notif-msg{ background:var(--panel2); border-radius:7px; padding:8px 10px;
    margin:7px 0; font-size:13px; }
  .notif-actions{ display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }
  /* ---- Visit state chips: estimated / pencilled / requested / confirmed ---- */
  .visit-chip{ display:inline-flex; align-items:center; gap:4px; vertical-align:middle;
    margin-left:5px; padding:1px 7px; border-radius:20px; font-size:10.5px;
    font-weight:700; letter-spacing:.02em; white-space:nowrap; line-height:1.6;
    border:1px solid var(--border); background:var(--panel2); color:var(--muted); }
  .visit-chip.compact{ padding:0 4px; margin-left:4px; font-size:10px; }
  .visit-chip.vs-estimated{ background:transparent; color:var(--muted);
    border-style:dashed; border-color:var(--border); }
  .visit-chip.vs-pencilled{ background:rgba(148,163,184,.18); color:#cbd5e1;
    border-style:dashed; border-color:rgba(148,163,184,.6); }
  .visit-chip.vs-requested{ background:rgba(245,158,11,.20); color:#fbbf24;
    border-color:rgba(245,158,11,.65); }
  .visit-chip.vs-confirmed{ background:rgba(34,197,94,.20); color:#4ade80;
    border-color:rgba(34,197,94,.65); }
  .cal-bar .visit-chip{ background:rgba(0,0,0,.22); }
  .cal-bar.vs-estimated{ border-style:dashed; }
  .cal-bar.vs-confirmed{ box-shadow:inset 3px 0 0 rgba(34,197,94,.9); }
  .cal-bar.has-request{ box-shadow:inset 3px 0 0 rgba(245,158,11,.95); }
  .cal-bar.vs-confirmed.has-request{ box-shadow:inset 3px 0 0 rgba(245,158,11,.95),
    inset 6px 0 0 rgba(34,197,94,.9); }

  /* Request detail — sits over the calendar like the reschedule dialog does */
  .req-grid{ display:grid; grid-template-columns:auto 1fr; gap:6px 14px;
    font-size:13.5px; margin:12px 0; }
  .req-grid dt{ color:var(--muted); font-size:12px; padding-top:2px; }
  .req-grid dd{ margin:0; }
  .req-msg{ background:var(--panel2); border:1px solid var(--border); border-radius:8px;
    padding:10px 12px; font-size:13px; margin:10px 0; white-space:pre-wrap; }
  .visit-state-choice{ display:flex; flex-direction:column; gap:8px; margin-bottom:14px; }
  .visit-state-choice label{ display:flex; gap:9px; align-items:flex-start;
    border:1px solid var(--border); border-radius:9px; padding:9px 11px; cursor:pointer;
    background:var(--panel2); }
  .visit-state-choice label:has(input:checked){ border-color:var(--accent, #3b82f6); }
  .visit-state-choice input{ margin-top:3px; flex-shrink:0; }
  .visit-state-choice .vsc-note{ display:block; font-size:11.5px; color:var(--muted);
    font-weight:400; margin-top:2px; }

  /* ---- Visit history ---- */
  .cal-hist-n{ display:inline-block; margin-left:5px; padding:0 6px; border-radius:20px;
    background:var(--panel2); border:1px solid var(--border); font-size:10.5px;
    font-weight:700; color:var(--muted); }
  .vh-list{ list-style:none; margin:12px 0; padding:0; max-height:46vh; overflow-y:auto; }
  .vh-item{ display:flex; gap:10px; padding:10px 0; border-bottom:1px solid var(--border); }
  .vh-item:last-child{ border-bottom:0; }
  .vh-icon{ flex-shrink:0; width:24px; text-align:center; font-size:14px; line-height:1.5; }
  .vh-body{ min-width:0; flex:1 1 auto; }
  .vh-head{ display:flex; gap:8px; align-items:baseline; font-size:13.5px; }
  .vh-who{ font-size:10.5px; text-transform:uppercase; letter-spacing:.05em;
    color:var(--muted); font-weight:700; }
  .vh-detail{ font-size:12.5px; color:var(--text); margin-top:2px; }
  .vh-note{ background:var(--panel2); border:1px solid var(--border); border-radius:7px;
    padding:7px 9px; font-size:12.5px; margin-top:5px; white-space:pre-wrap; }
  .vh-when{ font-size:11px; color:var(--muted); margin-top:3px; }
  .vh-item.vh-requested .vh-icon{ color:#fbbf24; }
  .vh-item.vh-confirmed .vh-icon, .vh-item.vh-accepted .vh-icon{ color:#4ade80; }
  .vh-item.vh-declined .vh-icon{ color:var(--fail); }
  .req-warn{ border:1px solid rgba(245,158,11,.65); background:rgba(245,158,11,.12);
    border-radius:9px; padding:10px 12px; font-size:13px; margin:12px 0; }

  .untested-box{ border:1px solid var(--warn, #f59e0b); border-radius:10px;
    background:rgba(245,158,11,.08); padding:12px; margin-bottom:12px; }
  .untested-head{ margin-bottom:8px; }
  .untested-head small{ display:block; }
  .untested-list{ display:flex; flex-direction:column; gap:5px; }
  .untested-item{ display:flex; align-items:center; gap:10px; font-size:13px; }
  .untested-item span{ flex:1 1 auto; color:var(--muted); overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; }
  .untested-item button{ padding:2px 8px; font-size:12px; flex-shrink:0; }

  .upload-chip{ display:inline-flex; align-items:center; gap:7px; vertical-align:middle; }
  .upload-chip img{ width:34px; height:34px; object-fit:cover; border-radius:6px;
    border:1px solid var(--border); }

  .dup-toggle{ display:flex; align-items:center; gap:7px; font-size:12.5px;
    color:var(--muted); cursor:pointer; margin-right:auto; }
  tr.repeat-test{ background:rgba(245,158,11,.10); }
  tr.repeat-test td:first-child::before{ content:'⚠ '; color:var(--warn, #f59e0b); }

  .dup-only{ display:inline-flex; align-items:center; gap:4px; margin-left:2px;
    font-size:12px; opacity:.85; }
  .repeat-chip{ display:inline-block; background:rgba(245,158,11,.18); color:#f59e0b;
    border-radius:20px; padding:1px 7px; font-size:11px; font-weight:700; margin-left:6px; }

  tr.has-repeat > td:first-child{ box-shadow:inset 3px 0 0 var(--warn, #f59e0b); }

  /* ---- Brand ---- */
  /* Both variants ship; CSS picks the one that suits the current theme, so there's
     no flash of the wrong logo while JS boots. */
  .brand-logo{ height:26px; width:auto; display:inline-block; vertical-align:-6px; }
  .logo-light{ display:none; }
  .logo-dark{ display:inline-block; }
  body[data-theme="light"] .logo-light{ display:inline-block; }
  body[data-theme="light"] .logo-dark{ display:none; }