/* ============================================================
   Till-only visual flattening.
   ------------------------------------------------------------
   Loaded ONLY when TILL_MODE is set — never on the live website, since
   TILL_MODE is never true there (see App\Http\Middleware\EnsurePaired).
   Every page, every field, every workflow stays byte-for-byte the same
   HTML the live system renders — this file only turns down the glossy
   "marketing site" polish (deep drop shadows, glossy gradients) that
   reads as a webpage, not a counter till. Nothing here removes shadows
   that carry actual meaning (a modal floating over the page, a dropdown
   above its trigger) — only the decorative ones on flat, in-page cards.
   ============================================================ */

/* The shared card system (premium-ui.css) — every module page's cards
   inherit from these two variables, so this one change is most of the
   visual weight reduction on its own. */
.pui-page {
    --pui-shadow:       0 1px 2px rgba(16, 24, 40, .05);
    --pui-shadow-hover: 0 1px 3px rgba(16, 24, 40, .08);
    --pui-radius: 8px;
}

/* The gradient banner at the top of most admin pages (dashboard,
   locations, till-pairing, reports...) — flattened to the plain brand
   colour instead of the two-tone glow. */
.page-header-band {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}

/* Card-style panels defined per-page rather than through premium-ui.css
   (locations, till-pairing) — same flattening, applied directly since
   these don't read the --pui-* tokens. */
.loc-card,
.til-card,
.new-code-banner {
    box-shadow: none !important;
}
.loc-card:hover {
    box-shadow: 0 1px 3px rgba(16, 24, 40, .08) !important;
}

/* Buttons: the glossy lifted-button shadow reads as a website's call to
   action, not a till control. */
.btn-brand,
.btn-primary,
.btn-hdr {
    box-shadow: none !important;
}
.btn-brand:hover,
.btn-primary:hover {
    box-shadow: none !important;
}

/* Dropdown/notification panels keep a shadow (they're floating above the
   page — that one's functional), just a lighter one than the default. */
.notif-menu,
.tb-menu,
.color-dropdown {
    box-shadow: 0 4px 16px rgba(16, 24, 40, .12) !important;
}

/* Login/register hero panel — the two-tone glow + light blooms read as a
   marketing page; flattened to the plain brand navy. */
.auth-brand {
    background: var(--ink, #06334F) !important;
}
.auth-brand::before,
.auth-brand::after,
.auth-brand .ab-grid {
    display: none !important;
}
.auth-card {
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05) !important;
}

/* ------------------------------------------------------------
   Everything below trades the "buttery SaaS marketing" motion
   and gradient language for something that reads as desktop
   software: solid colour, tighter corners, no hover-lift, a
   native-looking scrollbar. Still only CSS — no HTML changed,
   no page behaves differently.
   ------------------------------------------------------------ */

/* Sharper corners than the marketing site's rounded-2xl language —
   a till reads as a tool, not a landing page. */
.pui-page {
    --pui-radius: 6px;
}
.pui-page .btn,
.pui-page .btn-sm,
.pui-page .stat-card,
.pui-page .page-header-band,
.pui-page .pui-header,
.pui-page .nav-pills .nav-link,
.pui-page .hdr-ico,
.pui-page .stat-card .sc-icon,
.pui-page .settings-nav .list-group-item i {
    border-radius: 6px !important;
}

/* The header band's two-tone glow + radial blur blob is the single
   most "marketing hero section" element on every module page —
   flattened to the plain brand colour, blob hidden. page-header-band
   was already covered above; pui-header is the other name the same
   component goes by. */
.pui-page .pui-header {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}
.pui-page .page-header-band::after,
.pui-page .pui-header::after {
    display: none !important;
}

/* Buttons: solid fill instead of a diagonal gradient, and no
   hover/active lift — a till button should feel like it's being
   pressed, not like it's floating off a webpage. */
.pui-page .btn-primary,
.pui-page .btn-success {
    background-image: none !important;
}
.pui-page .btn-primary { background-color: var(--pui-primary, var(--app-primary, #0093DE)) !important; }
.pui-page .btn-success { background-color: #1D9E75 !important; }
.pui-page .btn,
.pui-page .btn:hover,
.pui-page .btn:active,
.pui-page .btn-primary:hover,
.pui-page .btn-success:hover,
.pui-page .stat-card,
.pui-page .stat-card:hover {
    transform: none !important;
    transition: background-color .12s, border-color .12s, box-shadow .12s !important;
}
.pui-page .stat-card:hover {
    box-shadow: var(--pui-shadow-hover);
}

/* Active nav pills / list-group items: same flattening as the
   buttons above, for the same reason. */
.pui-page .nav-pills .nav-link.active,
.pui-page .list-group-item.active {
    background: var(--pui-primary, var(--app-primary, #0093DE)) !important;
    background-image: none !important;
}

/* Uppercase table-header and stat-label letter-spacing reads as
   editorial/marketing type at the wider tracking; tightened for a
   denser, more utilitarian data-table feel. */
.pui-page .card .table thead th,
.pui-page .stat-card .sc-label {
    letter-spacing: .02em !important;
}

/* A thin, flat, native-desktop scrollbar rather than the OS-default
   wide one — this is purely cosmetic and only shows up in the
   Chromium shell the till actually runs in. */
body {
    scrollbar-width: thin;
    scrollbar-color: rgba(11, 61, 102, .35) transparent;
}
body::-webkit-scrollbar {
    width: 9px;
    height: 9px;
}
body::-webkit-scrollbar-track {
    background: transparent;
}
body::-webkit-scrollbar-thumb {
    background: rgba(11, 61, 102, .3);
    border-radius: 5px;
}
body::-webkit-scrollbar-thumb:hover {
    background: rgba(11, 61, 102, .5);
}

/* ------------------------------------------------------------
   Round two: the pass above covered the shared component system
   (premium-ui.css). Every one of the pages below builds its own
   <style> block with the same "elevated SaaS card" language —
   layered drop shadows, hover-lift, diagonal gradients — so each
   needs its own flattening. Same rule as before: colour and
   depth only, nothing here changes what a page shows or does.
   ------------------------------------------------------------ */

/* Top bar — every authenticated page. A blurred drop shadow read
   as a webpage's sticky header; a hairline border reads as a
   desktop toolbar. */
.top-nav {
    box-shadow: none !important;
    border-bottom: 1px solid #E7EBF0;
}
body.dark .top-nav {
    box-shadow: none !important;
    border-bottom: 1px solid #2a2b30;
}

/* Dashboard — the heaviest "marketing hero" page in the app:
   diagonal gradient banner with a radial-blur blob, double-layered
   drop shadows on every card, hover-lift everywhere. */
.db-welcome {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}
.db-welcome::after,
.db-welcome::before { display: none !important; }
.db-welcome .qbtn:hover { transform: none !important; box-shadow: none !important; }

.pf-btn.active {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}

.period-filter-bar,
.kpi-card,
.chart-card,
.section-card {
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05) !important;
}
.kpi-card,
.kpi-card:hover {
    transform: none !important;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05) !important;
}
.kpi-card .kpi-icon,
.quick-action-btn .qa-icon,
.online-staff .os-avatar {
    box-shadow: none !important;
}
.online-staff .os-avatar {
    background: var(--app-primary, #0093DE) !important;
    background-image: none !important;
}
.quick-action-btn:hover {
    transform: none !important;
    box-shadow: none !important;
}
.ai-ask-btn {
    background: #7c3aed !important;
    background-image: none !important;
}
.ai-ask-btn:hover { transform: none !important; }

/* Reports — category tiles keep their four distinguishing colours
   (that's real information, not decoration) but as flat fills
   instead of diagonal pastel gradients, and without the lift. */
.report-cat-card {
    box-shadow: none !important;
    transform: none !important;
}
.report-cat-card:hover {
    transform: none !important;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .08) !important;
}
[style*="f0fff4"] { background: #E7F7EE !important; }
[style*="eff6ff"] { background: #E8F1FC !important; }
[style*="fffbeb"] { background: #FCF3DC !important; }
[style*="f0f9ff"] { background: #E7F4FB !important; }

/* Printed/on-screen receipt — the two-tone header band, flattened
   like every other header band in the app. */
.receipt { box-shadow: 0 1px 3px rgba(16, 24, 40, .08) !important; }
.receipt-top {
    background: var(--app-primary, #0093DE) !important;
    background-image: none !important;
}

/* Inventory — bespoke card shadow, and the AI reorder modal's
   purple gradient header. */
.inv-card { box-shadow: none !important; }

/* Repairs board (Kanban) — ticket cards and avatar chips. The
   drag shadow stays: it's the one place motion communicates
   something real (this card is being moved). */
.qb-card,
.qb-card:hover {
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05) !important;
}
.qb-avatar {
    background: var(--app-primary, #0093DE) !important;
    background-image: none !important;
}

/* The AI-feature accent colour (purple for diagnosis/forecast
   actions, blue for the assistant) stays as a single flat colour
   instead of a two-tone gradient, wherever it's set inline. */
[style*="7c3aed"] {
    background: #7c3aed !important;
    background-image: none !important;
}
[style*="0077c0"] {
    background: var(--app-primary, #0093DE) !important;
    background-image: none !important;
}

/* Stray pill buttons outside the shared component system —
   tighter radius to match the rest of the app, no glow shadow. */
.report-btn a,
.tabs-txt .nav-link.active,
.salecont-icon {
    border-radius: 6px !important;
    box-shadow: none !important;
}
.boxfilter .paymentprice h3 {
    background: none !important;
    -webkit-text-fill-color: var(--ink, #06334F) !important;
    color: var(--ink, #06334F) !important;
}

/* ------------------------------------------------------------
   Round three: the actual source of most of what was still
   showing gradients/shadows/wide corners — app.blade.php's own
   <style> block. That's the shared layout every single page
   loads, and it defines its OWN base .btn / .btn-primary / .card
   system independently of premium-ui.css. premium-ui.css only
   re-styles those inside a .pui-page wrapper — the topbar and
   anything outside one (which is most of what's visible without
   scrolling: the header bar, the dashboard's own cards) was still
   running on these untouched base rules. This is the one that
   actually moves the topbar and the dashboard.
   ------------------------------------------------------------ */

.btn,
.btn-sm,
.tb-pos-btn,
.qa-btn,
.tb-store,
.dashoptions button#btn.tb-user,
.card,
.card-header,
.page-filters,
.customers-filters,
.inventory-filters,
.filters-container,
.db-welcome,
.kpi-card,
.kpi-card .kpi-icon,
.chart-card,
.section-card,
.period-filter-bar,
.quick-action-btn,
.quick-action-btn .qa-icon,
.report-cat-card,
.receipt,
.qb-card,
.inv-card {
    border-radius: 6px !important;
}
.card-footer { border-radius: 0 0 6px 6px !important; }

/* Base buttons: solid fill, no diagonal gradient, no hover glow —
   this is the rule that was still winning on the topbar's POS
   button and every plain .btn-primary/.btn-success/.btn-danger/
   .btn-warning across the app. */
.btn-primary,
.btn-primary:hover,
.btn-primary:focus {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}
.btn-success,
.btn-success:hover {
    background: #1D9E75 !important;
    box-shadow: none !important;
}
.btn-danger,
.btn-danger:hover {
    background: #DC3545 !important;
    box-shadow: none !important;
}
.btn-warning,
.btn-warning:hover {
    background: #FFC107 !important;
    box-shadow: none !important;
}
.btn-outline-primary:hover,
.btn-outline-secondary:hover,
.btn-outline-danger:hover,
.btn-outline-success:hover,
.btn-outline-info:hover {
    box-shadow: none !important;
}

/* The white-header action button (Inventory/Customers page
   headers) — its own separate gradient definition, missed by the
   .btn-hdr rule earlier because this one sets background directly
   rather than through the shared component. */
.page-header-band .btn-hdr,
.inventory-header .btn,
.customers-header .btn,
.page-header-band .btn-hdr:hover,
.inventory-header .btn:hover,
.customers-header .btn:hover {
    background: var(--app-primary, #0093DE) !important;
    box-shadow: none !important;
}

/* Cards: the same flat single shadow used everywhere else in this
   file, not the base layout's stronger default. */
.card,
.page-filters,
.customers-filters,
.inventory-filters,
.filters-container,
.period-filter-bar,
.kpi-card,
.chart-card,
.section-card,
.receipt,
.qb-card,
.inv-card {
    box-shadow: 0 1px 2px rgba(16, 24, 40, .05) !important;
}

/* Topbar controls specifically: no lift, no glow — a toolbar
   button should look pressed, not clicked-on-a-webpage. */
.tb-pos-btn,
.tb-pos-btn:hover {
    box-shadow: none !important;
}

/* ------------------------------------------------------------
   Round four: the POS screen itself - the single most-used page
   in the app, and it had its own bespoke <style> block untouched
   by every earlier pass. Same flattening as everywhere else.

   This section used to also swap the cart panel to the left of the
   product grid, as a deliberate "this is the till" cue. It came back
   from the counter: staff work both ends and the mirrored layout read
   as a different program rather than the same one, which is the exact
   opposite of what this project promises. The colour and shadow
   differences already distinguish the till, and they do it without
   moving the thing your hand reaches for. Cart is back on the right,
   the same side as the live system.
   ------------------------------------------------------------ */

.pos-cont,
.invoices-cont,
.pos-cont .items-box,
.cart-panel,
.qty-stepper,
.filter-bar .filter-search input,
.filter-btn button,
.cart-cell-input,
.ct-edit,
.method-icon-sm {
    border-radius: 6px !important;
}
.tabs-bar { border-radius: 6px !important; }
.tabs-txt .nav-link.active,
.pos-cat-pill,
.pos-cat-pill.active {
    border-radius: 6px !important;
}

.pos-cont,
.invoices-cont,
.cart-panel,
.pos-cont .items-box,
.filter-btn button,
.tabs-txt .nav-link.active,
.pos-cat-pill.active {
    box-shadow: none !important;
}
.pos-cont .items-box,
.pos-cont .items-box:hover,
.filter-btn button:hover {
    transform: none !important;
}

/* Cart header: solid brand colour instead of the diagonal
   gradient — this is the "Billing Amount" band. */
.cart-head,
body.dark .cart-head {
    background: var(--app-primary, #0093DE) !important;
    background-image: none !important;
}

/* Grand total row: flatten the faint gradient tint to a flat
   tinted background — same colour family, no direction to it. */
.cart-grand-total {
    background: rgba(var(--app-primary-rgb), .06) !important;
}

/* Pay Now: solid, no glow, no lift on hover — it should feel like
   a physical key on a till, not a marketing call-to-action. */
.cart-actions .btn-success,
.cart-actions .btn-success:hover:not(:disabled) {
    box-shadow: none !important;
    transform: none !important;
    border-radius: 6px !important;
}
.cart-actions .btn-outline-danger {
    border-radius: 6px !important;
}

/* ------------------------------------------------------------
   Round five: two changes big enough to feel like a different
   piece of software rather than a re-skinned page.
   ------------------------------------------------------------ */

/* 1. Every Bootstrap modal (payment, add-customer, AI dialogs,
   quick-add — all of them, since this targets the base .modal-*
   classes Bootstrap itself defines, not a per-page one) opens
   full-screen instead of as a floating dialog, and slides up from
   the bottom instead of fading in from the centre. That's a
   deliberate native-app pattern — a Windows app takes over the
   screen for a focused task; a website interrupts it with a
   floating box. The form fields inside stay a readable column
   width instead of stretching edge-to-edge on a wide monitor;
   the header/footer bars span the full width like an app's own
   title bar and action bar. Nothing about what's inside a modal,
   or the JS that opens/closes one, changes — only its shape. */
.modal-dialog {
    width: 100vw !important;
    max-width: 100vw !important;
    height: 100vh !important;
    margin: 0 !important;
}
.modal-content {
    height: 100vh !important;
    max-height: 100vh !important;
    border-radius: 0 !important;
    border: none !important;
    box-shadow: none !important;
    /* Pinning this to exactly the viewport height only works if the body
       scrolls internally when its content doesn't fit — otherwise (see the
       payment modal on a small window, or with split payment rows added)
       the footer and whatever's above it just overflow the box unclipped
       and float on top of the page behind the modal, buttons and all. */
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
.modal-header,
.modal-footer {
    flex: 0 0 auto !important;
    /* .modal-content is already square here, so Bootstrap's rounded top
       corners on the header drew a curve against a straight edge — most
       obvious on a phone, where the modal is the whole screen and those
       corners sit against the viewport. */
    border-radius: 0 !important;
}
.modal-body {
    max-width: 720px;
    margin-left: auto !important;
    margin-right: auto !important;
    width: 100%;
    flex: 1 1 auto !important;
    overflow-y: auto !important;
    min-height: 0 !important;
}
.modal.fade .modal-dialog {
    transform: translateY(4%) !important;
    transition: transform .28s cubic-bezier(.32, .72, 0, 1), opacity .2s !important;
}
.modal.show .modal-dialog {
    transform: translateY(0) !important;
}

/* 2. Poppins first, the OS UI font behind it.
   This rule used to put the OS font in front — Segoe UI on Windows —
   on the reasoning that a webfont is a "this is a website" tell and a
   CDN dependency an offline till should not carry. The first half of
   that was a judgement call and it went the wrong way: Poppins is the
   brand's own typeface, it is what thequickrepairs.com is set in, and
   the app reads better for it. The second half still stands, so the
   OS font stays as the very next candidate rather than being dropped:
   a till with no connection renders exactly what it renders today,
   because a font that cannot be fetched is simply skipped.

   Icons ride on a font too (Tabler Icons — every ti-* glyph is a
   character in that font, not an image), so they have to be
   explicitly carved back out or every icon in the app turns into
   a stray letter. .ti itself is already safe (tabler-icons.min.css
   sets it with its own !important, which beats this rule on
   specificity), but the rail's submenu chevron sets its icon font
   without !important and would lose to this otherwise — reasserted
   below, plus a catch-all for any icon usage this pass missed. */
* {
    font-family: 'Poppins', "Segoe UI", "Segoe UI Variable", -apple-system, system-ui, Roboto, Arial, sans-serif !important;
}
.ti,
[class^="ti-"],
[class*=" ti-"],
i[class],
body.rail-open .sidebar li.has-submenu > a.submenu-toggle::after {
    font-family: "tabler-icons" !important;
}

/* ------------------------------------------------------------
   Round six: the sidebar visibly sliding in on every single page
   load. Root cause is in style.css, not till-theme.css — .sidebar
   and .home (the content area that shifts to make room for it)
   both carry `transition: var(--tran-05)`, and the collapsed/
   expanded state is applied by JS reading localStorage *after*
   the page has already painted with its default state (see
   app.blade.php's `apply(localStorage.getItem(KEY) === '1')`).
   Every full page load — which on a server-rendered app is every
   single navigation — briefly shows the wrong state, then the
   transition animates the correction into place. That's the
   "slides in from the side for a split second" the arrows are
   pointing at.

   The real fix is applying that saved state before first paint;
   this instead does exactly what was asked — removes the
   animation — by neutralising the one shared variable both
   .sidebar and .home transition on. Nothing about collapse/expand
   behaviour changes, it just stops being animated, so the correct
   state is simply there instead of visibly arriving. */
:root {
    --tran-05: none !important;
}

/* ------------------------------------------------------------
   Round seven: the app shell itself scrolls as one long page,
   which is why the topbar disappears and Pay Now keeps drifting
   off the bottom no matter how the POS panel's own height is
   tuned — the whole window is scrolling past a fixed sidebar, not
   just the content beneath the topbar.

   .home is already pinned to exactly 100vh (style.css) — it was
   only ever missing `overflow: hidden`, so anything taller than
   the window simply overflowed it and grew the page underneath
   instead of scrolling inside it. Its direct children are the
   topbar form and, on every page, a shared `.container-fluid.
   pui-page` wrapper around @yield('content') (layouts/app.blade.
   php) — that structure is what makes this reliable across every
   screen rather than a per-page fix: the topbar stays put as a
   fixed-height flex item, and that one wrapper becomes the single
   scroll region for whatever's inside it, on every page in the
   app, not just POS. */
html, body {
    overflow: hidden !important;
    height: 100% !important;
}
.home {
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
.home > form#locationFilterForm {
    flex-shrink: 0;
}
.home > .container-fluid.pui-page {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
}

/* Round seven, continued: the topbar fix above surfaced a second,
   separate bug in the cart panel's own height math. Its sticky
   max-height (pos/index.blade.php, the @media (min-width:992px)
   block) was `calc(100vh - 40px)` — that was written assuming the
   panel has essentially the whole viewport to itself. It doesn't:
   .top-nav is `min-height: 66px` (app.blade.php) plus a 1px
   border, and the panel is `position: sticky; top: 20px`, so the
   real ceiling is 100vh minus the topbar minus that top offset
   minus a little breathing room at the bottom — no version of the
   old 40px number accounted for the topbar at all. Before this
   session's overflow fix, the whole page could still scroll past
   that overage, which hid the shortfall; now that .home properly
   clips at the window edge, the same oversized panel just runs
   past the visible area with nothing left to scroll it into view.
   Corrected to the real number instead of re-guessing another one. */
.cart-panel {
    max-height: calc(100vh - 110px) !important;
}

/* ------------------------------------------------------------
   Sync status pill — topbar, till-only. Tells staff whether this
   till can currently reach head office. Deliberately calm colours,
   never red/alarm-styled: offline is normal trading on a till, not
   a fault — the cashier carries on and sync catches up on its own.
   Markup + polling: layouts/app.blade.php.
   ------------------------------------------------------------ */
.sync-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 6px !important;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    background: #F4F6F9;
    color: #5A6B7B;
    border: 1px solid rgba(90, 107, 123, .18);
    margin-right: 10px;
    white-space: nowrap;
    box-shadow: none !important;
}
.sync-status__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #5A6B7B;
    flex: none;
}
.sync-status__bar {
    display: none;
    width: 44px;
    height: 4px;
    border-radius: 2px;
    background: rgba(46, 155, 214, .2);
    overflow: hidden;
    flex: none;
}
.sync-status__bar-fill {
    display: block;
    width: 40%;
    height: 100%;
    border-radius: 2px;
    background: #2E9BD6;
}

.sync-status[data-state="online"] {
    background: rgba(29, 158, 117, .08);
    color: #1D9E75;
    border-color: rgba(29, 158, 117, .28);
}
.sync-status[data-state="online"] .sync-status__dot { background: #1D9E75; }

.sync-status[data-state="offline"] {
    background: rgba(90, 107, 123, .08);
    color: #5A6B7B;
    border-color: rgba(90, 107, 123, .22);
}

.sync-status[data-state="syncing"] {
    background: rgba(46, 155, 214, .08);
    color: #2E9BD6;
    border-color: rgba(46, 155, 214, .28);
}
.sync-status[data-state="syncing"] .sync-status__dot {
    background: #2E9BD6;
    animation: sync-status-pulse 1s ease-in-out infinite;
}
.sync-status[data-state="syncing"] .sync-status__bar {
    display: inline-block;
}
.sync-status[data-state="syncing"] .sync-status__bar-fill {
    animation: sync-status-indeterminate 1.1s ease-in-out infinite;
}

@keyframes sync-status-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .35; transform: scale(.7); }
}
@keyframes sync-status-indeterminate {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}
@media (prefers-reduced-motion: reduce) {
    .sync-status__dot,
    .sync-status__bar-fill { animation: none !important; }
}

@media (max-width: 767px) {
    .sync-status__label { display: none; }
    .sync-status { padding: 5px 7px; }
}

/* ------------------------------------------------------------
   Round eight: the POS panels on the till, at any window size.

   The two-column POS layout — both panels pinned to one screenful,
   each scrolling its own contents — lives in pos/index.blade.php
   behind `@media (min-width: 992px)`, and below that breakpoint a
   mobile block deliberately undoes it: `.cart-panel { height: auto;
   min-height: 360px }`, cart stacked under the products, page
   scrolls. That is right for a phone.

   It is never right here. A till is a counter machine with a fixed
   window (1440x900 at minimum), and the cashier's own zoom — the
   View menu's Zoom In, which Electron remembers per origin — is
   enough to drop the CSS width under 992 and quietly hand them the
   phone layout: a stubby cart panel with a hole beside it, on a
   1920px screen. The website never shows this because a browser at
   100% is comfortably past the breakpoint.

   So the till states the desktop layout outright, with no width
   condition. Same rules, same --cart-offset measured at runtime by
   fitCartPanel(); only the breakpoint is dropped. Nothing here
   changes the website, which keeps its responsive behaviour.
   ------------------------------------------------------------ */

/* Keep the two columns side by side whatever the width. Below Bootstrap's
   lg breakpoint the grid stacks them — cart under the products — and a
   full-height panel then makes no sense, which is how forcing the height
   without this produced a 37px stub. A till is a counter machine, never a
   phone: the cashier needs the basket beside the catalogue at every size. */
.pos-col {
    flex: 0 0 66.666% !important;
    max-width: 66.666% !important;
}
.cart-col {
    flex: 0 0 33.333% !important;
    max-width: 33.333% !important;
}

.cart-col,
.pos-col {
    align-self: flex-start !important;
}
.cart-col {
    display: flex !important;
    flex-direction: column !important;
}

.cart-panel,
.pos-col .pos-cont {
    box-sizing: border-box !important;
    height: calc(100vh - var(--cart-offset, 150px) - 40px) !important;
    min-height: 0 !important;
    max-height: calc(100vh - var(--cart-offset, 150px) - 40px) !important;
    margin: 20px 0 10px 0 !important;
    position: sticky !important;
    top: 20px;
}

.pos-col .pos-cont {
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}

/* The height has to travel down to the scrolling area four levels
   below, and a flex child will not shrink under its content without
   min-height: 0. */
.pos-col .pos-cont > .card,
.pos-col .pos-cont > .card > form,
.pos-col .pos-cont > .card > form > fieldset {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 !important;
    min-height: 0 !important;
}

/* One scrollbar per tab: the tab content passes its height down, and
   each tab scrolls the one part of itself that should move. */
.pos-col #nav-tabContent {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 !important;
    min-height: 0 !important;
    overflow: hidden !important;
}
.pos-col #nav-tabContent > .tab-pane.active {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 !important;
    min-height: 0 !important;
}
.pos-col #repairWizardContainer {
    flex: 1 !important;
    height: auto !important;
    min-height: 0 !important;
}
.pos-col #nav-lastdays .products-grid {
    flex: 1 !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    align-content: flex-start !important;
}

/* The cart list keeps scrolling inside the panel, with the totals and
   Pay Now pinned under it. */
.cart-items-wrap {
    flex: 1 !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow-y: auto !important;
}
