  :root {
    --bg:        #374151;
    --bg2:       #4b5563;
    --bg3:       #6b7280;
    --border:    #9ca3af;
    --border2:   #d1d5db;
    --text:      #f9fafb;
    --text2:     #e5e7eb;
    --text3:     #d1d5db;
    --accent:    #5b8def;
    --accent2:   #3d6fd4;
    --green:     #16a34a;
    --green-bg:  #dcfce7;
    --yellow:    #d97706;
    --yellow-bg: #fef3c7;
    --red:       #dc2626;
    --red-bg:    #fee2e2;
    --content-bg: #e2e8f0;
    --card-bg:    #ffffff;
    --card-border: #e5e7eb;
    --topbar-bg:  #ffffff;
    --mono:      'IBM Plex Mono', monospace;
    --sans:      'IBM Plex Sans', sans-serif;
    --radius:    6px;
    --radius-lg: 10px;
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body { font-family: var(--sans); background: var(--content-bg); color: #111827; font-size: 13px; min-height: 100vh; }

  /* ── BOOT ── */
  /*
     Stage 3 made the session an httpOnly cookie, which this page cannot read.
     So on load it no longer knows whether anybody is signed in and has to ask
     the server, and that is a round trip. Without a state to sit in during it,
     the login form paints first and is then replaced by the application — a
     flash on every single reload for somebody already signed in, long enough to
     start typing a password into a form that is about to disappear.

     body.booting hides both screens and shows this instead; boot.js removes the
     class once it has an answer. If the scripts fail to load altogether the
     splash stays up, which is a clearer failure than a login form that cannot
     submit.
  */
  #boot-splash { display: none; }
  body.booting #boot-splash { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background: var(--bg); gap: 10px; }
  body.booting #login-screen { display: none; }
  #boot-splash .wordmark { font-family: var(--mono); font-size: 22px; font-weight: 500; color: var(--text); letter-spacing: 0.1em; }
  #boot-splash .boot-note { font-size: 12px; color: var(--text3); letter-spacing: 0.06em; }

  /* ── LOGIN ── */
  #login-screen { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: var(--bg); }
  .login-box { width: 380px; }
  .login-logo { margin-bottom: 32px; }
  .login-logo .wordmark { font-family: var(--mono); font-size: 22px; font-weight: 500; color: var(--text); letter-spacing: 0.1em; }
  .login-logo .tagline { font-size: 12px; color: var(--text3); margin-top: 4px; letter-spacing: 0.06em; text-transform: uppercase; }
  .login-card { background: var(--bg2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 28px; }
  .login-title { font-size: 15px; font-weight: 500; margin-bottom: 6px; }
  .login-sub { font-size: 12px; color: var(--text2); margin-bottom: 24px; }
  .form-group { margin-bottom: 16px; }
  .form-label { display: block; font-size: 11px; font-weight: 700; color: #374151; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
  .form-input { width: 100%; padding: 9px 12px; background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-size: 13px; font-family: var(--sans); transition: border-color 0.15s; }
  .form-input:focus { outline: none; border-color: var(--accent); }
  .btn-login { width: 100%; padding: 10px; background: var(--accent); color: #fff; border: none; border-radius: var(--radius); font-size: 13px; font-weight: 500; cursor: pointer; transition: background 0.15s; margin-top: 4px; }
  .btn-login:hover { background: var(--accent2); }
  .btn-login:disabled { opacity: 0.5; cursor: not-allowed; }
  .login-error { background: var(--red-bg); border: 1px solid var(--red); color: var(--red); padding: 10px 12px; border-radius: var(--radius); font-size: 12px; margin-bottom: 16px; display: none; }
  .login-hint { margin-top: 20px; padding: 12px; background: var(--bg3); border-radius: var(--radius); font-size: 11px; color: var(--text3); line-height: 1.8; font-family: var(--mono); }
  .login-hint strong { color: var(--text2); }

  /* ── APP SHELL ── */
  #app { display: none; height: 100vh; flex-direction: row; }
  .sidebar { width: 210px; background: var(--bg2); border-right: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; }
  .sidebar-top { padding: 10px 14px 10px; border-bottom: 1px solid var(--border); }
  .sidebar-logo-img { width: 130px; height: auto; display: block; }
  .sidebar-user { padding: 10px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 8px; }
  .user-avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; color: #fff; flex-shrink: 0; }
  .user-name { font-size: 12px; font-weight: 500; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .user-role { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.05em; }
  /* overflow-y is not cosmetic here. The nav is a flex child of a full-height
     sidebar, so on a window shorter than the menu the last items were simply
     clipped — with no scrollbar and no way to reach them. The last two are
     "My account" and "Settings", and Settings is where the rate card lives,
     so on a laptop screen the prices became uneditable. Found by looking for
     Settings on a 609px-tall window and not finding it. */
  .nav { padding: 8px 0; flex: 1; overflow-y: auto; }
  .nav-section { font-size: 10px; font-weight: 500; color: var(--text3); text-transform: uppercase; letter-spacing: 0.08em; padding: 10px 16px 4px; }
  .nav-item { display: flex; align-items: center; gap: 9px; padding: 7px 16px; cursor: pointer; font-size: 12px; color: var(--text2); border-left: 2px solid transparent; transition: all 0.1s; }
  .nav-item:hover { background: var(--bg3); color: var(--text); }
  .nav-item.active { color: var(--text); background: var(--bg3); border-left-color: var(--accent); font-weight: 500; }
  .nav-item i { font-size: 15px; }
  .sidebar-bottom { padding: 12px 16px; border-top: 1px solid var(--border); }
  .btn-logout { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 10px; background: none; border: 1px solid #6b7280; border-radius: var(--radius); color: #d1d5db; font-size: 12px; cursor: pointer; transition: all 0.1s; font-family: var(--sans); }
  .btn-logout:hover { border-color: #fca5a5; color: #fca5a5; }

  /* ── MAIN ── */
  .main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
  .topbar { background: var(--topbar-bg); border-bottom: 1px solid var(--card-border); padding: 0 22px; height: 50px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
  .topbar-title { font-size: 14px; font-weight: 500; color: #111827; }
  .topbar-title.dashboard-title { font-family: 'Raleway', sans-serif; font-size: 19px; font-weight: 700; color: #1e3a5f; letter-spacing: 0.04em; }
  .topbar-actions { display: flex; gap: 8px; }
  .content { flex: 1; overflow-y: auto; padding: 20px 22px; background: var(--content-bg); }

  /* ── BUTTONS ── */
  .btn { display: inline-flex; align-items: center; gap: 6px; padding: 6px 13px; border-radius: var(--radius); border: 1px solid var(--card-border); background: var(--card-bg); color: #374151; cursor: pointer; font-size: 12px; font-weight: 500; transition: all 0.1s; font-family: var(--sans); }
  .btn:hover { background: #f3f4f6; }
  .btn-primary { background: var(--accent); color: #fff; border-color: var(--accent); }
  .btn-primary:hover { background: var(--accent2); border-color: var(--accent2); }
  .btn-sm { padding: 4px 9px; font-size: 11px; }
  /* For the few controls that remove a protection or destroy something. The
     copy next to them says what will happen; this is so the button does not
     look like the one beside it that merely saves. */
  .btn-danger { border-color: #fca5a5; color: #b91c1c; }
  .btn-danger:hover { background: #fef2f2; border-color: #ef4444; }
  .btn i { font-size: 14px; }

  /* ── STATS ── */
  .stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
  .stat-card { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 14px 16px; }
  .stat-label { font-size: 10px; color: #374151; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; margin-bottom: 6px; }
  .stat-value { font-size: 24px; font-weight: 500; color: #111827; }
  .stat-sub { font-size: 11px; color: #374151; margin-top: 3px; }

  /* ── CARDS ── */
  .card { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 16px; margin-bottom: 14px; }

  /* A table wider than the space it has scrolls sideways inside its card
     rather than pushing the whole page sideways. This applied on phones only,
     so a wide table on a laptop ran off the right edge and the last column
     simply could not be read. */
  .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
  .card-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #374151; }

  /* ── DASHBOARD PANELS ──
     The three panels across the dashboard (recent evidence, recent invoices,
     calendar) used to be a 1fr/320px split with the first two sharing the left
     half. They came out 674px, 148px and 320px: a grid item's default
     min-width is `auto`, so the long evidence descriptions set that column's
     minimum and starved the invoice panel next to it. minmax(0, 1fr) lets a
     column shrink below its content, which is what makes three equal columns
     actually equal.

     The panel classes exist so the three share one definition. They were three
     copies of the same inline styles before, and had already drifted apart. */
  .dash-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: stretch; margin-bottom: 16px; }
  .panel { display: flex; flex-direction: column; min-width: 0; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); overflow: hidden; }
  .panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 10px 16px; border-bottom: 1px solid var(--card-border); }
  .panel-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: #374151; white-space: nowrap; }
  .panel-body { flex: 1; min-width: 0; }
  .panel-foot { border-top: 1px solid var(--card-border); padding: 12px 16px; }
  .panel-row { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 11px 16px; border-bottom: 1px solid var(--card-border); cursor: pointer; }
  .panel-row:last-child { border-bottom: none; }
  .panel-row:hover { background: #f9fafb; }
  .panel-empty { padding: 22px 16px; text-align: center; font-size: 12px; color: #6b7280; }

  /* Three narrow columns stop being readable well before a phone width. */
  @media (max-width: 1180px) { .dash-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 860px) {
    .dash-row { grid-template-columns: minmax(0, 1fr); }
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
  }

  /* ── TABLES ── */
  table { width: 100%; border-collapse: collapse; font-size: 12px; }
  th { text-align: left; font-size: 10px; font-weight: 700; color: #374151; text-transform: uppercase; letter-spacing: 0.07em; padding: 7px 12px; border-bottom: 1px solid var(--card-border); background: #f9fafb; }
  td { padding: 9px 12px; border-bottom: 1px solid var(--card-border); vertical-align: middle; color: #111827; font-size: 12px; }
  tr:last-child td { border-bottom: none; }
  tr.clickable:hover td { background: #f3f4f6; cursor: pointer; }

  /* ── BADGES ── */
  .badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 20px; font-size: 10px; font-weight: 600; }
  .badge-active   { background: #dcfce7; color: #14532d; }
  .badge-pending  { background: #fef3c7; color: #78350f; }
  .badge-released { background: #f3f4f6; color: #374151; }
  .badge-destroyed{ background: #fee2e2; color: #7f1d1d; }
  .badge-paid     { background: #dcfce7; color: #14532d; }
  .badge-unpaid   { background: #fee2e2; color: #7f1d1d; }
  .badge-partial  { background: #fef3c7; color: #78350f; }
  .badge-draft    { background: #f3f4f6; color: #374151; }
  .badge-overdue  { background: #fee2e2; color: #7f1d1d; }

  /* ── SEARCH ── */
  .search-bar { display: flex; gap: 8px; margin-bottom: 14px; }
  .search-bar input, .search-bar select { padding: 7px 11px; background: var(--card-bg); border: 1px solid #d1d5db; border-radius: var(--radius); color: #111827; font-size: 12px; font-family: var(--sans); }
  .search-bar input { flex: 1; }
  .search-bar input::placeholder { color: #6b7280; }
  .search-bar input:focus, .search-bar select:focus { outline: none; border-color: var(--accent); }
  /* .btn sets display:inline-flex, which beats the browser's own
     [hidden] { display: none } — so a hidden button stayed visible. */
  [hidden] { display: none !important; }

  .search-bar { align-items: center; flex-wrap: wrap; }

  /* Says which case the list has been narrowed to. Deliberately above the
     filter bar and not inside it: this filter was set on another screen, and a
     short list with no stated reason reads as records having gone missing. */
  .case-banner { display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; margin-bottom: 12px; padding: 10px 14px;
    background: rgba(91,141,239,0.10); border: 1px solid rgba(91,141,239,0.35);
    border-radius: var(--radius); }

  .filter-count { font-size: 11px; color: #6b7280; margin-left: auto; white-space: nowrap; }
  .filter-total { font-size: 11px; font-weight: 600; color: #111827; white-space: nowrap; padding-left: 12px; border-left: 1px solid var(--card-border); }

  /* What a filter left out, named and clickable: "4 released or destroyed".
     A link rather than a button because it sits inside the sentence about the
     count, and has to read as part of it — the point is that the number on
     screen admits what it is not showing. */
  .count-more { font: inherit; color: var(--accent); background: none; border: 0;
    padding: 0; cursor: pointer; text-decoration: underline; }
  .count-more:hover { color: #111827; }

  /* The bar that appears when rows are selected for printing. */
  .select-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; padding: 9px 14px; background: #eef2ff; border: 1px solid #c7d2fe; border-radius: var(--radius-lg); font-size: 12px; font-weight: 600; color: #1e3a5f; }
  .row-select { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

  /* ── MULTI-SELECT FILTERS ──
     A <select> can hold one value, so filtering to "everything except
     released" was not possible — you could show released, or show all. These
     are a button and a list of checkboxes: pick as many as you like, and an
     empty selection means all, the same as never having touched it. */
  .filter-menu { position: relative; }
  .filter-btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 11px; background: var(--card-bg); border: 1px solid #d1d5db; border-radius: var(--radius); color: #111827; font-size: 12px; font-family: var(--sans); cursor: pointer; white-space: nowrap; }
  .filter-btn:hover { border-color: #9ca3af; }
  .filter-btn.is-set { border-color: var(--accent); color: var(--accent); font-weight: 600; }
  .filter-btn i { font-size: 14px; opacity: 0.7; }

  .filter-pop { position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; min-width: 180px; padding: 6px; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); box-shadow: 0 8px 24px rgba(17, 24, 39, 0.12); }
  .filter-opt { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: var(--radius); font-size: 12px; color: #111827; cursor: pointer; user-select: none; }
  .filter-opt:hover { background: #f3f4f6; }
  .filter-opt input { width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; flex: none; }
  .filter-clear { width: 100%; margin-top: 4px; padding: 6px; background: none; border: none; border-top: 1px solid var(--card-border); border-radius: 0; color: var(--accent); font-size: 11px; font-weight: 600; font-family: var(--sans); cursor: pointer; }
  .filter-clear:disabled { color: #9ca3af; cursor: default; }

  /* ── MODAL ── */
  .modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 100; display: flex; align-items: flex-start; justify-content: center; padding-top: 48px; }
  .modal { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); width: 600px; max-width: 96vw; max-height: 84vh; overflow-y: auto; }
  .modal-wide { width: 740px; }
  .modal-header { padding: 18px 22px 14px; border-bottom: 1px solid var(--card-border); display: flex; justify-content: space-between; align-items: flex-start; position: sticky; top: 0; background: var(--card-bg); z-index: 1; }
  .modal-title { font-size: 14px; font-weight: 600; color: #111827; }
  .modal-sub { font-size: 11px; color: #374151; margin-top: 3px; }
  .modal-body { padding: 18px 22px; }
  .modal-footer { padding: 14px 22px; border-top: 1px solid var(--card-border); display: flex; justify-content: flex-end; gap: 8px; }

  /* ── FORM ── */
  .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .section-div { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #374151; margin: 16px 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--card-border); }

  /* ── CLIENT AND CASE PAGES ── */
  .crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13px; color: #374151; margin-bottom: 12px; }
  .crumbs a { color: #1e3a5f; text-decoration: none; font-weight: 500; }
  .crumbs a:hover { text-decoration: underline; }
  .crumbs i { font-size: 12px; color: #9ca3af; }
  .crumbs [aria-current] { color: #111827; font-weight: 600; }
  .page-head { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start; justify-content: space-between; }
  .page-head-title { font-size: 18px; font-weight: 600; color: #111827; }
  .page-head-actions { display: flex; flex-wrap: wrap; gap: 6px; }
  .card-list { padding: 0; overflow: hidden; }
  .card-list > .section-div { margin: 0; padding: 12px 16px 8px; }
  .card-list .panel-empty { padding: 12px 16px; }
  details.case-group > summary { cursor: pointer; list-style: none; }
  details.case-group > summary::-webkit-details-marker { display: none; }
  details.case-group > summary::before { content: '\25B8  '; }
  details.case-group[open] > summary::before { content: '\25BE  '; }

  /* ── TABS ── */
  .tabs { display: flex; border-bottom: 1px solid var(--card-border); margin-bottom: 16px; }
  .tab { padding: 8px 14px; font-size: 12px; cursor: pointer; color: #374151; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: all 0.1s; font-weight: 500; }
  .tab.active { color: #111827; border-bottom-color: var(--accent); font-weight: 600; }
  .tab:hover { color: #111827; }

  /* ── DETAIL ── */
  .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  .detail-field label { font-size: 10px; color: #374151; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 3px; display: block; }
  .detail-field p { font-size: 13px; font-weight: 500; color: #111827; }

  /* ── COC ── */
  .coc-entry { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--card-border); }
  .coc-entry:last-child { border-bottom: none; }
  .coc-dot { width: 7px; height: 7px; border-radius: 50%; background: #9ca3af; margin-top: 5px; flex-shrink: 0; }
  .coc-dot.first { background: #16a34a; }
  .coc-time { font-size: 10px; color: #374151; font-family: var(--mono); min-width: 130px; font-weight: 500; }
  .coc-action { font-size: 12px; font-weight: 600; color: #111827; }
  .coc-person { font-size: 11px; color: #374151; margin-top: 2px; }

  /* ── AUDIT ── */
  .audit-entry { display: flex; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--card-border); font-size: 11px; }
  .audit-entry:last-child { border-bottom: none; }
  .audit-ts { color: #374151; font-family: var(--mono); min-width: 130px; font-weight: 500; }
  .audit-user { color: #374151; min-width: 90px; font-weight: 500; }
  /* A flex item's default min-width is auto, which means "never shrink below
     your own content". The detail column holds free text, so one long entry made
     that span measure several million pixels wide — which is what the mobile
     overflow gate was reporting on this view. min-width: 0 lets it shrink, and
     overflow-wrap breaks a long unspaced string instead of letting a single
     word set the width of the page. */
  .audit-entry > span { min-width: 0; overflow-wrap: anywhere; }
  .audit-ts, .audit-user { flex: none; }

  /* ── MISC ── */
  .mono { font-family: var(--mono); font-size: 11px; color: #374151; }
  .upload-area { border: 1px dashed #9ca3af; border-radius: var(--radius); padding: 16px; text-align: center; cursor: pointer; color: #374151; font-size: 12px; font-weight: 500; }
  .upload-area:hover { background: #f9fafb; }
  .doc-item { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--card-border); }
  .doc-item:last-child { border-bottom: none; }
  .loading { text-align: center; padding: 40px; color: #374151; font-size: 12px; font-weight: 500; }
  .error-msg { background: var(--red-bg); border: 1px solid var(--red); color: var(--red); padding: 10px 12px; border-radius: var(--radius); font-size: 12px; margin-bottom: 14px; }
  .inv-preview { background: #fff; color: #111; border-radius: var(--radius); padding: 32px; font-family: var(--sans); }
  .inv-preview table { color: #111; }
  .inv-preview th { color: #666; }
  .inv-preview td { border-bottom: 1px solid #eee; }

    .notif-bell { position:relative; cursor:pointer; padding:6px 8px; border-radius:6px; color:var(--text2,#6b7280); display:flex; align-items:center; }
    .notif-bell:hover { background:var(--bg3,#f3f4f6); }
    .notif-badge { position:absolute; top:2px; right:2px; background:#dc2626; color:#fff; font-size:10px; font-weight:600; min-width:16px; height:16px; border-radius:99px; display:flex; align-items:center; justify-content:center; padding:0 3px; }
    .notif-panel { position:fixed; top:0; right:0; width:380px; height:100vh; background:#fff; box-shadow:-4px 0 24px rgba(0,0,0,0.12); z-index:1000; display:flex; flex-direction:column; transform:translateX(100%); transition:transform 0.25s ease; }
    .notif-panel.open { transform:translateX(0); }
    .notif-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.2); z-index:999; display:none; }
    .notif-overlay.open { display:block; }
    .notif-header { padding:16px 20px; border-bottom:1px solid #e5e7eb; display:flex; justify-content:space-between; align-items:center; }
    .notif-header-title { font-size:15px; font-weight:600; color:#111827; }
    .notif-list { flex:1; overflow-y:auto; }
    .notif-item { padding:14px 20px; border-bottom:1px solid #f3f4f6; cursor:pointer; transition:background 0.1s; }
    .notif-item:hover { background:#f9fafb; }
    .notif-item.unread { background:#eff6ff; border-left:3px solid #2563eb; }
    .notif-item.unread:hover { background:#dbeafe; }
    .notif-type { font-size:11px; font-weight:500; text-transform:uppercase; letter-spacing:.05em; margin-bottom:4px; }
    .notif-type.overdue { color:#dc2626; }
    .notif-type.expiring { color:#d97706; }
    .notif-type.info { color:#2563eb; }
    .notif-msg { font-size:13px; color:#111827; margin-bottom:4px; line-height:1.4; }
    .notif-time { font-size:11px; color:#9ca3af; }
    .notif-empty { padding:40px 20px; text-align:center; color:#9ca3af; font-size:13px; }
    .notif-footer { padding:12px 20px; border-top:1px solid #e5e7eb; display:flex; gap:8px; }

  /* ============================================================
     PHONES AND TABLETS

     The operational half of this system is phone work. A QR code is
     scanned with a phone camera, the label printer is Bluetooth, and an
     inspection happens standing next to the item. The desktop layout is
     for the office; this is for the floor.

     Everything below ≤860px. Above it, nothing here applies.
     ============================================================ */

  .nav-toggle { display: none; }
  .label-on-mobile { display: none; }
  .nav-backdrop { display: none; }

  @media (max-width: 860px) {

    /* ── Navigation becomes a drawer ──
       A 210px sidebar on a 414px screen leaves 204px for the actual work.
       It slides in over the content instead, and is off-screen by default. */
    .sidebar {
      position: fixed; z-index: 90; top: 0; bottom: 0; left: 0;
      width: 262px; max-width: 82vw;
      transform: translateX(-100%);
      transition: transform 0.22s ease;
      box-shadow: 2px 0 16px rgba(0,0,0,0.2);
    }
    #app.nav-open .sidebar { transform: translateX(0); }

    .nav-backdrop { position: fixed; inset: 0; z-index: 80; background: rgba(0,0,0,0.45); }
    #app.nav-open .nav-backdrop { display: block; }

    .nav-toggle {
      display: inline-flex; align-items: center; justify-content: center;
      width: 40px; height: 40px; margin-left: -8px; margin-right: 4px;
      flex: none; background: none; border: none; border-radius: var(--radius);
      color: #1e3a5f; cursor: pointer;
    }
    .nav-toggle i { font-size: 22px; }
    .nav-toggle:active { background: #e5e7eb; }

    /* Drawer items are tapped, not clicked. 44px is the size a finger
       actually hits. */
    .nav-item { padding: 12px 18px; font-size: 14px; }
    .nav-item i { font-size: 18px; }
    .nav-section { padding: 14px 18px 4px; }
    .sidebar-user { padding: 14px 18px; }
    .btn-logout { padding: 11px 12px; font-size: 13px; }

    /* ── Shell ── */
    .topbar { padding: 0 14px; height: 54px; gap: 8px; }
    .topbar-title {
      flex: 1; min-width: 0;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    /* The long wordmark does not fit beside a menu button and a bell. */
    .topbar-title.dashboard-title { font-size: 15px; }
    .content { padding: 14px 12px 28px; }

    /* ── Touch targets ──
       6px of padding is a mouse target. These are fingers, often gloved,
       often in a warehouse. */
    .btn { padding: 10px 14px; font-size: 13px; min-height: 40px; }
    .btn-sm { padding: 8px 11px; font-size: 12px; min-height: 36px; }
    .form-input, .search-bar input { padding: 11px 12px; font-size: 16px; }
    .filter-btn { padding: 10px 13px; font-size: 13px; min-height: 40px; }
    .filter-opt { padding: 11px 10px; font-size: 14px; }
    .filter-opt input, .row-select { width: 18px; height: 18px; }

    /* 16px on inputs specifically: iOS zooms the whole page in on any
       focused input with a smaller font, and never zooms back out. */

    /* ── One column everywhere ── */
    .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .dash-row { grid-template-columns: minmax(0, 1fr); }
    .form-row, .detail-grid { grid-template-columns: minmax(0, 1fr); }

    /* ── Search and filter bar ── */
    .search-bar { gap: 8px; }
    .search-bar input { flex: 1 1 100%; }
    .filter-count { margin-left: 0; }
    .filter-total { padding-left: 0; border-left: none; margin-left: auto; }
    .filter-pop { left: auto; right: 0; min-width: 210px; }

    .select-bar { flex-wrap: wrap; }

    /* ── Modals fill the screen ──
       A 600px dialog floating 48px down a 414px screen wastes the room it
       needs most. The detail view is the thing someone opens after
       scanning a label, so it gets the whole display. */
    .modal-overlay { padding-top: 0; align-items: stretch; }
    .modal, .modal-wide {
      width: 100%; max-width: 100%;
      max-height: 100%; height: 100%;
      border-radius: 0; border: none;
    }
    .modal-header { padding: 14px 16px 12px; }
    .modal-body { padding: 16px; }
    .modal-footer {
      padding: 12px 16px;
      position: sticky; bottom: 0; background: var(--card-bg);
    }
    .modal-footer .btn { flex: 1; justify-content: center; }

    /* Fields with no value are hidden on a phone. On a wide screen the
       blanks are useful — they show what has not been filled in — but on a
       phone they are just distance between the things that do have values. */
    .detail-field.is-empty, .detail-grid.is-empty, .section-empty { display: none; }

    .tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .tab { padding: 11px 14px; font-size: 13px; white-space: nowrap; }

    /* ── Tables become cards ──
       An eleven-column table on a 414px screen is a horizontal scroll with
       no winning position: the identifier and the status can never be on
       screen together. Each row becomes a block instead, with the column
       headings carried on the cells as data-label.

       Driven by the th-less markup rather than nth-child, so reordering a
       column cannot silently relabel the data. */
    table.stacked thead { display: none; }
    table.stacked, table.stacked tbody, table.stacked tr, table.stacked td { display: block; width: 100%; }
    table.stacked tr {
      padding: 12px 14px 12px 44px; position: relative;
      border-bottom: 1px solid var(--card-border);
    }
    table.stacked tr:last-child { border-bottom: none; }
    table.stacked td {
      padding: 2px 0; border: none; font-size: 13px;
      display: flex; align-items: baseline; gap: 8px;
      /* A description with no spaces in it would otherwise run off the card. */
      min-width: 0; overflow-wrap: anywhere;
    }
    /* 94px rather than 76: the longest labels in use — RELATIONSHIP,
       DESCRIPTION — broke mid-word at 76 and read as "RELATIONSHI / P". */
    table.stacked td::before {
      content: attr(data-label);
      flex: none; width: 94px;
      font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
      text-transform: uppercase; color: #6b7280;
    }
    /* A badge is a word on a pill; letting it break mid-word turns it into a
       vertical stack of letters. The wrap setting above is for descriptions. */
    table.stacked td .badge { flex: none; white-space: nowrap; overflow-wrap: normal; }

    /* The identifier leads the card, big, with no label in front of it. */
    table.stacked td.cell-lead { font-size: 15px; font-weight: 700; padding-bottom: 6px; }
    table.stacked td.cell-lead::before { display: none; }
    /* Cells that carry nothing useful without their row context. */
    table.stacked td.cell-hide, table.stacked .cell-hide { display: none; }
    /* The row checkbox sits in the gutter the padding above reserves. */
    table.stacked td.cell-select { position: absolute; left: 12px; top: 13px; width: auto; padding: 0; }
    table.stacked td.cell-select::before { display: none; }
    /* Actions go full width at the bottom of the card. */
    table.stacked td.cell-actions { margin-top: 8px; }
    table.stacked td.cell-actions::before { display: none; }
    table.stacked td.cell-actions .btn { flex: 1; justify-content: center; }

    .label-on-mobile { display: inline; }


    /* ── Notifications panel ── */
    .notif-panel { width: 100%; max-width: 100%; }
  }

  /* Phones proper. */
  @media (max-width: 460px) {
    /* Stat tiles stay two-up. One per row put four screens of scrolling
       between the top of the dashboard and anything actionable. */
    .card { padding: 12px 13px; }
    .filter-btn { flex: 1 1 auto; justify-content: space-between; }
  }

  /* ── GLOBAL SEARCH ──
     One box in the top bar, because someone arriving with a VIN or a shelf
     code should not have to work out which list it belongs to first. */
  .gs-wrap { position: relative; flex: 1 1 260px; max-width: 420px; margin-left: 16px; }
  .gs-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 15px; color: #9ca3af; pointer-events: none; }
  .gs-input { width: 100%; padding: 7px 11px 7px 31px; background: var(--card-bg); border: 1px solid #d1d5db; border-radius: var(--radius); color: #111827; font-size: 12px; font-family: var(--sans); }
  .gs-input::placeholder { color: #9ca3af; }
  .gs-input:focus { outline: none; border-color: var(--accent); }
  .gs-input::-webkit-search-cancel-button { cursor: pointer; }

  .gs-panel { position: absolute; z-index: 70; top: calc(100% + 6px); left: 0; right: 0; max-height: 65vh; overflow-y: auto; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); box-shadow: 0 12px 32px rgba(17,24,39,0.16); }
  .gs-group { padding: 9px 13px 5px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: #6b7280; background: #f9fafb; border-bottom: 1px solid var(--card-border); }
  .gs-more { font-weight: 500; text-transform: none; letter-spacing: 0; color: #9ca3af; }
  .gs-row { display: flex; align-items: center; gap: 10px; padding: 9px 13px; border-bottom: 1px solid var(--card-border); cursor: pointer; }
  .gs-row:last-child { border-bottom: none; }
  .gs-row:hover { background: #f3f4f6; }
  .gs-lead { font-family: var(--mono); font-size: 10px; color: #374151; }
  .gs-text { font-size: 13px; color: #111827; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .gs-meta { font-size: 11px; color: #6b7280; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .gs-empty { padding: 20px 14px; text-align: center; font-size: 12px; color: #6b7280; }

  /* On a phone the box would crush the title, so it drops below the bar. */
  @media (max-width: 860px) {
    .topbar { flex-wrap: wrap; height: auto; padding: 8px 14px; row-gap: 8px; }
    .gs-wrap { order: 10; flex: 1 1 100%; max-width: none; margin-left: 0; }
    .gs-input { padding-top: 10px; padding-bottom: 10px; font-size: 16px; }
    .gs-panel { max-height: 70vh; }
  }

  /* ── REPORTS ── */
  .rep-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
  .rep-tile { padding: 12px 14px; border: 1px solid var(--card-border); border-radius: var(--radius-lg); cursor: pointer; background: #fcfdfe; }
  .rep-tile:hover { background: #f3f4f6; }
  .rep-tile-n { font-size: 24px; font-weight: 600; line-height: 1.1; }
  .rep-tile-l { font-size: 11px; color: #374151; margin-top: 3px; line-height: 1.35; }

  .rep-money { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
  .rep-money-l { font-size: 11px; color: #6b7280; }
  .rep-money-n { font-size: 23px; font-weight: 600; color: #111827; margin-top: 2px; }
  .rep-money-s { font-size: 11px; color: #6b7280; margin-top: 2px; }

  /* Invoiced and collected share a scale, so the gap between them is the
     thing you see rather than something you have to work out. */
  .rep-chart { display: flex; align-items: flex-end; gap: 4px; height: 120px; padding: 0 2px; }
  .rep-bar-group { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; min-width: 0; }
  .rep-bars { flex: 1; display: flex; align-items: flex-end; gap: 2px; width: 100%; justify-content: center; }
  .rep-bar { width: 44%; min-height: 1px; border-radius: 2px 2px 0 0; }
  .rep-bar-inv { background: #93b4f0; }
  .rep-bar-col { background: var(--green); }
  .rep-bar-label { font-size: 9px; color: #6b7280; margin-top: 4px; white-space: nowrap; }
  .rep-legend { display: flex; gap: 14px; margin-top: 8px; font-size: 11px; color: #374151; }
  .rep-swatch { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; }

  .rep-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; }
  .rep-aged-row { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--card-border); font-size: 12px; color: #374151; }
  .rep-aged-row:last-child { border-bottom: none; }
  /* .form-input is width:100%, which made these fill the header and push the
     Apply button onto its own line. */
  .rep-date { width: auto; flex: 0 0 auto; padding: 6px 9px; font-size: 12px; background: #fff; border: 1px solid #d1d5db; border-radius: var(--radius); color: #111827; }

  @media (max-width: 860px) {
    .rep-chart { height: 96px; }
    .rep-bar-label { font-size: 8px; }
    .rep-date { font-size: 16px; padding: 9px; }
  }
