/* =====================================================================
   XOVENT — POS interaction & hierarchy corrections
   =====================================================================
   Loaded after xv-contrast-fixes.css, so this file owns anything the
   two overlap on.

   Presentation only: no markup, ids, names or handlers are changed, so
   pos.js keeps working exactly as before. Button ORDER is changed with
   flex `order`, not by moving DOM nodes.
   ===================================================================== */


/* =====================================================================
   1. HEADER — stop spending the whole bar on our own name
   =====================================================================
   The business name wrapped to three lines and consumed 82 of the
   header's 86px. There is one business location, so the value is
   near-zero information for the cashier. One line, truncated, quiet. */

.pos-header .tw-w-full > .tw-flex.tw-items-center{
    flex-wrap: nowrap !important;
    min-width: 0;
}
/* the inline `style="width: 28%"` wrapper around the location name/select */
.pos-header div[style*="width: 28%"]{
    width: auto !important;
    min-width: 0;
    max-width: 26ch;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 600;
    font-size: .82rem;
}
.pos-header div[style*="width: 28%"] select,
.pos-header div[style*="width: 28%"] .select2-container{
    max-width: 26ch;
}
.pos-header p{ margin: 0 !important; white-space: nowrap; }

/* Icon buttons were 32x32 — under the 44px touch minimum on a till that
   may be operated by finger. Give them a real target. */
.pos-header button,
.pos-header a.pull-right,
.pos-header a.btn{
    min-width: 40px !important;
    min-height: 40px !important;
}

/* The icon row used five hues with no meaning: red was BOTH "Close
   Register" and "Sell Return"; green was BOTH "Register Details" and
   "Calculator". Neutral by default, so colour can mean one thing. */
.pos-header button i,
.pos-header a.pull-right i{
    color: var(--xp-ink2) !important;
    font-size: 15px !important;
}
/* Red now means exactly one thing: this ends the session. */
.pos-header #close_register i{ color: var(--xp-crit) !important; }

/* The date/time chip is ambient information, not a control. It was a
   filled pill that read as a button. */
.pos-header div[class*="tw-bg-"]:not(:has(> div)):not(:has(> table)){
    background: transparent !important;
    box-shadow: none !important;
    padding-left: 0 !important;
}
.pos-header .curr_datetime{
    font-size: .8rem !important;
    font-weight: 500 !important;
}


/* =====================================================================
   2. ACTION BAR — put the money where the volume is
   =====================================================================
   SCOPED TO .xv-pos ON PURPOSE. These rules were written against the
   XOVENT pos-modern markup, where the whole bar is one flex container so
   `order` can re-sequence it. UltimatePOS 7.3 splits the same buttons
   across FOUR containers, so `order` only sorts within each group and the
   row came out scrambled (Cancel, Multiple Pay, Cash, then the utilities).
   .xv-pos only exists when pos_modern.blade.php is loaded, so on 7.3's POS
   none of this applies and 7.3's own arrangement stands.
   Measured on this dataset: cash 81.4% of payments, card 16.8%.
   Together 98.2%. Yet "Multiple Pay" (split payments) was the only
   primary button, Cash was the second-smallest control on the bar, and
   the nine controls sat at nine different heights (40px-83px) with no
   shared baseline. */

/* One baseline. This alone is most of what made the row read as unfinished. */
.xv-pos .pos-form-actions .tw-flex.tw-items-center.tw-gap-4{
    align-items: center !important;
    gap: 10px !important;
    padding: 10px 0 !important;
}
.xv-pos .pos-form-actions .tw-flex.tw-items-center.tw-gap-4 > button,
.xv-pos .pos-form-actions .tw-flex.tw-items-center.tw-gap-4 > .pos-total{
    height: 54px !important;
    min-height: 54px !important;
    align-self: center !important;
    flex: 0 0 auto;
}

/* Sequence: utilities, then the rare payment path, then the common ones,
   then a gap, then the destructive action, then the amount. */
.xv-pos .pos-form-actions #pos-draft                              { order: 1; }
.xv-pos .pos-form-actions #pos-quotation                          { order: 2; }
.xv-pos .pos-form-actions [data-pay_method="suspend"]             { order: 3; }
.xv-pos .pos-form-actions [data-pay_method="credit_sale"]         { order: 4; }
.xv-pos .pos-form-actions #pos-finalize                           { order: 5; }
.xv-pos .pos-form-actions [data-pay_method="card"]                { order: 6; }
.xv-pos .pos-form-actions [data-pay_method="cash"]                { order: 7; }
.xv-pos .pos-form-actions #pos-cancel                             { order: 8; }
.xv-pos .pos-form-actions #pos-delete                             { order: 8; }
.xv-pos .pos-form-actions .pos-total                              { order: 9; }

/* Secondary utilities: quiet, compact, icon over label. */
body .xv-pos .pos-form-actions #pos-draft,
body .xv-pos .pos-form-actions #pos-quotation,
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="suspend"],
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="credit_sale"],
body .xv-pos .pos-form-actions [data-pay_method="suspend"],
body .xv-pos .pos-form-actions [data-pay_method="credit_sale"]{
    min-width: 84px;
    padding: 0 10px !important;
    border-radius: 10px !important;
    border: 1px solid var(--xp-line) !important;
    background: var(--xp-card) !important;
    font-size: .74rem !important;
}

/* PRIMARY — cash. 81% of every payment taken here. */
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="cash"],
body .xv-pos .pos-form-actions [data-pay_method="cash"]{
    display: inline-flex !important;
    flex-direction: row !important;
    align-items: center; justify-content: center; gap: 8px;
    min-width: 190px !important;
    width: auto !important;
    padding: 0 26px !important;
    border: none !important;
    border-radius: 11px !important;
    background: #0E7C4A !important;
    color: #fff !important;
    font-size: 1.02rem !important;
    font-weight: 700 !important;
    box-shadow: 0 1px 2px rgba(14,124,74,.2), 0 8px 20px -10px rgba(14,124,74,.7);
}
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="cash"] i,
body .xv-pos .pos-form-actions [data-pay_method="cash"] i{ color: #fff !important; font-size: 1rem !important; }
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="cash"]:hover,
body .xv-pos .pos-form-actions [data-pay_method="cash"]:hover{ filter: brightness(1.07); }

/* SECONDARY payment — card. 17%. Present and obvious, clearly below cash. */
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="card"],
body .xv-pos .pos-form-actions [data-pay_method="card"]{
    display: inline-flex !important;
    flex-direction: row !important;
    align-items: center; justify-content: center; gap: 8px;
    min-width: 132px !important;
    padding: 0 18px !important;
    border-radius: 11px !important;
    border: 1.5px solid #0E7C4A !important;
    background: transparent !important;
    color: #0E7C4A !important;
    font-size: .92rem !important;
    font-weight: 700 !important;
}
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="card"] i,
body .xv-pos .pos-form-actions [data-pay_method="card"] i{ color: #0E7C4A !important; }
body .xv-pos .pos-form-actions .pos-express-finalize[data-pay_method="card"]:hover,
body .xv-pos .pos-form-actions [data-pay_method="card"]:hover{ background: rgba(14,124,74,.07) !important; }

/* Multiple Pay demoted from primary to what it is: an occasional path.
   (pos-modern.css promoted it with min-width:150 and a filled brand
   background; this file loads later and owns the button now.) */
body .xv-pos .pos-form-actions #pos-finalize,
body .xv-pos .pos-form-actions #pos-finalize{
    min-width: auto !important;
    width: auto !important;
    padding: 0 16px !important;
    height: 54px !important;
    border-radius: 10px !important;
    border: 1px solid var(--xp-line) !important;
    background: var(--xp-card) !important;
    color: var(--xp-ink2) !important;
    font-size: .8rem !important;
    font-weight: 600 !important;
    box-shadow: none !important;
}
body .xv-pos .pos-form-actions #pos-finalize i,
body .xv-pos .pos-form-actions #pos-finalize i{ color: var(--xp-ink2) !important; }

/* Destructive: separated from the payment cluster by a real gap, and
   no longer a filled red block competing with the pay buttons. */
body .xv-pos .pos-form-actions #pos-cancel,
body .xv-pos .pos-form-actions #pos-delete{
    margin-left: 22px !important;
    min-width: auto !important;
    width: auto !important;
    padding: 0 16px !important;
    border-radius: 10px !important;
    background: transparent !important;
    border: 1px solid var(--xp-crit) !important;
    color: var(--xp-crit) !important;
    font-size: .8rem !important;
    font-weight: 600 !important;
}
.xv-pos .pos-form-actions #pos-cancel i,
.xv-pos .pos-form-actions #pos-delete i{ color: var(--xp-crit) !important; }
.xv-pos .pos-form-actions #pos-cancel:hover,
.xv-pos .pos-form-actions #pos-delete:hover{ background: var(--xp-critS) !important; }

/* The amount: one line, not "Total" stacked above "Payable:". */
.xv-pos .pos-form-actions .pos-total{
    margin-left: auto !important;
    padding-left: 20px;
    gap: 10px !important;
}
.xv-pos .pos-form-actions .pos-total > div:first-child{
    flex-direction: row !important;
    gap: 5px !important;
    white-space: nowrap;
    font-size: 1rem !important;
    color: var(--xp-mut) !important;
    font-weight: 600 !important;
}
.xv-pos .pos-form-actions .pos-total #total_payable{
    font-size: 1.9rem !important;
    color: var(--xp-ink) !important;
    letter-spacing: -.02em;
}

/* Keep the pay buttons reachable: the page was 57px taller than the
   viewport at 1600x1000, so the action bar could scroll out of reach. */
.xv-pos .pos-form-actions{
    position: sticky;
    bottom: 0;
    z-index: 40;
}


/* =====================================================================
   2b. CUSTOMER SELECTOR — make the name readable
   =====================================================================
   304 of 318 contacts here have a blank `name`; their real identity is in
   supplier_business_name ("CLASSIC GARAGE"). Select2 sizes itself once at
   init from the element's width, which inside this input-group (icon addon
   + two buttons) left it 136px - every business name rendered as
   "CLASS...", and the dropdown inherited that width so results wrapped over
   three or four lines and were unpickable. */

body.lockscreen .col-md-4:has(#customer_id){ width: 40% !important; }
body.lockscreen .col-md-8:has(#search_product){ width: 60% !important; }

/* beats select2's inline width:136px */
body.lockscreen #customer_id + .select2-container{ width: 100% !important; }

/* Closed state still truncates - a long trading name cannot fit a till
   header - but with enough characters to identify the account, and the
   full name stays on the element's title attribute. */
body.lockscreen #customer_id + .select2-container .select2-selection__rendered{
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The dropdown is appended to <body>, so it can be wider than the field. */
body.lockscreen .select2-dropdown{ min-width: 340px !important; }
body.lockscreen .select2-results__option{
    white-space: normal;
    line-height: 1.35;
    padding: 7px 10px;
}

/* =====================================================================
   3. QUICK ADD — don't offer what can't be sold
   ===================================================================== */
/* NOTE: these tiles keep a white background in BOTH colour schemes, so
   these colours are fixed light-scheme values on purpose. Using the
   --xp-* tokens here put dark-mode text on a white card (2.6:1). */
.product_box.xv-out-of-stock .image-container{
    filter: grayscale(1);
    opacity: .4;
}
.product_box.xv-out-of-stock .text{ color: #6B7681 !important; }
/* Dimming the whole tile also dimmed the one word that has to be read,
   so the label itself stays at full strength. */
.product_box.xv-out-of-stock .xv-stock-line{
    color: #AE241D !important;
    font-weight: 700;
}
.xv-stock-line{ color: #6B7681 !important; }
/* The rail is ~330px wide, so col-md-3 gave 77px tiles - too narrow to
   read a part name in. Two per row doubles the usable width. */
.pos_product_div .product_list,
#product_list_body .product_list{ width: 50% !important; }

/* names were being clipped mid-tile */
.product_box .text_div{ overflow: visible; }
.product_box .text_div .text{
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; line-height: 1.25;
}


/* =====================================================================
   4. FLOATING BUTTONS
   =====================================================================
   The "Install app" reposition that used to live here is gone: xv-pwa.js
   now renders that button on the dashboard only, so it can no longer sit
   on top of the POS action bar. */


/* =====================================================================
   5. PAYMENT DIRECTION TABS  (Record Payment)
   =====================================================================
   Deliberately NOT scoped to a page wrapper: these moved from the retired
   quick desk onto Record Payment, and while they were still scoped to
   .xv-quick-pay they rendered as bare text there. */
.xv-qp-dir{ display:flex; gap:8px; margin-bottom:18px; }
.xv-qp-tab{
    flex:1 1 0; padding:12px 14px; border-radius:10px; cursor:pointer;
    border:1.5px solid #E2E7E9; background:#fff; color:#414B54;
    font-weight:700; font-size:.92rem; transition:all .15s;
}
.xv-qp-tab:hover{ border-color:#0E7C4A; color:#0E7C4A; }
.xv-qp-tab.active{ background:#0E7C4A; border-color:#0E7C4A; color:#fff; }
.xv-qp-due{
    margin-top:8px; padding:8px 12px; border-radius:8px;
    background:#E3F4EA; color:#0E7C4A; font-size:.9rem;
}
.xv-qp-amount{
    font-size:1.6rem !important; font-weight:700; height:auto !important; padding:10px 12px !important;
    font-variant-numeric:tabular-nums;
}
.xv-qp-actions{ display:flex; align-items:center; gap:16px; margin-top:6px; flex-wrap:wrap; }
.xv-qp-print{ font-weight:500; color:#6B7681; margin:0; }
.xv-qp-recent td{ vertical-align:middle; font-size:.88rem; }
.xv-qp-recent .text-muted{ font-size:.78rem; }
.xv-qp-due--credit{ background:#FBEFDF; color:#9A5300; }
.xv-qp-due--none{ background:#EFF2F3; color:#6B7681; }

/* lump-sum control on Record Payment */
.xv-rp-lump{ margin-bottom:14px; }
.xv-rp-lump-row{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; max-width:520px; }
.xv-rp-lump-row .form-control{ max-width:200px; font-size:1.15rem; font-weight:600; font-variant-numeric:tabular-nums; }
.xv-rp-lump #rp_lump_note{ display:block; margin-top:6px; }

/* ------------------------------------------------------------------
   DataTables toolbar ("Show N entries" / export buttons / search)

   The stock markup lays this row out as col-sm-1 + col-sm-8 + col-sm-3.
   col-sm-1 is 1/12 of the row - about 58px at this width - but the length
   control inside it is "Show" + a 75px select + "entries", roughly 180px.
   The select therefore overflows its own column by ~58px and lands on top
   of the first export button, and the label wraps into the buttons. It is
   wrong at every width, on every list page, before any column is touched.

   Lay the row out with flex so each control takes the width it needs, and
   let the buttons take the slack. Scoped to the toolbar row only, so the
   table, its scroll containers and the paging row are untouched.
   ------------------------------------------------------------------ */
.dataTables_wrapper > .row:first-child{
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:8px 14px;
}
.dataTables_wrapper > .row:first-child > [class*="col-sm-"]{
    width:auto;
    float:none;
    padding-left:0;
    padding-right:0;
}
/* buttons absorb the leftover width; min-width:0 lets them wrap instead of
   forcing the row wider than the card */
.dataTables_wrapper > .row:first-child > .col-sm-8{
    flex:1 1 auto;
    min-width:0;
}
/* search sits at the far right whatever the button count */
.dataTables_wrapper > .row:first-child > .col-sm-3{
    margin-left:auto;
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter{
    width:auto;
}
.dataTables_wrapper .dataTables_length label,
.dataTables_wrapper .dataTables_filter label{
    white-space:nowrap;
    margin-bottom:0;
}
.dataTables_wrapper .dt-buttons{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
}
.dataTables_wrapper .dt-buttons > .dt-button{
    margin:0;
}

/* ------------------------------------------------------------------
   Contact header card (View Contact)

   Identity and actions on one line, then the facts in a grid that sizes
   to its content. Replaces a 3 x col-sm-3 layout that left a quarter of
   the card empty and used a 56px top margin to line the columns up.
   ------------------------------------------------------------------ */
.xv-contact-head{
    display:flex;
    flex-wrap:wrap;
    align-items:flex-start;
    justify-content:space-between;
    gap:10px 20px;
    padding-bottom:12px;
    margin-bottom:14px;
    border-bottom:1px solid rgba(0,0,0,.08);
}
.xv-contact-id{
    display:flex;
    align-items:baseline;
    flex-wrap:wrap;
    gap:6px 10px;
    min-width:0;
}
.xv-contact-id > .fas{ color:#6b7280; }
.xv-contact-name{
    font-size:19px;
    font-weight:700;
    line-height:1.25;
}
/* the role reads as a tag, not as part of the business name */
.xv-contact-type{
    font-size:11px;
    font-weight:600;
    text-transform:uppercase;
    letter-spacing:.04em;
    padding:2px 8px;
    border-radius:999px;
    background:rgba(99,102,241,.12);
    color:#4338ca;
    white-space:nowrap;
}
.xv-contact-actions{
    display:flex;
    flex-wrap:wrap;
    gap:8px;
    margin-left:auto;
}
.xv-contact-actions .tw-dw-btn{ margin:0; }

/* auto-fit means the columns absorb the full width however many there are,
   so a contact with no tax block does not leave a hole */
.xv-contact-facts{
    display:grid;
    grid-template-columns:repeat(auto-fit, minmax(190px, 1fr));
    gap:12px 28px;
    align-items:start;
}
/* the per-partial wrappers exist only to group the includes; making them
   transparent lets each individual fact be a grid item, so the facts flow
   across the card instead of stacking in one tall column */
.xv-contact-fact-col{ display:contents; }
.xv-fact{ min-width:0; }
/* the stock partials emit bare <strong> + <p> pairs; tighten them into
   label/value rows instead of paragraph-spaced blocks */
.xv-fact strong{
    display:block;
    font-size:11px;
    font-weight:700;
    text-transform:uppercase;
    letter-spacing:.03em;
    color:#6b7280;
    margin:0;
}

.xv-fact strong .margin-r-5{ margin-right:4px; }
.xv-fact p{
    margin:1px 0 0;
    font-size:13.5px;
    line-height:1.4;
    color:#111827;
    overflow-wrap:anywhere;
}

/* Sidebar product mark. Replaces the business name that used to sit here and
   again in the top-bar brandmark - the customer's name twice, the product's
   nowhere. */
.xv-sidemark{
    display:inline-flex;
    align-items:center;
    gap:9px;
    min-width:0;
    width:100%;
    padding:0 12px;
}
.xv-sidemark-t{ display:flex; flex-direction:column; min-width:0; line-height:1.2; }
.xv-sidemark-p{
    font-size:13px; font-weight:800; letter-spacing:.02em; color:#fff; white-space:nowrap;
}
/* the customer's name is context - it may wrap to two lines but must never
   push the product name out of the 60px header */
.xv-sidemark-b{
    font-size:9.5px; font-weight:600; letter-spacing:.05em; text-transform:uppercase;
    color:rgba(255,255,255,.72);
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
    overflow:hidden;
}
.xv-sidemark-x{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:34px;
    height:34px;
    font-size:17px;
    flex-shrink:0;
    border-radius:7px;
    background:rgba(255,255,255,.16);
    border:1px solid rgba(255,255,255,.22);
    font-weight:800;
    font-size:14px;
    line-height:1;
    color:#fff;
}
.xv-sidemark-w{
    font-size:13.5px;
    font-weight:800;
    letter-spacing:.03em;
    color:#fff;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
}
.xv-sidemark-dot{
    width:8px;
    height:8px;
    flex-shrink:0;
    border-radius:50%;
    background:#4ade80;
}



/* ------------------------------------------------------------------
   POS brand lockup

   The till has no sidebar, so the mark that lives in the sidebar on the
   dashboard sits at the left of the bar here - the same corner of the
   screen, so the branding does not jump when staff move between them.
   The bar is white, so this is the dark counterpart of the sidebar mark.
   ------------------------------------------------------------------ */
.xv-posmark{
    display:inline-flex;
    align-items:center;
    gap:9px;
    min-width:0;
    padding-right:12px;
    margin-right:2px;
    border-right:1px solid rgba(15,23,42,.12);
    text-decoration:none;
}
.xv-posmark:hover{ text-decoration:none; }
.xv-posmark-x{
    display:inline-flex; align-items:center; justify-content:center;
    width:32px; height:32px; flex-shrink:0; border-radius:8px;
    background:#0d9488; color:#fff; font-weight:800; font-size:16px; line-height:1;
}
.xv-posmark-t{ display:flex; flex-direction:column; min-width:0; line-height:1.2; }
.xv-posmark-p{
    font-size:13px; font-weight:800; letter-spacing:.02em; color:#0f172a; white-space:nowrap;
}
.xv-posmark-b{
    font-size:9.5px; font-weight:600; letter-spacing:.05em; text-transform:uppercase;
    color:rgba(15,23,42,.55);
    max-width:270px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
@media (max-width:900px){ .xv-posmark-t{ display:none; } }

/* ------------------------------------------------------------------
   Cheque register summary

   The filters live in a collapsed panel, so the page used to open as a
   bare table with no way in. These tiles are the way in: each one is a
   link that applies the filter behind it.
   ------------------------------------------------------------------ */
.xvchq-tiles{
    display:grid;
    grid-template-columns:repeat(7, minmax(0, 1fr));
    gap:10px;
    margin-bottom:14px;
}
.xvchq-tile{
    display:block;
    padding:11px 13px;
    border-radius:11px;
    border:1px solid #e2e8f0;
    background:#fff;
    text-decoration:none;
    color:#0f172a;
    transition:.15s;
}
.xvchq-tile:hover{ border-color:#0d9488; text-decoration:none; color:#0f172a; }
.xvchq-tile .t{
    display:block; font-size:10.5px; font-weight:700; text-transform:uppercase;
    letter-spacing:.05em; color:#64748b; margin-bottom:3px;
}
.xvchq-tile b{ display:block; font-size:17px; font-variant-numeric:tabular-nums; }
.xvchq-tile small{ color:#64748b; font-size:11px; }
.xvchq-tile.in{ background:#ecfdf5; border-color:#a7f3d0; }
.xvchq-tile.in b{ color:#059669; }
.xvchq-tile.out{ background:#eff6ff; border-color:#bfdbfe; }
.xvchq-tile.out b{ color:#1d4ed8; }
.xvchq-tile.warn{ background:#fffbeb; border-color:#fde68a; }
.xvchq-tile.crit{ background:#fef2f2; border-color:#fecaca; }
.xvchq-tile.crit b{ color:#dc2626; }
.xvchq-bycontact td, .xvchq-bycontact th{ font-size:12.5px; }
@media (max-width:1200px){ .xvchq-tiles{ grid-template-columns:repeat(3, minmax(0,1fr)); } }
@media (max-width:640px){ .xvchq-tiles{ grid-template-columns:repeat(2, minmax(0,1fr)); } }
