/* ==========================================================================
   VC Asset Tracker — design system
   --------------------------------------------------------------------------
   Replaces Tabler/Bootstrap entirely (~110 KB of CSS+JS removed). It keeps
   their CLASS NAMES so the eleven page modules did not have to be rewritten;
   only the look changes. If you add markup, use the classes already listed
   here rather than reaching for a Bootstrap class this file does not define.

   Three visual layers, each with a rule for when it appears:
     1. The app        — sidebar shell, cards, tables. Everything routine.
     2. The document   — .working-paper, on Reports and anything printed for
                         audit. A schedule, not app chrome.
     3. The object     — .asset-tag, the header of a single asset's page. The
                         same tag that is stuck to the physical device.

   Brand is fixed by the Vantage Circle brand book: Lato only, the approved
   hexes below, capsule buttons, radii 8/12/16/21.
   ========================================================================== */

:root{
  /* --- Brand (Vc BrandBook 8) --- */
  --ink:#29294C;            /* Space Cadet */
  --accent:#FF6D05;         /* Pumpkin Orange */
  --canvas:#EEEEF6;         /* Ghost White */
  --surface:#CDCDE4;        /* Lavender Web */
  --white:#FFFFFF;
  --icon-bg:#3C3C69;

  --ink-800:#31315A; --ink-700:#3F3F74; --ink-600:#505095;
  --ink-500:#6A6AAF; --ink-400:#8B8BC0; --ink-300:#ACACD2; --ink-200:#CDCDE4;
  --acc-800:#FF7E39; --acc-600:#FF9D6C; --acc-400:#FFC8AD; --acc-200:#FFE4D6;

  /* Functional state colours. The brand book defines no success/danger, and a
     register with "damaged" and "sold" states needs them. Kept desaturated so
     they read as data, and never used for brand surfaces. Orange is reserved
     for "needs your attention", so it is deliberately not the danger colour. */
  --ok:#1F7A5C;   --ok-bg:#DCF0E9;
  --bad:#B3261E;  --bad-bg:#FBE4E2;
  --warn:#8A5A00; --warn-bg:#FDF0D5;
  --info:#2B5CA8; --info-bg:#DFE9F8;

  --radius-sm:8px; --radius-md:12px; --radius-lg:16px; --radius-xl:21px;
  --pill:9999px;
  --font:"Lato",system-ui,-apple-system,"Segoe UI",sans-serif;

  --shadow-sm:0 1px 2px rgba(20,20,40,.06);
  --shadow:0 4px 14px rgba(20,20,40,.10);
  --shadow-lg:0 16px 40px rgba(20,20,40,.22);

  --sidebar-w:244px;
}

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--font);
  font-size:15px;
  line-height:1.5;
  color:var(--ink);
  background:var(--canvas);
  min-height:100vh;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4,h5,h6{margin:0;font-weight:900;letter-spacing:-.015em;line-height:1.2}
p{margin:0 0 .75rem}
p:last-child{margin-bottom:0}
hr{border:0;border-top:1px solid var(--surface);margin:1rem 0}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px}

/* ==========================================================================
   1 · SHELL
   ========================================================================== */
.page{display:flex;min-height:100vh}
.page-wrapper{flex:1;min-width:0;display:flex;flex-direction:column}
.page-body{flex:1;padding:22px 0 64px}
.container-xl,.container-fluid{width:100%;max-width:1440px;margin:0 auto;padding:0 26px}

/* --- Sidebar --- */
.navbar-vertical{
  width:var(--sidebar-w);flex:none;background:var(--ink);color:var(--canvas);
  display:flex;flex-direction:column;padding:20px 14px;
}
.navbar-vertical .container-fluid{padding:0;display:flex;flex-direction:column;flex:1;max-width:none}
.navbar-brand{display:flex;align-items:center;margin:0 0 20px;padding:0 6px}
.navbar-brand a{display:flex;align-items:center;gap:10px;color:var(--white);text-decoration:none}
.navbar-brand span{font-size:15.5px;font-weight:900;letter-spacing:-.01em;line-height:1.15}
.navbar-brand .brand-mark{
  width:34px;height:34px;flex:none;border-radius:var(--pill);background:var(--accent);
  display:flex;align-items:center;justify-content:center;color:var(--white);font-size:17px;
}
.navbar-nav{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.nav-item{margin:0}
.nav-link{
  display:flex;align-items:center;gap:11px;padding:9px 13px;border-radius:var(--pill);
  color:var(--ink-300);font-size:14.5px;font-weight:700;text-decoration:none;
  transition:background .15s,color .15s;
}
.nav-link:hover{background:var(--ink-700);color:var(--white);text-decoration:none}
.nav-link.active{background:var(--white);color:var(--ink)}
.nav-link-icon{display:flex;flex:none;font-size:17px}
.nav-link-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* --- Header --- */
.page-wrapper > .navbar{
  background:var(--white);border-bottom:1px solid var(--surface);padding:16px 0;
}
.page-wrapper > .navbar .container-xl{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.page-pretitle{
  font-size:11px;font-weight:900;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-500);width:100%;
}
.page-title{font-size:26px;font-weight:900;letter-spacing:-.02em;margin:2px 0 0}

/* --- Footer --- */
.footer{padding:18px 0 26px;font-size:12.5px;color:var(--ink-500)}
.footer .row{align-items:center}

/* ==========================================================================
   2 · GRID + UTILITIES
   ========================================================================== */
.row{display:flex;flex-wrap:wrap;margin:0 -8px}
.row > *{padding:0 8px;min-width:0}
.g-2{margin:0 -6px}      .g-2 > *{padding:0 6px;margin-bottom:12px}
.g-3{margin:0 -10px}     .g-3 > *{padding:0 10px;margin-bottom:16px}
.row-cards > *,.row-deck > *{margin-bottom:16px}
.row-deck > *{display:flex}
.row-deck > * > .card{flex:1}

.col{flex:1 0 0}
.col-auto{flex:0 0 auto;width:auto}
.col-12{flex:0 0 100%;max-width:100%}
.col-6{flex:0 0 50%;max-width:50%}
@media (min-width:768px){
  .col-md-1{flex:0 0 8.3333%;max-width:8.3333%}
  .col-md-2{flex:0 0 16.6667%;max-width:16.6667%}
  .col-md-3{flex:0 0 25%;max-width:25%}
  .col-md-4{flex:0 0 33.3333%;max-width:33.3333%}
  .col-md-5{flex:0 0 41.6667%;max-width:41.6667%}
  .col-md-6{flex:0 0 50%;max-width:50%}
  .col-md-7{flex:0 0 58.3333%;max-width:58.3333%}
  .col-md-8{flex:0 0 66.6667%;max-width:66.6667%}
  .col-md-12{flex:0 0 100%;max-width:100%}
}
@media (min-width:576px){
  .col-sm-4{flex:0 0 33.3333%;max-width:33.3333%}
  .col-sm-6{flex:0 0 50%;max-width:50%}
}
@media (min-width:992px){ .col-lg-3{flex:0 0 25%;max-width:25%} }
@media (max-width:767.98px){ [class*="col-md-"]{flex:0 0 100%;max-width:100%} }
@media (max-width:575.98px){ [class*="col-sm-"]{flex:0 0 100%;max-width:100%} }

.d-flex{display:flex}
.d-none{display:none}
.flex-fill{flex:1 1 auto}
.flex-wrap{flex-wrap:wrap}
.flex-shrink-0{flex-shrink:0}
.align-items-center{align-items:center}
.align-items-start{align-items:flex-start}
.align-items-end{align-items:flex-end}
.justify-content-end{justify-content:flex-end}
.gap-2{gap:8px} .gap-3{gap:14px}
.ms-auto{margin-left:auto} .mt-auto{margin-top:auto} .m-auto{margin:auto}
.w-100{width:100%}
.position-fixed{position:fixed}
.bottom-0{bottom:0} .end-0{right:0}
.rounded{border-radius:var(--radius-sm)}
.border-top{border-top:1px solid var(--surface)}
.border-bottom{border-bottom:1px solid var(--surface)}
.border-start{border-left:1px solid var(--surface)}
.border-warning{border:1px solid var(--accent)!important}
.bg-light{background:var(--canvas)}

.mb-0{margin-bottom:0} .mb-1{margin-bottom:4px} .mb-2{margin-bottom:8px} .mb-3{margin-bottom:16px}
.mt-1{margin-top:4px} .mt-2{margin-top:8px} .mt-3{margin-top:16px}
.me-1{margin-right:4px} .me-2{margin-right:8px} .me-3{margin-right:14px}
.ms-1{margin-left:4px} .ms-2{margin-left:8px}
.p-0{padding:0} .p-3{padding:16px} .p-4{padding:22px}
.px-0{padding-left:0;padding-right:0} .px-1{padding-left:4px;padding-right:4px}
.py-0{padding-top:0;padding-bottom:0} .py-2{padding-top:8px;padding-bottom:8px}
.py-3{padding-top:16px;padding-bottom:16px}
.ps-3{padding-left:16px} .pt-2{padding-top:8px} .pt-3{padding-top:16px} .pb-3{padding-bottom:16px}
@media (min-width:992px){ .pt-lg-3{padding-top:16px} }

.text-start{text-align:left} .text-center{text-align:center} .text-end{text-align:right}
.text-uppercase{text-transform:uppercase;letter-spacing:.1em}
.text-decoration-none{text-decoration:none}
.text-reset{color:inherit}
.small,small{font-size:12.5px}
.h2{font-size:26px;font-weight:900;letter-spacing:-.02em}
.fw-bold{font-weight:700} .fw-medium,.font-weight-medium{font-weight:700}
.font-monospace{font-variant-numeric:tabular-nums;letter-spacing:.05em}

.text-secondary,.text-muted{color:var(--ink-500)}
.text-primary{color:var(--accent)}
.text-danger{color:var(--bad)}
.text-success{color:var(--ok)}
.text-warning{color:var(--warn)}
.text-white-50{color:var(--ink-300)}

/* ==========================================================================
   3 · CARD
   ========================================================================== */
.card{
  background:var(--white);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-sm);display:flex;flex-direction:column;min-width:0;
}
.card-header{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:16px 20px;border-bottom:1px solid var(--canvas);
}
.card-title{font-size:16px;font-weight:900;margin:0;letter-spacing:-.01em}
.card-body{padding:20px}
.card-footer{padding:14px 20px;border-top:1px solid var(--canvas);background:transparent}
.card-sm .card-body{padding:14px 16px}
.card > .table-responsive:last-child,
.card > .table:last-child{border-radius:0 0 var(--radius-lg) var(--radius-lg);overflow:hidden}

/* ==========================================================================
   4 · TABLE
   ========================================================================== */
.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}
.table{width:100%;border-collapse:collapse;font-size:14.5px}
.table th{
  text-align:left;font-size:11px;font-weight:900;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-500);padding:11px 20px;border-bottom:1px solid var(--surface);white-space:nowrap;
}
.table td{padding:13px 20px;border-bottom:1px solid var(--canvas);vertical-align:middle}
.table tbody tr:last-child td{border-bottom:0}
.table-vcenter td,.table-vcenter th{vertical-align:middle}
.table-sm td,.table-sm th{padding:8px 14px}
.card-table{margin:0}
.table-hoverable tbody tr:hover,
.table tbody tr.row-clickable:hover > td{background:var(--canvas)}
.table tbody tr.row-clickable > td{cursor:pointer}
.table tbody tr.row-clickable a,.table tbody tr.row-clickable button{cursor:pointer}
.table-danger > td,tr.table-danger > td{background:var(--bad-bg)}
.table-warning > td,tr.table-warning > td{background:var(--warn-bg)}
.table-sticky thead th{position:sticky;top:0;background:var(--white);z-index:2}

/* ==========================================================================
   5 · BUTTONS — capsule, per brand
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:42px;padding:0 20px;border-radius:var(--pill);
  font-family:var(--font);font-size:14.5px;font-weight:700;line-height:1;
  border:2px solid transparent;background:transparent;color:var(--ink);
  cursor:pointer;white-space:nowrap;text-decoration:none;
  transition:filter .15s,background .15s,color .15s,transform .1s;
}
.btn:hover{text-decoration:none;filter:brightness(1.04)}
.btn:active{transform:translateY(1px)}
.btn:disabled,.btn[disabled]{opacity:.5;cursor:not-allowed;transform:none}
.btn-sm{height:34px;padding:0 15px;font-size:13px;gap:6px}
.btn-icon{width:34px;height:34px;padding:0;flex:none}
.btn .ti{font-size:16px}

.btn-primary{background:var(--accent);border-color:var(--accent);color:var(--white)}
.btn-success{background:var(--ok);border-color:var(--ok);color:var(--white)}
.btn-danger{background:var(--bad);border-color:var(--bad);color:var(--white)}
.btn-secondary{background:var(--ink);border-color:var(--ink);color:var(--white)}
.btn-outline-primary{border-color:var(--accent);color:var(--accent)}
.btn-outline-primary:hover{background:var(--acc-200)}
.btn-outline-secondary{border-color:var(--surface);color:var(--ink-600);background:var(--white)}
.btn-outline-secondary:hover{background:var(--canvas);color:var(--ink)}
.btn-outline-danger{border-color:var(--bad);color:var(--bad)}
.btn-outline-danger:hover{background:var(--bad-bg)}
.btn-outline-warning{border-color:var(--accent);color:var(--accent)}
.btn-outline-warning:hover{background:var(--acc-200)}
.btn-ghost-secondary{color:var(--ink-600)}
.btn-ghost-secondary:hover{background:var(--canvas)}
.btn-ghost-danger{color:var(--bad)}
.btn-ghost-danger:hover{background:var(--bad-bg)}
.btn-link{color:var(--accent);height:auto;padding:0;border:0}
.btn-link:hover{text-decoration:underline}
.link-secondary{color:var(--ink-600)}

.btn-group{display:inline-flex;gap:6px}
.btn-group-sm .btn{height:34px;padding:0 14px;font-size:13px}

.btn-close{
  width:32px;height:32px;flex:none;border:0;background:transparent;cursor:pointer;
  border-radius:var(--pill);position:relative;color:var(--ink-600);
}
.btn-close::before,.btn-close::after{
  content:"";position:absolute;left:9px;top:15px;width:14px;height:2px;
  background:currentColor;border-radius:1px;
}
.btn-close::before{transform:rotate(45deg)} .btn-close::after{transform:rotate(-45deg)}
.btn-close:hover{background:rgba(0,0,0,.06)}
.btn-close-white{color:var(--white)}

/* ==========================================================================
   6 · BADGES
   ========================================================================== */
.badge{
  display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 11px;
  border-radius:var(--pill);font-size:11px;font-weight:900;
  letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;
  background:var(--canvas);color:var(--ink-600);
}
/* Page modules build these names dynamically (`bg-${color}-lt`), so every
   colour token they can emit must exist: blue, cyan, green, yellow, orange,
   red, purple, secondary. A missing one renders as an invisible disc. */
.bg-blue-lt{background:var(--info-bg);color:var(--info)}
.bg-cyan-lt{background:#DCEEF2;color:#15606B}
.bg-green-lt{background:var(--ok-bg);color:var(--ok)}
.bg-yellow-lt{background:var(--warn-bg);color:var(--warn)}
.bg-orange-lt{background:var(--acc-200);color:#9A4100}
.bg-red-lt{background:var(--bad-bg);color:var(--bad)}
.bg-purple-lt{background:#E6E2F5;color:#4B3A8F}
.bg-secondary-lt{background:var(--canvas);color:var(--ink-600)}
.text-orange{color:#9A4100}
.text-blue{color:var(--info)} .text-green{color:var(--ok)} .text-red{color:var(--bad)}
.text-yellow{color:var(--warn)} .text-cyan{color:#15606B} .text-purple{color:#4B3A8F}
/* Serialised vs bulk must never blur together — different shapes, not just hues. */
.badge-tracking-serialized{background:var(--info-bg);color:var(--info)}
.badge-tracking-bulk{background:var(--canvas);color:var(--ink-600);
  box-shadow:inset 0 0 0 1px var(--surface)}
/* Installed equipment: tracked per unit, but with no serial to look up. */
.badge-tracking-unit{background:#E6E2F5;color:#4B3A8F}

/* ==========================================================================
   7 · FORMS
   ========================================================================== */
.form-label{
  display:block;font-size:12px;font-weight:900;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-600);margin-bottom:5px;
}
.form-label.required::after{content:" *";color:var(--accent)}
.form-control,.form-select{
  display:block;width:100%;height:42px;padding:0 13px;
  font-family:var(--font);font-size:14.5px;color:var(--ink);
  background:var(--white);border:1.5px solid var(--surface);
  border-radius:var(--radius-sm);transition:border-color .15s,box-shadow .15s;
}
textarea.form-control{height:auto;padding:10px 13px;min-height:80px;resize:vertical}
.form-control::placeholder{color:var(--ink-400)}
.form-control:focus,.form-select:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--acc-200);
}
.form-control:disabled,.form-select:disabled{background:var(--canvas);color:var(--ink-500)}
.form-select{
  appearance:none;padding-right:36px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23505095' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;background-size:16px;
}
.form-control-sm,.form-select-sm{height:34px;font-size:13px;padding:0 10px}
.form-select-sm{padding-right:30px}
.form-control-plaintext{border:0;background:transparent;padding:0;height:auto}
.form-hint{font-size:12.5px;color:var(--ink-500);margin-top:4px}
/* Hidden until its field is actually marked invalid. Without the display rule
   the message renders permanently, so an untouched empty row accuses itself. */
.invalid-feedback{display:none;font-size:12.5px;color:var(--bad);margin-top:4px}
.is-invalid ~ .invalid-feedback,
.is-invalid + .invalid-feedback{display:block}
.form-control.is-invalid,.form-select.is-invalid{border-color:var(--bad)}
.form-modal-row{margin-bottom:14px}

.form-check{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.form-check-inline{display:inline-flex;margin-right:16px}
.form-check-input{
  width:18px;height:18px;flex:none;margin:0;cursor:pointer;accent-color:var(--accent);
}
.form-check-label{cursor:pointer;font-size:14.5px}
.form-switch .form-check-input{width:36px;height:20px;border-radius:var(--pill)}

/* --- Searchable select (see comboBox in js/ui.js) ------------------------ */
.combo{position:relative}
.combo-input{padding-right:34px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23505095' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;background-size:16px}
/* Fixed, not absolute: these sit inside `.modal-body` and `.card`, both of
   which clip overflow. Coordinates are computed in js/ui.js. */
.combo-list{
  position:fixed;z-index:1070;
  max-height:264px;overflow-y:auto;margin:0;padding:5px;list-style:none;
  background:var(--white);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);
}
.combo-opt{
  display:flex;align-items:baseline;gap:9px;padding:9px 11px;border-radius:var(--radius-sm);
  cursor:pointer;font-size:14.5px;
}
.combo-opt:hover,.combo-opt.is-active{background:var(--canvas)}
.combo-opt.is-active{box-shadow:inset 0 0 0 2px var(--accent)}
.combo-label{font-weight:700}
.combo-hint{font-size:12.5px;color:var(--ink-500);margin-left:auto;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.combo-empty{padding:11px;font-size:13.5px;color:var(--ink-500)}

/* ==========================================================================
   8 · DROPDOWN
   ========================================================================== */
.dropdown{position:relative}
/* The menus are authored as <ul><li><button>, so the list styling has to go. */
.dropdown-menu{
  display:none;position:absolute;top:100%;right:0;z-index:1055;min-width:190px;
  margin:6px 0 0;padding:6px;background:var(--white);list-style:none;
  border-radius:var(--radius-md);box-shadow:var(--shadow-lg);
}
.dropdown-menu li{list-style:none;margin:0}
/* Menus live inside .card > .table-responsive, which clips overflow. Fixed
   positioning takes them out of that box; app.js sets top/left. */
.dropdown-menu.show{display:block;position:fixed}
.dropdown-item{
  display:flex;align-items:center;gap:9px;width:100%;padding:9px 12px;
  border:0;background:transparent;border-radius:var(--radius-sm);
  font-family:var(--font);font-size:14px;font-weight:700;color:var(--ink);
  text-align:left;text-decoration:none;cursor:pointer;
}
.dropdown-item:hover{background:var(--canvas);text-decoration:none}
.dropdown-item.text-danger{color:var(--bad)}
.dropdown-item.text-danger:hover{background:var(--bad-bg)}
.dropdown-divider{height:1px;background:var(--surface);margin:5px 0;border:0}
.dropdown-toggle::after{
  content:"";display:inline-block;width:0;height:0;margin-left:6px;
  border:4px solid transparent;border-top-color:currentColor;
}

/* ==========================================================================
   9 · MODAL
   ========================================================================== */
.modal{
  position:fixed;inset:0;z-index:1060;display:none;
  align-items:flex-start;justify-content:center;padding:36px 16px;
  background:rgba(20,20,40,.55);overflow-y:auto;
}
.modal.show{display:flex}
.modal-dialog{
  width:100%;max-width:560px;margin:auto;
  animation:modal-in .22s cubic-bezier(.16,1,.3,1);
}
.modal-dialog.modal-lg{max-width:840px}
.modal-dialog.modal-xl{max-width:1140px}
@keyframes modal-in{from{opacity:0;transform:translateY(10px) scale(.99)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.modal-dialog{animation:none}}
.modal-content{
  background:var(--white);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-lg);display:flex;flex-direction:column;max-height:88vh;
}
.modal-header{
  display:flex;align-items:center;gap:12px;padding:18px 22px;
  border-bottom:1px solid var(--canvas);
}
.modal-title{font-size:17px;font-weight:900;margin:0;flex:1}
.modal-body{padding:22px;overflow-y:auto}
.modal-footer{
  display:flex;justify-content:flex-end;gap:10px;flex-wrap:wrap;
  padding:16px 22px;border-top:1px solid var(--canvas);
}

/* ==========================================================================
   10 · TOAST
   ========================================================================== */
.toast-container{position:fixed;right:18px;bottom:18px;z-index:1080;
  display:flex;flex-direction:column;gap:10px}
.toast{
  min-width:280px;max-width:400px;border-radius:var(--radius-md);
  box-shadow:var(--shadow-lg);color:var(--white);background:var(--ink);
  animation:toast-in .24s cubic-bezier(.16,1,.3,1);
}
@keyframes toast-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.toast.hiding{opacity:0;transform:translateY(8px);transition:opacity .2s,transform .2s}
.toast .d-flex{align-items:center}
.toast-body{padding:13px 8px 13px 16px;font-size:14px;font-weight:700;flex:1}
.toast.bg-green{background:var(--ok)} .toast.bg-red{background:var(--bad)}
.toast.bg-yellow{background:#8A5A00} .toast.bg-blue{background:var(--info)}

/* ==========================================================================
   11 · MISC COMPONENTS
   ========================================================================== */
.alert{padding:13px 16px;border-radius:var(--radius-md);font-size:14px;margin-bottom:14px}
.alert-info{background:var(--info-bg);color:var(--info)}
.alert-warning{background:var(--acc-200);color:#9A4100}
.alert-danger{background:var(--bad-bg);color:var(--bad)}

.list-group{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}
.list-group-item{padding:13px 20px;border-bottom:1px solid var(--canvas)}
.list-group-item:last-child{border-bottom:0}
.list-group-flush .list-group-item{padding-left:0;padding-right:0}

.nav-tabs{display:flex;gap:4px;flex-wrap:wrap;list-style:none;margin:0;padding:0;border:0}
.nav-tabs .nav-link{
  border-radius:var(--pill);padding:8px 16px;color:var(--ink-600);
  font-size:14px;background:transparent;
}
.nav-tabs .nav-link:hover{background:var(--canvas);color:var(--ink)}
.nav-tabs .nav-link.active{background:var(--ink);color:var(--white)}
.card-header-tabs{margin:0}

.avatar{
  width:38px;height:38px;flex:none;border-radius:var(--pill);
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:900;font-size:14px;
}
/* Only an avatar with no bg-* class of its own gets the default deep disc —
   otherwise this would flatten the severity colours the dashboard alerts use
   to distinguish "damaged" from "low stock" at a glance. */
.avatar:not([class*="bg-"]){background:var(--icon-bg);color:var(--white)}
.avatar-md{width:46px;height:46px;font-size:18px}
.avatar[class*="bg-"]{font-size:19px}

.spinner-border{
  display:inline-block;width:20px;height:20px;border:2.5px solid var(--surface);
  border-top-color:var(--accent);border-radius:var(--pill);
  animation:spin .7s linear infinite;vertical-align:-3px;
}
.spinner-border-sm{width:14px;height:14px;border-width:2px}
@keyframes spin{to{transform:rotate(360deg)}}

.empty-state{text-align:center;padding:56px 16px;color:var(--ink-500)}
.empty-state i{font-size:44px;color:var(--ink-300);display:block;margin-bottom:12px}
.empty-state p{margin:0}

/* ==========================================================================
   12 · LAYER 3 — the asset tag (single asset detail header)
   The same tag stuck to the physical device, so screen and desk agree.
   ========================================================================== */
.asset-tag{
  background:var(--white);border-radius:var(--radius-lg);overflow:hidden;
  box-shadow:var(--shadow-sm);margin-bottom:16px;
}
.asset-tag .tag-band{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 18px;background:var(--accent);color:var(--white);
}
.asset-tag .tag-band.is-flagged{background:var(--ink)}
.asset-tag .tag-band.is-bulk{background:var(--icon-bg)}
.asset-tag .tag-no{font-size:15px;font-weight:900;letter-spacing:.12em;
  font-variant-numeric:tabular-nums}
.asset-tag .tag-kind{font-size:10.5px;font-weight:900;letter-spacing:.14em;
  text-transform:uppercase;opacity:.94}
.asset-tag .tag-main{padding:18px 20px}
.asset-tag .tag-name{font-size:21px;font-weight:900;letter-spacing:-.015em}
.asset-tag .tag-serial{font-size:13.5px;font-weight:700;letter-spacing:.09em;
  color:var(--ink-600);font-variant-numeric:tabular-nums;margin-top:4px}
.asset-tag .tag-fields{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;
  background:var(--canvas);border-top:1px solid var(--canvas);
}
.asset-tag .tag-fields > div{background:var(--white);padding:12px 20px}
.asset-tag .tag-fields dt{font-size:10.5px;font-weight:900;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-500)}
.asset-tag .tag-fields dd{margin:3px 0 0;font-size:15px;font-weight:700;
  font-variant-numeric:tabular-nums}
.asset-tag .tag-bars{display:flex;align-items:flex-end;gap:2px;height:30px;
  padding:14px 20px 16px}
.asset-tag .tag-bars i{display:block;width:2px;background:var(--ink);border-radius:1px}

/* ==========================================================================
   13 · LAYER 2 — the working paper (Reports, and anything printed for audit)
   A schedule, not app chrome. State is a MARK, so it survives a black-and-white
   printout and does not depend on colour vision.
   ========================================================================== */
.working-paper{background:var(--canvas);padding:4px 0 0}
.working-paper .wp-head{
  display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;
  padding-bottom:12px;border-bottom:2px solid var(--ink);
}
.working-paper .wp-head h2{font-size:22px;font-weight:900;letter-spacing:-.02em}
.working-paper .wp-head .wp-sub{
  font-size:11.5px;font-weight:400;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-600);margin-top:5px;
}
.working-paper .wp-ref{display:grid;grid-template-columns:auto auto;gap:2px 18px;
  font-size:12.5px;text-align:right}
.working-paper .wp-ref dt{color:var(--ink-600);font-weight:400;margin:0}
.working-paper .wp-ref dd{margin:0;font-weight:700;font-variant-numeric:tabular-nums}

.working-paper .wp-legend{
  display:flex;flex-wrap:wrap;gap:20px;padding:12px 0 18px;
  border-bottom:1px solid var(--surface);font-size:12.5px;color:var(--ink-600);
}
.working-paper .wp-legend span{display:inline-flex;align-items:center;gap:7px}
.wp-mark{width:18px;height:18px;flex:none;color:var(--accent)}
.wp-mark svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.wp-mark.is-quiet{color:var(--ink-400)}

/* The schedule itself: ruled, not carded. */
.working-paper .table{background:transparent;font-size:14px}
.working-paper .card{background:transparent;box-shadow:none;border-radius:0}
.working-paper .card-header{border:0;padding:22px 0 8px;background:transparent}
.working-paper .card-title{font-size:12px;font-weight:900;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-600)}
.working-paper .table th{border-bottom:1px solid var(--ink);padding:0 12px 8px}
.working-paper .table td{padding:11px 12px;border-bottom:1px solid var(--ink-200)}
.working-paper .table tbody tr:last-child td{border-bottom:1px solid var(--ink-200)}
.working-paper .table tbody tr:hover{background:var(--white)}
/* A cast total is closed with the accounting double rule. */
.working-paper .wp-total td{
  border-top:1px solid var(--ink);border-bottom:3px double var(--ink);
  font-weight:900;font-variant-numeric:tabular-nums;padding-top:13px;
}
.working-paper .wp-sign{display:flex;gap:52px;margin-top:44px;font-size:12.5px;
  color:var(--ink-600);flex-wrap:wrap}
.working-paper .wp-sign > div{flex:1;min-width:180px;max-width:240px;
  border-top:1px solid var(--ink);padding-top:7px}
.working-paper .wp-sign b{display:block;color:var(--ink);font-size:13.5px}

/* ==========================================================================
   14 · ROLE + RESPONSIVE
   ========================================================================== */
/* HR is read-only. The API enforces it; this stops HR seeing controls that
   would only fail. */
body.role-hr [data-edit],body.role-hr [data-del],body.role-hr [data-return],
body.role-hr [data-damage],body.role-hr [data-repair],body.role-hr [data-repair-complete],
body.role-hr [data-sell],body.role-hr [data-bulk-return],body.role-hr [data-bulk-replace],
body.role-hr [data-bulk-sell],body.role-hr [data-add-serials-line],
body.role-hr [data-bs-toggle="dropdown"],
body.role-hr #btn-add,body.role-hr #btn-bulk,body.role-hr #btn-add-line,
body.role-hr #btn-save,body.role-hr #btn-delete,body.role-hr #btn-recalc-total,
body.role-hr a[href="#/invoices/new"],body.role-hr a[href^="#/onboarding"],
body.role-hr .btn-danger,body.role-hr .action-write,
body.role-hr .quick-action-admin{display:none!important}

.navbar-toggler{display:none;width:40px;height:40px;border:0;background:transparent;
  color:var(--white);cursor:pointer;border-radius:var(--radius-sm)}
.navbar-toggler-icon{display:block;width:20px;height:2px;background:currentColor;
  position:relative;margin:0 auto;border-radius:1px}
.navbar-toggler-icon::before,.navbar-toggler-icon::after{
  content:"";position:absolute;left:0;width:20px;height:2px;background:currentColor;border-radius:1px}
.navbar-toggler-icon::before{top:-6px} .navbar-toggler-icon::after{top:6px}

@media (max-width:991.98px){
  .page{flex-direction:column}
  .navbar-vertical{width:100%;padding:12px 16px}
  .navbar-vertical .container-fluid{flex-direction:row;flex-wrap:wrap;align-items:center}
  .navbar-brand{margin:0;flex:1}
  .navbar-toggler{display:block}
  .navbar-collapse{flex-basis:100%;display:none;padding-top:12px}
  .navbar-collapse.show{display:block}
  .container-xl,.container-fluid{padding:0 16px}
  .page-title{font-size:22px}
}
@media (min-width:992px){ .navbar-collapse{display:flex!important;flex-direction:column;flex:1} }

/* ==========================================================================
   15 · PRINT — the audit artefact
   ========================================================================== */
@media print{
  @page{margin:14mm}
  body{background:#fff;color:#000;font-size:10.5pt}
  .navbar-vertical,.page-wrapper > .navbar,#page-actions,.toast-container,
  .footer,.dropdown,.btn,#report-tabs,[data-print],[data-csv],
  #role-switcher,.navbar-toggler,.d-print-none{display:none!important}
  .page,.page-wrapper{display:block}
  .page-body{padding:0}
  .container-xl{max-width:100%;padding:0}
  .card{box-shadow:none;border:1px solid #999;break-inside:avoid;border-radius:0}
  .card-header{background:none;border-bottom:1px solid #999}
  .table th{color:#000;border-bottom:1px solid #000}
  .table td{border-bottom:1px solid #bbb}
  .badge{background:none!important;color:#000!important;
    box-shadow:inset 0 0 0 1px #000;font-weight:700}
  /* Marks are strokes, so they survive with no colour at all. */
  .wp-mark{color:#000}
  .working-paper .card{border:0}
  .working-paper .wp-head{border-bottom:2px solid #000}
  .working-paper .table th,.working-paper .wp-total td{border-color:#000}
  a{color:#000;text-decoration:none}
}
