/* ==========================================================================
   APP.CSS — Global Styles for M_Wallet
   Organized: Animations → Utilities → Components → MudBlazor Overrides → Responsive
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. ANIMATIONS
   -------------------------------------------------------------------------- */

@keyframes jiggle {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-4px); }
    40% { transform: translateX(4px); }
    60% { transform: translateX(-4px); }
    80% { transform: translateX(4px); }
}

@keyframes slideIn {
    from { opacity: 0; transform: translateX(20px); }
    to   { opacity: 1; transform: translateX(0); }
}


/* --------------------------------------------------------------------------
   2. UTILITY CLASSES
   -------------------------------------------------------------------------- */

.cursor-pointer {
    cursor: pointer;
    transition: transform 0.2s;
}
.cursor-pointer:hover {
    transform: scale(1.05);
}

.text-nowrap { white-space: nowrap; }

.scroll-x-touch { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.text-amount {
    font-weight: 600;
    font-size: 1rem;
}

.no-focus-steal button,
.no-focus-steal .mud-toggle-item {
    -webkit-tap-highlight-color: transparent;
}


/* --------------------------------------------------------------------------
   3. STATUS BADGES
   -------------------------------------------------------------------------- */

.badge {
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 4px;
    display: inline-block;
}
.badge-success  { background: rgba(var(--mud-palette-success-rgb), 0.15);   color: var(--mud-palette-success); }
.badge-warning  { background: rgba(var(--mud-palette-warning-rgb), 0.15);   color: var(--mud-palette-warning); }
.badge-error    { background: rgba(var(--mud-palette-error-rgb), 0.15);     color: var(--mud-palette-error); }
.badge-info     { background: rgba(var(--mud-palette-info-rgb), 0.15);      color: var(--mud-palette-info); }
.badge-primary  { background: rgba(var(--mud-palette-primary-rgb), 0.15);   color: var(--mud-palette-primary); }
.badge-secondary{ background: rgba(var(--mud-palette-secondary-rgb), 0.15); color: var(--mud-palette-secondary); }

/* ── App-bar: pinned favourites scroll horizontally — smooth, but snap to whole icons so a
      swipe never leaves a half-cut one. A thin scrollbar sits low under the strip and fades
      out on its own when idle. A divider keeps bell + search pinned apart. ── */
.appbar-favorites {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    scroll-snap-type: x proximity;     /* settle on a whole icon — no half transitions */
    scroll-behavior: smooth;
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;   /* hidden until actively scrolling */
}
.appbar-favorites > * { scroll-snap-align: start; }
.appbar-favorites::-webkit-scrollbar { height: 3px; }
.appbar-favorites::-webkit-scrollbar-thumb { background: transparent; border-radius: 3px; }
/* Reveal the thin scrollbar only while the strip is being scrolled (JS toggles .is-scrolling). */
.appbar-favorites.is-scrolling { scrollbar-color: rgba(127, 127, 127, 0.4) transparent; }
.appbar-favorites.is-scrolling::-webkit-scrollbar-thumb { background: rgba(127, 127, 127, 0.4); }

/* ── App-bar nav (desktop top-bar + mobile bottom-bar): flat full-height square slots, like the app's
   tabs. Menu / bell / search are fixed squares pinned to the bar ends; favourites scroll horizontally
   between them so they never cram and nothing is hidden. The active favourite shows a flat underline on
   the bar edge. --slot = bar height, so slots stay square and the underline lands on the edge. ── */
header.mud-appbar .mud-toolbar { --slot: 56px; --slot-w: var(--slot); align-items: stretch; padding: 0; }
/* Phone: split the bar evenly into 7 slots — menu + 4 favourites + bell + search — so each is exactly
   1/7 of the screen wide (favourites grow to fill their share; any extras scroll). --slot stays the bar
   height; only the width (--slot-w) changes, so the bar doesn't get taller. */
@media (max-width: 599.98px) { header.mud-appbar .mud-toolbar { --slot-w: calc(100vw / 7); } }
@media (min-width: 960px) { header.mud-appbar .mud-toolbar { --slot: 64px; } }

/* Each slot is a fixed square (menu/bell/search are direct toolbar children; favourites sit in the strip). */
header.mud-appbar .mud-toolbar > button.mud-icon-button,
header.mud-appbar .mud-toolbar > .mud-menu,
.appbar-favorites > * {
    flex: 0 0 var(--slot-w) !important; min-width: 0 !important;
    display: inline-flex !important; align-items: stretch;
}
header.mud-appbar .mud-toolbar > .appbar-pinned-divider { flex: 0 0 1px !important; }
header.mud-appbar .mud-toolbar .mud-menu-activator,
header.mud-appbar .mud-toolbar .mud-menu .mud-badge-root { width: 100%; }
/* Compact bar: stretch the favourites to fill the strip right up to the divider (no trailing gap).
   Once there are too many to fit they stop growing and scroll instead (grow only eats positive slack). */
@media (max-width: 959px) { .appbar-favorites > * { flex-grow: 1 !important; } }

/* Buttons fill their slot: square, full bar height, centred icon, flat (the active page is shown by the
   underline, not a fill). MudBlazor's .mud-ripple::after tap ripple is left intact. */
header.mud-appbar .mud-toolbar button.mud-icon-button {
    width: 100% !important; height: var(--slot) !important;
    margin: 0 !important; padding: 0 !important; border-radius: 0 !important;
    display: inline-flex !important; align-items: center; justify-content: center;
    background-color: transparent !important;
}

/* Bell unread badge: the toolbar stretches the bell's slot to the full bar height AND width with the
   icon centred, so by default the badge anchors to the SLOT's top-right corner — floating above and to
   the right of the bell. Pin it to the ICON's own top-right corner instead: (slot − icon)/2 in from the
   top, and (slot-width − icon)/2 in from the right. Works at any bar size (mobile 1/7-screen slots /
   desktop 64px). */
header.mud-appbar .mud-toolbar .mud-menu .mud-badge.mud-badge-overlap {
    top: calc((var(--slot) - 24px) / 2) !important;
    right: calc((var(--slot-w) - 24px) / 2) !important;
    left: auto !important;        /* MudBlazor sets `left`, which would override `right` — clear it */
    bottom: auto !important;
    transform: translate(40%, -40%) !important;   /* straddle the icon's top-right corner */
}

/* Active favourite: a flat underline on the bar edge — desktop bottom, mobile top — like the active tab. */
.appbar-favorites > *:has(.appbar-fav-active) { box-shadow: inset 0 -3px 0 0 var(--mud-palette-primary); }
@media (max-width: 959px) {
    .appbar-favorites > *:has(.appbar-fav-active) { box-shadow: inset 0 3px 0 0 var(--mud-palette-primary); }
}

/* Mobile card field icons (MobileIconLabel): tap an icon to reveal the field name as a small
   themed bubble above it. Bubble fades in/out; the component handles timing and single-open. */
.mobile-icon-label { position: relative; display: inline-flex; align-items: center; margin-right: 4px; cursor: pointer; user-select: none; }
.mobile-icon-label__pop {
    position: absolute;
    bottom: calc(100% + 4px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    border: 1px solid var(--mud-palette-lines-default);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    padding: 7px 13px;
    border-radius: 8px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
    z-index: 50;
    pointer-events: none;
    animation: mil-pop-in 150ms ease both;
}
.mobile-icon-label__pop.is-closing { animation: mil-pop-out 190ms ease forwards; }
@keyframes mil-pop-in {
    from { opacity: 0; transform: translate(-50%, 5px) scale(0.94); }
    to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
@keyframes mil-pop-out {
    from { opacity: 1; transform: translate(-50%, 0) scale(1); }
    to   { opacity: 0; transform: translate(-50%, 3px) scale(0.94); }
}
.appbar-pinned-divider {
    flex: 0 0 auto;
    align-self: stretch;
    width: 1px;
    margin: 12px 0;
    background: currentColor;
    opacity: 0.3;
}


/* --------------------------------------------------------------------------
   4. NOTIFICATION TOAST
   -------------------------------------------------------------------------- */

.notification-toast {
    position: fixed;
    top: 12px;
    right: 12px;
    z-index: 9999;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: 6px;
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    animation: slideIn 0.15s ease-out;
}
.notification-success { background: #4caf50; color: white; }
.notification-warning { background: #ff9800; color: white; }
.notification-error   { background: #f44336; color: white; }
.notification-info    { background: #2196f3; color: white; }


/* --------------------------------------------------------------------------
   5. FORM VALIDATION
   -------------------------------------------------------------------------- */

.field-error {
    animation: jiggle 0.4s ease-in-out;
}
.field-error .mud-input-outlined-border,
.field-invalid .mud-input-outlined-border {
    border-color: var(--mud-palette-error) !important;
    border-width: 2px !important;
}
.field-error .mud-input-label,
.field-invalid .mud-input-label {
    color: var(--mud-palette-error) !important;
}


/* --------------------------------------------------------------------------
   6. FILTER GRID
   -------------------------------------------------------------------------- */

.filter-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}


/* --------------------------------------------------------------------------
   7. POS CART
   -------------------------------------------------------------------------- */

.pos-payment-row { align-items: stretch; }
.pos-payment-row > *,
.pos-payment-row > .mud-button-group-root {
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
}
.pos-payment-row > .mud-button-group-root .mud-button-root { height: 100% !important; }
.pos-payment-row > .mud-tooltip-root,
.pos-payment-row > .mud-tooltip-root > .mud-icon-button {
    height: 40px !important;
    min-height: 40px !important;
}
.pos-payment-row > .mud-input-control {
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
}
.pos-payment-row > .mud-input-control .mud-input-slot {
    height: 40px !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

.cart-item-image {
    width: 36px; height: 36px;
    object-fit: cover; border-radius: 6px;
    margin-right: 1px;
    background-color: var(--mud-palette-grey-light);
    flex-shrink: 0;
}
.cart-item-image-sm {
    width: 32px; height: 32px;
    object-fit: cover; border-radius: 6px;
    margin-right: 4px;
    background-color: var(--mud-palette-grey-light);
    flex-shrink: 0;
}
/* ===== POS cart tabs (active cart + parked carts) ===== */
.pos-cart-tabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    flex-wrap: wrap;
    border-bottom: 2px solid var(--mud-palette-lines-default);
    margin-bottom: 12px;
}
.pos-tab {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    cursor: pointer;
    user-select: none;
    border: 1px solid var(--mud-palette-lines-default);
    border-bottom: none;
    border-radius: 8px 8px 0 0;
    /* inactive tabs sit a shade darker than the panel, so they read as recessed */
    background: var(--mud-palette-gray-light);
    color: var(--mud-palette-text-secondary);
    font-size: 0.82rem;
    line-height: 1.2;
    max-width: 180px;
    transition: background-color .15s, color .15s;
    margin-bottom: -2px; /* overlap the strip's bottom border */
}
.pos-tab:hover { background: var(--mud-palette-gray-lighter); }
.pos-tab--active {
    /* match the cart panel exactly so the active tab merges into the content below */
    background: var(--mud-palette-gray-lighter);
    color: var(--mud-palette-text-primary);
    font-weight: 600;
    border-color: var(--mud-palette-lines-default);
    border-bottom: 2px solid var(--mud-palette-gray-lighter);
    cursor: default;
}
.pos-tab--active:hover { background: var(--mud-palette-gray-lighter); }
/* accent stripe along the top of the active tab */
.pos-tab--active { box-shadow: inset 0 3px 0 0 var(--mud-palette-primary); }
.pos-tab--import.pos-tab--active { box-shadow: inset 0 3px 0 0 var(--mud-palette-info); }
.pos-tab--import { color: var(--mud-palette-info); }
.pos-tab-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pos-tab-count {
    flex: 0 0 auto;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: rgba(var(--mud-palette-primary-rgb), 0.15);
    color: var(--mud-palette-primary);
    font-size: 0.7rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.pos-tab--import .pos-tab-count {
    background: rgba(var(--mud-palette-info-rgb), 0.18);
    color: var(--mud-palette-info);
}
.pos-tab-close {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    font-size: 0.95rem;
    line-height: 1;
    opacity: 0.6;
}
.pos-tab-close:hover {
    opacity: 1;
    background: rgba(var(--mud-palette-error-rgb), 0.18);
    color: var(--mud-palette-error);
}
.pos-tab-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-bottom: 2px;
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 8px;
    background: transparent;
    color: var(--mud-palette-text-secondary);
    cursor: pointer;
    font-size: 1.1rem;
    transition: background-color .15s, color .15s, border-color .15s;
}
.pos-tab-add:hover:not(:disabled) {
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
    background: rgba(var(--mud-palette-primary-rgb), 0.08);
}
.pos-tab-add:disabled { opacity: 0.4; cursor: default; }

.cart-item-card   { border-radius: 8px; }
.cart-item-line   { display: flex; align-items: center; justify-content: space-between; gap: 2px 8px; flex-wrap: wrap; }
/* min-width reserves real room for the product name: when the quantity/price controls don't fit
   next to it, they wrap below instead of crushing the name to a few characters. */
.cart-item-info   { display: flex; align-items: center; gap: 8px; min-width: min(200px, 100%); flex: 1 1 0; overflow: hidden; }
.cart-item-right  { display: flex; align-items: center; justify-content: flex-end; gap: 4px; flex: 0 0 auto; flex-wrap: nowrap; margin-left: auto; }
.cart-quantity-editor {
    display: flex;
    align-items: center;
    gap: 0;
    flex-shrink: 0;
    height: 28px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    background: var(--mud-palette-surface);
    overflow: hidden;
}
.cart-quantity-editor .mud-icon-button {
    width: 22px !important;
    height: 26px !important;
    min-width: 22px !important;
    padding: 0 !important;
    border-radius: 0 !important;
    color: var(--mud-palette-text-primary);
}
.cart-quantity-editor .mud-icon-button:hover {
    background-color: rgba(var(--mud-palette-primary-rgb), 0.1);
    color: var(--mud-palette-primary);
}
.cart-quantity-editor .mud-icon-button .mud-icon-root {
    font-size: 0.9rem !important;
}
.cart-qty-input { width: 24px; text-align: center; }
.cart-quantity-editor .cart-qty-input .mud-input,
.cart-quantity-editor .cart-qty-input .mud-input-control {
    margin: 0 !important;
    padding: 0 !important;
    background: transparent !important;
}
.cart-quantity-editor .cart-qty-input .mud-input:before,
.cart-quantity-editor .cart-qty-input .mud-input:after,
.cart-quantity-editor .cart-qty-input .mud-input-underline:before,
.cart-quantity-editor .cart-qty-input .mud-input-underline:after {
    border-bottom: none !important;
    display: none !important;
}
.cart-quantity-editor .cart-qty-input input {
    text-align: center;
    padding: 0 !important;
    font-size: 0.85rem;
    font-weight: 600;
    height: 26px;
}
.cart-price-total { display: flex; align-items: center; gap: 2px; flex-wrap: nowrap; }
.cart-price-edit  { display: flex; align-items: center; gap: 2px; font-size: 0.85em; }
.cart-item-subtotal,
.cart-total-display {
    min-width: 50px; text-align: right;
    display: flex; flex-direction: column; align-items: flex-end; line-height: 1; gap: 0;
}
.cart-amount   { font-size: 1.05em; font-weight: 700; line-height: 1; }
.cart-currency { font-size: 0.65em; font-weight: 600; letter-spacing: 0.3px; line-height: 1; }

.responsive-card-width { width: 50%; flex: 0 0 auto; }


/* --------------------------------------------------------------------------
   8. TABLE CELLS & FOOTER
   -------------------------------------------------------------------------- */

/* AppTable's Height= is a CAP, not a fixed size (it lands here as --mw-table-h,
   set on the table root instead of MudTable's fixed-height container): short
   pages hug their rows so the pager sits right under the last one — no tall
   empty paper — and the container only scrolls internally (sticky header intact)
   once content exceeds the cap. For page tables, appTableSticky.js refines the
   cap to the real remaining viewport space (--mw-table-fit), so the pager +
   sum footer always stay on screen no matter the window height; --mw-table-h
   is the pre-JS first-paint fallback and the cap for dialog tables. */
.compact-table .mud-table-container {
    overflow-x: auto;
    overflow-y: auto;
    max-height: var(--mw-table-fit, var(--mw-table-h, none));
}
.compact-table .mud-table-container > table {
    table-layout: auto; width: 100%; min-width: 800px;
}
.compact-table .mud-table-container > table td,
.compact-table .mud-table-container > table th {
    white-space: nowrap; padding: 6px 10px;
}

.table-footer-cell      { border-top: 3px solid #7c4dff; }
.table-footer-cell-bold { border-top: 3px solid #7c4dff; font-weight: bold; }
.table-footer-cell-gray { font-weight: bold; background: var(--mud-palette-background-gray); }

td.cell-name, td.cell-name * { font-weight: 700 !important; }

/* Ghost action slot: a not-applicable row action (e.g. Refund on a refunded
   order, Codes on a non-digital one) still renders — invisible — so it holds
   its exact natural width and every action lines up in its own column across
   rows. Card view drops ghosts entirely so the real buttons share the full
   card width. */
td.cell-actions .action-ghost { visibility: hidden; pointer-events: none; }
@media (max-width: 599.98px) {
    .card-view td.cell-actions .action-ghost { display: none !important; }
}

/* Collapse a ghost slot entirely when NO row in the table has a live instance
   of it (e.g. the physical-products tab, where no row has Codes): ghosts only
   exist to align against live buttons — with none, they just waste width.
   Each ghostable action carries a slot-* identity class for this. */
.compact-table:not(:has(.cell-actions .slot-refund:not(.action-ghost))) .cell-actions .slot-refund.action-ghost,
.compact-table:not(:has(.cell-actions .slot-codes:not(.action-ghost))) .cell-actions .slot-codes.action-ghost,
.compact-table:not(:has(.cell-actions .slot-promo:not(.action-ghost))) .cell-actions .slot-promo.action-ghost,
.compact-table:not(:has(.cell-actions .slot-invoice:not(.action-ghost))) .cell-actions .slot-invoice.action-ghost,
.compact-table:not(:has(.cell-actions .slot-whatsapp:not(.action-ghost))) .cell-actions .slot-whatsapp.action-ghost,
.compact-table:not(:has(.cell-actions .slot-rowedit:not(.action-ghost))) .cell-actions .slot-rowedit.action-ghost {
    display: none;
}

/* RTL flips layout but never icon glyphs, so directional icons (chevrons, back
   arrows, logout door…) end up pointing the wrong way in Arabic. Tag the icon —
   or its host button — with .rtl-mirror to flip the glyph with the layout. */
[dir="rtl"] .rtl-mirror svg,
[dir="rtl"] svg.rtl-mirror { transform: scaleX(-1); }
td.cell-name { white-space: nowrap; }
td.cell-name .statement-btn { vertical-align: middle; }

.statement-btn { min-width: 28px; min-height: 28px; width: 28px; height: 28px; padding: 2px; }


/* --------------------------------------------------------------------------
   9. TABLE PAGINATION
   -------------------------------------------------------------------------- */

.hide-skip-buttons .mud-table-pagination-actions button:first-child,
.hide-skip-buttons .mud-table-pagination-actions button:last-child { display: none; }

.hide-info-text .mud-table-pagination-information { display: none; }
.hide-info-text .mud-table-pagination-actions { display: none; }
.hide-info-text.mud-table-pagination .mud-toolbar { min-height: 0 !important; padding: 0; border: none; }
.hide-info-text.mud-table-pagination { border-top: none !important; }


/* --------------------------------------------------------------------------
   10. TABS
   -------------------------------------------------------------------------- */

/* Full-width tabs: each tab stretches equally */
.full-width-tabs { width: 100%; }
.full-width-tabs .mud-tabs-toolbar { width: 100% !important; }
.full-width-tabs .mud-tabs-toolbar-content { width: 100% !important; display: flex !important; }
.full-width-tabs .mud-tabs-toolbar-content .mud-tab { flex: 1 1 0px !important; max-width: none !important; min-width: 0 !important; }

/* Hide tab header (used when custom AppTabs are present) */
.hide-tab-header .mud-tabs-toolbar,
.hide-tab-header .mud-tabs-tabbar,
.hide-tab-header .mud-tabs-tabbar-content {
    display: none !important; visibility: hidden !important;
    height: 0 !important; padding: 0 !important;
}
.hide-tab-header.mud-tabs {
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    margin-top: 0 !important;
}
.hide-tab-header .mud-table,
.hide-tab-header .mud-table-toolbar {
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}


/* --------------------------------------------------------------------------
   11. RTL FIXES
   -------------------------------------------------------------------------- */

[dir="rtl"] .mud-input-control .mud-input-slot { text-align: right; direction: rtl; }
[dir="rtl"] .mud-input-control .mud-input-label {
    width: 50%; text-align: right; transform-origin: top right; right: 0; left: auto;
}
[dir="rtl"] .mud-input-control.mud-input-outlined-with-label .mud-input-label {
    transform: translate(-1px, 10px) scale(1.0);
}

input, textarea { unicode-bidi: plaintext !important; }


/* --------------------------------------------------------------------------
   12. MUDBLAZOR GLOBAL OVERRIDES
   -------------------------------------------------------------------------- */

/* Remove stuck focus highlight on ghost/text buttons. Filled variants keep
   their background — without the :not, the rule strips the fill and the
   button visually disappears into the row behind it. */
.mud-icon-button:not(.mud-button-filled):focus,
.mud-button-root:not(.mud-button-filled):focus,
.mud-checkbox:focus-within .mud-button-root:not(.mud-button-filled) {
    background-color: transparent !important;
}

/* Offline banner: pinned just below the AppBar on desktop and at the very
   top on mobile (where the AppBar is a bottom nav). Main content gets extra
   top padding only while the banner is rendered. */
.offline-banner-wrapper {
    position: fixed;
    top: 64px;
    left: 0;
    right: 0;
    z-index: 1100;
}
body:has(.offline-banner-wrapper) .mud-main-content {
    padding-top: 104px !important;
}

/* Consistent 56px table toolbar height */
.mud-table-toolbar {
    min-height: 56px !important;
    max-height: 56px !important;
}

/* Dialog: compact title bar (48px) with inline close button */
.mud-dialog-title {
    padding: 0px 8px 0px 16px !important;
    min-height: 48px !important;
    display: flex !important;
    align-items: center !important;
    flex-shrink: 0;
}
.mud-dialog-title .mud-button-close {
    position: static !important;
    margin-left: auto;
    flex-shrink: 0;
}

/* Dialog: flexbox internal scrolling constraints */
.mud-dialog {
    transition: all 0.3s ease !important;
    display: flex !important;
    flex-direction: column !important;
    max-height: 90vh !important;
    overflow: hidden !important;
}

/* Dialog: tighter content padding and scrollable body */
.mud-dialog-content {
    padding: 0px 8px !important;
    flex: 1 1 auto;
    min-height: 0 !important;
    overflow-y: auto !important;
}

/* Dialog: pinned actions */
.mud-dialog-actions {
    flex-shrink: 0;
}

/* =========================================================
   DIALOG FULLSCREEN MODES
   =========================================================*/

/* 
   MODE 1: Absolute Fullscreen (Desktop & Mobile)
   Usage: Add Class="always-fullscreen" to <MudDialog> 
   Effect: Forces the dialog to consume 100% of the viewport on ALL devices.
*/
.mud-dialog-container:has(.always-fullscreen),
.mud-dialog-container:has(.mud-dialog.always-fullscreen) {
    overflow: hidden !important;
}
.mud-dialog.always-fullscreen,
.mud-dialog:has(.always-fullscreen) {
    max-width: 100% !important; max-height: 100% !important;
    width: 100vw !important; height: 100dvh !important;
    margin: 0 !important; border-radius: 0 !important;
    position: fixed !important; top: 0 !important; left: 0 !important;
}
.mud-dialog.always-fullscreen .mud-table-container,
.mud-dialog:has(.always-fullscreen) .mud-table-container {
    max-height: unset !important;
    height: auto !important;
}

/* ------------------------------------------------------------------
   Shared table-page fill height. A virtualized MudTable needs a stable,
   viewport-anchored height so it (a) fills the screen below the fixed
   chrome and (b) never collapses to 0 rows when a keep-alive page is
   hidden (which caused the "flash white then populate" on re-entry).
   Applied via Height="var(--table-fill-h)" on every table page — one
   source of truth. Subtracts only real fixed constants (app bar + tab
   strip; on mobile the app bar is a bottom nav, so a bit more). Tune the
   two values here once and every table page follows. -------------------- */
:root { --table-fill-h: calc(100dvh - 110px); }
/* ≤959px the app bar becomes a bottom nav (app.css ~681), so subtract more.
   This breakpoint MUST match that one — otherwise tablets run under the bottom nav. */
@media (max-width: 959px) { :root { --table-fill-h: calc(100dvh - 175px); } }


/* --------------------------------------------------------------------------
   13. RESPONSIVE — DESKTOP (min-width: 600px)
   -------------------------------------------------------------------------- */

@media (min-width: 600px) {
    .responsive-card-width { width: 33.33%; }
    .filter-grid { grid-template-columns: repeat(4, 1fr); }

    /* Right-align currency columns */
    td.cell-currency, th.cell-currency,
    .table-footer-cell-bold.cell-currency,
    .table-footer-cell.cell-currency {
        text-align: right !important;
    }

    /* Money cells wrap their value in a flex row for the mobile leading icon; flex ignores the
       inherited text-align, so pin the value to the end under its right-aligned header. RTL already
       aligns (flex-start is the right edge), so scope to LTR only. */
    [dir="ltr"] td.cell-currency > .d-flex { justify-content: flex-end; }

    /* Compact desktop action buttons */
    td.cell-actions { padding-top: 4px !important; padding-bottom: 4px !important; white-space: nowrap; }
    td.cell-actions .card-action-btn {
        border-radius: 8px; padding: 6px 12px !important;
        font-size: 0.85rem !important; font-weight: 700 !important;
        text-transform: none !important; line-height: 1.2; gap: 4px;
        flex-shrink: 0;
    }
    /* Action buttons (Edit/Stock/Delete/...) must stay on one row even when the
       viewport is narrow — stacking them was visually loud and easy to misclick.
       The cell expands to fit; horizontal scroll on the table handles overflow. */
    td.cell-actions > div { flex-wrap: nowrap !important; }
    td.cell-actions .card-action-btn .mud-button-icon-start { margin-right: 2px !important; margin-left: 0 !important; }
    td.cell-actions .mud-menu .mud-icon-button { padding: 8px !important; }
    td.cell-actions .mud-divider.mud-divider-vertical { margin: 0 4px !important; }

    /* Sum footer (tfoot) sticks to the bottom of the scroll area, mirroring the
       sticky header: totals stay visible while the body scrolls. z-index 2 keeps
       it above the pinned Actions body cells (z1), below the header (z3). The
       zero-specificity :where() backing lets classed footers (e.g.
       .table-footer-cell-gray) keep their own background. */
    .compact-table .mud-table-container tfoot th,
    .compact-table .mud-table-container tfoot td {
        position: sticky;
        bottom: 0;
        z-index: 2;
    }
    :where(.compact-table .mud-table-container tfoot th,
           .compact-table .mud-table-container tfoot td) {
        background-color: var(--mud-palette-surface);
    }

    /* ── Pinned Actions column ──────────────────────────────────────────────
       Wide tables overflow horizontally; keep the row actions reachable by
       sticking the Actions column to the trailing (inline-end) edge. No
       .card-view exclusion needed: the .card-view class can be present on
       desktop (it's a persisted preference) but its card layout only applies
       under 600px, and this whole block is ≥600px-only. Scrolled cells slide
       under the pinned cell, so it needs an OPAQUE backing: a solid surface
       base plus a state overlay (hover / inactive row) layered on via
       --mw-pin-overlay, keeping it seam-matched to the rest of the row. */
    .compact-table th.cell-actions,
    .compact-table td.cell-actions {
        position: sticky;
        inset-inline-end: 0;
        background-color: var(--mud-palette-surface);
        background-image: linear-gradient(var(--mw-pin-overlay, transparent), var(--mw-pin-overlay, transparent));
    }
    .compact-table td.cell-actions { z-index: 1; }
    .compact-table th.cell-actions { z-index: 3; }

    /* Floating cue — only while row content is actually hidden under the pinned
       column (appTableSticky.js adds .mw-pin-floating): a crisp inner edge + a
       shadow so it reads as hovering above the scrolled content. Gone when the
       table fits AND once the user scrolls fully to the column's natural end —
       then it looks like a normal last column. */
    .compact-table .mw-pin-floating th.cell-actions,
    .compact-table .mw-pin-floating td.cell-actions {
        border-inline-start: 1px solid var(--mud-palette-table-lines);
    }
    /* The shadow is a flat gradient strip per cell hanging over the scrolled
       content (content-facing side), NOT a box-shadow: a box-shadow's blur fades
       at every cell's top/bottom edge, so stacked rows read as a dashed line.
       Strips span the cell's full height (borders included) and butt together
       seamlessly row-to-row = one continuous shadow. */
    .compact-table .mw-pin-floating th.cell-actions::after,
    .compact-table .mw-pin-floating td.cell-actions::after {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        inset-inline-end: 100%; /* hangs off the content-facing edge in both LTR and RTL */
        width: 8px;
        pointer-events: none;
    }
    [dir="ltr"] .compact-table .mw-pin-floating th.cell-actions::after,
    [dir="ltr"] .compact-table .mw-pin-floating td.cell-actions::after {
        background: linear-gradient(to left, rgba(0, 0, 0, 0.14), transparent);
    }
    [dir="rtl"] .compact-table .mw-pin-floating th.cell-actions::after,
    [dir="rtl"] .compact-table .mw-pin-floating td.cell-actions::after {
        background: linear-gradient(to right, rgba(0, 0, 0, 0.14), transparent);
    }
}

/* Pinned Actions column — tint the pinned cell exactly when its row is hovered
   (mirrors MudBlazor's own row-hover rule; fine-pointer + desktop only). */
@media (min-width: 600px) and (hover: hover) and (pointer: fine) {
    .compact-table.mud-table-hover .mud-table-container .mud-table-root .mud-table-body .mud-table-row:hover {
        --mw-pin-overlay: var(--mud-palette-table-hover);
    }
}

@media (min-width: 960px) {
    .responsive-card-width { width: 25%; }
}


/* --------------------------------------------------------------------------
   14. RESPONSIVE — MOBILE (max-width: 959px)
   -------------------------------------------------------------------------- */

/* Bottom app bar */
@media (max-width: 959px) {
    header.mud-appbar {
        top: auto !important; bottom: 0 !important;
        position: fixed !important;
        box-shadow: 0 -3px 10px rgba(0,0,0,0.2) !important;
        border-top: 1px solid rgba(255,255,255,0.1) !important;
    }
    .mud-main-content,
    .mud-main-content.pt-16 {
        padding-top: 0px !important;
        margin-top: 0px !important;
        padding-bottom: 80px !important;
    }
    .offline-banner-wrapper { top: 0 !important; }
    body:has(.offline-banner-wrapper) .mud-main-content,
    body:has(.offline-banner-wrapper) .mud-main-content.pt-16 {
        padding-top: 40px !important;
    }
    .mud-layout { padding-top: 0px !important; }
    .mud-drawer.mud-drawer-pos-left,
    .mud-drawer.mud-drawer-pos-right {
        top: 0 !important; height: 100% !important; padding-top: 0 !important;
    }
}


/* --------------------------------------------------------------------------
   15. RESPONSIVE — SMALL SCREENS (max-width: 599.98px)
   -------------------------------------------------------------------------- */

@media (max-width: 599.98px) {
    
    /* 
       MODE 2: Responsive Mobile Fullscreen
       Usage: Add Class="mobile-fullscreen" to <MudDialog>
       Effect: On screens < 600px, it balloons to 100% width/height. On desktop, it remains a normal popup.
    */
    .mud-dialog-container:has(.mobile-fullscreen),
    .mud-dialog-container:has(.mud-dialog.mobile-fullscreen) {
        overflow: hidden !important;
    }
    
    .mud-dialog.mobile-fullscreen,
    .mud-dialog:has(.mobile-fullscreen) {
        max-width: 100% !important; max-height: 100% !important;
        width: 100vw !important; height: 100dvh !important; /* dvh handles mobile address bars perfectly */
        margin: 0 !important; border-radius: 0 !important;
        position: fixed !important; top: 0 !important; left: 0 !important;
    }
    .mud-dialog.mobile-fullscreen .mud-dialog-content,
    .mud-dialog:has(.mobile-fullscreen) .mud-dialog-content {
        padding-left: 4px !important;
        padding-right: 4px !important;
    }
    .mud-dialog.mobile-fullscreen .mud-dialog-actions,
    .mud-dialog:has(.mobile-fullscreen) .mud-dialog-actions {
        padding-bottom: calc(env(safe-area-inset-bottom, 8px) + 12px) !important;
    }
    .mud-dialog.mobile-fullscreen .mud-table-container,
    .mud-dialog:has(.mobile-fullscreen) .mud-table-container {
        max-height: unset !important;
        height: auto !important;
    }

    /* Touch-friendly menu items */
    .mud-menu-item.mud-menu-item-dense {
        min-height: 44px !important;
        max-height: 44px !important;
    }

    /* Card view: description icon + statement button order */
    .card-view td.cell-description::before {
        content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 24 24' fill='%23757575'%3E%3Cpath d='M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z'/%3E%3C/svg%3E") !important;
        flex-shrink: 0; margin-inline-end: 6px; vertical-align: middle;
    }
    .card-view .statement-btn { order: 1; margin: -4px -4px -4px 0; }
}


/* --------------------------------------------------------------------------
   16. RESPONSIVE — MOBILE TABS (max-width: 600px)
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
    .compact-tabs-mobile .mud-tab {
        min-width: 56px !important;
        padding-left: 8px !important;
        padding-right: 8px !important;
    }
    .compact-tabs-mobile .mud-tab .mud-typography { display: none !important; }

    .responsive-tabs .mud-tabs-toolbar .mud-tabs-tabbar { width: 100%; display: flex; }
    .responsive-tabs .mud-tab {
        flex: 1 1 0px; min-width: 0 !important;
        padding-left: 0 !important; padding-right: 0 !important;
    }
    .responsive-tabs .mud-tab .mud-tab-text { display: none !important; }
}


/* --------------------------------------------------------------------------
   17. TOUCH DEVICE OVERRIDES
   -------------------------------------------------------------------------- */

@media (hover: none) and (pointer: coarse) {
    .mud-tooltip-root .mud-popover-provider,
    .mud-tooltip { display: none !important; }
}

/* --------------------------------------------------------------------------
   18. AI THEME
   -------------------------------------------------------------------------- */

.ai-scan-btn {
    background: linear-gradient(135deg, #7c3aed, #a855f7, #6366f1) !important;
    color: white !important;
}

.ai-scan-btn *,
.ai-scan-btn.mud-disabled,
.ai-scan-btn.mud-disabled * {
    color: white !important;
    opacity: 1 !important;
}

.ai-scan-btn.mud-disabled {
    background: linear-gradient(135deg, #7c3aed, #a855f7, #6366f1) !important;
}

.ai-progress-bar .mud-progress-linear-bar {
    background: linear-gradient(135deg, #7c3aed, #a855f7, #6366f1) !important;
}

.ai-progress-bar.mud-progress-linear {
    background-color: rgba(124, 58, 237, 0.15) !important;
}


/* TRUNCATED TEXT COMPONENT */
.truncated-text-container { display: flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; box-sizing: border-box; }
.truncated-text-container .mud-tooltip-root { display: flex !important; min-width: 0; flex: 1 1 auto; overflow: hidden; }
/* unicode-bidi: plaintext — direction follows the text itself, so in the RTL UI an English
   name truncates at its end ("Grand Theft A…") instead of losing its start ("…eft Auto V") */
.truncated-text-value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; max-width: 100%; display: block; unicode-bidi: plaintext; }
.truncated-text-button { flex-shrink: 0; }

