:root {
    --sidebar-width: 250px;
    --sidebar-collapsed-width: 70px;
    --sidebar-bg: #1e2a38;
    --sidebar-text: #c9d4de;
    --sidebar-active: #2f7ed8;
    --topbar-height: 60px;

    --boutique-blush: #f7e4e0;
    --boutique-blush-deep: #e3a9ae;
    --boutique-gold: #c9a15a;
    --boutique-gold-dark: #a17d3f;
    --boutique-cream: #fdf8f3;
    --boutique-charcoal: #3d3229;
    --boutique-muted: #9a8a7c;
}

body {
    background-color: #f4f6f9;
}

.app-wrapper {
    min-height: 100vh;
}

/* Sidebar */
.sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-width);
    background-color: var(--sidebar-bg);
    color: var(--sidebar-text);
    z-index: 1040;
    transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    overflow-x: hidden;
    overflow-y: auto;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    height: var(--topbar-height);
    padding: 0 1rem;
    font-size: 1.15rem;
    font-weight: 600;
    color: #fff;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    white-space: nowrap;
}

.sidebar-brand i {
    font-size: 1.4rem;
    flex-shrink: 0;
}

.sidebar-menu {
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
}

.sidebar-menu li a {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 1.1rem;
    color: var(--sidebar-text);
    text-decoration: none;
    white-space: nowrap;
    border-left: 3px solid transparent;
}

.sidebar-menu li a i {
    font-size: 1.1rem;
    width: 1.25rem;
    text-align: center;
    flex-shrink: 0;
}

.sidebar-menu li a:hover {
    background-color: rgba(255,255,255,0.06);
    color: #fff;
}

.sidebar-menu li a.active {
    background-color: rgba(47,126,216,0.15);
    border-left-color: var(--sidebar-active);
    color: #fff;
}

/* Parent-child (collapsible) sidebar groups */
.sidebar-menu .submenu-caret {
    font-size: 0.7rem;
    transition: transform 0.2s ease;
    flex-shrink: 0;
}

.sidebar-menu .submenu-toggle[aria-expanded="true"] .submenu-caret {
    transform: rotate(90deg);
}

.sidebar-menu .submenu {
    list-style: none;
    margin: 0;
    padding: 0;
    background-color: rgba(0, 0, 0, 0.15);
}

.sidebar-menu .submenu li a {
    padding-left: 1.9rem;
    font-size: 0.92rem;
}

/* Collapsed (desktop icon-only) */
.sidebar.collapsed {
    width: var(--sidebar-collapsed-width);
}

.sidebar.collapsed .sidebar-brand-text,
.sidebar.collapsed .sidebar-menu li a span {
    display: none;
}

.sidebar.collapsed .sidebar-brand {
    justify-content: center;
    padding: 0;
}

/* Icon-only mode has no room for a caret or an indented nested list, so force every group shut
   regardless of which page is active - expand the sidebar first to navigate within a group. */
.sidebar.collapsed .submenu-caret {
    display: none;
}

.sidebar.collapsed .submenu.show {
    display: none;
}

/* Main area */
.main-area {
    margin-left: var(--sidebar-width);
    transition: margin-left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.sidebar.collapsed ~ .main-area {
    margin-left: var(--sidebar-collapsed-width);
}

.topbar {
    height: var(--topbar-height);
    background-color: #fff;
    border-bottom: 1px solid #e3e7ec;
    display: flex;
    align-items: center;
    padding: 0 1rem;
    position: sticky;
    top: 0;
    z-index: 1030;
}

.topbar-toggle {
    font-size: 1.4rem;
    color: #333;
    text-decoration: none;
}

.topbar-spacer {
    flex: 1 1 auto;
}

.topbar-user-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    color: #333;
}

.topbar-user-btn i {
    font-size: 1.5rem;
}

.topbar-role-badge {
    font-weight: 400;
}

.main-content {
    padding: 1.25rem;
    flex: 1 1 auto;
    animation: pageFadeIn 0.35s ease both;
}

/*  Opacity only -- do NOT add transform back into these keyframes.

    Every modal in this application is authored inside the content placeholder,
    which means it is a descendant of .main-content. A transform on an element
    does two things to its descendants:

      1. it becomes the containing block for position:fixed children, so the
         modal is sized and centred against the content area instead of the
         viewport; and
      2. it creates a stacking context, which traps the modal's z-index:1055
         inside .main-content -- while Bootstrap appends .modal-backdrop
         (z-index:1050) to <body>, outside that context.

    The result is a backdrop painted OVER the dialog: the screen greys out and
    every click in the modal lands on the backdrop instead of the form. Note
    that translateY(0) is still a transform for these purposes, so ending the
    animation at zero does not help -- the transform has to be gone entirely.

    Scripts/site.js also relocates modals out of here as a second line of
    defence, but this rule is the actual fix. */
@keyframes pageFadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 1035;
}

/* Mobile: off-canvas sidebar */
@media (max-width: 767.98px) {
    .sidebar {
        width: var(--sidebar-width);
        transform: translateX(-100%);
    }

    .sidebar.show {
        transform: translateX(0);
    }

    .sidebar.show ~ .sidebar-backdrop,
    .sidebar-backdrop.show {
        display: block;
    }

    .main-area,
    .sidebar.collapsed ~ .main-area {
        margin-left: 0;
    }
}

/* Mobile: bottom tab bar (see Site.Master #bottomNav) - a fixed shortcut row for the handful of
   things staff do most, plus a Menu button that opens the existing sidebar drawer for everything
   else. Hidden outside the mobile breakpoint by this base rule regardless of whether the .d-md-none
   utility class also applies (belt and suspenders, not a conflict - .d-md-none only acts at
   >=768px, same place this rule already hides it). */
.bottom-nav {
    display: none;
}

@media (max-width: 767.98px) {
    .bottom-nav {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1040;
        background-color: #fff;
        border-top: 1px solid #e3e7ec;
        box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
        /* Cushions the bar itself off the home-indicator area on notched phones. */
        padding-bottom: env(safe-area-inset-bottom, 0);
    }

    .bottom-nav-link {
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.15rem;
        padding: 0.4rem 0.25rem;
        border: none;
        background: none;
        color: #6c757d;
        text-decoration: none;
        font-size: 0.7rem;
        line-height: 1.15;
    }

    .bottom-nav-link i {
        font-size: 1.3rem;
    }

    .bottom-nav-link.active {
        color: var(--sidebar-active);
    }

    /* Room for the fixed bar so page content - including the POS page's own fixed
       .cart-action-buttons row - never ends up hidden underneath it. ~56px covers the bar's own
       content height across common phone font-scale settings; the safe-area term covers the rest. */
    .main-content {
        padding-bottom: calc(1.25rem + 56px + env(safe-area-inset-bottom, 0));
    }
}

/* Every grid in the app (DataTables-rendered or plain HTML) sits inside Bootstrap's
   .table-responsive, which already scrolls horizontally when a table is wider than its
   container - but only if the table is actually allowed to be that wide. Without this, a
   header like "Due Date" wraps into "Due" / "Date" and gets squeezed down to a stray "D" as
   the browser shrinks columns to fit instead of scrolling (worst on Dashboard's Supplier
   Payables/Receivables and Customer Payables tables, which have the longest header words).
   Holding headers to their natural width is what makes the container actually overflow and
   scroll like it's supposed to. Data cells are deliberately left free to wrap (a long Remarks/
   Address value wrapping onto two lines is existing, fine behavior) - only headers need this. */
.table-responsive th {
    white-space: nowrap;
}

/* Login page - boutique redesign */
.login-page {
    min-height: 100vh;
    margin: 0;
    font-family: 'Jost', 'Segoe UI', sans-serif;
    background: var(--boutique-cream);
}

.boutique-login-wrap {
    min-height: 100vh;
    display: flex;
}

.boutique-login-panel {
    flex: 1 1 55%;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1.25rem;
    position: relative;
    background:
        radial-gradient(circle at 12% 18%, rgba(201, 161, 90, 0.10) 0, transparent 45%),
        radial-gradient(circle at 88% 82%, rgba(227, 169, 174, 0.22) 0, transparent 50%),
        var(--boutique-cream);
}

.boutique-login-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(201, 161, 90, 0.16) 1px, transparent 1px);
    background-size: 26px 26px;
    opacity: 0.5;
    pointer-events: none;
}

.login-card {
    width: 100%;
    max-width: 380px;
    border: none;
    border-radius: 1rem;
    box-shadow: 0 1.5rem 3rem rgba(61, 50, 41, 0.16);
    position: relative;
    z-index: 1;
    animation: loginRiseIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes loginRiseIn {
    from {
        opacity: 0;
        transform: translateY(26px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.login-card .card-body {
    padding: 2.25rem 2rem;
}

.login-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    font-family: 'Playfair Display', 'Georgia', serif;
    font-size: 1.9rem;
    font-weight: 700;
    color: var(--boutique-charcoal);
}

.login-brand i {
    color: var(--boutique-gold);
}

.login-tagline {
    text-align: center;
    color: var(--boutique-muted);
    font-size: 0.85rem;
    margin: 0.15rem 0 1.5rem;
}

/* Floating labels (Bootstrap's .form-floating mechanics, boutique re-skin) */
.login-page .form-floating > .form-control {
    border: 1px solid #ecdfd2;
    border-radius: 0.6rem;
    background: var(--boutique-cream);
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.login-page .form-floating > .form-control:focus {
    border-color: var(--boutique-gold);
    box-shadow: 0 0 0 0.2rem rgba(201, 161, 90, 0.18);
    background: #fff;
}

.login-page .form-floating > label {
    color: var(--boutique-muted);
}

.login-page .form-floating > .form-control:focus ~ label,
.login-page .form-floating > .form-control:not(:placeholder-shown) ~ label {
    color: var(--boutique-gold-dark);
}

.btn-boutique {
    background: linear-gradient(135deg, var(--boutique-gold) 0%, var(--boutique-gold-dark) 100%);
    border: none;
    color: #fff;
    font-weight: 600;
    letter-spacing: 0.03em;
    padding: 0.65rem 1rem;
    border-radius: 0.6rem;
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.btn-boutique:hover,
.btn-boutique:focus {
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0 0.5rem 1rem rgba(161, 125, 63, 0.35);
    filter: brightness(1.05);
}

.btn-boutique:active {
    transform: translateY(0) scale(0.98);
    box-shadow: 0 0.2rem 0.4rem rgba(161, 125, 63, 0.3);
}

.btn-boutique:disabled {
    opacity: 0.7;
    transform: none;
}

/* Right-side visual panel */
.boutique-visual-panel {
    flex: 1 1 45%;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    color: var(--boutique-cream);
    background: linear-gradient(160deg, var(--boutique-blush-deep) 0%, var(--boutique-gold) 100%);
}

.boutique-visual-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(255, 255, 255, 0.18) 1.5px, transparent 1.5px);
    background-size: 28px 28px;
    opacity: 0.6;
    pointer-events: none;
}

.boutique-visual-inner {
    text-align: center;
    padding: 2rem;
    position: relative;
    z-index: 1;
    animation: pageFadeIn 0.8s ease 0.15s both;
}

.boutique-visual-svg {
    width: 170px;
    height: 170px;
    color: rgba(255, 255, 255, 0.92);
    margin-bottom: 1rem;
    animation: gentleFloat 6s ease-in-out infinite;
}

@keyframes gentleFloat {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-10px);
    }
}

.visual-heading {
    font-family: 'Playfair Display', 'Georgia', serif;
    font-size: 2.1rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    margin-bottom: 0.4rem;
}

.visual-sub {
    font-size: 0.95rem;
    opacity: 0.9;
    letter-spacing: 0.03em;
    margin-bottom: 0;
}

@media (max-width: 991.98px) {
    .boutique-visual-panel {
        display: none;
    }

    .boutique-login-panel {
        flex: 1 1 100%;
    }
}

/* ============================================================
   Permission-driven UI hiding (see Scripts/permissions.js)
   The body gets classes like "perm-noadd-Suppliers" / "perm-noedit-X" /
   "perm-nodelete-X" for every form the current role lacks that right on.
   These rules hide the known Add/Edit/Delete controls per module - this
   also covers buttons rendered dynamically inside DataTables rows, since
   it's a live CSS rule rather than a one-time DOM edit.
   ============================================================ */

/* Setup (Locations / Product Categories / Expense Categories) */
body.perm-noadd-Setup #btnAddLocation,
body.perm-noadd-Setup #btnAddCategory,
body.perm-noadd-Setup #btnAddExpCategory { display: none !important; }
body.perm-noedit-Setup .btn-edit-location,
body.perm-noedit-Setup .btn-edit-category,
body.perm-noedit-Setup .btn-edit-expcategory { display: none !important; }
body.perm-nodelete-Setup .btn-delete-location,
body.perm-nodelete-Setup .btn-delete-category,
body.perm-nodelete-Setup .btn-delete-expcategory { display: none !important; }

/* Suppliers */
body.perm-noadd-Suppliers #btnAddSupplier,
body.perm-noadd-Suppliers .supplier-picker-add { display: none !important; }
body.perm-noedit-Suppliers .btn-edit-supplier { display: none !important; }
body.perm-nodelete-Suppliers .btn-delete-supplier { display: none !important; }

/* Customers */
body.perm-noadd-Customers #btnAddCustomer,
body.perm-noadd-Customers .customer-picker-add { display: none !important; }
body.perm-noedit-Customers .btn-edit-customer { display: none !important; }
body.perm-nodelete-Customers .btn-delete-customer { display: none !important; }

/* Products */
body.perm-noadd-Products #btnAddProduct,
body.perm-noadd-Products .product-picker-add { display: none !important; }
body.perm-noedit-Products .btn-edit-product { display: none !important; }
body.perm-nodelete-Products .btn-delete-product { display: none !important; }

/* Stock Transfer */
body.perm-noadd-StockTransfer #btnAddTransfer { display: none !important; }
body.perm-noedit-StockTransfer .btn-edit-transfer { display: none !important; }
body.perm-nodelete-StockTransfer .btn-delete-transfer { display: none !important; }

/* Purchases (no in-place edit by design) */
body.perm-noadd-Purchases #btnAddPurchase { display: none !important; }
body.perm-nodelete-Purchases .btn-delete-purchase { display: none !important; }

/* Purchase Returns (no in-place edit by design) */
body.perm-noadd-PurchaseReturns #btnAddReturn { display: none !important; }
body.perm-nodelete-PurchaseReturns .btn-delete-return { display: none !important; }

/* Sale Invoice (POS) */
body.perm-noadd-Sales #btnHoldBill,
body.perm-noadd-Sales #btnCompleteSale { display: none !important; }
body.perm-noedit-Sales .btn-edit-sale { display: none !important; }
body.perm-nodelete-Sales .btn-delete-sale { display: none !important; }

/* Sale Returns (no in-place edit by design) */
body.perm-noadd-SaleReturns #btnAddFromInvoice,
body.perm-noadd-SaleReturns #btnAddStandalone { display: none !important; }
body.perm-nodelete-SaleReturns .btn-delete-sr { display: none !important; }

/* Supplier Ledger (payment vouchers - no in-place edit by design) */
body.perm-noadd-SupplierLedger #btnMakePayment { display: none !important; }
body.perm-nodelete-SupplierLedger .btn-delete-payment { display: none !important; }

/* Customer Ledger (receipt vouchers - no in-place edit by design) */
body.perm-noadd-CustomerLedger #btnReceivePayment { display: none !important; }
body.perm-nodelete-CustomerLedger .btn-delete-receipt { display: none !important; }

/* Employees */
body.perm-noadd-Employees #btnAddEmployee,
body.perm-noadd-Employees .employee-picker-add { display: none !important; }
body.perm-noedit-Employees .btn-edit-employee { display: none !important; }
body.perm-nodelete-Employees .btn-delete-employee { display: none !important; }

/* Employee Ledger (payment vouchers - no in-place edit by design) */
body.perm-noadd-EmployeeLedger #btnPayEmployee { display: none !important; }
body.perm-nodelete-EmployeeLedger .btn-delete-epayment { display: none !important; }

/* Expenses */
body.perm-noadd-Expenses #btnAddExpense { display: none !important; }
body.perm-noedit-Expenses .btn-edit-expense { display: none !important; }
body.perm-nodelete-Expenses .btn-delete-expense { display: none !important; }

body.perm-noadd-Reminders #btnAddReminder { display: none !important; }
body.perm-noedit-Reminders .btn-edit-reminder,
body.perm-noedit-Reminders .btn-mark-done { display: none !important; }
body.perm-nodelete-Reminders .btn-delete-reminder { display: none !important; }

/* Dashboard */
.dash-header-banner {
    background: linear-gradient(120deg, var(--boutique-gold) 0%, var(--boutique-blush-deep) 100%);
    border-radius: 14px;
    padding: 1.25rem 1.5rem;
    box-shadow: 0 0.5rem 1.5rem rgba(161, 125, 63, 0.25);
}

.dash-header-banner h4,
.dash-header-banner p,
.dash-header-banner strong {
    color: #fff;
}

.dash-header-banner p {
    color: rgba(255, 255, 255, 0.85);
}

.kpi-card,
.chart-card {
    border: 1px solid rgba(0, 0, 0, 0.06);
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.04);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.kpi-card:hover,
.chart-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.12);
}

/* Every Dashboard KPI box links through to its detail page/report (see dashboard.js's
   data-href click handler) - cursor + focus ring are the only extra affordance needed since
   the existing hover lift above already signals interactivity. */
.kpi-card--clickable {
    cursor: pointer;
}

.kpi-card--clickable:focus-visible {
    outline: 2px solid var(--boutique-gold-dark, #a17d3f);
    outline-offset: 2px;
}

.chart-card {
    border-top: 4px solid var(--boutique-gold);
}

.kpi-icon {
    width: 48px;
    height: 48px;
    min-width: 48px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
    color: #fff;
}

/* Each KPI gets its own soft gradient card + a matching solid icon badge,
   so the seven metrics stay visually distinct at a glance rather than
   uniform white tiles with a tinted icon. */
.kpi-card--sales { background: linear-gradient(135deg, #eafaf1 0%, #d3f3e0 100%); }
.kpi-card--sales .kpi-icon { background: #21b573; }

.kpi-card--purchases { background: linear-gradient(135deg, #eaf1fd 0%, #d6e6fb 100%); }
.kpi-card--purchases .kpi-icon { background: #3a7bd5; }

.kpi-card--receivable { background: linear-gradient(135deg, #e6fbfb 0%, #cdf3f2 100%); }
.kpi-card--receivable .kpi-icon { background: #17a2b8; }

.kpi-card--payable { background: linear-gradient(135deg, #fdecec 0%, #fad3d3 100%); }
.kpi-card--payable .kpi-icon { background: #e05260; }

.kpi-card--cash { background: linear-gradient(135deg, #fdf6e8 0%, #f7e6bf 100%); }
.kpi-card--cash .kpi-icon { background: var(--boutique-gold-dark); }

.kpi-card--lowstock { background: linear-gradient(135deg, #fff3e6 0%, #ffe1bf 100%); }
.kpi-card--lowstock .kpi-icon { background: #e07b1f; }

.kpi-card--expenses { background: linear-gradient(135deg, #f3edf9 0%, #e4d5f2 100%); }
.kpi-card--expenses .kpi-icon { background: #7952b3; }

.kpi-card--todaysprofit { background: linear-gradient(135deg, #f2f9e6 0%, #dff0c0 100%); }
.kpi-card--todaysprofit .kpi-icon { background: #8bc34a; }

.kpi-card--stockvalue { background: linear-gradient(135deg, #ecedfb 0%, #d6d9f5 100%); }
.kpi-card--stockvalue .kpi-icon { background: #5b6fd8; }

.kpi-card--bankbalance { background: linear-gradient(135deg, #e9edf1 0%, #d1d9e0 100%); }
.kpi-card--bankbalance .kpi-icon { background: #34495e; }

.kpi-card--dailysalesstock { background: linear-gradient(135deg, #fdeef2 0%, #f8d7e3 100%); }
.kpi-card--dailysalesstock .kpi-icon { background: #d6336c; }

.kpi-card--reminders { background: linear-gradient(135deg, #fef2e6 0%, #fbdfc0 100%); }
.kpi-card--reminders .kpi-icon { background: #d68910; }

.chart-wrap {
    position: relative;
    height: 260px;
}

@keyframes dashFadeSlideIn {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.dash-anim {
    opacity: 0;
    animation: dashFadeSlideIn 0.5s ease forwards;
}

#kpiRow > div:nth-child(1) .dash-anim { animation-delay: 0.02s; }
#kpiRow > div:nth-child(2) .dash-anim { animation-delay: 0.08s; }
#kpiRow > div:nth-child(3) .dash-anim { animation-delay: 0.14s; }
#kpiRow > div:nth-child(4) .dash-anim { animation-delay: 0.20s; }
#kpiRow > div:nth-child(5) .dash-anim { animation-delay: 0.26s; }
#kpiRow > div:nth-child(6) .dash-anim { animation-delay: 0.32s; }
#kpiRow > div:nth-child(7) .dash-anim { animation-delay: 0.38s; }
#kpiRow > div:nth-child(8) .dash-anim { animation-delay: 0.44s; }
#kpiRow > div:nth-child(9) .dash-anim { animation-delay: 0.50s; }
#kpiRow > div:nth-child(10) .dash-anim { animation-delay: 0.56s; }

#chartRow > div:nth-child(1) .dash-anim { animation-delay: 0.15s; }
#chartRow > div:nth-child(2) .dash-anim { animation-delay: 0.22s; }
#chartRow > div:nth-child(3) .dash-anim { animation-delay: 0.29s; }
#chartRow > div:nth-child(4) .dash-anim { animation-delay: 0.36s; }
#chartRow > div:nth-child(5) .dash-anim { animation-delay: 0.43s; }

@media (max-width: 575.98px) {
    .chart-wrap {
        height: 220px;
    }
}

/* ---------------- Sitewide animation pass ---------------- */

/* Button micro-interactions (applies app-wide - Bootstrap already transitions color/background) */
.btn {
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease, color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.btn:hover:not(:disabled) {
    transform: translateY(-1px);
}

.btn:active:not(:disabled) {
    transform: translateY(0) scale(0.97);
}

/* Modal fade + scale (Bootstrap toggles .show on open; we override the default translate-only transition) */
.modal.fade .modal-dialog {
    transform: scale(0.92) translateY(-12px);
    transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;
}

.modal.show .modal-dialog {
    transform: scale(1) translateY(0);
}

/* Mobile: every modal becomes a tray / bottom sheet instead of a centered popup - the standard
   native-app pattern. Pure CSS, no markup changes anywhere: every modal in this app already
   follows the same Bootstrap 5 structure (.modal > .modal-dialog > .modal-content > .modal-header/
   .modal-body/.modal-footer) with no .modal-dialog-centered/.modal-fullscreen/.modal-dialog-
   scrollable variants to special-case, so one override here covers all ~30 of them. Declared
   after the desktop scale/fade rules above so it wins at the same specificity once this media
   query is in effect; untouched at >=768px. */
@media (max-width: 767.98px) {
    .modal-dialog {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        margin: 0;
        width: 100%;
        max-width: 100%;
    }

    /* Slide up from the bottom edge instead of the desktop scale-in. */
    .modal.fade .modal-dialog {
        transform: translateY(100%);
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
    }

    .modal.show .modal-dialog {
        transform: translateY(0);
    }

    .modal-content {
        border: none;
        border-radius: 1rem 1rem 0 0;
        max-height: 92vh;
        display: flex;
        flex-direction: column;
        padding-top: 0.75rem;
        padding-bottom: env(safe-area-inset-bottom, 0);
    }

    /* Standard bottom-sheet "grab handle" visual cue - decorative only, not wired to a swipe-to-
       dismiss gesture. The X button, Cancel, and backdrop tap already cover closing a modal. */
    .modal-content::before {
        content: "";
        display: block;
        width: 40px;
        height: 4px;
        margin: 0 auto 0.6rem;
        border-radius: 2px;
        background-color: #dcdfe4;
        flex-shrink: 0;
    }

    .modal-header,
    .modal-footer {
        flex-shrink: 0;
    }

    .modal-body {
        overflow-y: auto;
    }
}

/* Table loading overlay - shown briefly over a grid's .table-responsive while its Refresh/Load AJAX
   call is in flight (wired generically in site.js), replacing the blank flash between clearing the
   old rows and rendering the new ones. */
.table-responsive {
    position: relative;
}

.table-loading-overlay {
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.72);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
}

.table-loading-overlay.show {
    opacity: 1;
}

.table-loading-overlay .spinner-border {
    color: var(--sidebar-active);
}

/* Mobile: stack the POS cart action buttons full-width instead of crowding them into one row */
@media (max-width: 575.98px) {
    .cart-action-buttons {
        flex-direction: column;
    }

    .cart-action-buttons .btn {
        width: 100%;
    }
}

/* Mobile: turn line-item "cart" tables (Sales POS, Purchases, Stock Transfer, Sale/Purchase
   Returns) into stacked cards instead of a 5-7 column table squeezed into a phone's width -
   the classic responsive-table-to-cards technique (thead hidden, each td becomes its own
   labeled row via data-label). Scoped to .line-item-table so desktop/tablet keep today's
   compact table completely untouched - this only fires below the same breakpoint the POS
   cart action buttons above already use.
   Row-builder JS (Scripts/sales.js renderCart, Scripts/purchases.js addItemRow, and the
   equivalent in stockTransfer.js/saleReturns.js/purchaseReturns.js) tags each <td> with
   data-label="...", plus two special cells: .cart-product-cell (the product name/picker -
   no label prefix, shown full-width as the card's title) and .cart-action-cell (the delete
   button - no label prefix, right-aligned). .cart-img-cell (Sales' product thumbnail) is
   dropped entirely on mobile; it's the least useful cell in a cramped card. */
@media (max-width: 575.98px) {
    .line-item-table thead {
        display: none;
    }

    .line-item-table,
    .line-item-table tbody,
    .line-item-table tr,
    .line-item-table td {
        display: block;
        width: 100%;
    }

    .line-item-table {
        border: none;
    }

    .line-item-table tbody tr {
        border: 1px solid #dee2e6;
        border-radius: 0.5rem;
        margin-bottom: 0.75rem;
        padding: 0.6rem 0.75rem;
        background: #fff;
    }

    .line-item-table td {
        border: none !important;
        padding: 0.3rem 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.5rem;
    }

    .line-item-table td::before {
        content: attr(data-label);
        font-weight: 600;
        color: #6c757d;
        font-size: 0.78rem;
        flex: 0 0 auto;
    }

    .line-item-table td:not(.cart-product-cell) input,
    .line-item-table td:not(.cart-product-cell) select {
        max-width: 140px;
        text-align: right;
    }

    .line-item-table td.cart-img-cell {
        display: none;
    }

    .line-item-table td.cart-product-cell {
        justify-content: flex-start;
        font-weight: 600;
        padding-bottom: 0.5rem;
        margin-bottom: 0.4rem;
        border-bottom: 1px solid #eee !important;
    }

    .line-item-table td.cart-product-cell::before {
        content: none;
    }

    .line-item-table td.cart-product-cell .input-group,
    .line-item-table td.cart-product-cell select {
        width: 100%;
        max-width: none;
    }

    .line-item-table td.cart-action-cell {
        justify-content: flex-end;
    }

    .line-item-table td.cart-action-cell::before {
        content: none;
    }

    /* Sales.aspx's below-purchase-price warning (Scripts/sales.js recomputeCart) is appended as
       a sibling of the Rate <input> inside its td - force it onto its own full-width line rather
       than competing for space in the flex row next to the input. */
    .line-item-table td {
        flex-wrap: wrap;
    }

    .line-item-table .cart-cost-warning {
        flex-basis: 100%;
        text-align: right;
    }
}

/* ---------------- Print (PrintHelper.printElement) ---------------- */
/* Whichever element currently carries .print-area is the only thing shown when printing - used
   consistently across every document/report view: Sale/Purchase invoice and return detail modals,
   the Supplier/Customer/Employee Ledger statements, and every Reports tab. PrintHelper itself
   injects the .print-header/.print-footer nodes as children of .print-area right before printing,
   so they inherit its visibility automatically and need no extra selector here. */
@media print {
    * {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    body * {
        visibility: hidden;
    }

    .print-area,
    .print-area * {
        visibility: visible;
    }

    .print-area {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        padding: 1rem;
        font-size: 0.85rem;
        color: #2a241d;
    }

    .no-print {
        display: none !important;
    }

    .print-header {
        text-align: center;
        margin-bottom: 1.25rem;
        padding-bottom: 0.75rem;
        border-top: 3px solid var(--boutique-gold, #c9a15a);
        border-bottom: 1px solid #2a241d;
        padding-top: 0.6rem;
    }

    .print-shop-name {
        font-size: 1.6rem;
        font-weight: 700;
        font-family: 'Playfair Display', Georgia, serif;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: #2a241d;
    }

    .print-doc-title {
        font-size: 0.8rem;
        font-weight: 600;
        color: var(--boutique-gold-dark, #a17d3f);
        margin-top: 0.3rem;
        text-transform: uppercase;
        letter-spacing: 0.12em;
    }

    .print-area table {
        width: 100%;
        border-collapse: collapse !important;
        font-size: 0.8rem;
    }

    .print-area table th,
    .print-area table td {
        border: 1px solid #c9c2b8 !important;
        padding: 0.4rem 0.55rem !important;
        background: transparent !important;
    }

    .print-area table thead th {
        background: #f3ead9 !important;
        color: #2a241d;
        font-weight: 700;
        text-transform: uppercase;
        font-size: 0.7rem;
        letter-spacing: 0.04em;
        border-bottom: 2px solid var(--boutique-gold, #c9a15a) !important;
    }

    .print-area table tbody tr:nth-child(even) td {
        background: #faf7f1 !important;
    }

    .print-area .card {
        border: none !important;
        box-shadow: none !important;
    }

    .print-footer {
        margin-top: 1.5rem;
        padding-top: 0.5rem;
        border-top: 1px solid #c9c2b8;
        font-size: 0.7rem;
        font-style: italic;
        color: #7a7167;
        text-align: center;
    }

    @page {
        margin: 1.5cm;
    }
}

.share-note {
    font-size: 0.8rem;
}
