/* ============================================================================
   bi-v2.css - WafiLife BI progressive modernization
   ----------------------------------------------------------------------------
   Loaded AFTER AdminLTE.min.css in index.html. Every rule is scoped under the
   `bi-v2` class on <body>, so removing that one word from index.html reverts
   the entire application to the original AdminLTE look with no other change.

     1  Tokens
     2  Typography
     3  Widgets   (phase 1 - restyles what every existing screen already uses)
     4  Content surface
     5  Shell     (phase 2 - the light sidebar + thin topbar)
     6  v2 pages  (phase 3 - the `biv2-*` chrome the rebuilt templates use)
     7  Legacy screens (maps the untouched AdminLTE templates onto the v2 idiom)
     8  Scrollbars

   Sections 1-4 touch no markup at all. Section 5 goes with the rewritten
   navmenu/siteheader templates; delete it and the old dark shell comes back.

   AdminLTE declares its label/background utilities with `!important`, so the
   overrides that replace them have to carry `!important` too. That is not
   decoration - without it the saturated originals win.
   ========================================================================= */


/* -- 1. Tokens ----------------------------------------------------------- */

.bi-v2 {
  --bi-bg:            #f6f5f3;   /* content surface   (was #ecf0f5) */
  --bi-surface:       #ffffff;
  --bi-surface-alt:   #faf9f7;   /* table heads, footers, inputs    */
  --bi-border:        #e6e3de;   /* card + table rules (was #d2d6de)*/
  --bi-border-input:  #e0dcd5;
  --bi-row-rule:      #f6f4f0;   /* between table rows              */

  --bi-accent:        #b8650f;   /* was #f29434 / #3c8dbc           */
  --bi-accent-hover:  #8a4a08;
  --bi-accent-tint:   #f4ece2;
  --bi-accent-ink:    #8f4a12;

  --bi-text:          #1f1d1a;   /* was #333333 */
  --bi-text-soft:     #4a463f;
  --bi-muted:         #8a8478;   /* was #777777 */
  --bi-faint:         #a39c90;
  --bi-fainter:       #b8b0a2;

  --bi-ok-tint:       #e8f2ea;  --bi-ok-ink:      #2f6b46;
  --bi-info-tint:     #e6eef5;  --bi-info-ink:    #2c5d86;
  --bi-warn-tint:     #f7ecea;  --bi-warn-ink:    #8f2c20;
  --bi-neutral-tint:  #f0eee9;  --bi-neutral-ink: #6f6a63;
  --bi-alt-tint:      #efeaf3;  --bi-alt-ink:     #5a4573;

  --bi-mono: ui-monospace, Menlo, Consolas, monospace;

  /* Type scale - the single place to retune the whole UI's text size.
     Raised ~12% over the original v2 values (body text was 12.5px) after
     users reported the interface read too small. Old value in each comment. */
  --bi-fs-head:  10.5px;  /* mono uppercase table heads   (was 9.5) */
  --bi-fs-micro: 11px;    /* counters, tiny badges        (was 10)  */
  --bi-fs-mini:  12px;    /* dense chrome                 (was 10.5)*/
  --bi-fs-xs:    12.5px;  /* labels, status pills         (was 11)  */
  --bi-fs-sm:    13px;    /* meta / secondary text        (was 11.5)*/
  --bi-fs-md:    13.5px;  /* small buttons, input-sm      (was 12)  */
  --bi-fs-base:  14px;    /* body, table cells, buttons   (was 12.5)*/
  --bi-fs-lg:    14.5px;  /* form controls                (was 13)  */
  --bi-fs-xl:    15px;    /* emphasis                     (was 13.5)*/
  --bi-fs-2xl:   15.5px;  /* section leads                (was 14)  */
}


/* -- 2. Typography ------------------------------------------------------- */

/* Noto Sans Bengali sits IN the stack rather than on a `.bn` class, so every
   Bengali product / publisher / author name in the catalogue picks it up with
   no template change anywhere. */
.bi-v2,
.bi-v2 .btn,
.bi-v2 input,
.bi-v2 select,
.bi-v2 textarea,
.bi-v2 .form-control {
  font-family: 'Source Sans 3', 'Source Sans Pro', 'Noto Sans Bengali',
               'Helvetica Neue', Helvetica, Arial, sans-serif;
}

.bi-v2 {
  color: var(--bi-text);
  font-size: var(--bi-fs-base);
  -webkit-font-smoothing: antialiased;
}

.bi-v2 .text-muted,
.bi-v2 small,
.bi-v2 .small { color: var(--bi-muted); }

.bi-v2 a         { color: var(--bi-accent); }
.bi-v2 a:hover,
.bi-v2 a:focus   { color: var(--bi-accent-hover); }

.bi-v2 h1, .bi-v2 h2, .bi-v2 h3, .bi-v2 h4, .bi-v2 h5 {
  letter-spacing: -.015em;
  font-weight: 600;
}


/* -- 3. Widgets ---------------------------------------------------------- */

/* .box - the container every screen builds out of */
.bi-v2 .box {
  border-radius: 9px;
  border: 1px solid var(--bi-border);
  border-top: 2px solid var(--bi-border);
  box-shadow: none;
  background: var(--bi-surface);
}
.bi-v2 .box.box-primary { border-top-color: var(--bi-accent); }
.bi-v2 .box.box-info    { border-top-color: var(--bi-info-ink); }
.bi-v2 .box.box-success { border-top-color: var(--bi-ok-ink); }
.bi-v2 .box.box-warning { border-top-color: var(--bi-accent-ink); }
.bi-v2 .box.box-danger  { border-top-color: var(--bi-warn-ink); }

.bi-v2 .box-header { padding: 13px 16px; color: var(--bi-text); }
.bi-v2 .box-header.with-border { border-bottom: 1px solid var(--bi-row-rule); }
.bi-v2 .box-title { font-size: 17px; font-weight: 600; letter-spacing: -.01em; }

.bi-v2 .box-body { padding: 14px 16px; }

.bi-v2 .box-footer {
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-border);
  border-radius: 0 0 8px 8px;
  padding: 10px 16px;
  color: var(--bi-muted);
}
.bi-v2 .box-footer.text-center a { font-weight: 600; text-transform: none; }

/* .info-box - the dashboard stat card. The 90px saturated icon block becomes a
   small tinted square; the card itself takes the v2 accent rail. */
.bi-v2 .info-box {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-left: 3px solid var(--bi-accent);
  border-radius: 9px;
  box-shadow: none;
  min-height: 78px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.bi-v2 .info-box-icon {
  float: none;
  flex: none;
  width: 40px;
  height: 40px;
  line-height: 40px;
  font-size: 19px;
  border-radius: 9px;
  background: var(--bi-neutral-tint) !important;
  color: var(--bi-neutral-ink) !important;
}
.bi-v2 .info-box-icon.bg-green,
.bi-v2 .info-box-icon.bg-green-active { background: var(--bi-ok-tint) !important;      color: var(--bi-ok-ink) !important; }
.bi-v2 .info-box-icon.bg-aqua,
.bi-v2 .info-box-icon.bg-blue,
.bi-v2 .info-box-icon.bg-light-blue    { background: var(--bi-info-tint) !important;   color: var(--bi-info-ink) !important; }
.bi-v2 .info-box-icon.bg-yellow,
.bi-v2 .info-box-icon.bg-orange        { background: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important; }
.bi-v2 .info-box-icon.bg-red,
.bi-v2 .info-box-icon.bg-maroon        { background: var(--bi-warn-tint) !important;   color: var(--bi-warn-ink) !important; }

.bi-v2 .info-box-content { margin-left: 0; padding: 0; flex: 1; min-width: 0; }
.bi-v2 .info-box-text {
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  text-transform: none;
  color: var(--bi-muted);
  letter-spacing: 0;
}
.bi-v2 .info-box-number {
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--bi-text);
}
.bi-v2 .info-box-number + .info-box-number {
  font-size: var(--bi-fs-base);
  font-weight: 400;
  color: var(--bi-muted);
}

/* Tables - quiet horizontal rules, mono uppercase heads */
.bi-v2 .table > thead > tr > th {
  background: var(--bi-surface-alt);
  border-bottom: 1px solid var(--bi-border);
  border-top: none;
  font-family: var(--bi-mono);
  font-size: var(--bi-fs-head);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bi-faint);
  padding: 8px 12px;
  vertical-align: middle;
}
.bi-v2 .table > tbody > tr > td {
  border-top: 1px solid var(--bi-row-rule);
  padding: 9px 12px;
  vertical-align: top;
}
.bi-v2 .table > tbody > tr:hover > td { background: var(--bi-surface-alt); }
.bi-v2 .table-striped > tbody > tr:nth-of-type(odd) { background: #fdfcfa; }

/* .table-bordered draws a full cell grid; horizontal rules alone read better
   in the dense order/product grids. */
.bi-v2 .table-bordered,
.bi-v2 .table-bordered > thead > tr > th,
.bi-v2 .table-bordered > tbody > tr > td,
.bi-v2 .table-bordered > tbody > tr > th { border: none; }
.bi-v2 .table-bordered > thead > tr > th { border-bottom: 1px solid var(--bi-border); }
.bi-v2 .table-bordered > tbody > tr > td,
.bi-v2 .table-bordered > tbody > tr > th { border-top: 1px solid var(--bi-row-rule); }

.bi-v2 td.number, .bi-v2 th.number { font-variant-numeric: tabular-nums; }

/* Buttons */
.bi-v2 .btn {
  border-radius: 8px;
  font-size: var(--bi-fs-base);
  font-weight: 600;
  box-shadow: none;
  padding: 7px 13px;
  border: 1px solid transparent;
}
.bi-v2 .btn-sm, .bi-v2 .btn-xs { border-radius: 7px; font-size: var(--bi-fs-md); padding: 5px 10px; }
.bi-v2 .btn:focus, .bi-v2 .btn:active:focus { outline: none; box-shadow: 0 0 0 3px var(--bi-accent-tint); }

.bi-v2 .btn-default {
  background: var(--bi-surface);
  border-color: var(--bi-border-input);
  color: var(--bi-text-soft);
}
.bi-v2 .btn-default:hover, .bi-v2 .btn-default:focus { background: var(--bi-surface-alt); border-color: var(--bi-faint); color: var(--bi-text); }

.bi-v2 .btn-primary,
.bi-v2 .btn-primary:focus {
  background: var(--bi-accent);
  border-color: var(--bi-accent);
  color: #fff;
}
.bi-v2 .btn-primary:hover, .bi-v2 .btn-primary:active { background: var(--bi-accent-hover); border-color: var(--bi-accent-hover); }

.bi-v2 .btn-success { background: var(--bi-ok-ink);   border-color: var(--bi-ok-ink);   color: #fff; }
.bi-v2 .btn-danger  { background: var(--bi-warn-ink); border-color: var(--bi-warn-ink); color: #fff; }
.bi-v2 .btn-warning { background: var(--bi-accent-ink); border-color: var(--bi-accent-ink); color: #fff; }
.bi-v2 .btn-info    { background: var(--bi-info-ink); border-color: var(--bi-info-ink); color: #fff; }
.bi-v2 .btn-link    { color: var(--bi-accent); font-weight: 600; }

/* The dashboard/report date search button is hard-coded blue in styles.css. */
.bi-v2 .date .btn,
.bi-v2 .date-search,
.bi-v2 .date-search:hover {
  background-color: var(--bi-accent);
  border-color: var(--bi-accent);
  color: #fff;
}

/* Form controls */
.bi-v2 .form-control,
.bi-v2 .input-group-addon {
  border-radius: 7px;
  border-color: var(--bi-border-input);
  background: var(--bi-surface-alt);
  color: var(--bi-text);
  box-shadow: none;
  font-size: var(--bi-fs-lg);
}
.bi-v2 .form-control:focus {
  border-color: var(--bi-accent);
  box-shadow: 0 0 0 3px var(--bi-accent-tint);
  background: var(--bi-surface);
}
.bi-v2 .form-control::placeholder { color: var(--bi-fainter); }
.bi-v2 .input-group-addon { background: var(--bi-neutral-tint); }
.bi-v2 label { font-weight: 600; font-size: var(--bi-fs-base); color: var(--bi-text-soft); }

/* ng-select is used across the filter bars; keep it in the same family. */
.bi-v2 .ng-select .ng-select-container {
  border-radius: 7px;
  border-color: var(--bi-border-input);
  background: var(--bi-surface-alt);
  min-height: 34px;
}
.bi-v2 .ng-select.ng-select-focused > .ng-select-container {
  border-color: var(--bi-accent);
  box-shadow: 0 0 0 3px var(--bi-accent-tint);
}

/* ── bi-datepicker ─────────────────────────────────────────────────────────
   The shared picker (used on ~78 templates) still draws itself as a <table> of
   three separately bordered cells - icon / field / clear - which is a pre-bi-v2
   shape: 36px tall against 32px inputs, square corners against 7px ones, and
   #d2d6de against the warm border token. Its field is readonly, so it also
   picked up the greyed-out [readonly] fill and read as disabled next to live
   controls, and the focus ring landed on that invisible inner input rather than
   on the box you can see.

   Restyled from here rather than from the component so every page moves at
   once and no template has to change: the host element takes the one border,
   the cells give theirs up. */
.bi-v2 bi-datepicker {
  display: block;
  border: 1px solid var(--bi-border-input);
  border-radius: 7px;
  background: var(--bi-surface-alt);
}
.bi-v2 bi-datepicker:focus-within {
  border-color: var(--bi-accent);
  box-shadow: 0 0 0 3px var(--bi-accent-tint);
}
/* the cells carry their borders and padding inline, hence the !important */
/* Every rule below excludes `.md-drppicker` descendants, because the calendar is
   rendered INSIDE the field row's middle cell: a plain `bi-datepicker td` /
   `bi-datepicker .btn` reaches the day cells and the Apply/Cancel buttons too,
   and the field's own chrome (no border, no padding, quiet ghost button) is the
   wrong look for either. The exclusion is written against the calendar rather
   than as a `> table > tr > td` child chain because the field's table is built
   by Angular and so has no <tbody> - a chain would have to guess. */
.bi-v2 bi-datepicker table:not(.md-drppicker table) { width: 100%; margin: 0; }
.bi-v2 bi-datepicker td:not(.md-drppicker td) { border: none !important; padding: 0 !important; }
.bi-v2 bi-datepicker td:not(.md-drppicker td):first-child { padding: 0 0 0 9px !important; }
.bi-v2 bi-datepicker td:not(.md-drppicker td):first-child .fa { font-size: var(--bi-fs-md); color: var(--bi-faint); }
/* readonly is how the control is meant to work - the calendar is the only way
   to edit it - so it must not take the disabled-looking [readonly] fill. */
.bi-v2 bi-datepicker .form-control,
.bi-v2 bi-datepicker .form-control[readonly] {
  height: 30px;
  padding: 3px 9px;
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--bi-text);
  cursor: pointer;
}
/* the clear (×) button in the field's last cell - NOT the calendar's Apply and
   Cancel, which sit further down the same cell tree */
.bi-v2 bi-datepicker .btn:not(.md-drppicker .btn) {
  padding: 0 9px 0 3px;
  height: 28px;
  line-height: 1;
  font-size: var(--bi-fs-md);
  border: none;
  background: none;
  box-shadow: none;
  color: var(--bi-faint);
}
.bi-v2 bi-datepicker .btn:not(.md-drppicker .btn):hover,
.bi-v2 bi-datepicker .btn:not(.md-drppicker .btn):focus { background: none; color: var(--bi-text); }

/* The calendar itself is ViewEncapsulation.None Material - indigo #3f51b5 for
   the selected day, the range and the buttons, Roboto, uppercase 2px-radius
   buttons under a heavy shadow. Its rules are plain (no /deep/ attributes), so
   prefixing with .bi-v2 is enough to win on specificity. */
.bi-v2 .md-drppicker {
  font-family: inherit;
  font-size: var(--bi-fs-lg);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
  color: var(--bi-text);
  /* The library pulls the panel up by 10px, so it lands ON the field it drops
     from and hides its bottom edge. Sit it clear instead. */
  margin-top: 4px;
}
/* A picker set to drop upwards gets an explicit `top`, so the same gap has to
   be taken off that edge rather than added to it. */
.bi-v2 .md-drppicker[class*="drops-up"] { margin-top: -4px; }
.bi-v2 .md-drppicker .calendar-table { background: none; border: none; }
.bi-v2 .md-drppicker th { color: var(--bi-muted); font-weight: 600; }
.bi-v2 .md-drppicker td.available:hover,
.bi-v2 .md-drppicker th.available:hover { background-color: var(--bi-neutral-tint); }
.bi-v2 .md-drppicker td.in-range { background-color: var(--bi-accent-tint); color: var(--bi-accent-ink); }
.bi-v2 .md-drppicker td.active,
.bi-v2 .md-drppicker td.active:hover { background-color: var(--bi-accent); color: #fff; }
.bi-v2 .md-drppicker td.off,
.bi-v2 .md-drppicker td.off.in-range,
.bi-v2 .md-drppicker td.off.start-date,
.bi-v2 .md-drppicker td.off.end-date { background: none; color: var(--bi-fainter); }
.bi-v2 .md-drppicker td.week,
.bi-v2 .md-drppicker th.week { color: var(--bi-fainter); }
.bi-v2 .md-drppicker .show-ranges .drp-calendar.left { border-left-color: var(--bi-border); }
/* the named ranges down the side read like the .biv2-pill row, not like a
   solid indigo block */
.bi-v2 .md-drppicker .ranges ul li button { font-size: var(--bi-fs-base); border-radius: 6px; }
.bi-v2 .md-drppicker .ranges ul li:hover { background-color: transparent; }
.bi-v2 .md-drppicker .ranges ul li button:hover { background-color: var(--bi-neutral-tint); }
.bi-v2 .md-drppicker .ranges ul li button.active {
  background-color: var(--bi-accent-tint);
  color: var(--bi-accent-ink);
  font-weight: 600;
}
.bi-v2 .md-drppicker .dropdowns select { border-color: var(--bi-border-input); border-radius: 6px; }
.bi-v2 .md-drppicker .label-input { border-color: var(--bi-border-input); border-radius: 7px; color: var(--bi-text); }
.bi-v2 .md-drppicker .label-input.active { border-color: var(--bi-accent); border-radius: 7px; }
.bi-v2 .md-drppicker .btn {
  border-radius: 7px;
  padding: 0 13px;
  line-height: 30px;
  font-size: var(--bi-fs-base);
  font-weight: 600;
  text-transform: none;
  box-shadow: none;
  background-color: var(--bi-accent);
  color: #fff;
}
.bi-v2 .md-drppicker .btn:hover,
.bi-v2 .md-drppicker .btn:focus { background-color: var(--bi-accent-hover); }
/* Cancel / Clear are the quiet pair beside Apply */
.bi-v2 .md-drppicker .btn.btn-default {
  background-color: var(--bi-surface);
  border: 1px solid var(--bi-border-input);
  color: var(--bi-text-soft);
}
.bi-v2 .md-drppicker .btn.btn-default:hover,
.bi-v2 .md-drppicker .btn.btn-default:focus {
  background-color: var(--bi-surface-alt);
  border-color: var(--bi-faint);
  color: var(--bi-text);
}
.bi-v2 .md-drppicker .btn.btn-default svg { fill: currentColor; }

/* The calendar is `position:absolute` and the library positions it with a left
   offset measured from the field's offsetParent - so it lands under the field
   only when the field's own wrapper is the nearest positioned ancestor. The
   pre-bi-v2 pages got that for free: the picker sat in an AdminLTE `.box`,
   which is `position:relative`. The v2 filter bar and panel head are not, so
   the calendar fell through to the Bootstrap column and opened at the content's
   left edge, on top of the bar it belongs to. Anchoring the wrapper puts it
   back under the field.

   Only wrappers that actually hold a picker are anchored: making the calendar's
   containing block a descendant of a scrolling or clipping box would let that
   box cut the calendar off, which is why the panel that holds one also has to
   stop clipping (same reason as `.is-unclipped`). */
.bi-v2 .biv2-filter-date,
.bi-v2 .biv2-panel-date { position: relative; }
/* The form-field wrapper is generic, so only the ones holding a picker are
   anchored - and, as elsewhere in this file, the `:has()` selectors keep their
   own rules so a browser without support drops only those. */
.bi-v2 .biv2-field:has(> bi-datepicker) { position: relative; }
.bi-v2 .biv2-panel:has(bi-datepicker) { overflow: visible; }

/* Labels - pills. AdminLTE sets both the background and the colour with
   !important, on .label-* AND on the .bg-* utilities the order/product grids
   use, so every replacement below has to match that weight. */
.bi-v2 .label {
  border-radius: 20px;
  padding: 3px 9px;
  font-size: var(--bi-fs-xs);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.5;
  display: inline-block;
}
/* The order grid tags rows with the whole AdminLTE colour set, `-active`
   variants included. Every one of them needs a home here or the saturated
   original survives next to the new pills. */
.bi-v2 .label-default,
.bi-v2 .label.bg-gray, .bi-v2 .label.bg-gray-active,
.bi-v2 .label.bg-black, .bi-v2 .label.bg-black-active,
.bi-v2 .label.bg-navy, .bi-v2 .label.bg-navy-active {
  background-color: var(--bi-neutral-tint) !important; color: var(--bi-neutral-ink) !important;
}
.bi-v2 .label-success,
.bi-v2 .label.bg-green, .bi-v2 .label.bg-green-active,
.bi-v2 .label.bg-olive, .bi-v2 .label.bg-olive-active,
.bi-v2 .label.bg-teal, .bi-v2 .label.bg-teal-active,
.bi-v2 .label.bg-lime, .bi-v2 .label.bg-lime-active {
  background-color: var(--bi-ok-tint) !important; color: var(--bi-ok-ink) !important;
}
.bi-v2 .label-info, .bi-v2 .label-primary,
.bi-v2 .label.bg-aqua, .bi-v2 .label.bg-aqua-active,
.bi-v2 .label.bg-blue, .bi-v2 .label.bg-blue-active,
.bi-v2 .label.bg-light-blue, .bi-v2 .label.bg-light-blue-active {
  background-color: var(--bi-info-tint) !important; color: var(--bi-info-ink) !important;
}
.bi-v2 .label-warning,
.bi-v2 .label.bg-yellow, .bi-v2 .label.bg-yellow-active,
.bi-v2 .label.bg-orange, .bi-v2 .label.bg-orange-active {
  background-color: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important;
}
.bi-v2 .label-danger,
.bi-v2 .label.bg-red, .bi-v2 .label.bg-red-active,
.bi-v2 .label.bg-maroon, .bi-v2 .label.bg-maroon-active {
  background-color: var(--bi-warn-tint) !important; color: var(--bi-warn-ink) !important;
}
/* Purple/fuchsia carry their own meaning in the order grid (tracking requests),
   so they keep a distinct hue rather than collapsing into the red bucket. */
.bi-v2 .label.bg-purple, .bi-v2 .label.bg-purple-active,
.bi-v2 .label.bg-fuchsia, .bi-v2 .label.bg-fuchsia-active {
  background-color: var(--bi-alt-tint) !important; color: var(--bi-alt-ink) !important;
}

/* Order/product grids also colour labels with inline style="background:#00c0ef";
   nothing can be done about those without touching markup, so they stay. */

.bi-v2 .badge {
  background: var(--bi-neutral-tint);
  color: var(--bi-neutral-ink);
  font-weight: 600;
  border-radius: 20px;
}

/* Tabs, alerts, modals, pagination */
.bi-v2 .nav-tabs { border-bottom: 1px solid var(--bi-border); }
.bi-v2 .nav-tabs > li > a { border: none; color: var(--bi-muted); font-weight: 600; font-size: var(--bi-fs-lg); border-radius: 0; }
.bi-v2 .nav-tabs > li.active > a,
.bi-v2 .nav-tabs > li.active > a:hover,
.bi-v2 .nav-tabs > li.active > a:focus {
  border: none;
  border-bottom: 2px solid var(--bi-accent);
  color: var(--bi-accent);
  background: transparent;
}
.bi-v2 .nav-tabs-custom { border-radius: 9px; box-shadow: none; border: 1px solid var(--bi-border); }

.bi-v2 .alert { border-radius: 9px; border: 1px solid transparent; }
.bi-v2 .alert-warning { background-color: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important; border-color: #ead9c4; }
.bi-v2 .alert-danger, .bi-v2 .alert-error { background-color: var(--bi-warn-tint) !important; color: var(--bi-warn-ink) !important; border-color: #eed4cf; }
.bi-v2 .alert-success { background-color: var(--bi-ok-tint) !important; color: var(--bi-ok-ink) !important; border-color: #d3e6d8; }
.bi-v2 .alert-info { background-color: var(--bi-info-tint) !important; color: var(--bi-info-ink) !important; border-color: #d3e0ec; }

.bi-v2 .modal-content { border-radius: 11px; border: 1px solid var(--bi-border); box-shadow: 0 12px 40px rgba(0,0,0,.16); }
.bi-v2 .modal-header { border-bottom: 1px solid var(--bi-row-rule); padding: 14px 18px; }
.bi-v2 .modal-title { font-size: 18px; font-weight: 600; }
.bi-v2 .modal-footer { border-top: 1px solid var(--bi-row-rule); background: var(--bi-surface-alt); border-radius: 0 0 10px 10px; }

.bi-v2 .pagination > li > a,
.bi-v2 .pagination > li > span { border-color: var(--bi-border); color: var(--bi-text-soft); }
.bi-v2 .pagination > .active > a,
.bi-v2 .pagination > .active > a:hover,
.bi-v2 .pagination > .active > span { background: var(--bi-accent); border-color: var(--bi-accent); color: #fff; }

.bi-v2 .progress-bar { background-color: var(--bi-accent); }

/* Shared helpers already in styles.css */
.bi-v2 .filter-drawer { border-left: 1px solid var(--bi-border); }
.bi-v2 .filter-drawer-footer { background: var(--bi-surface-alt); border-top: 1px solid var(--bi-border); }


/* -- 4. Content surface -------------------------------------------------- */

.bi-v2 .content-wrapper { background: var(--bi-bg); }
.bi-v2 .content-header { padding: 15px 15px 0; }


/* -- 5. Shell ------------------------------------------------------------ */
/* Replaces AdminLTE's 230px dark sidebar + 50px orange navbar with the design's
   236px full-height light sidebar and a 52px white topbar. Goes with the
   rewritten navmenu.component / siteheader.component templates. */

.bi-v2 .main-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 236px;
  padding-top: 0;
  min-height: 100%;
  background-color: var(--bi-surface);
  border-right: 1px solid var(--bi-border);
  z-index: 1035;
  display: flex;
  flex-direction: column;
}

.bi-v2 .content-wrapper,
.bi-v2 .main-footer { margin-left: 236px; }

.bi-v2 .main-header { z-index: 1030; }
.bi-v2 .main-header .logo { display: none; }
.bi-v2 .main-header .navbar {
  margin-left: 236px;
  min-height: 52px;
  height: 52px;
  background-color: var(--bi-surface) !important;
  border-bottom: 1px solid var(--bi-border);
  display: flex;
  align-items: center;
  padding: 0 8px 0 4px;
}

.bi-v2 .main-footer {
  background: var(--bi-surface);
  border-top: 1px solid var(--bi-border);
  color: var(--bi-muted);
  font-size: var(--bi-fs-base);
  padding: 12px 20px;
}

/* Topbar bits */
.bi-v2 .biv2-toggle {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  color: var(--bi-faint) !important;
  background: transparent !important;
  font-size: var(--bi-fs-2xl);
  padding: 0 !important;
}
.bi-v2 .biv2-toggle:hover { background: var(--bi-neutral-tint) !important; color: var(--bi-text) !important; }

.bi-v2 .biv2-crumb {
  font-size: var(--bi-fs-xl);
  font-weight: 600;
  color: var(--bi-text);
  padding-left: 6px;
  letter-spacing: -.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Sidebar: brand */
.bi-v2 .biv2-brand {
  flex: none;
  height: 52px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 14px;
  border-bottom: 1px solid var(--bi-border);
}
.bi-v2 .biv2-mark {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 7px;
  background: var(--bi-accent);
  color: #fff;
  display: grid; place-items: center;
  font-weight: 700; font-size: var(--bi-fs-lg);
}
.bi-v2 .biv2-brand-text { line-height: 1.1; min-width: 0; }
.bi-v2 .biv2-brand-text b { display: block; font-weight: 600; font-size: var(--bi-fs-xl); letter-spacing: -.01em; white-space: nowrap; }
.bi-v2 .biv2-brand-text span { display: block; font-size: var(--bi-fs-mini); color: var(--bi-faint); }

/* Sidebar: search */
.bi-v2 .biv2-search { flex: none; padding: 10px 10px 4px; position: relative; }
.bi-v2 .biv2-search > .fa {
  position: absolute; left: 19px; top: 19px;
  font-size: var(--bi-fs-xs); color: var(--bi-faint); pointer-events: none;
}
.bi-v2 .biv2-search input {
  width: 100%; height: 30px;
  border: 1px solid var(--bi-border-input);
  border-radius: 7px;
  background: var(--bi-surface-alt);
  padding: 0 42px 0 27px;
  font-size: var(--bi-fs-base);
  color: var(--bi-text);
  outline: none;
}
.bi-v2 .biv2-search input:focus { border-color: var(--bi-accent); background: var(--bi-surface); }
.bi-v2 .biv2-search input::placeholder { color: var(--bi-faint); }
.bi-v2 .biv2-kbd {
  position: absolute; right: 17px; top: 17px;
  font: 11px var(--bi-mono);
  color: var(--bi-fainter);
  border: 1px solid var(--bi-border);
  border-radius: 4px;
  padding: 1px 4px;
  pointer-events: none;
}

/* Sidebar: scroll body */
.bi-v2 .biv2-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 6px 8px 10px; }

.bi-v2 .biv2-sec {
  font: 600 10.5px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-fainter);
  padding: 13px 9px 4px;
}
.bi-v2 .biv2-scroll > div:first-child > .biv2-sec { padding-top: 6px; }

.bi-v2 .biv2-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 9px;
  border-radius: 7px;
  font-size: var(--bi-fs-lg);
  color: var(--bi-text-soft);
  cursor: pointer;
  text-decoration: none;
}
.bi-v2 .biv2-item:hover { background: var(--bi-surface-alt); color: var(--bi-text); text-decoration: none; }
.bi-v2 .biv2-item > .fa:first-child { flex: none; width: 14px; font-size: var(--bi-fs-md); color: var(--bi-faint); text-align: center; }
.bi-v2 .biv2-item > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bi-v2 .biv2-item.is-active,
.bi-v2 .biv2-item.is-active:hover {
  background: var(--bi-accent-tint);
  color: var(--bi-accent-ink);
  font-weight: 600;
}
.bi-v2 .biv2-item.is-active > .fa:first-child { color: var(--bi-accent); }

.bi-v2 .biv2-caret { flex: none; font-size: var(--bi-fs-micro); color: var(--bi-fainter); transition: transform .15s ease; }
.bi-v2 .biv2-item.is-open .biv2-caret { transform: rotate(90deg); }

/* The badge and the search-result group tag are <span>s too, so they have to
   out-specify `.biv2-item > span { flex: 1 }` above or they share the label's
   width and truncate it. */
.bi-v2 .biv2-item > span.biv2-badge {
  flex: none;
  font: 12px var(--bi-mono);
  background: var(--bi-neutral-tint);
  color: var(--bi-neutral-ink);
  padding: 1px 6px;
  border-radius: 8px;
}
.bi-v2 .biv2-item.is-active > span.biv2-badge { background: var(--bi-accent); color: #fff; }

.bi-v2 .biv2-pin {
  flex: none;
  width: 16px;
  font-size: var(--bi-fs-xs);
  color: var(--bi-fainter);
  opacity: 0;
  text-align: center;
}
.bi-v2 .biv2-item:hover .biv2-pin { opacity: 1; }
.bi-v2 .biv2-pin.is-pinned { opacity: 1; color: var(--bi-accent); }
.bi-v2 .biv2-pin:hover { color: var(--bi-accent); }

.bi-v2 .biv2-children { padding-left: 10px; margin-left: 13px; border-left: 1px solid var(--bi-border); }
.bi-v2 .biv2-children .biv2-item { font-size: var(--bi-fs-base); padding: 5px 9px; }

.bi-v2 .biv2-item > span.biv2-hit-group { flex: none; font: 11px var(--bi-mono); color: var(--bi-fainter); text-transform: uppercase; letter-spacing: .06em; }
.bi-v2 .biv2-empty { padding: 14px 10px; font-size: var(--bi-fs-base); color: var(--bi-faint); }

/* Topbar: account block, hard right. It sat in the sidebar footer until it was
   moved up here; `margin-left: auto` inside the navbar's flex row is what puts
   it against the right edge. */
.bi-v2 .biv2-user {
  flex: none;
  position: relative;
  margin-left: auto;
  padding-left: 10px;
  display: flex;
  align-items: center;
  gap: 9px;
}
.bi-v2 .biv2-avatar {
  flex: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--bi-neutral-tint);
  color: var(--bi-neutral-ink);
  display: grid; place-items: center;
  font-weight: 600; font-size: var(--bi-fs-mini);
}
.bi-v2 .biv2-user-text { flex: none; min-width: 0; max-width: 160px; line-height: 1.15; }
.bi-v2 .biv2-user-text b { display: block; font-weight: 600; font-size: var(--bi-fs-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-v2 .biv2-user-text span { display: block; font-size: var(--bi-fs-mini); color: var(--bi-faint); }
.bi-v2 .biv2-gear {
  flex: none;
  width: 26px; height: 26px;
  border: none; background: transparent;
  border-radius: 7px;
  color: var(--bi-faint);
  font-size: var(--bi-fs-md);
  cursor: pointer;
}
.bi-v2 .biv2-gear:hover { background: var(--bi-neutral-tint); color: var(--bi-text); }

/* Drops DOWN from the topbar, and wide enough for "Change Password" on one
   line - in the sidebar it opened upwards into the footer's own width. */
.bi-v2 .biv2-usermenu {
  position: absolute;
  top: calc(100% + 4px); right: 0;
  min-width: 168px;
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
  padding: 5px;
  z-index: 5;
}
.bi-v2 .biv2-usermenu a {
  display: block;
  padding: 7px 10px;
  border-radius: 6px;
  font-size: var(--bi-fs-base);
  color: var(--bi-text-soft);
  cursor: pointer;
}
.bi-v2 .biv2-usermenu a:hover { background: var(--bi-surface-alt); color: var(--bi-text); text-decoration: none; }

/* On a phone the topbar has room for the page title OR the name, not both; the
   avatar and the gear still identify the account. */
@media (max-width: 640px) {
  .bi-v2 .biv2-user-text { display: none; }
}

/* Collapsed rail. AdminLTE forces `width:50px` AND `margin-left:50px` with
   !important on the collapsed state, so both sides of the override need the
   same weight - otherwise the rail is 60px while the content still starts at
   50px and the two overlap. */
.bi-v2.sidebar-collapse .main-sidebar { width: 60px !important; }
.bi-v2.sidebar-collapse .content-wrapper,
.bi-v2.sidebar-collapse .main-footer,
.bi-v2.sidebar-collapse .main-header .navbar { margin-left: 60px !important; }
.bi-v2.sidebar-collapse .biv2-search,
.bi-v2.sidebar-collapse .biv2-sec,
.bi-v2.sidebar-collapse .biv2-brand-text,
.bi-v2.sidebar-collapse .biv2-children,
.bi-v2.sidebar-collapse .biv2-badge,
.bi-v2.sidebar-collapse .biv2-pin,
.bi-v2.sidebar-collapse .biv2-caret,
.bi-v2.sidebar-collapse .biv2-item > span { display: none; }
.bi-v2.sidebar-collapse .biv2-brand { justify-content: center; padding: 0; }
.bi-v2.sidebar-collapse .biv2-item { justify-content: center; padding: 8px 0; }

/* Off-canvas below AdminLTE's own breakpoint */
@media (max-width: 767px) {
  .bi-v2 .main-sidebar { transform: translate(-236px, 0); }
  .bi-v2.sidebar-open .main-sidebar { transform: translate(0, 0); }
  .bi-v2 .content-wrapper,
  .bi-v2 .main-footer,
  .bi-v2 .main-header .navbar { margin-left: 0; }
  .bi-v2.sidebar-collapse .main-sidebar { width: 236px !important; }
  .bi-v2.sidebar-collapse .content-wrapper,
  .bi-v2.sidebar-collapse .main-footer,
  .bi-v2.sidebar-collapse .main-header .navbar { margin-left: 0 !important; }
}

@media print {
  .bi-v2 .main-sidebar { display: none !important; }
  .bi-v2 .content-wrapper, .bi-v2 .main-footer { margin-left: 0 !important; }
}


/* -- 6. v2 pages --------------------------------------------------------- */
/* Chrome for the screens converted in phase 3 (dashboard, order, product).
   It lives here rather than in the components' own .css files because the
   production build caps any single component stylesheet at 6kb. */

/* ── page header: title, count, right-hand actions ───────────────────────── */
.bi-v2 .biv2-pagehead {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.bi-v2 .biv2-pagehead h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -.015em;
  line-height: 1.2;
}
.bi-v2 .biv2-pagehead .biv2-sub { font-size: var(--bi-fs-base); color: var(--bi-muted); margin-top: 2px; }
.bi-v2 .biv2-pagehead-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ── filter bar ──────────────────────────────────────────────────────────── */
.bi-v2 .biv2-filterbar {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.bi-v2 .biv2-filterbar .form-control,
.bi-v2 .biv2-filterbar select { height: 32px; padding: 4px 9px; font-size: var(--bi-fs-base); }
.bi-v2 .biv2-filter-right { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bi-v2 .biv2-filter-date { width: 260px; }
.bi-v2 .biv2-filter-date .form-control { width: 100%; }

/* search field with a leading glyph */
.bi-v2 .biv2-search-field { position: relative; flex: 0 1 280px; min-width: 190px; }
.bi-v2 .biv2-search-field > .fa {
  position: absolute; left: 10px; top: 9px;
  font-size: var(--bi-fs-sm); color: var(--bi-faint); pointer-events: none;
}
.bi-v2 .biv2-search-field input { width: 100%; padding-left: 29px !important; }

/* ── filter chips ────────────────────────────────────────────────────────── */
.bi-v2 .biv2-chips { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.bi-v2 .biv2-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 11px;
  border-radius: 20px;
  border: 1px solid var(--bi-border-input);
  background: var(--bi-surface);
  color: var(--bi-text-soft);
  font-size: var(--bi-fs-md);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.bi-v2 .biv2-chip:hover { background: var(--bi-surface-alt); }
.bi-v2 .biv2-chip.is-on {
  background: var(--bi-accent);
  border-color: var(--bi-accent);
  color: #fff;
}

/* ── converted list grids (order, product) ───────────────────────────────── */
.bi-v2 .biv2-grid {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  overflow: hidden;
  margin-bottom: 18px;
}
/* A grid's table is either a direct child of .biv2-grid or wrapped in the Bootstrap
   .table-responsive scroller (the orders grid does the latter). Both forms are spelled
   out here so the layout below reaches either; a bare descendant selector would also
   catch the line-item table nested inside a row and restyle that too. */
.bi-v2 .biv2-grid > .table,
.bi-v2 .biv2-grid > .table-responsive > .table { margin-bottom: 0; }
/* Order rows are six lines tall and carry their own tinted note blocks and chips; a
   hover wash over all of that reads as a selection, so this grid opts out of it. */
.bi-v2 .biv2-grid.biv2-grid-flat > .table > tbody > tr:hover > td,
.bi-v2 .biv2-grid.biv2-grid-flat .table > tbody > tr:hover > td { background: transparent; }
.bi-v2 .biv2-grid > .table > tbody > tr > td,
.bi-v2 .biv2-grid > .table-responsive > .table > tbody > tr > td { padding: 11px 14px; font-size: var(--bi-fs-base); line-height: 1.55; }
.bi-v2 .biv2-grid > .table > thead > tr > th,
.bi-v2 .biv2-grid > .table-responsive > .table > thead > tr > th { padding: 8px 14px; }
/* Unscoped on purpose: this is a utility, and it is used in modal tables and
   report panels that have no `.biv2-grid` ancestor. It was written as
   `.biv2-grid .biv2-num` when only the two big grids used it, which silently
   left every number in a `biv2-modal-table` ranged left. */
.bi-v2 .biv2-num { text-align: right; font-variant-numeric: tabular-nums; }
.bi-v2 .biv2-grid .biv2-strong { font-size: var(--bi-fs-2xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.bi-v2 .biv2-grid .biv2-meta { font-size: var(--bi-fs-sm); color: var(--bi-muted); }
.bi-v2 .biv2-grid .biv2-meta a { color: var(--bi-accent); }
/* "Track order" was an 11.5px link wedged between two other meta lines - a target
   only a few pixels tall. Give it its own padded row so it is comfortable to hit. */
.bi-v2 .biv2-grid .biv2-tracklink {
  display: inline-block;
  margin: 3px 0;
  padding: 3px 8px;
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  line-height: 1.4;
  border: 1px solid var(--bi-border);
  border-radius: 4px;
  background: var(--bi-surface-alt);
}
.bi-v2 .biv2-grid .biv2-tracklink:hover,
.bi-v2 .biv2-grid .biv2-tracklink:focus {
  background: var(--bi-accent-tint);
  border-color: #e7d6c1;
  text-decoration: none;
}
.bi-v2 .biv2-grid .biv2-title { font-weight: 600; font-size: var(--bi-fs-xl); }
.bi-v2 .biv2-grid .biv2-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 6px; }
.bi-v2 .biv2-grid .biv2-tags .label { margin-right: 0; }
.bi-v2 .biv2-grid .biv2-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.bi-v2 .biv2-grid .biv2-mono { font-family: var(--bi-mono); font-size: var(--bi-fs-xs); }
/* status pill with the design's leading dot */
.bi-v2 .biv2-grid .biv2-statuspill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 20px;
}
.bi-v2 .biv2-grid .biv2-statuspill:before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}

/* expanded line items: the design insets the panel and floats a white card on a
   tinted strip, so it reads as belonging to the row above it */
.bi-v2 .biv2-grid .biv2-lineitems-cell {
  background: #fbfaf8;
  padding: 13px 14px 14px 44px !important;
}
.bi-v2 .biv2-grid .biv2-lineitems-card {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 8px;
  overflow: hidden;
}
.bi-v2 .biv2-grid .biv2-lineitems-card > .table { margin-bottom: 0; }
/* Action bar at the head of the panel, so it is reachable no matter how many
   lines the order has. */
.bi-v2 .biv2-grid .biv2-lineitems-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 9px 14px;
  background: var(--bi-surface-alt);
  border-bottom: 1px solid var(--bi-border);
}
.bi-v2 .biv2-grid .biv2-lineitems-head .btn { display: inline-flex; align-items: center; gap: 5px; font-size: var(--bi-fs-sm); font-weight: 500; }
.bi-v2 .biv2-grid .biv2-lineitems-head .btn-default .fa { color: var(--bi-faint); }
/* Products grid: a requested MRP / purchase-percentage change sits under the
   figure it would replace - the tinted new value, then the verdict pair. They
   used to be two bare link glyphs a few pixels tall; the design gives each its
   own tinted tile. */
.bi-v2 .biv2-grid .biv2-newval {
  display: inline-block;
  padding: 3px 6px;
  border-radius: 6px;
  background: var(--bi-accent-tint);
  color: var(--bi-accent-ink);
  font-size: var(--bi-fs-xs);
  font-weight: 600;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.bi-v2 .biv2-grid .biv2-verdict { display: flex; gap: 5px; justify-content: flex-end; margin-top: 5px; }
.bi-v2 .biv2-grid .biv2-verdict > a {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  font-size: var(--bi-fs-micro);
  cursor: pointer;
}
.bi-v2 .biv2-grid .biv2-verdict > a.is-yes { background: var(--bi-ok-tint);   color: var(--bi-ok-ink); }
.bi-v2 .biv2-grid .biv2-verdict > a.is-no  { background: var(--bi-warn-tint); color: var(--bi-warn-ink); }
.bi-v2 .biv2-grid .biv2-verdict > a:hover  { text-decoration: none; filter: brightness(.96); }

/* Stock reads at a glance: nothing on hand is a warning, a thin cushion a caution. */
.bi-v2 .biv2-grid .biv2-stock-out, .bi-v2 .biv2-grid .biv2-stock-out a { color: var(--bi-warn-ink); }
.bi-v2 .biv2-grid .biv2-stock-low, .bi-v2 .biv2-grid .biv2-stock-low a { color: var(--bi-accent-ink); }

.bi-v2 .biv2-gridfoot {
  padding: 10px 14px;
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-border);
  font-size: var(--bi-fs-md);
  color: var(--bi-muted);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.bi-v2 .biv2-gridfoot .biv2-filter-right { margin-left: auto; }
.bi-v2 .biv2-empty-row { padding: 34px 14px; text-align: center; color: var(--bi-faint); font-size: var(--bi-fs-lg); }

/* bulk action bar shown once rows are selected */
.bi-v2 .biv2-bulkbar {
  background: var(--bi-accent-tint);
  border: 1px solid #e8d9c4;
  border-radius: 9px;
  padding: 8px 12px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.bi-v2 .biv2-bulkbar .biv2-bulkcount { font-weight: 600; font-size: var(--bi-fs-base); color: var(--bi-accent-ink); margin-right: 4px; }
/* Inside a grid card the bar is the card's own top band, not a floating box. */
.bi-v2 .biv2-grid > .biv2-bulkbar {
  margin-bottom: 0;
  border: 0;
  border-bottom: 1px solid #e7d6c1;
  border-radius: 9px 9px 0 0;
}
/* The grid's table sits inside a .table-responsive wrapper, so a direct-child
   selector never reaches it and ticking a row showed no tint at all. */
.bi-v2 .biv2-grid > .table > tbody.biv2-rowsel > tr > td,
.bi-v2 .biv2-grid > .table-responsive > .table > tbody.biv2-rowsel > tr > td { background: #fdf7f0; }

.bi-v2 .biv2-danger-btn { color: var(--bi-warn-ink); border-color: #eddcd8; }
.bi-v2 .biv2-accent-btn { color: var(--bi-accent-ink); border-color: #e0cdb2; background: #fdf7f0; }
.bi-v2 .biv2-accent-btn:hover, .bi-v2 .biv2-accent-btn:focus { color: var(--bi-accent-ink); background: #fbefe0; border-color: #d6bd9d; }
.bi-v2 .biv2-rowactions .biv2-accent-btn .fa { color: var(--bi-accent); }
.bi-v2 .biv2-danger-btn:hover { color: var(--bi-warn-ink); background: var(--bi-warn-tint); border-color: #e3c6c0; }

/* ── filter-bar popovers (courier multi-select, grouped "Filter by") ──────── */
.bi-v2 .biv2-menu-anchor { position: relative; }
.bi-v2 .biv2-toolbar .biv2-menu-btn { font-weight: 400; white-space: nowrap; }
.bi-v2 .biv2-toolbar .biv2-menu-btn.is-on {
  background: #fdf7f0;
  border-color: #e7d6c1;
  font-weight: 600;
}
.bi-v2 .biv2-menu-btn .fa { font-size: var(--bi-fs-xs); color: var(--bi-faint); }
.bi-v2 .biv2-menu {
  position: absolute;
  left: 0;
  top: 34px;
  z-index: 1035;
  background: var(--bi-surface);
  border: 1px solid var(--bi-border-input);
  border-radius: 9px;
  box-shadow: 0 12px 30px rgba(31, 29, 26, .16);
  padding: 5px;
  text-align: left;
}
.bi-v2 .biv2-menu-scroll { max-height: 400px; overflow-y: auto; }
.bi-v2 .biv2-menu-group {
  font: 600 10px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-fainter);
  padding: 9px 9px 4px;
}
.bi-v2 .biv2-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 9px;
  border-radius: 6px;
  font-size: var(--bi-fs-base);
  color: var(--bi-text);
  cursor: pointer;
}
.bi-v2 .biv2-menu-item:hover { background: var(--bi-surface-alt); }
.bi-v2 .biv2-menu-item.is-on { background: var(--bi-accent-tint); color: var(--bi-accent-ink); font-weight: 600; }
.bi-v2 .biv2-menu-text { flex: 1; min-width: 0; }
.bi-v2 .biv2-menu-mark { width: 11px; flex: none; font-size: 10px; color: var(--bi-accent); }

/* ── row notes ───────────────────────────────────────────────────────────── */
.bi-v2 .biv2-note {
  border-left: 2px solid #c9c2b6;
  background: #f8f7f4;
  border-radius: 0 6px 6px 0;
  padding: 6px 9px;
  margin-top: 7px;
}
.bi-v2 .biv2-note.is-admin { border-left-color: var(--bi-accent); background: #fdf7f0; }
.bi-v2 .biv2-note-head {
  font: 600 10px var(--bi-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bi-neutral-ink);
  margin-bottom: 2px;
}
.bi-v2 .biv2-note.is-admin .biv2-note-head { color: var(--bi-accent-ink); }
.bi-v2 .biv2-note-body { font-size: var(--bi-fs-md); line-height: 1.6; color: var(--bi-text-soft); }

/* ── per-row action strip ────────────────────────────────────────────────── */
/* The action buttons sit in their own <tr> inside the order's tbody, so Bootstrap's
   cell border drew a rule straight across the middle of every order. The rule between
   orders (the first row of each tbody) is the one that matters; this one is noise. */
.bi-v2 .biv2-grid .table > tbody > tr > td.biv2-rowactions-cell {
  border-top: 0 none;
  padding-top: 0;
}
.bi-v2 .biv2-rowactions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding-left: 30px;
}
.bi-v2 .biv2-rowactions .btn { display: inline-flex; align-items: center; gap: 5px; }
.bi-v2 .biv2-rowactions .btn .fa { color: var(--bi-faint); }
.bi-v2 .biv2-rowactions .btn-primary .fa,
.bi-v2 .biv2-rowactions .biv2-danger-btn .fa { color: inherit; }
.bi-v2 .biv2-leadtime { margin-left: auto; font-size: var(--bi-fs-md); color: var(--bi-text-soft); }

/* ── empty state ─────────────────────────────────────────────────────────── */
.bi-v2 .biv2-empty { padding: 44px 20px; text-align: center; }
.bi-v2 .biv2-empty > .fa { font-size: 25px; color: #d5cfc4; margin-bottom: 9px; }
.bi-v2 .biv2-empty-title { font-size: var(--bi-fs-2xl); font-weight: 600; margin-bottom: 4px; }
.bi-v2 .biv2-empty-hint { font-size: var(--bi-fs-base); color: var(--bi-muted); margin-bottom: 14px; }

/* ── modal shell ─────────────────────────────────────────────────────────────
   The design's modal: a tinted icon tile and a subtitle in the header, an
   optional callout / stat strip / two-column field grid in the body, and a
   footer that states what will happen next to the confirm button. Every piece
   is optional - a modal uses only the parts it needs. */
.bi-v2 .modal-header.biv2-modal-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 15px 20px;
  border-bottom: 1px solid var(--bi-border);
}
.bi-v2 .biv2-modal-head .close { float: none; order: 3; margin: 2px 0 0; opacity: .5; font-weight: 400; }
.bi-v2 .biv2-modal-head .close:hover { opacity: 1; }
.bi-v2 .biv2-modal-icon {
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--bi-fs-md);
  background: var(--bi-accent-tint);
  color: var(--bi-accent);
}
.bi-v2 .biv2-modal-icon.is-ok     { background: var(--bi-ok-tint);      color: var(--bi-ok-ink); }
.bi-v2 .biv2-modal-icon.is-danger { background: var(--bi-warn-tint);    color: var(--bi-warn-ink); }
.bi-v2 .biv2-modal-icon.is-info   { background: var(--bi-info-tint);    color: var(--bi-info-ink); }
.bi-v2 .biv2-modal-icon.is-muted  { background: var(--bi-neutral-tint); color: var(--bi-neutral-ink); }
.bi-v2 .biv2-modal-heading { flex: 1; min-width: 0; }
.bi-v2 .biv2-modal-heading .modal-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bi-v2 .biv2-modal-sub { font-size: var(--bi-fs-md); color: var(--bi-muted); margin-top: 2px; }
.bi-v2 .biv2-modal-tag {
  font: 12.5px var(--bi-mono);
  background: var(--bi-neutral-tint);
  color: var(--bi-neutral-ink);
  padding: 2px 7px;
  border-radius: 8px;
}

.bi-v2 .modal-body.biv2-modal-body { padding: 16px 20px; }
.bi-v2 .biv2-modal-body > * + * { margin-top: 15px; }

/* callout: the sentence explaining what the action will do */
.bi-v2 .biv2-callout {
  display: flex;
  gap: 10px;
  border-left: 2px solid var(--bi-accent);
  background: #fdf7f0;
  border-radius: 0 7px 7px 0;
  padding: 9px 12px;
  font-size: var(--bi-fs-base);
  line-height: 1.6;
  color: var(--bi-text-soft);
}
.bi-v2 .biv2-callout > .fa { color: var(--bi-accent); padding-top: 3px; font-size: var(--bi-fs-xs); }
.bi-v2 .biv2-callout.is-danger { border-left-color: var(--bi-warn-ink); background: #fdf6f5; }
.bi-v2 .biv2-callout.is-danger > .fa { color: var(--bi-warn-ink); }
.bi-v2 .biv2-callout.is-info { border-left-color: var(--bi-info-ink); background: #f4f8fb; }
.bi-v2 .biv2-callout.is-info > .fa { color: var(--bi-info-ink); }

/* stat strip: the numbers a confirmation is about */
.bi-v2 .biv2-statstrip {
  /* A grid rather than a flex row: accounting builds strips of six and seven
     readings, which have to wrap onto a second line instead of squeezing every
     value unreadable - and a wrapped flex row has no rule between its rows. The
     1px gap over the container background draws the dividers in both
     directions, so no cell needs its own border. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(145px, 1fr));
  gap: 1px;
  background: var(--bi-row-rule);
  border: 1px solid var(--bi-border);
  border-radius: 8px;
  overflow: hidden;
}
.bi-v2 .biv2-statstrip > div { min-width: 0; padding: 11px 14px; background: var(--bi-surface); }
.bi-v2 .biv2-stat-label {
  font: 600 10px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-faint);
  margin-bottom: 5px;
}
.bi-v2 .biv2-stat-value { font-size: 21px; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

/* two-column field grid */
.bi-v2 .biv2-fieldgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px 14px; }
.bi-v2 .biv2-fieldgrid > .biv2-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bi-v2 .biv2-fieldgrid > .biv2-field.is-wide { grid-column: span 2; }
.bi-v2 .biv2-field > label {
  font-size: var(--bi-fs-md);
  font-weight: 600;
  color: var(--bi-text-soft);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 5px;
}
.bi-v2 .biv2-field > label .biv2-req { color: var(--bi-accent); }
.bi-v2 .biv2-field > label .biv2-hint { font-size: var(--bi-fs-xs); font-weight: 400; color: var(--bi-faint); }
.bi-v2 .biv2-field .form-control { width: 100%; }
.bi-v2 .biv2-field .biv2-check { display: flex; align-items: center; gap: 8px; font-size: var(--bi-fs-base); color: var(--bi-text-soft); font-weight: 400; margin: 0; }

/* read-only blocks */
.bi-v2 .biv2-modal-text {
  border: 1px solid var(--bi-border);
  border-radius: 8px;
  background: var(--bi-surface-alt);
  padding: 12px 14px;
  font: 13.5px/1.7 var(--bi-mono);
  color: var(--bi-text-soft);
  white-space: pre-wrap;
}
.bi-v2 .biv2-modal-table { border: 1px solid var(--bi-border); border-radius: 8px; overflow: hidden; }
.bi-v2 .biv2-modal-table > .table,
.bi-v2 .biv2-modal-table > .table-responsive > .table { margin-bottom: 0; }
.bi-v2 .biv2-modal-table .table > tbody > tr > td { font-size: var(--bi-fs-base); }
.bi-v2 .biv2-footnote { font-size: var(--bi-fs-sm); color: var(--bi-faint); }

/* footer: state on the left, actions on the right */
.bi-v2 .modal-footer.biv2-modal-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  text-align: left;
}
.bi-v2 .biv2-modal-foot .biv2-modal-state {
  font-size: var(--bi-fs-md);
  color: var(--bi-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.bi-v2 .biv2-modal-foot .biv2-modal-state:before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #d5cfc4;
}
.bi-v2 .biv2-modal-foot .biv2-modal-state.is-ready:before { background: var(--bi-accent); }
.bi-v2 .biv2-modal-foot .biv2-modal-actions { margin-left: auto; display: flex; gap: 8px; }
.bi-v2 .biv2-modal-foot .btn { margin: 0; }

/* ── edit-line-items modal ───────────────────────────────────────────────────
   A tabbed modal: the header keeps the design's icon/title/subtitle shape and
   the tabs get their own row underneath, so a long buyer name never collides
   with them. */
/* `.modal-header.biv2-modal-head` above is a three-class selector, so this variant
   has to carry `.modal-header` too. Written as `.bi-v2 .biv2-modal-head-tabs` it
   lost on specificity no matter where it sat in the file, and the header kept both
   its own bottom rule and its full 15px bottom padding - the tab strip then read as
   a separate band between two horizontal rules instead of hanging off the header. */
.bi-v2 .modal-header.biv2-modal-head-tabs { border-bottom: 0; padding-bottom: 11px; }
.bi-v2 .biv2-modal-tabsrow { padding: 0 20px; border-bottom: 1px solid var(--bi-border); }
.bi-v2 .biv2-modal-tabsrow .nav-tabs { border-bottom: 0; }
.bi-v2 .biv2-modal-tabsrow .nav-tabs > li > a { padding: 0 1px 9px; margin-right: 20px; background: transparent; cursor: pointer; }
.bi-v2 .biv2-modal-tabsrow .nav-tabs > li.active > a { border-bottom-width: 2px; }
.bi-v2 .biv2-modal-head .modal-title .label { font-size: var(--bi-fs-mini); vertical-align: middle; }

/* the five order-level selects above the items */
.bi-v2 .biv2-metagrid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 11px;
  margin-bottom: 14px;
}
.bi-v2 .biv2-metagrid .biv2-field > label { font-size: var(--bi-fs-sm); }
.bi-v2 .biv2-lock { font-size: 10px; color: var(--bi-fainter); }
.bi-v2 .biv2-metagrid select[disabled] { background: var(--bi-surface-alt); color: var(--bi-muted); }
@media (max-width: 1100px) {
  .bi-v2 .biv2-metagrid { grid-template-columns: repeat(3, 1fr); }
}

/* the items table and its totals block */
.bi-v2 .biv2-litable > tbody > tr:hover > td { background: transparent; }
.bi-v2 .biv2-litable > tbody > tr > td { vertical-align: middle; word-wrap: break-word; }
.bi-v2 .biv2-litable > tfoot { background: var(--bi-surface-alt); }
.bi-v2 .biv2-litable > tfoot > tr > td { border-top: 0; padding: 5px 8px; font-size: var(--bi-fs-base); }
.bi-v2 .biv2-litable > tfoot .form-control { height: 30px; padding: 3px 9px; font-size: var(--bi-fs-base); }
.bi-v2 .biv2-litable > tfoot > tr:first-child > td { padding-top: 10px; }
.bi-v2 .biv2-litable > tfoot > tr:last-child > td { padding-bottom: 10px; color: var(--bi-accent-ink); }

/* Bootstrap 3 gives .modal-header a clearfix; on a flex header those pseudo-elements
   become stray flex items and the tabs row below it gets pulled into the title block.
   Kill them, and drop the .nav-tabs negative margin that pulls the tab strip up over
   the header's bottom rule. */
.bi-v2 .modal-header.biv2-modal-head:before,
.bi-v2 .modal-header.biv2-modal-head:after { display: none; }
.bi-v2 .biv2-modal-tabsrow .nav-tabs > li { margin-bottom: 0; }
.bi-v2 .biv2-modal-tabsrow { padding-top: 4px; }
/* Only the selected tab is bold in the design; bi-v2 bolds them all by default. */
.bi-v2 .biv2-modal-tabsrow .nav-tabs > li > a { font-weight: 400; }
.bi-v2 .biv2-modal-tabsrow .nav-tabs > li.active > a { font-weight: 600; }

/* Type scale, measured off the design export rather than guessed. */
.bi-v2 .biv2-grid .biv2-buyer { font-size: var(--bi-fs-xl); font-weight: 500; margin-top: 3px; }
.bi-v2 .biv2-grid .biv2-addr { font-size: var(--bi-fs-base); line-height: 1.55; color: var(--bi-text-soft); }
.bi-v2 .biv2-grid .biv2-mono { font-size: var(--bi-fs-mini); }
.bi-v2 .biv2-grid .biv2-title { font-size: var(--bi-fs-lg); }
.bi-v2 .biv2-rowactions .btn-xs { font-size: var(--bi-fs-sm); font-weight: 500; }

/* The line-item table sits outside .biv2-grid, so it was inheriting Bootstrap's 14px
   instead of the design's 13/13.5. */
.bi-v2 .biv2-litable > tbody > tr > td { font-size: var(--bi-fs-lg); }
.bi-v2 .biv2-litable .biv2-li-name { font-size: var(--bi-fs-xl); font-weight: 500; }
.bi-v2 .biv2-litable .biv2-li-pub { font-size: var(--bi-fs-sm); color: var(--bi-muted); margin-top: 1px; }
.bi-v2 .biv2-metagrid select { font-size: var(--bi-fs-base); }

/* Delete / overflow on a line item are 26px icon buttons, not full-height controls. */
.bi-v2 .biv2-litable .biv2-li-icon {
  width: 26px;
  height: 26px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  font-size: var(--bi-fs-xs);
  color: var(--bi-muted);
}
.bi-v2 .biv2-litable a.biv2-li-icon { color: var(--bi-warn-ink); }
.bi-v2 .biv2-litable a.biv2-li-icon:hover { background: var(--bi-warn-tint); }
.bi-v2 .biv2-litable a.biv2-li-icon.disabled { color: var(--bi-fainter); background: none; }

/* ── pill groups inside the filter drawer ────────────────────────────────── */
.bi-v2 .biv2-pills { display: flex; gap: 6px; flex-wrap: wrap; }
.bi-v2 .biv2-pills .biv2-chip { height: 27px; padding: 0 10px; font-size: var(--bi-fs-md); }

/* ── filter drawer ───────────────────────────────────────────────────────────
   Base geometry lives here rather than in a per-page <style> block, so any v2
   screen can use the drawer without carrying its own copy. */
.bi-v2 .filter-drawer-overlay { position: fixed; inset: 0; background: rgba(31, 29, 26, .28); z-index: 1040; }
.bi-v2 .filter-drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: 392px;
  max-width: 92vw;
  background: var(--bi-surface);
  box-shadow: -4px 0 20px rgba(31, 29, 26, .15);
  z-index: 1050;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.bi-v2 .filter-drawer.open { transform: translateX(0); }
.bi-v2 .filter-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--bi-border);
  flex-shrink: 0;
}
.bi-v2 .filter-drawer-title { margin: 0; font-size: 17px; font-weight: 600; color: var(--bi-text); }
.bi-v2 .filter-drawer-title .badge { margin-left: 6px; background: var(--bi-accent-tint); color: var(--bi-accent-ink); }
.bi-v2 .filter-drawer-close {
  background: none;
  border: none;
  font-size: var(--bi-fs-2xl);
  color: var(--bi-faint);
  cursor: pointer;
  padding: 4px 8px;
  line-height: 1;
}
.bi-v2 .filter-drawer-close:hover { color: var(--bi-text); }
.bi-v2 .filter-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 17px;
}
.bi-v2 .filter-drawer-field { display: flex; flex-direction: column; gap: 6px; }
.bi-v2 .filter-drawer-label {
  font-size: var(--bi-fs-md);
  font-weight: 600;
  color: var(--bi-text-soft);
  margin: 0;
}
.bi-v2 .filter-drawer-footer {
  padding: 12px 18px;
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.bi-v2 .filter-drawer-footer .btn { flex: 1; }
/* the design gives the confirm button the width and keeps Clear all compact */
.bi-v2 .filter-drawer-footer .biv2-drawer-clear { flex: 0 0 auto; }

/* ── dashboard ───────────────────────────────────────────────────────────── */
.bi-v2 .biv2-sec-head { display: flex; align-items: baseline; gap: 10px; margin: 4px 0 11px; }
.bi-v2 .biv2-sec-label {
  font: 600 10.5px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-faint);
}
.bi-v2 .biv2-sec-hint { font-size: var(--bi-fs-sm); color: var(--bi-fainter); }

.bi-v2 .biv2-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 11px; margin-bottom: 18px; }
.bi-v2 .biv2-kpi {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-left: 3px solid var(--bi-accent);
  border-radius: 9px;
  padding: 12px 14px;
}
.bi-v2 .biv2-kpi.is-hold  { border-left-color: #c9a227; }
.bi-v2 .biv2-kpi.is-alert { border-left-color: #a8564a; }
.bi-v2 .biv2-kpi-head { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.bi-v2 .biv2-kpi-head .fa { font-size: var(--bi-fs-xs); color: var(--bi-accent); }
.bi-v2 .biv2-kpi.is-hold .biv2-kpi-head .fa  { color: #c9a227; }
.bi-v2 .biv2-kpi.is-alert .biv2-kpi-head .fa { color: #a8564a; }
.bi-v2 .biv2-kpi-head span { font-size: var(--bi-fs-sm); font-weight: 600; color: var(--bi-neutral-ink); }
.bi-v2 .biv2-kpi-line { display: flex; align-items: baseline; gap: 8px; }
.bi-v2 .biv2-kpi-num {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.bi-v2 .biv2-kpi-amt { font-size: var(--bi-fs-md); color: var(--bi-muted); font-variant-numeric: tabular-nums; }
.bi-v2 .biv2-kpi-foot { font-size: var(--bi-fs-sm); color: var(--bi-muted); margin-top: 6px; }

.bi-v2 .biv2-flow {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  display: flex;
  overflow: hidden;
  margin-bottom: 18px;
}
.bi-v2 .biv2-flow-seg { flex: 1; min-width: 0; padding: 13px 15px; border-right: 1px solid var(--bi-row-rule); }
.bi-v2 .biv2-flow-seg:last-child { border-right: none; }
.bi-v2 .biv2-flow-title { font-size: var(--bi-fs-sm); color: var(--bi-muted); margin-bottom: 5px; }
.bi-v2 .biv2-flow-num { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -.02em; line-height: 1.1; }
.bi-v2 .biv2-flow-amt { font-size: var(--bi-fs-sm); color: var(--bi-faint); font-variant-numeric: tabular-nums; margin-top: 3px; }
.bi-v2 .biv2-flow-track { height: 3px; border-radius: 2px; background: var(--bi-row-rule); margin-top: 9px; overflow: hidden; }
.bi-v2 .biv2-flow-bar { height: 3px; border-radius: 2px; background: var(--bi-accent); }

.bi-v2 .biv2-cols { display: flex; gap: 16px; align-items: stretch; flex-wrap: wrap; margin-bottom: 18px; }
.bi-v2 .biv2-col-grow  { flex: 1 1 420px; min-width: 0; }
.bi-v2 .biv2-col-fixed { flex: 0 0 300px; }
.bi-v2 .biv2-col-half  { flex: 1 1 380px; min-width: 0; }

.bi-v2 .biv2-panel {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin-bottom: 18px;
}
.bi-v2 .biv2-cols .biv2-panel { margin-bottom: 0; }
/* .biv2-panel clips to its own rounded box, which slices a date picker's
   calendar (or any other popup a panel head hosts) off at the panel's bottom
   edge. A panel that hosts one opts out; safe as long as nothing inside it
   paints its own background out to a corner. */
.bi-v2 .biv2-panel.is-unclipped { overflow: visible; }
.bi-v2 .biv2-panel-head {
  padding: 12px 16px;
  border-bottom: 1px solid var(--bi-row-rule);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.bi-v2 .biv2-panel-title { font-size: var(--bi-fs-2xl); font-weight: 600; }
.bi-v2 .biv2-panel-note { font-size: var(--bi-fs-sm); color: var(--bi-faint); }
.bi-v2 .biv2-panel-right { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.bi-v2 .biv2-panel-body { padding: 16px; flex: 1; }
.bi-v2 .biv2-panel-pad { padding: 14px 16px; }
.bi-v2 .biv2-panel-empty { padding: 22px 16px; font-size: var(--bi-fs-base); color: var(--bi-faint); }
.bi-v2 .biv2-panel-foot {
  padding: 10px 16px;
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-border);
  font-size: var(--bi-fs-base);
  font-weight: 600;
  /* A single child (the dashboard's "Show top 50" link) still sits left; a
     label/value pair (the balance sheet's totals) pushes apart. */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.bi-v2 .biv2-total-num { font-size: 35px; font-weight: 600; letter-spacing: -.025em; font-variant-numeric: tabular-nums; line-height: 1; margin-top: 12px; }
.bi-v2 .biv2-total-sub { font-size: var(--bi-fs-lg); color: var(--bi-neutral-ink); margin-top: 4px; font-variant-numeric: tabular-nums; }
.bi-v2 .biv2-total-split { margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--bi-row-rule); display: flex; flex-direction: column; gap: 9px; }
.bi-v2 .biv2-split-row { display: flex; align-items: center; gap: 9px; font-size: var(--bi-fs-base); }
.bi-v2 .biv2-split-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.bi-v2 .biv2-split-label { flex: 1; min-width: 0; color: var(--bi-text-soft); }
.bi-v2 .biv2-split-value { font-variant-numeric: tabular-nums; color: var(--bi-muted); }

.bi-v2 .biv2-pills { display: flex; gap: 4px; }
.bi-v2 .biv2-pill {
  font-size: var(--bi-fs-sm);
  padding: 3px 10px;
  border-radius: 20px;
  color: var(--bi-muted);
  cursor: pointer;
}
.bi-v2 .biv2-pill.is-on { background: var(--bi-accent-tint); color: var(--bi-accent); font-weight: 600; }

.bi-v2 table.biv2-mini { width: 100%; border-collapse: collapse; }
.bi-v2 table.biv2-mini > thead > tr > th {
  text-align: left;
  padding: 7px 16px;
  background: var(--bi-surface-alt);
  border-bottom: 1px solid var(--bi-border);
  font: 600 10.5px var(--bi-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bi-faint);
}
.bi-v2 table.biv2-mini > tbody > tr > td {
  padding: 8px 16px;
  border-bottom: 1px solid var(--bi-row-rule);
  font-size: var(--bi-fs-lg);
}
.bi-v2 table.biv2-mini .num { text-align: right; font-variant-numeric: tabular-nums; }
.bi-v2 table.biv2-mini .biv2-mini-empty { text-align: center; color: var(--bi-faint); padding: 22px 16px; }

@media (max-width: 1200px) {
  .bi-v2 .biv2-kpis { grid-template-columns: repeat(2, 1fr); }
  .bi-v2 .biv2-flow { flex-wrap: wrap; }
  .bi-v2 .biv2-flow-seg { flex: 1 1 33%; }
}
@media (max-width: 767px) {
  .bi-v2 .biv2-kpis { grid-template-columns: 1fr; }
  .bi-v2 .biv2-flow-seg { flex: 1 1 100%; border-right: none; border-bottom: 1px solid var(--bi-row-rule); }
  .bi-v2 .biv2-col-fixed { flex: 1 1 100%; }
}

/* Chart.js needs an explicitly-sized parent. Without one, a responsive canvas
   inside an auto-height flex column resizes its own container and the two feed
   each other until the renderer locks up. */
.bi-v2 .biv2-chartbox { height: 230px; padding: 14px 16px 8px; position: relative; }
.bi-v2 .biv2-chartbox canvas { width: 100% !important; height: 100% !important; }

/* ── dashboard: the "Dashboard v2" artboard ──────────────────────────────────
   The panels above are shared with the accounting screens, which are drawn to
   their own artboards; everything the operations dashboard sizes differently is
   scoped to .biv2-dash so those pages are left where they are.

   Two things change: each section's label moves out of a header line and into a
   120px rail beside its cards, and the whole page runs one size tighter (9px
   gutters, 8px radii) so the four bands fit above the fold. */

/* the load hairline that replaces the floating spinner */
.bi-v2 .biv2-loadbar { height: 2px; border-radius: 2px; background: transparent; margin-bottom: 9px; }
.bi-v2 .biv2-loadbar.is-on { background: var(--bi-accent); animation: biv2-barin .6s ease-in-out infinite alternate; }
@keyframes biv2-barin { from { opacity: .4; } to { opacity: 1; } }

/* label rail + the cards it names */
.bi-v2 .biv2-band { display: flex; align-items: stretch; gap: 9px; margin-bottom: 9px; }
.bi-v2 .biv2-band-rail {
  width: 120px;
  flex: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding-right: 4px;
}
.bi-v2 .biv2-band-rail .biv2-sec-hint { font-size: var(--bi-fs-mini); line-height: 1.35; }
.bi-v2 .biv2-band-rail .biv2-sec-label { line-height: 1.35; }

.bi-v2 .biv2-dash .biv2-cols { gap: 9px; margin-bottom: 9px; }
.bi-v2 .biv2-dash .biv2-col-fixed { flex: 0 0 274px; }
.bi-v2 .biv2-dash > .biv2-panel { margin-bottom: 9px; }

/* The pipeline strip: on-hold and the two "awaiting" stages used to be a row of
   bordered KPI cards above this, in a second card style. They are all the same
   kind of fact, so they are all segments of this one strip now.

   Nine segments do not stay on one line at every width, so this is a grid rather
   than the base rule's flex row, and its separators are 1px gaps showing the
   container's own ground through - that draws a clean hairline between cells in
   BOTH directions, which per-segment borders cannot do once a row wraps. */
.bi-v2 .biv2-dash .biv2-flow {
  flex: 1;
  min-width: 0;
  border-radius: 8px;
  margin-bottom: 0;
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  gap: 1px;
  background: var(--bi-neutral-tint);
}
.bi-v2 .biv2-dash .biv2-flow-seg {
  padding: 8px 10px;
  border: none;
  background: var(--bi-surface);
}
.bi-v2 .biv2-dash .biv2-flow-title {
  margin-bottom: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* A ninth of the row is too narrow for count and taka side by side, so the two
   stack; the count still leads. */
.bi-v2 .biv2-dash .biv2-flow-line { display: flex; flex-direction: column; align-items: flex-start; gap: 0; margin-top: 2px; }
.bi-v2 .biv2-dash .biv2-flow-count { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.bi-v2 .biv2-dash .biv2-flow-num { font-size: 19px; }
.bi-v2 .biv2-dash .biv2-flow-amt {
  font-size: 16px;
  font-weight: 600;
  color: var(--bi-text-soft);
  margin-top: 2px;
}
/* Cancelled is the one segment that is not a stage an order is progressing
   through. It keeps the card style and tints only its figure. */
.bi-v2 .biv2-dash .biv2-flow-seg.is-alert .biv2-flow-num { color: #a8412f; }
.bi-v2 .biv2-dash .biv2-flow-foot {
  font-size: var(--bi-fs-mini);
  color: var(--bi-fainter);
  white-space: nowrap;
}

/* panels */
.bi-v2 .biv2-dash .biv2-panel { border-radius: 8px; }
.bi-v2 .biv2-dash .biv2-panel-head { padding: 9px 12px; gap: 9px; border-bottom-color: var(--bi-neutral-tint); }
.bi-v2 .biv2-dash .biv2-panel-title { font-size: var(--bi-fs-lg); }
.bi-v2 .biv2-dash .biv2-panel-pad { padding: 10px 13px; }
.bi-v2 .biv2-dash .biv2-panel-empty { padding: 22px 12px; font-size: var(--bi-fs-md); text-align: center; }
.bi-v2 .biv2-dash .biv2-panel-foot {
  padding: 7px 12px;
  justify-content: center;
  border-top: none;
  font-size: var(--bi-fs-sm);
}
/* The single-day picker reads as a chip beside the panel title. The shared
   bi-datepicker rules already give it its border and one-field layout; this
   only takes it a size down so it sits level with the head's btn-sm. */
.bi-v2 .biv2-dash .biv2-panel-date { width: 150px; }
.bi-v2 .biv2-dash .biv2-panel-date bi-datepicker { border-radius: 5px; }
/* field row only, for the reason given with the shared bi-datepicker rules */
.bi-v2 .biv2-dash .biv2-panel-date td:not(.md-drppicker td):first-child { padding: 0 0 0 8px !important; }
.bi-v2 .biv2-dash .biv2-panel-date td:not(.md-drppicker td):first-child .fa { font-size: var(--bi-fs-sm); }
.bi-v2 .biv2-dash .biv2-panel-date .form-control,
.bi-v2 .biv2-dash .biv2-panel-date .form-control[readonly] { height: 27px; font-size: var(--bi-fs-sm); }
.bi-v2 .biv2-dash .biv2-panel-date .btn:not(.md-drppicker .btn) { padding: 0 7px 0 2px; height: 25px; font-size: var(--bi-fs-xs); }
.bi-v2 .biv2-dash .biv2-chartbox { height: 172px; padding: 11px 12px 8px; }

/* period total: the taka is the figure the card is read for as often as the
   count is, so it is a figure in its own right rather than a caption beside
   one. Three short lines against a full-height chart panel is not enough to
   fill a column, so rather than shrink the card (which leaves a hole beside
   the chart) the block sits in the middle of it and centres on its own axis. */
/* The heading stays where a heading belongs - top of the card, on the centre
   line - and the figures take the space under it, centred in what is left.
   (.biv2-col-fixed sits ON the panel, not around it, hence the compound
   selector rather than a descendant one.) */
.bi-v2 .biv2-dash .biv2-panel.biv2-col-fixed .biv2-panel-pad { flex: 1; display: flex; flex-direction: column; }
.bi-v2 .biv2-dash .biv2-total-head { display: flex; align-items: baseline; justify-content: center; gap: 8px; }
.bi-v2 .biv2-dash .biv2-total-line { display: flex; flex-direction: column; align-items: center; gap: 0; margin: auto 0; }
.bi-v2 .biv2-dash .biv2-total-num { font-size: 29px; margin-top: 0; }
.bi-v2 .biv2-dash .biv2-total-sub { font-size: 22px; font-weight: 600; color: var(--bi-text-soft); margin-top: 4px; line-height: 1.2; }
.bi-v2 .biv2-dash .biv2-total-avg { font-size: var(--bi-fs-sm); color: var(--bi-muted); margin-top: 3px; }

/* sort pills: the unchosen one keeps a quiet ground rather than none */
.bi-v2 .biv2-dash .biv2-pill { font-size: var(--bi-fs-xs); padding: 3px 9px; background: var(--bi-surface-alt); }
.bi-v2 .biv2-dash .biv2-pill.is-on { background: var(--bi-accent-tint); }

/* trending / drill-down tables */
.bi-v2 .biv2-dash table.biv2-mini > thead > tr > th { padding: 6px 12px; font-size: 10px; border-bottom-color: var(--bi-neutral-tint); }
.bi-v2 .biv2-dash table.biv2-mini > tbody > tr > td { padding: 5px 12px; font-size: var(--bi-fs-md); }
.bi-v2 .biv2-dash table.biv2-mini .biv2-mini-empty { padding: 22px 12px; }
/* the name column takes whatever the two fixed number columns leave; max-width:0
   is what lets a table cell ellipsis at all. */
.bi-v2 .biv2-dash table.biv2-mini .biv2-mini-name {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* On a laptop the nine still fit on one line, but only once the segments give
   back their side padding and the labels go a size down. */
@media (max-width: 1440px) {
  .bi-v2 .biv2-dash .biv2-flow-seg { padding: 8px 8px; }
  .bi-v2 .biv2-dash .biv2-flow-title { font-size: var(--bi-fs-mini); }
}

/* Nine segments only read on a wide screen; below that the strip folds into a
   3x3 block rather than squeezing every label to an ellipsis. It folds to a
   DIVISOR of nine so the last row is never part-empty - a leftover cell would
   show the container's ground as a tinted hole in the card. */
@media (max-width: 1200px) { .bi-v2 .biv2-dash .biv2-flow { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Below the artboard's 1060px the rail has nowhere to stand, so it goes back to
   being a header line above its cards. */
@media (max-width: 1200px) {
  .bi-v2 .biv2-band { flex-wrap: wrap; }
  .bi-v2 .biv2-band-rail {
    width: 100%;
    flex: 1 1 100%;
    flex-direction: row;
    align-items: baseline;
    justify-content: flex-start;
    gap: 10px;
    padding-right: 0;
  }
  .bi-v2 .biv2-dash .biv2-col-fixed { flex: 1 1 100%; }
}

/* Expanded line-items table inside an order row. The old markup painted its own
   header (#432E36) and total row (#AF8D86) inline; those are gone, so the panel
   reads as a nested table rather than a second colour scheme. */
.bi-v2 .biv2-grid .biv2-lineitems { background: var(--bi-surface-alt); border-radius: 8px; padding: 4px 8px; }
.bi-v2 .biv2-grid .biv2-lineitems > .table { background: transparent; }
.bi-v2 .biv2-grid tr.biv2-lineitem-total > td {
  font-weight: 600;
  background: var(--bi-accent-tint);
  color: var(--bi-accent-ink);
}

/* Product cover thumbnail: the design's 44x60 portrait plate. The old inline
   width/height attributes on the <img> are gone, so size lives here. */
.bi-v2 .biv2-cover { position: relative; width: 44px; height: 60px; cursor: pointer; }
.bi-v2 .biv2-cover img {
  width: 44px; height: 60px;
  object-fit: scale-down;
  border: 1px solid var(--bi-border);
  border-radius: 5px;
  background: var(--bi-surface-alt);
  display: block;
}

/* Supplier logo plate (publishers grid, design 2b). */
.bi-v2 .biv2-logo { display: block; width: 34px; height: 34px; }
.bi-v2 .biv2-logo img {
  width: 34px; height: 34px;
  object-fit: scale-down;
  border: 1px solid var(--bi-border);
  border-radius: 8px;
  background: var(--bi-surface-alt);
  display: block;
}

/* Round author portrait (writers grid, design 2c). */
.bi-v2 .biv2-avatar-lg { display: block; width: 40px; height: 40px; position: relative; }
.bi-v2 .biv2-avatar-lg img {
  width: 40px; height: 40px;
  object-fit: cover;
  border: 1px solid var(--bi-border);
  border-radius: 50%;
  background: var(--bi-surface-alt);
  display: block;
}

/* Placement strip: the five yes/no columns collapse into lit / unlit pills. */
.bi-v2 .biv2-flags { display: flex; gap: 5px; flex-wrap: wrap; }
.bi-v2 .biv2-flag {
  font-size: var(--bi-fs-xs);
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 8px;
  background: var(--bi-neutral-tint);
  color: var(--bi-fainter);
}
.bi-v2 .biv2-flag.is-on { background: var(--bi-accent-tint); color: var(--bi-accent-ink); }

/* ── compact toolbar (design 1e / 1g, revised) ───────────────────────────── */
/* Orders and Products no longer carry a tall page header above the filter bar:
   title, count, search, chips and the primary action all sit in one row. The
   taller .biv2-pagehead is still what Publishers and Writers use. */
.bi-v2 .biv2-toolbar {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.bi-v2 .biv2-toolbar-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex: none;
  padding-right: 3px;
}
.bi-v2 .biv2-toolbar-title h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.01em;
}
.bi-v2 .biv2-toolbar-count {
  font-size: var(--bi-fs-sm);
  color: var(--bi-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bi-v2 .biv2-toolbar-sep { width: 1px; height: 20px; background: var(--bi-border); flex: none; }

.bi-v2 .biv2-toolbar .biv2-search-field { flex: 1 1 200px; min-width: 180px; max-width: 250px; }
.bi-v2 .biv2-toolbar .form-control,
.bi-v2 .biv2-toolbar select { height: 30px; padding: 3px 9px; font-size: var(--bi-fs-base); }
.bi-v2 .biv2-toolbar .biv2-search-field > .fa { top: 8px; }

.bi-v2 .biv2-toolbar .biv2-chip { height: 26px; padding: 0 9px; font-size: var(--bi-fs-sm); }
.bi-v2 .biv2-toolbar .biv2-filter-right { gap: 6px; }
.bi-v2 .biv2-toolbar .btn { height: 30px; padding: 0 10px; display: inline-flex; align-items: center; gap: 6px; }
.bi-v2 .biv2-toolbar .btn-primary { padding: 0 12px; border-radius: 7px; }

/* icon-only action (Export) - a square that matches the 30px row */
.bi-v2 .biv2-toolbar .biv2-iconbtn { width: 30px; padding: 0; justify-content: center; }

/* Clearing the search is the ✕ inside the field rather than a button beside it.
   The leading-glyph rule above targets every `.fa` in the field and pins it left
   with pointer-events:none, so both have to be undone here or the ✕ lands on top
   of the magnifier and cannot be clicked. */
.bi-v2 .biv2-search-field > .fa.biv2-search-clear {
  position: absolute;
  left: auto;
  right: 9px;
  top: 9px;
  font-size: var(--bi-fs-xs);
  color: var(--bi-faint);
  cursor: pointer;
  pointer-events: auto;
}
.bi-v2 .biv2-toolbar .biv2-search-field > .fa.biv2-search-clear { top: 8px; }
.bi-v2 .biv2-search-field > .fa.biv2-search-clear:hover { color: var(--bi-text); }
/* Only the fields that actually carry a ✕ need room for it. Browsers without
   :has() simply drop this rule and lose a few pixels of padding. */
.bi-v2 .biv2-search-field:has(> .biv2-search-clear) input { padding-right: 26px; }

/* Type-ahead popover under a search or lookup field. Absolute inside whatever
   position:relative wrapper holds the input. */
.bi-v2 .biv2-suggest {
  position: absolute;
  left: 0;
  top: 100%;
  margin-top: 3px;
  z-index: 1036;
  width: 100%;
  max-height: 210px;
  overflow-y: auto;
  list-style: none;
  padding: 4px;
  background: var(--bi-surface);
  border: 1px solid var(--bi-border-input);
  border-radius: 9px;
  box-shadow: 0 12px 30px rgba(31, 29, 26, .16);
}
.bi-v2 .biv2-suggest > li {
  padding: 6px 9px;
  border-radius: 6px;
  font-size: var(--bi-fs-base);
  cursor: pointer;
}
.bi-v2 .biv2-suggest > li:hover { background: var(--bi-surface-alt); }
.bi-v2 .biv2-suggest-alt { color: var(--bi-faint); }

/* Selected rows tint. The order grid puts each order in its own <tbody>; a
   single-tbody grid marks the <tr> instead. */
.bi-v2 .biv2-grid > .table > tbody > tr.biv2-rowsel > td,
.bi-v2 .biv2-grid > .table-responsive > .table > tbody > tr.biv2-rowsel > td { background: #fdf7f0; }

/* ── drawer toggle rows ──────────────────────────────────────────────────── */
/* The switch leads the row with its explanation beside it, so the label and the
   thing it describes are not separated by the control. */
.bi-v2 .biv2-switchrow {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  margin: 0;
  font-weight: 400;
  cursor: pointer;
}
.bi-v2 .biv2-switchtext { flex: 1; min-width: 0; font-size: var(--bi-fs-base); color: var(--bi-text); }
.bi-v2 .biv2-switchtext small {
  display: block;
  font-size: var(--bi-fs-sm);
  line-height: 1.45;
  color: var(--bi-muted);
}
.bi-v2 .switch-toggle {
  position: relative;
  display: inline-block;
  width: 34px;
  height: 19px;
  margin: 1px 0 0;
  flex: none;
}
.bi-v2 .switch-toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
.bi-v2 .switch-slider {
  position: absolute;
  inset: 0;
  cursor: pointer;
  background-color: #ddd8cf;
  border-radius: 20px;
  transition: background-color .2s;
}
.bi-v2 .switch-slider:before {
  position: absolute;
  content: "";
  height: 15px;
  width: 15px;
  left: 2px;
  top: 2px;
  background-color: #fff;
  border-radius: 50%;
  transition: transform .2s;
}
.bi-v2 .switch-toggle input:checked + .switch-slider { background-color: var(--bi-accent); }
.bi-v2 .switch-toggle input:checked + .switch-slider:before { transform: translateX(15px); }

/* ── modal extras ────────────────────────────────────────────────────────── */
/* Section heading above a field grid ("Identity", "Commercial terms"). */
.bi-v2 .biv2-group-label {
  font: 600 10.5px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-faint);
  margin-bottom: 10px;
}
.bi-v2 .biv2-modal-body > .biv2-group-label + .biv2-fieldgrid { margin-top: 0; }
/* Inside a tab pane the grids are not direct children of .biv2-modal-body, so the
   generic sibling spacing above never reaches them. */
.bi-v2 .biv2-fieldgrid + .biv2-group-label { margin-top: 18px; }
.bi-v2 .biv2-fieldgrid + .biv2-modal-table { margin-top: 15px; }

/* Rendered-email panel: a titled frame around HTML the app did not author, so
   the supplier's own markup cannot bleed into the modal's chrome. */
.bi-v2 .biv2-preview-head {
  padding: 9px 13px;
  border-bottom: 1px solid var(--bi-row-rule);
  background: var(--bi-surface-alt);
  font-size: var(--bi-fs-md);
  color: var(--bi-muted);
}
.bi-v2 .biv2-preview-body {
  padding: 14px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--bi-surface);
  font-size: var(--bi-fs-base);
  line-height: 1.65;
  color: var(--bi-text-soft);
}


/* ── purchase orders (design "Purchase Orders v2") ───────────────────────────
   This screen is not a grid of rows but a stack of publisher cards, each with
   its own header, its own item table and its own totals strip, so it needs its
   own chrome rather than `biv2-grid`. The one structural difference from every
   other v2 card: `overflow: visible`, because both the card header and every
   item row carry a Bootstrap dropdown that would otherwise be clipped. */

/* The drawer toggle and its count badge, shared with the five other screens
   that carry a filter drawer; they each had their own copy. */
.bi-v2 .btn-advance-toggle { white-space: nowrap; }
.bi-v2 .btn-advance-toggle.active {
  background: var(--bi-accent-tint);
  border-color: #e0cdb2;
  color: var(--bi-accent-ink);
}
.bi-v2 .btn-advance-toggle .fa { color: var(--bi-faint); }
.bi-v2 .btn-advance-toggle.active .fa { color: var(--bi-accent); }
.bi-v2 .filter-count-badge,
.bi-v2 .po-filter-badge {
  background: var(--bi-accent-tint) !important;
  color: var(--bi-accent-ink) !important;
  font: 600 12px var(--bi-mono);
  padding: 1px 5px;
}

/* ── the action row under the filter bar ─────────────────────────────────── */
.bi-v2 .biv2-poactions {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 9px;
}
.bi-v2 .biv2-poactions .btn {
  height: 30px;
  padding: 0 11px;
  font-size: var(--bi-fs-md);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bi-v2 .biv2-poactions .btn .fa { color: var(--bi-faint); }
.bi-v2 .biv2-poactions .btn-primary .fa { color: rgba(255, 255, 255, .8); }

/* The four money readings that close the action row. Cash and bank keep a hue
   of their own so the split reads at a glance. */
.bi-v2 .biv2-pototals {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  font-size: var(--bi-fs-base);
  color: var(--bi-muted);
}
.bi-v2 .biv2-pototals > span { display: inline-flex; align-items: baseline; gap: 5px; }
.bi-v2 .biv2-pototals strong {
  color: var(--bi-text);
  font-size: var(--bi-fs-xl);
  font-variant-numeric: tabular-nums;
}
.bi-v2 .biv2-pototals > span.is-cash strong { color: #6b5b32; }
.bi-v2 .biv2-pototals > span.is-bank strong { color: var(--bi-info-ink); }

/* ── the publisher card ──────────────────────────────────────────────────── */
.bi-v2 .biv2-pocard {
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 9px;
  margin-bottom: 10px;
  overflow: visible;          /* see the note at the top of this block */
}

.bi-v2 .biv2-pohead {
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--bi-border);
  border-radius: 9px 9px 0 0;
}
.bi-v2 .biv2-pohead-top { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.bi-v2 .biv2-pohead-main { flex: 1 1 0; min-width: 280px; }
.bi-v2 .biv2-pohead-title { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.bi-v2 .biv2-pohead-name { font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.bi-v2 .biv2-pohead-id { font: 13px var(--bi-mono); color: var(--bi-muted); }
.bi-v2 .biv2-pohead-dist {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--bi-fs-sm);
  color: var(--bi-neutral-ink);
}
.bi-v2 .biv2-pohead-dist .fa { font-size: var(--bi-fs-micro); color: var(--bi-faint); }
.bi-v2 .biv2-pohead-addr { font-size: var(--bi-fs-sm); color: var(--bi-muted); font-style: italic; margin-top: 3px; }
.bi-v2 .biv2-pohead-pct {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  flex-wrap: wrap;
  font-size: var(--bi-fs-md);
  color: var(--bi-neutral-ink);
}
.bi-v2 .biv2-pohead-pct strong { color: var(--bi-text); font-variant-numeric: tabular-nums; }

/* The AI receipt verdict was an icon with a title attribute; the design reads it
   out as a pill, which is the same one bit of information said out loud. */
.bi-v2 .biv2-poai {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--bi-fs-xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
}
.bi-v2 .biv2-poai .fa { font-size: var(--bi-fs-head); }
.bi-v2 .biv2-poai.is-ok  { background: var(--bi-ok-tint);   color: var(--bi-ok-ink); }
.bi-v2 .biv2-poai.is-bad { background: var(--bi-warn-tint); color: var(--bi-warn-ink); }

.bi-v2 .biv2-pohead-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: 660px;
}
.bi-v2 .biv2-pohead-actions .btn {
  height: 28px;
  padding: 0 10px;
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bi-v2 .biv2-pohead-actions .btn .fa { font-size: var(--bi-fs-head); color: var(--bi-faint); }
.bi-v2 .biv2-pohead-actions .btn-group .btn:first-child { border-radius: 7px 0 0 7px; }
.bi-v2 .biv2-pohead-actions .btn-group .dropdown-toggle { width: 24px; padding: 0; justify-content: center; }

/* ── the item table inside a card ────────────────────────────────────────── */
/* Kept a <table> rather than the design's flex rows: the column widths below
   reproduce the same layout, and the header checkbox / colspan behaviour that
   `selectAllPublisher` relies on stays where it was. */
/* `.table-responsive` computes to `overflow: auto` on BOTH axes (setting either
   axis to a non-visible value forces the other to auto), so it was clipping every
   row's action menu at the card's bottom edge - the last row of each card could
   not reach Edit / Delete / Related orders. This table has one flexible column
   and five narrow fixed ones, so it always fits its container and the wrapper was
   buying nothing; `break-word` covers the pathological long-token case that
   horizontal scrolling would otherwise have handled. */
.bi-v2 .biv2-pocard > .table-responsive { overflow: visible; }
.bi-v2 .biv2-pocard > .table-responsive > .table { margin-bottom: 0; }
.bi-v2 .biv2-pocard .table > tbody > tr > td { overflow-wrap: break-word; }
.bi-v2 .biv2-pocard .table > thead > tr > th { padding: 8px 14px; }
.bi-v2 .biv2-pocard .table > tbody > tr > td {
  padding: 10px 14px;
  vertical-align: top;
  border-top: 1px solid var(--bi-row-rule);
  font-size: var(--bi-fs-base);
}
.bi-v2 .biv2-pocard .table > tbody > tr:first-child > td { border-top: 0; }
.bi-v2 .biv2-pocard .table > tbody > tr:hover > td { background: var(--bi-surface-alt); }

.bi-v2 .biv2-poname { font-size: var(--bi-fs-xl); font-weight: 600; line-height: 1.4; }

/* The pipe-separated "S Price: x | P Price: y | ..." line becomes label/value
   pairs on a wrapping row, which is what makes it scannable at 11.5px. */
.bi-v2 .biv2-pometa {
  display: flex;
  gap: 4px 14px;
  flex-wrap: wrap;
  margin-top: 5px;
  font-size: var(--bi-fs-sm);
  color: var(--bi-muted);
  font-variant-numeric: tabular-nums;
}
.bi-v2 .biv2-pometa > span { display: inline-flex; gap: 4px; }
.bi-v2 .biv2-pometa > span > span { color: var(--bi-faint); }
.bi-v2 .biv2-pometa > span > b { color: var(--bi-text-soft); font-weight: 400; }

.bi-v2 .biv2-pocalc {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 5px;
  font-size: var(--bi-fs-sm);
  color: var(--bi-neutral-ink);
}
.bi-v2 .biv2-pocalc strong { color: var(--bi-text); }

/* `warningIfPriceIsNotSet()` returns a `.text-yellow` span or nothing at all, so
   the wrapper is hidden when empty and the span inside it becomes the pill. */
.bi-v2 .biv2-powarn { margin: 5px 0 0; }
.bi-v2 .biv2-powarn:empty { display: none; }
.bi-v2 .biv2-powarn .text-yellow {
  display: inline-block;
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  color: var(--bi-accent-ink) !important;
  background: var(--bi-accent-tint);
  padding: 2px 8px;
  border-radius: 20px;
}

.bi-v2 .biv2-ponote {
  margin: 6px 0 0;
  font-size: var(--bi-fs-md);
  color: var(--bi-text-soft);
  background: var(--bi-surface-alt);
  border-left: 2px solid var(--bi-border-input);
  padding: 5px 9px;
  border-radius: 0 6px 6px 0;
}
.bi-v2 .biv2-ponote small { color: var(--bi-muted); }

.bi-v2 .biv2-poqty { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.bi-v2 .biv2-poqty-n { font-size: var(--bi-fs-xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.bi-v2 .biv2-poqty-edit {
  width: 64px;
  height: 26px;
  margin-top: 6px;
  padding: 0 8px;
  font-size: var(--bi-fs-md);
  border: 1px solid var(--bi-border-input);
  border-radius: 6px;
}

.bi-v2 .biv2-postatus { display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.bi-v2 .biv2-postatus .biv2-po-oncredit { font-size: var(--bi-fs-xs); color: var(--bi-muted); }

.bi-v2 .biv2-pofoot {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-border);
  border-radius: 0 0 9px 9px;
  font-size: var(--bi-fs-md);
  color: var(--bi-muted);
}
.bi-v2 .biv2-pofoot > span { display: inline-flex; gap: 5px; }
.bi-v2 .biv2-pofoot > span > span { color: var(--bi-faint); }
.bi-v2 .biv2-pofoot strong { color: var(--bi-text); font-variant-numeric: tabular-nums; }


/* ── awaiting purchase orders (design "Awaiting Purchase Orders v2") ─────────
   A grid whose rows come in two kinds: a tinted publisher band and the item
   rows under it. The page groups with one `<tbody>` per publisher, which is
   what `selectGroup()` drives, so the band is a `<tr>` rather than the design's
   flex block and these rules dress the two row kinds differently. */

.bi-v2 .biv2-apo .table > tbody > tr.biv2-apo-band > td {
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-border);
  padding: 10px 14px;
  vertical-align: top;
}
.bi-v2 .biv2-apo .table > tbody:first-child > tr.biv2-apo-band > td { border-top: 0; }
/* The band is a heading, not a row you point at. */
.bi-v2 .biv2-apo .table > tbody > tr.biv2-apo-band:hover > td { background: var(--bi-surface-alt); }

.bi-v2 .biv2-apo .table > tbody > tr > td {
  padding: 9px 14px;
  vertical-align: top;
  border-top: 1px solid var(--bi-row-rule);
  font-size: var(--bi-fs-base);
}

/* Publisher identity line: name, then whatever qualifies it. */
.bi-v2 .biv2-apo-pub {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.bi-v2 .biv2-apo-pubname { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.bi-v2 .biv2-apo-count { font-size: var(--bi-fs-sm); color: var(--bi-muted); font-variant-numeric: tabular-nums; }

/* Payment method reads as a pill, and cash/bank keep the hue they have in the
   purchase-order totals so the two screens agree. */
.bi-v2 .biv2-apo-pay {
  font-size: var(--bi-fs-xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--bi-neutral-tint);
  color: var(--bi-neutral-ink);
}
.bi-v2 .biv2-apo-pay.is-cash { background: #f2efe6; color: #6b5b32; }
.bi-v2 .biv2-apo-pay.is-bank { background: var(--bi-info-tint); color: var(--bi-info-ink); }

/* Second line of the band: phone chips and the two actions. */
.bi-v2 .biv2-apo-contact {
  display: flex;
  gap: 9px;
  margin-top: 6px;
  flex-wrap: wrap;
  align-items: center;
}
.bi-v2 .biv2-apo-phone {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 13px var(--bi-mono);
  color: var(--bi-text-soft);
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 7px;
  padding: 2px 8px;
}
.bi-v2 .biv2-apo-phone > .fa { font-size: var(--bi-fs-head); color: var(--bi-faint); }
.bi-v2 .biv2-apo-phone a { color: var(--bi-faint); }
.bi-v2 .biv2-apo-phone a:hover { color: var(--bi-accent); }

.bi-v2 .biv2-apo-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  color: var(--bi-accent);
  cursor: pointer;
}
.bi-v2 .biv2-apo-link:hover { color: var(--bi-accent-hover); text-decoration: none; }
.bi-v2 .biv2-apo-link > .fa { font-size: var(--bi-fs-head); }

/* Item rows. */
.bi-v2 .biv2-apo-title { font-size: var(--bi-fs-xl); line-height: 1.4; color: var(--bi-text); }

/* The order ids were one run of "1234 , 5678 , 9012"; as chips each id is a
   thing you can read and pick out. */
.bi-v2 .biv2-apo-orders { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; }
.bi-v2 .biv2-apo-order {
  font: 12px var(--bi-mono);
  color: var(--bi-accent-ink);
  background: var(--bi-surface);
  border: 1px solid var(--bi-border);
  border-radius: 6px;
  padding: 2px 6px;
}

/* Stock sits in its own column now instead of a "Stock: 6" line under the
   title; the dash is what "no stock recorded" looked like before. */
.bi-v2 .biv2-apo-stock { font-variant-numeric: tabular-nums; color: var(--bi-accent-ink); }
.bi-v2 .biv2-apo-stock.is-none { color: var(--bi-faint); }


/* -- 7. Legacy screens ---------------------------------------------------- */
/* Phases 2-3 rebuilt six templates onto the `biv2-*` chrome. Every other screen
   in the app - roughly 240 of them - is still the original AdminLTE shape:

       section.content-header > .row > .col-md-12 > .box.box-primary[padding:10px]
       section.content        > .row > .col-md-12 > .box.box-primary
                                        > .box-header.with-border > h3.box-title
                                        > .box-body.table-responsive.no-padding > table.table
                                        > .box-footer > ul.pagination

   That shape is remarkably consistent, which means it can be mapped onto the v2
   idiom from the stylesheet alone. Everything below is a restyle of markup that
   already exists: no rule here depends on a class being added to a template, and
   none of them hides, moves or reorders a control. That is deliberate - the
   redesign is a re-skin (see the phase-3 notes above), and a CSS-only layer
   cannot accidentally add or drop an affordance the way a template rewrite can.

   Sections 1-4 already restyled the atoms (.box, .table, .btn, .form-control,
   .label, .alert, .info-box). What was left were the compounds: the page-header
   filter card, grid density, modal chrome, and the AdminLTE/Bootstrap widgets
   that no v2 screen happened to use - .callout, .panel, .well, .list-group,
   .progress, .dropdown-menu, .nav-tabs-custom.

   AdminLTE declares its .callout backgrounds with `!important`, so the overrides
   that replace them have to carry it too. */


/* ── 7.1 The page-header filter card ─────────────────────────────────────── */
/* Legacy pages put their filters in a `.box.box-primary` with an inline
   `padding:10px;margin-bottom:0`. Given the same compact padding and a plain
   border it reads as the `.biv2-toolbar` strip Orders/Products/Publishers use.
   The inline style is why the padding and margin need `!important`. */

.bi-v2 .content-header > .row > [class*="col-"] > .box,
.bi-v2 .content-header > .box {
  margin-bottom: 0 !important;
  padding: 9px 12px !important;
  border-radius: 9px;
  border-top-width: 1px !important;
  border-top-color: var(--bi-border) !important;
}
/* A dozen or so screens still print the page name as an <h1> here. It duplicates
   what TitleService already puts in the topbar, but it is content and carries a
   <small> subtitle on several screens, so it is toned to the `biv2-pagehead`
   type rather than removed. */
.bi-v2 .content-header > h1 {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--bi-text);
  margin: 0 0 12px;
}
.bi-v2 .content-header > h1 > small {
  font-size: var(--bi-fs-base);
  color: var(--bi-muted);
  margin-left: 8px;
}

.bi-v2 .content-header .box > .row { margin-left: -8px; margin-right: -8px; }
.bi-v2 .content-header .box > .row > [class*="col-"] { padding-left: 8px; padding-right: 8px; }
.bi-v2 .content-header .box .form-group:last-child { margin-bottom: 0; }

/* Toolbar-height controls. Left as `input`/`select`/`.btn` rather than a blanket
   `.form-control` so a <textarea> in a header (a couple of screens have one)
   is not squashed to a single line. */
.bi-v2 .content-header .box input.form-control,
.bi-v2 .content-header .box select.form-control {
  height: 32px;
  padding: 4px 9px;
  font-size: var(--bi-fs-base);
}
.bi-v2 .content-header .box .btn {
  height: 32px;
  padding: 0 11px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
/* .btn-block must stay full-width, so it gets flex rather than inline-flex. */
.bi-v2 .content-header .box .btn.btn-block { display: flex; width: 100%; }
.bi-v2 .content-header .box .btn .badge { margin-left: 2px; }

/* Filter labels sitting over their control - the quiet caption the drawer uses,
   not the 12.5px bold body label. */
.bi-v2 .content-header .box label {
  font: 600 12px var(--bi-mono);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--bi-faint);
  margin-bottom: 4px;
}
.bi-v2 .content-header .box p { font-size: var(--bi-fs-base); }
.bi-v2 .content-header .box p:last-child { margin-bottom: 0; }

/* ng-select and bi-datepicker sit in these bars everywhere; match the height. */
.bi-v2 .content-header .box .ng-select .ng-select-container { min-height: 32px; height: 32px; }
.bi-v2 .content-header .box .ng-select .ng-select-container .ng-value-container { padding-top: 0; }


/* ── 7.2 Cards ───────────────────────────────────────────────────────────── */
/* `.box-primary` is this app's *default* box - 216 of them, chosen for no reason
   other than that it was first in AdminLTE's list - so its accent rail is noise
   rather than meaning, and three stacked orange lines is what a legacy page
   opens with. The rails that were picked deliberately (info / success / warning
   / danger) keep theirs. */
.bi-v2 .box.box-primary { border-top-color: var(--bi-border); }

.bi-v2 .box.box-solid { border: 1px solid var(--bi-border); box-shadow: none; }
.bi-v2 .box.box-solid > .box-header {
  background: var(--bi-surface-alt) !important;
  color: var(--bi-text) !important;
  border-radius: 8px 8px 0 0;
}
.bi-v2 .box.box-solid > .box-header .box-title { color: var(--bi-text); }

.bi-v2 .box-header > .box-tools { top: 9px; right: 12px; }
.bi-v2 .btn-box-tool { color: var(--bi-faint); }
.bi-v2 .btn-box-tool:hover { color: var(--bi-text); }

/* AdminLTE's own loading veil over a box. */
.bi-v2 .overlay { background: rgba(255, 255, 255, .72); border-radius: 9px; }


/* ── 7.3 Grids ───────────────────────────────────────────────────────────── */
/* `.box-body.no-padding > table` is the legacy grid. `.biv2-grid` puts its rows
   at 12.5px on 11px/14px padding; matching that here is what makes a legacy list
   sit at the same density as the Orders and Products grids. */
.bi-v2 .box-body.no-padding > .table,
.bi-v2 .box-body.no-padding > .table-responsive > .table,
.bi-v2 .box-body > .table-responsive > .table { margin-bottom: 0; }

.bi-v2 .box-body.no-padding > .table > thead > tr > th,
.bi-v2 .box-body.no-padding > .table-responsive > .table > thead > tr > th,
.bi-v2 .box-body > .table-responsive > .table > thead > tr > th { padding: 8px 14px; }

.bi-v2 .box-body.no-padding > .table > tbody > tr > td,
.bi-v2 .box-body.no-padding > .table-responsive > .table > tbody > tr > td,
.bi-v2 .box-body > .table-responsive > .table > tbody > tr > td {
  padding: 10px 14px;
  font-size: var(--bi-fs-base);
  line-height: 1.55;
}

/* Totals rows. Section 3 never reached <tfoot>, so a bordered table's footer kept
   Bootstrap's full cell grid - a stray vertical rule under the total. */
.bi-v2 .table:not(.biv2-litable) > tfoot { background: var(--bi-surface-alt); }
.bi-v2 .table:not(.biv2-litable) > tfoot > tr > td,
.bi-v2 .table:not(.biv2-litable) > tfoot > tr > th {
  border-top: 1px solid var(--bi-border);
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  padding: 9px 14px;
  font-size: var(--bi-fs-base);
  font-weight: 600;
  color: var(--bi-text);
}
.bi-v2 .table-bordered > tfoot > tr > td,
.bi-v2 .table-bordered > tfoot > tr > th { border-left: 0; border-right: 0; }

/* Row action buttons run tight in a grid cell; give them the pilot's spacing. */
.bi-v2 .box-body .table .btn-xs + .btn-xs,
.bi-v2 .box-body .table .btn-sm + .btn-sm { margin-left: 4px; }

.bi-v2 .table .label + .label { margin-left: 3px; }

/* The pagination strip in a box footer. */
.bi-v2 .box-footer .pagination { margin: 0; }
.bi-v2 .pagination > li > a,
.bi-v2 .pagination > li > span { padding: 4px 10px; font-size: var(--bi-fs-base); }
.bi-v2 .pagination > li:first-child > a,
.bi-v2 .pagination > li:first-child > span { border-radius: 7px 0 0 7px; }
.bi-v2 .pagination > li:last-child > a,
.bi-v2 .pagination > li:last-child > span { border-radius: 0 7px 7px 0; }
.bi-v2 .pagination > li > a:hover { background: var(--bi-surface-alt); color: var(--bi-text); }


/* ── 7.4 Forms ───────────────────────────────────────────────────────────── */
.bi-v2 .form-group { margin-bottom: 14px; }
.bi-v2 .help-block { font-size: var(--bi-fs-sm); color: var(--bi-muted); margin: 5px 0 0; }
.bi-v2 .text-danger,
.bi-v2 .invalid-feedback,
.bi-v2 .has-error .help-block,
.bi-v2 .has-error .control-label { color: var(--bi-warn-ink); }
.bi-v2 .has-error .form-control { border-color: #d9b7b0; }
.bi-v2 .has-error .form-control:focus { border-color: var(--bi-warn-ink); box-shadow: 0 0 0 3px var(--bi-warn-tint); }
.bi-v2 .form-control[disabled],
.bi-v2 .form-control[readonly] { background: var(--bi-neutral-tint); color: var(--bi-muted); }
.bi-v2 .form-horizontal .control-label { padding-top: 8px; }
.bi-v2 .checkbox label,
.bi-v2 .radio label { font-weight: 400; font-size: var(--bi-fs-base); color: var(--bi-text-soft); }

/* `.btn-warning` is this app's Cancel / Close / Back button - the AdminLTE yellow
   that BS3 pages reach for as a secondary. Solid, it competed with the primary
   next to it in every modal footer, so it becomes the tinted "quiet warm" button
   the v2 grids already use for their own accent actions. The handful of genuine
   warning verbs on it (Ignore, Merge, Run now) still read as warm and distinct
   from `.btn-default`. */
.bi-v2 .btn-warning,
.bi-v2 .btn-warning:focus {
  background: var(--bi-accent-tint);
  border-color: #e0cdb2;
  color: var(--bi-accent-ink);
}
.bi-v2 .btn-warning:hover,
.bi-v2 .btn-warning:active { background: #f0e2d1; border-color: #d5bd9c; color: var(--bi-accent-ink); }

.bi-v2 .btn[disabled],
.bi-v2 .btn.disabled { opacity: .5; box-shadow: none; }


/* ── 7.5 Modals ──────────────────────────────────────────────────────────── */
/* The v2 modal shell (`biv2-modal-head` and friends) needs markup: an icon tile,
   a subtitle, a state dot. None of that can be conjured from CSS and adding it
   would be adding elements, so legacy modals instead get the same chrome the
   shell sits in - the header rule, the body rhythm, the footer band. */

.bi-v2 .modal-header:not(.biv2-modal-head) .close {
  font-size: 22px;
  font-weight: 400;
  text-shadow: none;
  color: var(--bi-muted);
  opacity: .55;
  margin-top: 1px;
}
.bi-v2 .modal-header:not(.biv2-modal-head) .close:hover { opacity: 1; color: var(--bi-text); }
.bi-v2 .modal-header .modal-title small { color: var(--bi-muted); font-size: var(--bi-fs-md); }

.bi-v2 .modal-body { padding: 16px 20px; }
.bi-v2 .modal-body > .box-body { padding: 0; }
.bi-v2 .modal-body > .table:last-child,
.bi-v2 .modal-body > .table-responsive:last-child > .table { margin-bottom: 0; }

/* Half the legacy modals close with `.box-footer` instead of `.modal-footer`,
   which left the buttons hanging bottom-left on a white ground. Both get the
   same band. Kept on `text-align` rather than flex on purpose: Bootstrap 3's
   clearfix on these blocks turns into stray flex items the moment they are
   flexed - the trap documented against `biv2-modal-head` above. */
.bi-v2 .modal-content > .modal-footer:not(.biv2-modal-foot),
.bi-v2 .modal-content > .box-footer,
.bi-v2 .modal-content > .modal-body + .box-footer {
  background: var(--bi-surface-alt);
  border-top: 1px solid var(--bi-row-rule);
  border-radius: 0 0 10px 10px;
  padding: 12px 18px;
  text-align: right;
}
.bi-v2 .modal-content > .modal-footer:not(.biv2-modal-foot) > .btn,
.bi-v2 .modal-content > .box-footer > .btn,
.bi-v2 .modal-content > .modal-footer:not(.biv2-modal-foot) > input.btn,
.bi-v2 .modal-content > .box-footer > input.btn { margin-left: 8px; }
.bi-v2 .modal-content > .modal-footer:not(.biv2-modal-foot) > .btn:first-child,
.bi-v2 .modal-content > .box-footer > .btn:first-child { margin-left: 0; }

/* Several modals scroll their own body with an inline max-height on a wrapper
   `.content`; that element is AdminLTE's page-content class, which brings 15px
   of padding and a min-height with it. */
.bi-v2 .modal-content > .content { padding: 0; min-height: 0; }

.bi-v2 .modal-backdrop.in { opacity: .28; background: #1f1d1a; }


/* ── 7.6 Widgets no v2 screen happened to use ────────────────────────────── */

/* .callout - AdminLTE fills these with a saturated cyan/orange and white text.
   Same shape as the v2 `biv2-callout`: tinted ground, coloured left rule. */
.bi-v2 .callout {
  border-radius: 9px;
  padding: 12px 15px;
  border: 1px solid transparent;
  border-left: 3px solid var(--bi-border);
  box-shadow: none;
  margin-bottom: 16px;
}
.bi-v2 .callout h4 { font-size: var(--bi-fs-lg); font-weight: 600; margin: 0 0 5px; }
.bi-v2 .callout p:last-child { margin-bottom: 0; }
.bi-v2 .callout p { font-size: var(--bi-fs-base); line-height: 1.6; }
.bi-v2 .callout a { color: inherit; text-decoration: underline; }
.bi-v2 .callout.callout-info {
  background-color: var(--bi-info-tint) !important; color: var(--bi-info-ink) !important;
  border-color: #d3e0ec !important; border-left-color: var(--bi-info-ink) !important;
}
.bi-v2 .callout.callout-warning {
  background-color: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important;
  border-color: #ead9c4 !important; border-left-color: var(--bi-accent) !important;
}
.bi-v2 .callout.callout-danger {
  background-color: var(--bi-warn-tint) !important; color: var(--bi-warn-ink) !important;
  border-color: #eed4cf !important; border-left-color: var(--bi-warn-ink) !important;
}
.bi-v2 .callout.callout-success {
  background-color: var(--bi-ok-tint) !important; color: var(--bi-ok-ink) !important;
  border-color: #d3e6d8 !important; border-left-color: var(--bi-ok-ink) !important;
}

/* .panel - the login/forgot-password shell and a few detail screens. */
.bi-v2 .panel {
  border-radius: 9px;
  border-color: var(--bi-border);
  box-shadow: none;
  background: var(--bi-surface);
}
.bi-v2 .panel > .panel-heading {
  background: var(--bi-surface-alt);
  border-color: var(--bi-row-rule);
  border-radius: 8px 8px 0 0;
  color: var(--bi-text);
  padding: 12px 16px;
}
.bi-v2 .panel-title { font-size: var(--bi-fs-2xl); font-weight: 600; letter-spacing: -.01em; }
.bi-v2 .panel-body { padding: 14px 16px; }
.bi-v2 .panel > .panel-footer {
  background: var(--bi-surface-alt);
  border-color: var(--bi-row-rule);
  border-radius: 0 0 8px 8px;
  color: var(--bi-muted);
}
/* Coloured panels lose the saturated bar and keep the hue as a tint. */
.bi-v2 .panel-primary > .panel-heading { background: var(--bi-accent-tint); border-color: #ead9c4; color: var(--bi-accent-ink); }
.bi-v2 .panel-info    > .panel-heading { background: var(--bi-info-tint);   border-color: #d3e0ec; color: var(--bi-info-ink); }
.bi-v2 .panel-success > .panel-heading { background: var(--bi-ok-tint);     border-color: #d3e6d8; color: var(--bi-ok-ink); }
.bi-v2 .panel-warning > .panel-heading { background: var(--bi-accent-tint); border-color: #ead9c4; color: var(--bi-accent-ink); }
.bi-v2 .panel-danger  > .panel-heading { background: var(--bi-warn-tint);   border-color: #eed4cf; color: var(--bi-warn-ink); }
.bi-v2 .panel-primary, .bi-v2 .panel-info, .bi-v2 .panel-success,
.bi-v2 .panel-warning, .bi-v2 .panel-danger { border-color: var(--bi-border); }

.bi-v2 .well {
  background: var(--bi-surface-alt);
  border-color: var(--bi-border);
  border-radius: 9px;
  box-shadow: none;
  padding: 14px 16px;
}

/* .list-group */
.bi-v2 .list-group { border-radius: 9px; }
.bi-v2 .list-group-item {
  border-color: var(--bi-row-rule);
  font-size: var(--bi-fs-base);
  padding: 10px 14px;
  color: var(--bi-text-soft);
}
.bi-v2 .list-group-item:first-child { border-radius: 8px 8px 0 0; border-top-color: var(--bi-border); }
.bi-v2 .list-group-item:last-child  { border-radius: 0 0 8px 8px; }
.bi-v2 a.list-group-item:hover,
.bi-v2 .list-group-item-action:hover { background: var(--bi-surface-alt); color: var(--bi-text); }
.bi-v2 .list-group-item.active,
.bi-v2 .list-group-item.active:hover {
  background: var(--bi-accent-tint);
  border-color: var(--bi-border);
  color: var(--bi-accent-ink);
  font-weight: 600;
}
.bi-v2 .list-group-item > .badge { background: var(--bi-neutral-tint); color: var(--bi-neutral-ink); }

/* .progress - the AdminLTE bar is 20px of saturated fill with the number written
   inside it. The fill is toned to the accent (section 3 already did the colour);
   what is left is the track and the label sitting on it. */
.bi-v2 .progress {
  background: var(--bi-neutral-tint);
  border-radius: 6px;
  box-shadow: none;
  overflow: hidden;
}
.bi-v2 .progress-bar { box-shadow: none; font-size: var(--bi-fs-mini); font-weight: 600; }
.bi-v2 .progress-bar-success { background-color: var(--bi-ok-ink); }
.bi-v2 .progress-bar-info    { background-color: var(--bi-info-ink); }
.bi-v2 .progress-bar-warning { background-color: var(--bi-accent-ink); }
.bi-v2 .progress-bar-danger  { background-color: var(--bi-warn-ink); }

/* Dropdowns - row kebabs, export menus, the bulk-action menus. Written for both
   the BS3 (`> li > a`) and BS4 (`.dropdown-item`) spellings, because the app uses
   each in about equal measure. */
.bi-v2 .dropdown-menu {
  border-radius: 9px;
  border-color: var(--bi-border-input);
  box-shadow: 0 12px 30px rgba(31, 29, 26, .14);
  padding: 4px;
  font-size: var(--bi-fs-base);
}
.bi-v2 .dropdown-menu > li > a,
.bi-v2 .dropdown-menu .dropdown-item {
  border-radius: 6px;
  padding: 6px 10px;
  font-size: var(--bi-fs-base);
  color: var(--bi-text-soft);
}
.bi-v2 .dropdown-menu > li > a:hover,
.bi-v2 .dropdown-menu > li > a:focus,
.bi-v2 .dropdown-menu .dropdown-item:hover,
.bi-v2 .dropdown-menu .dropdown-item:focus { background: var(--bi-surface-alt); color: var(--bi-text); }
.bi-v2 .dropdown-menu > .active > a,
.bi-v2 .dropdown-menu .dropdown-item.active { background: var(--bi-accent-tint); color: var(--bi-accent-ink); }
.bi-v2 .dropdown-menu > .divider,
.bi-v2 .dropdown-menu .dropdown-divider { background: var(--bi-row-rule); margin: 4px 0; }
.bi-v2 .dropdown-header {
  font: 600 10.5px var(--bi-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bi-faint);
  padding: 7px 10px 4px;
}

/* .nav-tabs-custom - AdminLTE's tabbed box. Section 3 gave the shell its border
   and radius; the strip inside still needed the v2 treatment. */
.bi-v2 .nav-tabs-custom > .nav-tabs {
  margin: 0;
  padding: 0 8px;
  background: var(--bi-surface-alt);
  border-radius: 8px 8px 0 0;
  border-bottom: 1px solid var(--bi-border);
}
.bi-v2 .nav-tabs-custom > .nav-tabs > li { margin-bottom: 0; border-top: 0; }
.bi-v2 .nav-tabs-custom > .nav-tabs > li > a { padding: 10px 13px; background: transparent; }
.bi-v2 .nav-tabs-custom > .nav-tabs > li.active { border-top-color: transparent; }
.bi-v2 .nav-tabs-custom > .nav-tabs > li.active > a,
.bi-v2 .nav-tabs-custom > .nav-tabs > li.active > a:hover,
.bi-v2 .nav-tabs-custom > .nav-tabs > li.active > a:focus {
  background: var(--bi-surface);
  border: none;
  border-bottom: 2px solid var(--bi-accent);
  color: var(--bi-accent-ink);
}
.bi-v2 .nav-tabs-custom > .nav-tabs > li.header { color: var(--bi-muted); font-size: var(--bi-fs-base); }
.bi-v2 .nav-tabs-custom > .tab-content { padding: 15px 16px; border-radius: 0 0 8px 8px; }

/* Plain (non-boxed) tab strips get a little breathing room under them. */
.bi-v2 .nav-tabs > li > a { padding: 9px 13px; }
.bi-v2 .nav-tabs + .tab-content { padding-top: 14px; }

/* .nav-pills, used by a few report screens as a segmented control. */
.bi-v2 .nav-pills > li > a { border-radius: 7px; font-size: var(--bi-fs-base); font-weight: 600; color: var(--bi-muted); padding: 6px 12px; }
.bi-v2 .nav-pills > li > a:hover { background: var(--bi-surface-alt); color: var(--bi-text); }
.bi-v2 .nav-pills > li.active > a,
.bi-v2 .nav-pills > li.active > a:hover,
.bi-v2 .nav-pills > li.active > a:focus { background: var(--bi-accent-tint); color: var(--bi-accent-ink); }

/* AdminLTE's vertical activity list, used by a couple of audit screens. */
.bi-v2 .timeline > li > .timeline-item {
  border-radius: 9px;
  border: 1px solid var(--bi-border);
  box-shadow: none;
}
.bi-v2 .timeline > li > .timeline-item > .timeline-header {
  border-bottom-color: var(--bi-row-rule);
  font-size: var(--bi-fs-lg);
  font-weight: 600;
}
.bi-v2 .timeline > li > .fa,
.bi-v2 .timeline > li > .glyphicon { background: var(--bi-neutral-tint); color: var(--bi-neutral-ink); }

/* Tooltips and popovers. */
.bi-v2 .tooltip-inner { background: var(--bi-text); border-radius: 7px; font-size: var(--bi-fs-sm); padding: 5px 9px; }
.bi-v2 .tooltip.top .tooltip-arrow { border-top-color: var(--bi-text); }
.bi-v2 .tooltip.bottom .tooltip-arrow { border-bottom-color: var(--bi-text); }
.bi-v2 .popover { border-radius: 9px; border-color: var(--bi-border-input); box-shadow: 0 12px 30px rgba(31, 29, 26, .14); }
.bi-v2 .popover-title { background: var(--bi-surface-alt); border-bottom-color: var(--bi-row-rule); font-size: var(--bi-fs-lg); font-weight: 600; border-radius: 8px 8px 0 0; }

/* The loader gif every screen overlays while fetching. */
.bi-v2 .loading > img { height: 40px; }


/* ── 7.7 Tabbed modal headers ────────────────────────────────────────────── */
/* A few modals (clone order, exchange) put their tab strip inside the header
   rather than under it. The phase-3 shell has `biv2-modal-head-tabs` for that
   shape; this is the same result for the ones still on plain markup - the strip
   hangs off the bottom rule instead of floating in the middle of the header. */
/* The rule under the strip is written `!important` because the two templates
   that carry this shape both kill it with an inline `border-bottom: 0`. */
.bi-v2 .modal-header:has(> .nav-tabs) {
  padding-bottom: 0;
  border-bottom: 1px solid var(--bi-border) !important;
}
.bi-v2 .modal-header > .nav-tabs { border-bottom: 0; margin-top: 11px; }
.bi-v2 .modal-header > .nav-tabs > li { margin-bottom: 0; }
.bi-v2 .modal-header > .nav-tabs > li > a { padding: 0 1px 9px; margin-right: 20px; background: transparent; cursor: pointer; }
.bi-v2 .modal-header > .nav-tabs > li.active > a { border-bottom-width: 2px; }


/* ── 7.8 App-specific status classes ─────────────────────────────────────── */
/* index.html declares six purchase-order status colours as `!important` global
   classes (`.New`, `.Purchasing`, ...), applied through
   `PurchaseOrderComponent.getStatusColor()` as `"<status> badge"`. They predate
   the label palette in section 3 and so kept AdminLTE's saturated cyan/blue/
   green. Overridden here rather than edited in index.html so that they revert
   with the `bi-v2` class like everything else. The five states stay visually
   distinct - that is what they are for. */
.bi-v2 .badge.New {
  background-color: var(--bi-neutral-tint) !important; color: var(--bi-neutral-ink) !important;
}
.bi-v2 .badge.Purchasing {
  background-color: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important;
}
.bi-v2 .badge.Purchased,
.bi-v2 .badge.InStock {
  background-color: var(--bi-info-tint) !important; color: var(--bi-info-ink) !important;
}
.bi-v2 .badge.Authorized {
  background-color: var(--bi-alt-tint) !important; color: var(--bi-alt-ink) !important;
}
.bi-v2 .badge.Completed {
  background-color: var(--bi-ok-tint) !important; color: var(--bi-ok-ink) !important;
}
/* The remaining four `StatusCodeEnum` names had no rule at all and so fell back
   to the neutral `.badge` ground, which read the same as `New`. */
.bi-v2 .badge.NotFound,
.bi-v2 .badge.Cancelled {
  background-color: var(--bi-warn-tint) !important; color: var(--bi-warn-ink) !important;
}
.bi-v2 .badge.AwaitingForStockCorrection {
  background-color: var(--bi-accent-tint) !important; color: var(--bi-accent-ink) !important;
}
.bi-v2 .badge.Draft {
  background-color: var(--bi-neutral-tint) !important; color: var(--bi-neutral-ink) !important;
}
/* `getStatusColor()` emits "<Status> badge", so these sit on the status pill in
   the purchase-order grid; give them the pill shape the design draws. */
.bi-v2 .biv2-postatus > .badge {
  font-size: var(--bi-fs-sm);
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 20px;
}
/* Short-purchased rows are flagged with this on the quantity cell. */
.bi-v2 .allPurchased { color: var(--bi-warn-ink); }
.bi-v2 .invalid-feedback { color: var(--bi-warn-ink); }


/* ── 7.9 AdminLTE colour utilities ───────────────────────────────────────── */
/* `.text-*` and the bare `.bg-*` blocks are sprinkled through the report and
   purchasing screens (margin warnings, highlighted totals). AdminLTE declares
   them `!important`. The `.label` and `.info-box-icon` mappings in section 3 are
   three-class selectors and so still win over the two-class rules here. */
.bi-v2 .text-red, .bi-v2 .text-maroon      { color: var(--bi-warn-ink) !important; }
.bi-v2 .text-green, .bi-v2 .text-olive,
.bi-v2 .text-success                        { color: var(--bi-ok-ink) !important; }
.bi-v2 .text-yellow, .bi-v2 .text-orange,
.bi-v2 .text-warning                        { color: var(--bi-accent-ink) !important; }
.bi-v2 .text-aqua, .bi-v2 .text-blue,
.bi-v2 .text-light-blue, .bi-v2 .text-info  { color: var(--bi-info-ink) !important; }
.bi-v2 .text-purple, .bi-v2 .text-navy      { color: var(--bi-alt-ink) !important; }
.bi-v2 .text-primary                        { color: var(--bi-accent) !important; }

.bi-v2 .bg-red, .bi-v2 .bg-maroon      { background-color: var(--bi-warn-tint) !important;    color: var(--bi-warn-ink) !important; }
.bi-v2 .bg-green, .bi-v2 .bg-olive,
.bi-v2 .bg-teal, .bi-v2 .bg-lime       { background-color: var(--bi-ok-tint) !important;      color: var(--bi-ok-ink) !important; }
.bi-v2 .bg-yellow, .bi-v2 .bg-orange   { background-color: var(--bi-accent-tint) !important;  color: var(--bi-accent-ink) !important; }
.bi-v2 .bg-aqua, .bi-v2 .bg-blue,
.bi-v2 .bg-light-blue, .bi-v2 .bg-info { background-color: var(--bi-info-tint) !important;    color: var(--bi-info-ink) !important; }
.bi-v2 .bg-purple, .bi-v2 .bg-fuchsia  { background-color: var(--bi-alt-tint) !important;     color: var(--bi-alt-ink) !important; }
.bi-v2 .bg-gray, .bi-v2 .bg-gray-active,
.bi-v2 .bg-black, .bi-v2 .bg-navy,
.bi-v2 .bg-light                       { background-color: var(--bi-neutral-tint) !important; color: var(--bi-neutral-ink) !important; }
.bi-v2 .bg-primary                     { background-color: var(--bi-accent-tint) !important;  color: var(--bi-accent-ink) !important; }


/* -- 8. Scrollbars ------------------------------------------------------- */
/* The default chunky grey bars are the loudest thing left on a page whose palette is
   otherwise warm and low-contrast, and this app scrolls in a lot of places: the order
   grid sideways, the filter drawer, the "Filter by" menu, the sidebar. These are thin,
   transparent-tracked and drawn in the palette's own greys.

   Three things to know before editing:

   1. `html` is reached through `:has(> body.bi-v2)` rather than styled directly, so
      the rule still dies with the `bi-v2` class like everything else in this file.
   2. Those `:has()` selectors sit in their own rules. A browser that supports
      ::-webkit-scrollbar but not :has() (Chrome <105, Safari <15.4) treats an
      unknown selector as invalidating the WHOLE list, which would drop the .bi-v2
      rules alongside it.
   3. The colours are literals, not var(). Custom properties do not resolve inside
      ::-webkit-scrollbar-* pseudo-elements; a var() there silently yields no
      background at all. Keep them in step with --bi-faint / --bi-accent by hand. */

.bi-v2::-webkit-scrollbar,
.bi-v2 ::-webkit-scrollbar { width: 11px; height: 11px; }
html:has(> body.bi-v2)::-webkit-scrollbar { width: 11px; height: 11px; }

.bi-v2::-webkit-scrollbar-track,
.bi-v2 ::-webkit-scrollbar-track { background: transparent; }
html:has(> body.bi-v2)::-webkit-scrollbar-track { background: transparent; }

/* The transparent border plus background-clip is what makes the thumb read as a
   floating pill instead of filling the gutter edge to edge. */
.bi-v2::-webkit-scrollbar-thumb,
.bi-v2 ::-webkit-scrollbar-thumb,
html:has(> body.bi-v2)::-webkit-scrollbar-thumb {
  background: #cdc7bd;
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 8px;
}
.bi-v2::-webkit-scrollbar-thumb:hover,
.bi-v2 ::-webkit-scrollbar-thumb:hover,
html:has(> body.bi-v2)::-webkit-scrollbar-thumb:hover {
  background: #a39c90;                 /* --bi-faint */
  background-clip: content-box;
}
.bi-v2::-webkit-scrollbar-thumb:active,
.bi-v2 ::-webkit-scrollbar-thumb:active,
html:has(> body.bi-v2)::-webkit-scrollbar-thumb:active {
  background: #b8650f;                 /* --bi-accent */
  background-clip: content-box;
}

.bi-v2::-webkit-scrollbar-corner,
.bi-v2 ::-webkit-scrollbar-corner { background: transparent; }
html:has(> body.bi-v2)::-webkit-scrollbar-corner { background: transparent; }

/* Firefox has no ::-webkit-scrollbar, so it gets the standard properties instead.
   Kept mutually exclusive on purpose: from Chrome 121 scrollbar-color wins over the
   ::-webkit-scrollbar rules above, which would give Chrome a different bar to Safari. */
@supports not selector(::-webkit-scrollbar) {
  html:has(> body.bi-v2),
  .bi-v2 {
    scrollbar-width: thin;
    scrollbar-color: #cdc7bd transparent;
  }
}

/* ── Orders grid: hover-revealed row actions ─────────────────────────────────
   The action strip is chrome, not content: on a page of 50 orders it was 50
   permanent button bars. It collapses to nothing and opens when the pointer is
   over the order (or something in the strip takes focus), so the grid reads as
   one block per order. Scoped to .biv2-hoveractions - every other v2 page keeps
   its strip on show. */
.bi-v2 .biv2-hoveractions .table > tbody > tr > td.biv2-rowactions-cell {
  padding-top: 0;
  padding-bottom: 7px;
}
/* The strip keeps its space whether or not it is showing - revealing it must not
   shove the rest of the page down under the pointer. */
.bi-v2 .biv2-hoveractions .biv2-rowactions {
  opacity: 0;
  pointer-events: none;
  transition: opacity .13s ease;
}
.bi-v2 .biv2-hoveractions tbody:hover > tr > td.biv2-rowactions-cell > .biv2-rowactions,
.bi-v2 .biv2-hoveractions .biv2-rowactions:focus-within {
  opacity: 1;
  pointer-events: auto;
}
/* The revealed buttons are smaller than the row's own controls - they are a
   secondary strip, not the row. */
.bi-v2 .biv2-hoveractions .biv2-rowactions .btn,
.bi-v2 .biv2-hoveractions .biv2-rowactions .btn-xs {
  padding: 3px 8px;
  font-size: var(--bi-fs-mini);
  border-radius: 6px;
  gap: 4px;
}
.bi-v2 .biv2-hoveractions .biv2-rowactions .btn .fa { font-size: var(--bi-fs-xs); }
/* Touch, where there is no hover to reveal anything. */
@media (hover: none) {
  .bi-v2 .biv2-hoveractions .biv2-rowactions {
    opacity: 1;
    pointer-events: auto;
  }
}

/* The ship-to phone is dialled off the grid, so it reads at the address's size
   rather than the size of the meta lines around it. */
.bi-v2 .biv2-grid .biv2-phone { font-size: var(--bi-fs-base); }

/* "Edit line item(s)" moved into the head of the expanded line-item table; with
   no lead time and no edit rights that bar has nothing left to show. */
.bi-v2 .biv2-grid .biv2-lineitems-head:empty { display: none; }

/* One <tbody> per order means Bootstrap's `tbody + tbody` rule - a 2px #ddd bar
   meant for grouped tables - drew the divider between orders. A hairline in the
   grid's own rule colour is enough. */
.bi-v2 .biv2-grid .table > tbody + tbody { border-top: 1px solid var(--bi-border); }

/* Notes now sit above the address, so the gap they need is below them. */
.bi-v2 .biv2-grid .biv2-note + .biv2-addr { margin-top: 7px; }

/* Notes are typed with line breaks (and appended to, a line at a time, by the
   cancel/merge flows), so the breaks have to survive to the grid. */
.bi-v2 .biv2-note-body { white-space: pre-line; }

/* Every other chip in the State cell is a tinted pill; "stock reduced" is solid,
   because it is the one that says the warehouse has already moved. */
.bi-v2 .biv2-grid .biv2-chip-stock {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background-color: var(--bi-ok-ink) !important;
  color: #fff !important;
}
.bi-v2 .biv2-grid .biv2-chip-stock .fa { font-size: 10px; opacity: .85; }
