/* ==========================================================================
   JSONS Admin -- design system layer
   Loaded LAST, on top of Velzon (bootstrap.min.css + app.min.css).
   Presentation only: no markup contracts, ids, names or JS hooks depend on it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
    --jx-radius-xs: 6px;
    --jx-radius-sm: 8px;
    --jx-radius: 12px;
    --jx-radius-lg: 16px;

    --jx-shadow-xs: 0 1px 2px rgba(16, 24, 40, .04);
    --jx-shadow-sm: 0 1px 3px rgba(16, 24, 40, .06), 0 1px 2px rgba(16, 24, 40, .04);
    --jx-shadow-md: 0 4px 12px rgba(16, 24, 40, .08);
    --jx-shadow-pop: 0 8px 28px rgba(16, 24, 40, .12);

    --jx-topbar-h: 58px;
    --jx-sidebar-w: 244px;
    --jx-sidebar-w-icon: 72px;
    --jx-footer-h: 44px;

    --jx-gap: .75rem;
    --jx-pad-card: 1rem;

    --jx-focus: 0 0 0 3px rgba(64, 81, 137, .28);

    /* surfaces resolved from Velzon so dark mode follows automatically */
    --jx-surface: var(--vz-card-bg, #fff);
    --jx-border: var(--vz-border-color, #e9ebec);
    --jx-text: var(--vz-body-color, #212529);
    --jx-muted: var(--vz-text-muted, #878a99);
    --jx-heading: var(--vz-heading-color, #495057);
    --jx-subtle-bg: rgba(var(--vz-light-rgb, 243, 246, 249), .55);
}

html[data-layout-mode="dark"] {
    --jx-shadow-xs: 0 1px 2px rgba(0, 0, 0, .3);
    --jx-shadow-sm: 0 1px 3px rgba(0, 0, 0, .35);
    --jx-shadow-md: 0 4px 14px rgba(0, 0, 0, .4);
    --jx-shadow-pop: 0 10px 30px rgba(0, 0, 0, .5);
    --jx-focus: 0 0 0 3px rgba(120, 140, 205, .35);
    --jx-subtle-bg: rgba(255, 255, 255, .04);
}

/* --------------------------------------------------------------------------
   2. Base / density
   -------------------------------------------------------------------------- */
body {
    font-size: .875rem;
    -webkit-font-smoothing: antialiased;
}

/* Reclaim vertical space the stock theme wastes above the fold.
   The theme ships both a 70px margin-top and a padding-top; both are reset
   here so the compact topbar height is the single source of truth. */
.page-content {
    margin-top: var(--jx-topbar-h);
    padding: 1rem .75rem calc(var(--jx-footer-h) + .5rem) .75rem;
    min-height: calc(100vh - var(--jx-topbar-h) - var(--jx-footer-h));
}

.main-content > .page-content > .container-fluid {
    padding-left: .25rem;
    padding-right: .25rem;
    max-width: 100%;
}

/* Nothing may push the page sideways -- overflow belongs inside components. */
html,
body {
    overflow-x: hidden;
}

/* --------------------------------------------------------------------------
   3. Topbar
   -------------------------------------------------------------------------- */
#page-topbar {
    box-shadow: var(--jx-shadow-xs);
    border-bottom: 1px solid var(--jx-border);
}

#page-topbar .navbar-header {
    height: var(--jx-topbar-h);
    padding: 0 .75rem;
}

#page-topbar .btn-topbar {
    height: 34px;
    width: 34px;
    line-height: 34px;
}

#page-topbar .btn-topbar i {
    font-size: 18px !important;
}

.topnav-hamburger {
    height: 34px;
    width: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--jx-radius-xs);
}

/* Keep the three bars horizontal -- the flex centering above would otherwise
   collapse the icon box the theme sizes its spans against. */
.topnav-hamburger .hamburger-icon {
    width: 20px;
    height: 14px;
    position: relative;
    display: block;
}

.topnav-hamburger:hover {
    background-color: var(--jx-subtle-bg);
}

.topbar-user .header-profile-user {
    height: 32px;
    width: 32px;
}

.topbar-user .user-name-text {
    font-size: .8125rem;
}

/* --------------------------------------------------------------------------
   4. Sidebar
   -------------------------------------------------------------------------- */
.app-menu {
    width: var(--jx-sidebar-w);
    border-right: 1px solid rgba(255, 255, 255, .06);
}

.app-menu .navbar-brand-box {
    width: var(--jx-sidebar-w);
    height: var(--jx-topbar-h);
    display: flex;
    align-items: center;
    padding: 0 1rem;
}

/* JSONS logo scales inside the brand box instead of being cropped by it. */
.app-menu .navbar-brand-box .logo img,
#page-topbar .navbar-brand-box .logo img {
    max-width: 100%;
    height: auto;
    max-height: 32px;
    object-fit: contain;
}

.app-menu .navbar-nav .nav-link {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5rem .75rem;
    margin: 1px .5rem;
    border-radius: var(--jx-radius-sm);
    font-size: .8125rem;
    font-weight: 500;
    transition: background-color .12s ease, color .12s ease;
}

.app-menu .navbar-nav .nav-link > i {
    font-size: 17px;
    min-width: 20px;
    text-align: center;
    line-height: 1;
}

.app-menu .navbar-nav .nav-link:hover {
    background-color: rgba(255, 255, 255, .06);
}

.app-menu .navbar-nav .nav-link.active {
    background-color: rgba(255, 255, 255, .11);
    font-weight: 600;
}

.app-menu .navbar-nav .nav-sm .nav-link {
    padding: .375rem .75rem .375rem 2.35rem;
    font-size: .8125rem;
}

.app-menu .menu-title {
    padding: 1rem 1.25rem .35rem;
    font-size: .6875rem;
    letter-spacing: .06em;
}

.main-content {
    margin-left: var(--jx-sidebar-w);
}

.footer {
    left: var(--jx-sidebar-w);
    height: var(--jx-footer-h);
    line-height: var(--jx-footer-h);
    padding: 0 1rem;
    font-size: .75rem;
}

/* --------------------------------------------------------------------------
   5. Page header + breadcrumbs
   -------------------------------------------------------------------------- */
/* The theme pulls this block outside the content box with negative margins
   (-23px/-1.5rem), which clips it under the sidebar. Reset to flow. */
.page-title-box {
    margin: 0 0 .25rem !important;
    padding: 0 0 .875rem;
    background-color: transparent !important;
    box-shadow: none !important;
    border: 0 !important;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .25rem .75rem;
    min-width: 0;
}

.page-title-box h4 {
    font-size: 1.0625rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: -.01em;
    margin: 0;
    color: var(--jx-heading);
}

.page-title-box .breadcrumb {
    font-size: .75rem;
    margin: 0;
}

.page-title-box .breadcrumb-item + .breadcrumb-item::before {
    content: "\203A";
    font-size: .95rem;
    line-height: 1;
    position: relative;
    top: 1px;
}

/* --------------------------------------------------------------------------
   6. Cards
   -------------------------------------------------------------------------- */
.card {
    border: 1px solid var(--jx-border);
    border-radius: var(--jx-radius);
    box-shadow: var(--jx-shadow-sm);
    margin-bottom: 1rem;
}

.card-header {
    padding: .8125rem var(--jx-pad-card);
    border-bottom: 1px solid var(--jx-border);
    background-color: transparent;
    border-top-left-radius: var(--jx-radius);
    border-top-right-radius: var(--jx-radius);
}

.card-body {
    padding: var(--jx-pad-card);
}

.card-title {
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: -.01em;
}

/* Card header that carries a toolbar needs to breathe vertically, not sideways. */
.jx-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .625rem;
}

/* --------------------------------------------------------------------------
   7. Buttons -- clear primary / secondary / destructive hierarchy
   -------------------------------------------------------------------------- */
.btn {
    --bs-btn-border-radius: var(--jx-radius-sm);
    border-radius: var(--jx-radius-sm);
    font-weight: 500;
    font-size: .8125rem;
    padding: .4375rem .875rem;
    line-height: 1.35;
    transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}

.btn-sm {
    font-size: .75rem;
    padding: .3125rem .5625rem;
    border-radius: var(--jx-radius-xs);
}

.btn-lg {
    font-size: .9375rem;
    padding: .625rem 1.25rem;
    border-radius: var(--jx-radius);
}

/* Full-width form submits (login) stay comfortable to hit. */
.btn.w-100 {
    padding-top: .5625rem;
    padding-bottom: .5625rem;
    font-size: .875rem;
}

.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
a:focus-visible,
.nav-link:focus-visible,
.form-check-input:focus-visible {
    outline: none;
    box-shadow: var(--jx-focus);
}

/* Icon-only buttons stay square and hit-target sized. */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.jx-btn-icon {
    width: 30px;
    height: 30px;
    padding: 0;
}

/* --------------------------------------------------------------------------
   8. Forms
   -------------------------------------------------------------------------- */
.form-control,
.form-select {
    border-radius: var(--jx-radius-sm);
    font-size: .8125rem;
    padding: .4375rem .625rem;
    min-height: 34px;
    border-color: var(--jx-border);
}

.form-control:focus,
.form-select:focus {
    box-shadow: var(--jx-focus);
}

.form-label {
    font-size: .75rem;
    font-weight: 600;
    color: var(--jx-muted);
    margin-bottom: .25rem;
}

textarea.form-control {
    min-height: 80px;
}

.form-check-input {
    border-radius: 5px;
}

.form-check-input:focus {
    box-shadow: var(--jx-focus);
}

.input-group > .form-control,
.input-group > .form-select {
    min-height: 34px;
}

/* select2 (Products filters) matched to native inputs */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border-radius: var(--jx-radius-sm) !important;
    border-color: var(--jx-border) !important;
    background-color: var(--vz-input-bg, #fff) !important;
    min-height: 34px !important;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 32px !important;
    font-size: .8125rem;
    color: var(--jx-text) !important;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 32px !important;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    border-radius: var(--jx-radius-xs) !important;
    font-size: .75rem;
}

.select2-dropdown {
    border-radius: var(--jx-radius-sm) !important;
    border-color: var(--jx-border) !important;
    background-color: var(--vz-input-bg, #fff) !important;
    box-shadow: var(--jx-shadow-pop);
}

.select2-container--default .select2-results__option {
    font-size: .8125rem;
    color: var(--jx-text);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    border-radius: var(--jx-radius-xs);
    border-color: var(--jx-border);
    background-color: var(--vz-input-bg, #fff);
    color: var(--jx-text);
}

/* --------------------------------------------------------------------------
   9. Toolbar -- the reflowing filter/action bar
   -------------------------------------------------------------------------- */
.jx-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .625rem;
    width: 100%;
}

.jx-toolbar-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .625rem;
    flex: 1 1 auto;
    min-width: 0;
}

.jx-toolbar-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-left: auto;
}

/* One labelled control. Grows to fill, never forces overflow. */
.jx-field {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 140px;
    max-width: 200px;
}

.jx-field-sm {
    flex-basis: 104px;
    max-width: 130px;
}

.jx-field-wide {
    flex-basis: 200px;
    max-width: 280px;
}

.jx-field > label {
    font-size: .6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--jx-muted);
    margin-bottom: .25rem;
    white-space: nowrap;
}

/* select2 must obey the flex track, not its inline width */
.jx-field .select2-container {
    width: 100% !important;
}

/* Legend chips for the products status colour key */
.jx-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem .875rem;
    font-size: .75rem;
    color: var(--jx-muted);
}

.jx-legend-item {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    white-space: nowrap;
}

.jx-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    border: 1px solid var(--jx-border);
    flex: 0 0 auto;
}

/* Collapsible filter panel (used at narrow widths via <details>) */
.jx-filters {
    border-top: 1px solid var(--jx-border);
    margin-top: .75rem;
    padding-top: .75rem;
}

/* --------------------------------------------------------------------------
   10. KPI cards
   -------------------------------------------------------------------------- */
.jx-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: .875rem;
}

.jx-kpi {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: .9375rem 1rem;
    background-color: var(--jx-surface);
    border: 1px solid var(--jx-border);
    border-radius: var(--jx-radius);
    box-shadow: var(--jx-shadow-sm);
    min-width: 0;
    transition: box-shadow .15s ease, border-color .15s ease;
}

.jx-kpi:hover {
    box-shadow: var(--jx-shadow-md);
    border-color: rgba(var(--vz-primary-rgb, 64, 81, 137), .35);
}

.jx-kpi-icon {
    width: 42px;
    height: 42px;
    border-radius: var(--jx-radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 21px;
    flex: 0 0 auto;
}

.jx-kpi-body {
    min-width: 0;
    flex: 1 1 auto;
}

.jx-kpi-label {
    font-size: .6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--jx-muted);
    margin: 0 0 .125rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jx-kpi-value {
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.025em;
    font-variant-numeric: tabular-nums;
    color: var(--jx-heading);
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Long currency totals get a step down so they never clip in a 4-up grid. */
.jx-kpi-value.jx-kpi-value-long {
    font-size: 1.1875rem;
}

.jx-kpi-value .jx-kpi-unit {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--jx-muted);
    margin-right: .1875rem;
}

.jx-kpi-link {
    font-size: .75rem;
    font-weight: 500;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: .1875rem;
    margin-top: .1875rem;
}

.jx-kpi-link:hover {
    text-decoration: underline;
}

/* --------------------------------------------------------------------------
   11. Tables
   -------------------------------------------------------------------------- */
.table {
    --bs-table-bg: transparent;
    font-size: .8125rem;
    margin-bottom: 0;
}

.table > :not(caption) > * > * {
    padding: .5rem .625rem;
}

.table > thead th {
    font-size: .6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--jx-muted);
    background-color: var(--jx-subtle-bg);
    border-bottom: 1px solid var(--jx-border);
    white-space: nowrap;
    vertical-align: middle;
}

.table > tbody > tr {
    border-color: var(--jx-border);
}

.table-hover > tbody > tr:hover > * {
    background-color: var(--jx-subtle-bg);
}

/* Scroll horizontally *inside* the table only, never the page. */
.table-responsive {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--jx-radius-sm);
}

/* Header stays visible while scanning long lists. */
.jx-table-sticky thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: var(--vz-card-bg, #fff);
    box-shadow: inset 0 -1px 0 var(--jx-border);
}

/* Action clusters stay on one line -- wrapping them would multiply row height
   across the whole table. The table itself scrolls instead. */
.table td .d-flex.gap-2 {
    gap: .3125rem !important;
    flex-wrap: nowrap;
    align-items: center;
}

.table td, .table th {
    vertical-align: middle;
}

.table td .btn-sm {
    font-size: .6875rem;
    padding: .25rem .5rem;
    white-space: nowrap;
}

.table td .form-check-input {
    margin-top: 0;
}

/* Inline editable cells inside tables */
.table td .form-control,
.table td .form-select {
    min-height: 30px;
    padding: .25rem .5rem;
    font-size: .75rem;
    min-width: 74px;
}

/* Ctn-only switch cell */
.table td .form-check.form-switch {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    margin: 0;
    padding-left: 2.1em;
    white-space: nowrap;
}

.table td .form-check.form-switch .form-check-label {
    font-size: .6875rem;
    color: var(--jx-muted);
    margin: 0;
}

/* Product thumbnails -- fixed box so a missing file can't stretch the row. */
.table td img {
    width: 38px;
    height: 38px;
    object-fit: contain;
    border-radius: var(--jx-radius-xs);
    border: 1px solid var(--jx-border);
    background-color: var(--jx-subtle-bg);
    font-size: 0; /* hides broken-image alt text */
}

/* Long free text truncates cleanly; full value stays available via title. */
/* Superseded by the per-column .jx-c-* treatment in sections 16-17.
   Kept only so any cell still carrying the class degrades sensibly. */
.jx-cell-clip {
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Everything else keeps its natural width so DataTables allocates columns
   correctly and labels ("Incomplete", "Ctn Only") are never sliced. */
/* Structural cells (numbers, switches, buttons) stay on one line; the text
   columns opt back into wrapping in section 17. Never applies in card mode. */
[data-jx-table]:not(.jx-cards-on) > thead th,
[data-jx-table]:not(.jx-cards-on) > tbody td {
    white-space: nowrap;
}

/* Row status colours -- semantic classes replace hard-coded inline styles
   so they survive dark mode and hover. Same three states as before. */
.table > tbody > tr.jx-row-oos > * {
    --bs-table-bg: #e9ebec;
    --bs-table-accent-bg: #e9ebec;
    background-color: #e9ebec !important;
    color: #495057 !important;
}

.table > tbody > tr.jx-row-inactive > * {
    --bs-table-bg: #fbe0e0;
    --bs-table-accent-bg: #fbe0e0;
    background-color: #fbe0e0 !important;
    color: #6c2c2c !important;
}

.table > tbody > tr.jx-row-ctn > * {
    --bs-table-bg: #fbf1cf;
    --bs-table-accent-bg: #fbf1cf;
    background-color: #fbf1cf !important;
    color: #5c4a10 !important;
}

html[data-layout-mode="dark"] .table > tbody > tr.jx-row-oos > * {
    background-color: #2f3542 !important;
    color: #c8ccd4 !important;
}

html[data-layout-mode="dark"] .table > tbody > tr.jx-row-inactive > * {
    background-color: #4a2b2f !important;
    color: #f2c9cb !important;
}

html[data-layout-mode="dark"] .table > tbody > tr.jx-row-ctn > * {
    background-color: #4a4227 !important;
    color: #f0e2b0 !important;
}

/* CMS rich-text cells: an entire policy document used to be dumped into one
   row. It is capped to a scrollable panel -- all content is still there. */
.jx-richtext {
    max-height: 220px;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: .5rem;
    font-size: .8125rem;
    line-height: 1.55;
}

.jx-richtext > *:first-child {
    margin-top: 0;
}

.jx-richtext > *:last-child {
    margin-bottom: 0;
}

.jx-richtext h1,
.jx-richtext h2,
.jx-richtext h3,
.jx-richtext h4 {
    font-size: .9375rem;
    font-weight: 600;
    margin: .75rem 0 .375rem;
}

.jx-richtext p,
.jx-richtext ul,
.jx-richtext ol {
    margin-bottom: .5rem;
}

.jx-richtext img {
    max-width: 100%;
    height: auto;
}

/* --------------------------------------------------------------------------
   12. DataTables chrome (core build, no BS integration file)
   -------------------------------------------------------------------------- */
div.dt-container {
    width: 100%;
}

div.dt-container .dt-layout-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    margin: 0 0 .75rem;
}

div.dt-container .dt-layout-row:last-child {
    margin: .875rem 0 0;
}

div.dt-container .dt-layout-cell {
    padding: 0 !important;
}

div.dt-container .dt-search {
    margin-left: auto;
}

div.dt-container .dt-search label {
    font-size: .75rem;
    font-weight: 600;
    color: var(--jx-muted);
    margin-right: .375rem;
}

div.dt-container .dt-search input,
div.dt-container .dt-length select {
    border: 1px solid var(--jx-border);
    border-radius: var(--jx-radius-sm);
    background-color: var(--vz-input-bg, #fff);
    color: var(--jx-text);
    padding: .3125rem .625rem;
    font-size: .8125rem;
    min-height: 32px;
}

div.dt-container .dt-search input:focus {
    outline: none;
    box-shadow: var(--jx-focus);
}

div.dt-container .dt-info {
    font-size: .75rem;
    color: var(--jx-muted);
    padding-top: 0 !important;
}

div.dt-container .dt-paging {
    margin-left: auto;
}

div.dt-container .dt-paging .dt-paging-button {
    border-radius: var(--jx-radius-xs) !important;
    border: 1px solid transparent !important;
    padding: .25rem .5625rem !important;
    margin: 0 1px !important;
    font-size: .75rem !important;
    min-width: 30px;
    color: var(--jx-text) !important;
    background: transparent !important;
}

div.dt-container .dt-paging .dt-paging-button:hover:not(.disabled) {
    background: var(--jx-subtle-bg) !important;
    border-color: var(--jx-border) !important;
}

div.dt-container .dt-paging .dt-paging-button.current {
    background: var(--vz-primary, #405189) !important;
    border-color: var(--vz-primary, #405189) !important;
    color: #fff !important;
}

div.dt-container .dt-paging .dt-paging-button.disabled {
    opacity: .4;
}

div.dt-container .dt-processing {
    border-radius: var(--jx-radius-sm);
    box-shadow: var(--jx-shadow-pop);
    background-color: var(--jx-surface);
    color: var(--jx-text);
    border: 1px solid var(--jx-border);
    font-size: .8125rem;
}

table.dataTable thead th.dt-orderable-asc,
table.dataTable thead th.dt-orderable-desc {
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   13. Modals, dropdowns, alerts
   -------------------------------------------------------------------------- */
.modal-content {
    border: 1px solid var(--jx-border);
    border-radius: var(--jx-radius);
    box-shadow: var(--jx-shadow-pop);
}

.modal-header {
    padding: .875rem 1rem;
    border-bottom: 1px solid var(--jx-border);
}

.modal-header .modal-title {
    font-size: .9375rem;
    font-weight: 600;
}

.modal-body {
    padding: 1rem;
}

.modal-footer {
    padding: .75rem 1rem;
    border-top: 1px solid var(--jx-border);
    gap: .5rem;
}

.modal-footer > * {
    margin: 0;
}

.dropdown-menu {
    border-radius: var(--jx-radius-sm);
    border-color: var(--jx-border);
    box-shadow: var(--jx-shadow-pop);
    padding: .3125rem;
    font-size: .8125rem;
}

.dropdown-item {
    border-radius: var(--jx-radius-xs);
    padding: .4375rem .625rem;
}

.alert {
    border-radius: var(--jx-radius-sm);
    font-size: .8125rem;
    padding: .625rem .875rem;
}

.badge {
    border-radius: 999px;
    font-weight: 600;
    padding: .3em .6em;
}

/* Validation messages emitted by the page scripts */
.text-danger,
[class^="error-"],
[class*=" error-"] {
    font-size: .75rem;
}

/* --------------------------------------------------------------------------
   14. Login page
   -------------------------------------------------------------------------- */
.auth-page-wrapper .card {
    border-radius: var(--jx-radius-lg);
    box-shadow: var(--jx-shadow-pop);
}

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */

/* --- Narrow desktop / tablet / Windows split-screen: sidebar goes icon-only
       and expands on hover as an overlay, so content keeps the full width.
       The lower bound matches the theme, which only switches to its drawer
       below 768px -- without this the 768-991px band kept a full-width
       sidebar sitting on top of the content. --- */
@media (min-width: 768px) and (max-width: 1299.98px) {
    html[data-sidebar-size="lg"] .app-menu {
        width: var(--jx-sidebar-w-icon);
        z-index: 1003;
        transition: width .15s ease;
    }

    html[data-sidebar-size="lg"] .app-menu .navbar-brand-box {
        width: var(--jx-sidebar-w-icon);
        padding: 0;
        justify-content: center;
    }

    html[data-sidebar-size="lg"] .app-menu .logo-lg {
        display: none;
    }

    html[data-sidebar-size="lg"] .app-menu .logo-sm {
        display: inline-block;
    }

    html[data-sidebar-size="lg"] .app-menu .navbar-nav .nav-link {
        justify-content: center;
        padding: .5rem;
    }

    html[data-sidebar-size="lg"] .app-menu .navbar-nav .nav-link > span,
    html[data-sidebar-size="lg"] .app-menu .menu-title,
    html[data-sidebar-size="lg"] .app-menu #vertical-hover {
        display: none;
    }

    html[data-sidebar-size="lg"] .app-menu .navbar-nav .menu-dropdown {
        display: none !important;
    }

    html[data-sidebar-size="lg"] .main-content,
    html[data-sidebar-size="lg"] .footer {
        margin-left: var(--jx-sidebar-w-icon);
        left: var(--jx-sidebar-w-icon);
    }

    /* hover reveals the full menu on top of the content */
    html[data-sidebar-size="lg"] .app-menu:hover {
        width: var(--jx-sidebar-w);
        box-shadow: var(--jx-shadow-pop);
    }

    html[data-sidebar-size="lg"] .app-menu:hover .navbar-brand-box {
        width: var(--jx-sidebar-w);
        padding: 0 1rem;
        justify-content: flex-start;
    }

    html[data-sidebar-size="lg"] .app-menu:hover .logo-lg {
        display: inline-block;
    }

    html[data-sidebar-size="lg"] .app-menu:hover .logo-sm {
        display: none;
    }

    html[data-sidebar-size="lg"] .app-menu:hover .navbar-nav .nav-link {
        justify-content: flex-start;
        padding: .5rem .75rem;
    }

    html[data-sidebar-size="lg"] .app-menu:hover .navbar-nav .nav-link > span,
    html[data-sidebar-size="lg"] .app-menu:hover .menu-title {
        display: inline-block;
    }

    html[data-sidebar-size="lg"] .app-menu:hover .navbar-nav .menu-dropdown {
        display: block !important;
    }
}

/* --- Toolbars start reflowing before the sidebar does. --- */
@media (max-width: 991.98px) {
    .page-content {
        padding-left: .625rem;
        padding-right: .625rem;
    }

    .jx-toolbar-actions {
        margin-left: 0;
        width: 100%;
    }

    .jx-field {
        max-width: none;
        flex-basis: 150px;
    }
}

/* --- Below 768px the theme's own drawer takes over and the sidebar leaves
       the flow entirely, so the content reclaims the full width. --- */
@media (max-width: 767.98px) {
    .main-content {
        margin-left: 0;
    }

    .footer {
        left: 0;
    }
}

/* --- Split-screen / small tablet --- */
@media (max-width: 767.98px) {
    :root {
        --jx-pad-card: .875rem;
    }

    .page-title-box h4 {
        font-size: 1rem;
    }

    .jx-kpi-grid {
        grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
        gap: .625rem;
    }

    .jx-kpi {
        padding: .75rem;
        gap: .625rem;
    }

    .jx-kpi-icon {
        width: 36px;
        height: 36px;
        font-size: 18px;
    }

    .jx-kpi-value {
        font-size: 1.25rem;
    }

    .jx-field {
        flex-basis: calc(50% - .3125rem);
        max-width: none;
    }

    .jx-field-wide {
        flex-basis: 100%;
    }

    .jx-toolbar-actions .btn {
        flex: 1 1 auto;
    }

    div.dt-container .dt-search,
    div.dt-container .dt-paging {
        margin-left: 0;
        width: 100%;
    }

    div.dt-container .dt-search input {
        width: 100%;
    }

    .jx-cell-clip {
        max-width: 160px;
    }
}

/* --- Phones --- */
@media (max-width: 575.98px) {
    /* Topbar has to survive 390px: tighter gutter, and nothing in it may
       refuse to shrink. */
    #page-topbar .navbar-header {
        padding: 0 .5rem;
        gap: .25rem;
    }

    #page-topbar .navbar-header > div {
        min-width: 0;
    }

    .topbar-user .btn {
        padding-left: .25rem;
        padding-right: .25rem;
    }

    /* All side padding moves to the container so Bootstrap's -12px row
       margins land exactly on the edge instead of poking past it. */
    .page-content {
        padding-left: 0;
        padding-right: 0;
    }

    .main-content > .page-content > .container-fluid {
        padding-left: .75rem;
        padding-right: .75rem;
    }

    .jx-kpi-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .jx-kpi {
        flex-direction: column;
        align-items: flex-start;
        gap: .5rem;
    }

    /* In a column flex box with align-items:flex-start the body would size to
       its content and push past the card; force it back to the track width. */
    .jx-kpi-body {
        width: 100%;
        align-self: stretch;
    }

    .jx-field {
        flex-basis: 100%;
    }

    .modal-dialog {
        margin: .5rem;
    }
}

/* ==========================================================================
   16. CARD MODE -- reflow, not scroll
   --------------------------------------------------------------------------
   Below its breakpoint a grid table stops being a grid of columns and becomes
   a stack of records: the <tr> turns into a CSS grid and each <td> is placed
   into a named area. Nothing is duplicated and nothing is hidden -- every cell
   keeps its original DOM node, so all delegated handlers, inline onclick
   attributes, checkbox state and inline-edit inputs keep working untouched.

   A table opts in with data-jx-cards="lg|md|sm", which picks the width at
   which it flips:
     lg  -> below 1200px  (Products, Orders, Users: 9-11 columns)
     md  -> below  992px  (Variants, Notifications: 6-8 columns)
     sm  -> below  576px  (Categories, Brands: 5 columns)
   ========================================================================== */

/* ---- Shared card-mode skeleton (applied by the per-breakpoint blocks) ---- */
.jx-cards-on {
    display: block;
    width: 100% !important;
    border: 0;
}

.jx-cards-on > thead {
    display: none;
}

.jx-cards-on > tbody {
    display: block;
    width: 100%;
}

.jx-cards-on > tbody > tr {
    display: grid;
    align-items: start;
    gap: .125rem .5rem;
    padding: .625rem .75rem;
    margin-bottom: .5rem;
    border: 1px solid var(--jx-border);
    border-radius: var(--jx-radius-sm);
    background-color: var(--jx-surface);
}

.jx-cards-on > tbody > tr:last-child {
    margin-bottom: 0;
}

.jx-cards-on > tbody > tr > td {
    display: block;
    border: 0 !important;
    padding: 0 !important;
    min-width: 0;
    max-width: none !important;
    white-space: normal !important;
    overflow: visible;
    text-overflow: clip;
    font-size: .8125rem;
    line-height: 1.4;
}

/* Label chips generated from the column's semantic class. */
.jx-cards-on > tbody > tr > td[class*="jx-c-"]::before {
    display: block;
    font-size: .625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--jx-muted);
    line-height: 1.4;
}

/* Cells that carry their own label or need none */
.jx-cards-on > tbody > tr > td.jx-c-chk::before,
.jx-cards-on > tbody > tr > td.jx-c-img::before,
.jx-cards-on > tbody > tr > td.jx-c-title::before,
.jx-cards-on > tbody > tr > td.jx-c-act::before,
.jx-cards-on > tbody > tr > td.jx-c-print::before,
.jx-cards-on > tbody > tr > td.jx-c-ctn::before,
.jx-cards-on > tbody > tr > td.jx-c-status::before,
.jx-cards-on > tbody > tr > td.jx-c-user::before {
    content: none;
}

.jx-cards-on > tbody > tr > td.jx-c-sr::before      { content: "SR"; }
.jx-cards-on > tbody > tr > td.jx-c-serial::before  { content: "Serial"; }
.jx-cards-on > tbody > tr > td.jx-c-brand::before   { content: "Brand"; }
.jx-cards-on > tbody > tr > td.jx-c-cat::before     { content: "Category"; }
.jx-cards-on > tbody > tr > td.jx-c-price::before   { content: "Price"; }
.jx-cards-on > tbody > tr > td.jx-c-city::before    { content: "City"; }
.jx-cards-on > tbody > tr > td.jx-c-phone::before   { content: "Mobile"; }
.jx-cards-on > tbody > tr > td.jx-c-items::before   { content: "Items"; }
.jx-cards-on > tbody > tr > td.jx-c-total::before   { content: "Amount"; }
.jx-cards-on > tbody > tr > td.jx-c-time::before    { content: "Placed"; }
.jx-cards-on > tbody > tr > td.jx-c-name::before    { content: "Customer"; }
.jx-cards-on > tbody > tr > td.jx-c-business::before{ content: "Business"; }
.jx-cards-on > tbody > tr > td.jx-c-address::before { content: "Address"; }
.jx-cards-on > tbody > tr > td.jx-c-type::before    { content: "Type"; }
.jx-cards-on > tbody > tr > td.jx-c-image::before   { content: "Image"; }
.jx-cards-on > tbody > tr > td.jx-c-detail::before  { content: "Detail"; }

/* Card-mode cell treatments */
.jx-cards-on > tbody > tr > td.jx-c-title {
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--jx-heading);
    overflow-wrap: anywhere;
}

.jx-cards-on > tbody > tr > td.jx-c-img img,
.jx-cards-on > tbody > tr > td.jx-c-image img {
    width: 46px;
    height: 46px;
}

.jx-cards-on > tbody > tr > td.jx-c-act > div,
.jx-cards-on > tbody > tr > td.jx-c-print > div {
    flex-wrap: wrap !important;
    gap: .3125rem !important;
}

.jx-cards-on > tbody > tr > td.jx-c-act {
    padding-top: .375rem !important;
    margin-top: .125rem;
    border-top: 1px dashed var(--jx-border) !important;
}

/* Inline-edit inputs go full width of their area in card mode */
.jx-cards-on > tbody > tr > td .form-control {
    width: 100% !important;
    min-width: 0;
}

/* Row status colours as a left accent bar -- a full flood would fight the
   card surface and hurt contrast on stacked text. */
.jx-cards-on > tbody > tr.jx-row-oos,
.jx-cards-on > tbody > tr.jx-row-inactive,
.jx-cards-on > tbody > tr.jx-row-ctn {
    border-left-width: 4px;
}

.jx-cards-on > tbody > tr.jx-row-oos > * ,
.jx-cards-on > tbody > tr.jx-row-inactive > *,
.jx-cards-on > tbody > tr.jx-row-ctn > * {
    background-color: transparent !important;
    color: inherit !important;
}

.jx-cards-on > tbody > tr.jx-row-oos    { border-left-color: #878a99; background-color: rgba(135, 138, 153, .06); }
.jx-cards-on > tbody > tr.jx-row-inactive { border-left-color: #f06548; background-color: rgba(240, 101, 72, .06); }
.jx-cards-on > tbody > tr.jx-row-ctn    { border-left-color: #f7b84b; background-color: rgba(247, 184, 75, .08); }

/* ---- Layouts: PRODUCTS ---- */
[data-jx-table="products"].jx-cards-on > tbody > tr {
    grid-template-columns: 20px 46px minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
        "chk img title  title"
        "chk img serial serial"
        "chk img brand  cat"
        "chk img price  ctn"
        "pin pin pin    pin"
        "act act act    act";
}

[data-jx-table="products"].jx-cards-on .jx-c-chk    { grid-area: chk; }
[data-jx-table="products"].jx-cards-on .jx-c-img    { grid-area: img; }
[data-jx-table="products"].jx-cards-on .jx-c-title  { grid-area: title; }
[data-jx-table="products"].jx-cards-on .jx-c-serial { grid-area: serial; }
[data-jx-table="products"].jx-cards-on .jx-c-brand  { grid-area: brand; }
[data-jx-table="products"].jx-cards-on .jx-c-cat    { grid-area: cat; }
[data-jx-table="products"].jx-cards-on .jx-c-price  { grid-area: price; }
[data-jx-table="products"].jx-cards-on .jx-c-ctn    { grid-area: ctn; align-self: end; }
[data-jx-table="products"].jx-cards-on .jx-c-act    { grid-area: act; }

/* ---- Layouts: ORDERS ---- */
[data-jx-table="orders"].jx-cards-on > tbody > tr {
    grid-template-columns: 20px minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
        "chk user   status"
        "chk city   time"
        "chk phone  items"
        "chk total  total"
        "act act    print";
}

[data-jx-table="orders"].jx-cards-on .jx-c-chk    { grid-area: chk; }
[data-jx-table="orders"].jx-cards-on .jx-c-sr     { grid-area: user; align-self: start; }
[data-jx-table="orders"].jx-cards-on .jx-c-user   { grid-area: user; }
[data-jx-table="orders"].jx-cards-on .jx-c-city   { grid-area: city; }
[data-jx-table="orders"].jx-cards-on .jx-c-phone  { grid-area: phone; }
[data-jx-table="orders"].jx-cards-on .jx-c-items  { grid-area: items; }
[data-jx-table="orders"].jx-cards-on .jx-c-total  { grid-area: total; }
[data-jx-table="orders"].jx-cards-on .jx-c-time   { grid-area: time; }
[data-jx-table="orders"].jx-cards-on .jx-c-status { grid-area: status; justify-self: end; }
[data-jx-table="orders"].jx-cards-on .jx-c-act    { grid-area: act; }
[data-jx-table="orders"].jx-cards-on .jx-c-print  { grid-area: print; justify-self: end; padding-top: .375rem !important; margin-top: .125rem; border-top: 1px dashed var(--jx-border) !important; }

/* SR No. rides along with the customer block as an order reference */
[data-jx-table="orders"].jx-cards-on .jx-c-sr {
    display: none;
}

[data-jx-table="orders"].jx-cards-on .jx-c-total {
    font-weight: 700;
    font-size: .9375rem;
    color: var(--jx-heading);
}

/* ---- Layouts: USERS (inline-edit grid) ---- */
[data-jx-table="users"].jx-cards-on > tbody > tr {
    grid-template-columns: 20px minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
        "chk name     name"
        "chk business business"
        "chk phone    city"
        "chk address  address"
        "chk type     type"
        "act act      act";
    gap: .375rem .5rem;
}

[data-jx-table="users"].jx-cards-on .jx-c-chk      { grid-area: chk; }
[data-jx-table="users"].jx-cards-on .jx-c-sr       { display: none; }
[data-jx-table="users"].jx-cards-on .jx-c-name     { grid-area: name; }
[data-jx-table="users"].jx-cards-on .jx-c-business { grid-area: business; }
[data-jx-table="users"].jx-cards-on .jx-c-phone    { grid-area: phone; }
[data-jx-table="users"].jx-cards-on .jx-c-city     { grid-area: city; }
[data-jx-table="users"].jx-cards-on .jx-c-address  { grid-area: address; }
[data-jx-table="users"].jx-cards-on .jx-c-type     { grid-area: type; }
[data-jx-table="users"].jx-cards-on .jx-c-act      { grid-area: act; }

/* ---- Layouts: simple 5-column tables (Categories, Brands, Variants) ---- */
[data-jx-table="categories"].jx-cards-on > tbody > tr,
[data-jx-table="product-brands"].jx-cards-on > tbody > tr,
[data-jx-table="variants"].jx-cards-on > tbody > tr,
[data-jx-table="notifications"].jx-cards-on > tbody > tr {
    grid-template-columns: 20px 46px minmax(0, 1fr);
}

[data-jx-table="categories"].jx-cards-on .jx-c-chk,
[data-jx-table="product-brands"].jx-cards-on .jx-c-chk {
    grid-row: span 2;
}

[data-jx-table="categories"].jx-cards-on .jx-c-image,
[data-jx-table="product-brands"].jx-cards-on .jx-c-image {
    grid-row: span 2;
}

[data-jx-table="categories"].jx-cards-on .jx-c-image::before,
[data-jx-table="product-brands"].jx-cards-on .jx-c-image::before {
    content: none;
}

/* ---- Roomy card mode (768px+): spread the metadata across more tracks so a
        record stays 2-4 lines tall instead of one line per field. ---- */
@media (min-width: 768px) {
    [data-jx-table="products"].jx-cards-on > tbody > tr {
        grid-template-columns: 20px 46px repeat(4, minmax(0, 1fr));
        grid-template-areas:
            "chk img title  title  title title"
            "chk img serial serial brand cat"
            "chk img price  price  ctn   ctn"
            "pin pin pin    pin    pin   pin"
            "act act act    act    act   act";
    }

    [data-jx-table="orders"].jx-cards-on > tbody > tr {
        grid-template-columns: 20px repeat(5, minmax(0, 1fr));
        grid-template-areas:
            "chk user  user  city  time  status"
            "chk phone items total act   print";
    }

    [data-jx-table="orders"].jx-cards-on .jx-c-act {
        border-top: 0 !important;
        margin-top: 0;
        padding-top: 0 !important;
    }

    [data-jx-table="orders"].jx-cards-on .jx-c-print {
        border-top: 0 !important;
        margin-top: 0;
        padding-top: 0 !important;
    }

    [data-jx-table="users"].jx-cards-on > tbody > tr {
        grid-template-columns: 20px repeat(3, minmax(0, 1fr));
        grid-template-areas:
            "chk name    business phone"
            "chk city    address  type"
            "act act     act      act";
    }
}

/* ---- Very narrow: collapse metadata to a single column ---- */
@media (max-width: 479.98px) {
    [data-jx-table="products"].jx-cards-on > tbody > tr {
        grid-template-columns: 20px 44px minmax(0, 1fr);
        grid-template-areas:
            "chk img title"
            "chk img serial"
            "chk img brand"
            "chk img cat"
            ".   .   price"
            ".   .   ctn"
            "pin pin pin"
            "act act act";
    }

    [data-jx-table="orders"].jx-cards-on > tbody > tr,
    [data-jx-table="users"].jx-cards-on > tbody > tr {
        grid-template-columns: 20px minmax(0, 1fr);
    }

    [data-jx-table="orders"].jx-cards-on > tbody > tr {
        grid-template-areas:
            "chk user"
            "chk status"
            "chk city"
            "chk phone"
            "chk time"
            "chk items"
            "chk total"
            "act act"
            "print print";
    }

    [data-jx-table="orders"].jx-cards-on .jx-c-status,
    [data-jx-table="orders"].jx-cards-on .jx-c-print {
        justify-self: start;
    }

    [data-jx-table="users"].jx-cards-on > tbody > tr {
        grid-template-areas:
            "chk name"
            "chk business"
            "chk phone"
            "chk city"
            "chk address"
            "chk type"
            "act act";
    }
}

/* The .jx-cards-on class is toggled per table by assets/js/jsons-admin.js
   from the data-jx-cards breakpoint. In card mode the wrapper has nothing
   to scroll, so its overflow is released. */
.jx-cards-wrap {
    overflow-x: visible !important;
    overflow-y: visible !important;
}

/* --------------------------------------------------------------------------
   17. Table-mode compaction -- the widths that let the desktop table fit
        without ever needing a horizontal scrollbar.
   -------------------------------------------------------------------------- */
[data-jx-table]:not(.jx-cards-on) {
    table-layout: auto;
}

[data-jx-table]:not(.jx-cards-on) > thead th,
[data-jx-table]:not(.jx-cards-on) > tbody td {
    padding: .375rem .4375rem !important;
}

/* Structural columns shrink to their content (`width:1%` + nowrap is the
   standard table idiom for that) so every spare pixel goes to the text
   columns instead of padding out checkbox / image / status columns. */
[data-jx-table]:not(.jx-cards-on) .jx-c-chk,
[data-jx-table]:not(.jx-cards-on) .jx-c-sr,
[data-jx-table]:not(.jx-cards-on) .jx-c-serial,
[data-jx-table]:not(.jx-cards-on) .jx-c-img,
[data-jx-table]:not(.jx-cards-on) .jx-c-image,
[data-jx-table]:not(.jx-cards-on) .jx-c-items,
[data-jx-table]:not(.jx-cards-on) .jx-c-ctn,
[data-jx-table]:not(.jx-cards-on) .jx-c-status,
[data-jx-table]:not(.jx-cards-on) .jx-c-type,
[data-jx-table]:not(.jx-cards-on) .jx-c-phone,
[data-jx-table]:not(.jx-cards-on) .jx-c-total,
[data-jx-table]:not(.jx-cards-on) .jx-c-time {
    width: 1%;
    white-space: nowrap;
}

/* Selection column: only as wide as the box, and the box sits in the middle
   of it -- Bootstrap's own indent would push it against the next column. */
[data-jx-table]:not(.jx-cards-on) .jx-c-chk {
    padding-left: .25rem !important;
    padding-right: .25rem !important;
    text-align: center;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-chk .form-check {
    min-height: 0;
    margin: 0;
    padding-left: 0;
    display: flex;
    justify-content: center;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-chk .form-check .form-check-input {
    float: none;
    margin: 0;
}

/* These carry only a floor -- the `width:1%` rule above sizes them to
   content so the surplus goes to the text columns. */
[data-jx-table]:not(.jx-cards-on) .jx-c-sr {
    min-width: 30px;
    text-align: center;
    color: var(--jx-muted);
}

[data-jx-table]:not(.jx-cards-on) .jx-c-serial {
    min-width: 56px;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-img,
[data-jx-table]:not(.jx-cards-on) .jx-c-image {
    min-width: 48px;
    text-align: center;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-items {
    min-width: 38px;
    text-align: center;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-price {
    width: 84px;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-price .form-control {
    min-width: 0;
    width: 100%;
}

/* Text columns wrap at word boundaries and never split a word.
   IMPORTANT: no display/overflow/max-width is ever set on a th or td here.
   Changing a cell's display (e.g. -webkit-box) computes to flow-root and
   yanks the cell out of the table's column flow, which collapses columns
   into each other. All clamping happens on the .jx-clamp span inside. */
[data-jx-table] .jx-c-title,
[data-jx-table] .jx-c-brand,
[data-jx-table] .jx-c-cat,
[data-jx-table] .jx-c-city,
[data-jx-table] .jx-c-user,
[data-jx-table] .jx-c-business,
[data-jx-table] .jx-c-name,
[data-jx-table] .jx-c-address {
    white-space: normal !important;
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: none;
    line-height: 1.3;
}

/* Width hints. min-width keeps a column from being squeezed to the point of
   breaking words; the percentage lets the browser share out the surplus. */
[data-jx-table]:not(.jx-cards-on) .jx-c-title    { min-width: 150px; width: 20%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-brand    { min-width: 88px;  width: 9%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-cat      { min-width: 104px; width: 12%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-city     { min-width: 96px;  width: 9%; }

/* On Users the city/address cells are <input>s, which clip instead of
   wrapping, so they need enough room for a real city name. */
[data-jx-table="users"]:not(.jx-cards-on) .jx-c-city    { min-width: 124px; width: 11%; }
[data-jx-table="users"]:not(.jx-cards-on) .jx-c-address { min-width: 150px; width: 18%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-user     { min-width: 132px; width: 16%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-name     { min-width: 120px; width: 15%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-business { min-width: 120px; width: 15%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-address  { min-width: 120px; width: 14%; }
[data-jx-table]:not(.jx-cards-on) .jx-c-phone    { min-width: 104px; }
[data-jx-table]:not(.jx-cards-on) .jx-c-type     { min-width: 70px; }

/* City sits one notch down so a single-word name such as "Faisalabad" or
   "Rawalpindi" fits on one line at the width above. Multi-word names still
   wrap at the space ("Dera Ghazi / Khan") rather than shrinking further. */
[data-jx-table]:not(.jx-cards-on) .jx-c-city {
    font-size: .78125rem;
}

/* Two-line clamp, applied to the inner span so the cell stays a table-cell.
   The span carries the full value in its title attribute. */
.jx-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: normal;
    word-break: keep-all;
}

.jx-cards-on .jx-clamp {
    -webkit-line-clamp: 3;
}

/* Inline-edit inputs fill their column instead of leaving dead space. */
[data-jx-table] td .form-control {
    width: 100%;
}

/* Stacked date / time */
.jx-stack {
    display: block;
    line-height: 1.3;
    white-space: nowrap;
}

.jx-stack-sub {
    display: block;
    font-size: .75rem;
    color: var(--jx-muted);
    line-height: 1.3;
    white-space: nowrap;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-time {
    width: 88px;
}

/* --------------------------------------------------------------------------
   18. Compact status / flag pills driven by the switch's own state
   -------------------------------------------------------------------------- */
.jx-c-status .form-check.form-switch,
.jx-c-ctn .form-check.form-switch,
.jx-switch-pill .form-check.form-switch {
    display: inline-flex;
    align-items: center;
    gap: .3125rem;
    margin: 0;
    padding-left: 0;
    max-width: 100%;
    /* One line in table mode: stacking the pill under the switch made the row
       taller without making the column any narrower. */
    flex-wrap: nowrap;
    white-space: nowrap;
}

/* Only in card mode, where vertical space is cheap, may it wrap. */
.jx-cards-on .jx-c-status .form-check.form-switch,
.jx-cards-on .jx-c-ctn .form-check.form-switch {
    flex-wrap: wrap;
}

/* Status / CTN columns are sized to the pill, nothing more. */
[data-jx-table]:not(.jx-cards-on) .jx-c-status {
    min-width: 108px;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-ctn {
    width: 96px;
}

.jx-c-status .form-check.form-switch .form-check-input,
.jx-c-ctn .form-check.form-switch .form-check-input,
.jx-switch-pill .form-check.form-switch .form-check-input {
    margin: 0;
    flex: 0 0 auto;
    width: 28px;
    height: 16px;
    cursor: pointer;
}

.table td.jx-c-status .form-check-label,
.table td.jx-c-ctn .form-check-label,
.jx-switch-pill .form-check-label {
    margin: 0;
    padding: .1875rem .4375rem;
    border-radius: 999px;
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    background-color: rgba(135, 138, 153, .14);
    color: #6c7183;
    cursor: pointer;
}

.table td.jx-c-status .form-check-input:checked ~ .form-check-label,
.jx-switch-pill .form-check-input:checked ~ .form-check-label {
    background-color: rgba(10, 179, 156, .16);
    color: #0a8f7e;
}

.table td.jx-c-status .form-check-input:not(:checked) ~ .form-check-label,
.jx-switch-pill .form-check-input:not(:checked) ~ .form-check-label {
    background-color: rgba(247, 184, 75, .18);
    color: #a4701a;
}

.table td.jx-c-ctn .form-check-input:checked ~ .form-check-label {
    background-color: rgba(247, 184, 75, .2);
    color: #8a5d0e;
}

html[data-layout-mode="dark"] .jx-c-status .form-check-label,
html[data-layout-mode="dark"] .jx-c-ctn .form-check-label,
html[data-layout-mode="dark"] .jx-switch-pill .form-check-label {
    color: #adb5bd;
}

html[data-layout-mode="dark"] .jx-c-status .form-check-input:checked ~ .form-check-label,
html[data-layout-mode="dark"] .jx-switch-pill .form-check-input:checked ~ .form-check-label {
    color: #4ad3bf;
}

html[data-layout-mode="dark"] .jx-c-status .form-check-input:not(:checked) ~ .form-check-label,
html[data-layout-mode="dark"] .jx-switch-pill .form-check-input:not(:checked) ~ .form-check-label {
    color: #f7c66b;
}

/* --------------------------------------------------------------------------
   19. Compact icon action buttons
   -------------------------------------------------------------------------- */
[data-jx-table] .jx-c-act > div,
[data-jx-table] .jx-c-print > div {
    display: flex;
    align-items: center;
    gap: .25rem !important;
    flex-wrap: nowrap;
}

/* Shrink-to-content: the surplus width belongs to the text columns, not to
   a column holding three icon buttons. */
[data-jx-table]:not(.jx-cards-on) .jx-c-act,
[data-jx-table]:not(.jx-cards-on) .jx-c-print {
    width: 1%;
    white-space: nowrap;
}

[data-jx-table] .jx-c-act .btn-sm,
[data-jx-table] .jx-c-print .btn-sm {
    padding: .25rem .375rem;
    font-size: .6875rem;
    line-height: 1;
}

/* Square icon-only buttons */
[data-jx-table] .jx-btn-ico {
    width: 26px;
    height: 26px;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

[data-jx-table] .jx-btn-ico i {
    font-size: 14px;
    line-height: 1;
}

/* The status dropdown keeps its full text -- it is the current value, not a
   label, so truncating it to "Active/In Sto..." helped nobody. */
[data-jx-table] .jx-c-act .dropdown-toggle {
    font-size: .6875rem;
    padding: .25rem .4375rem;
    white-space: nowrap;
}

/* In table mode the CTN column header already says CTN, so the repeated
   "Ctn Only" label is dropped and the column shrinks to the switch. */
[data-jx-table]:not(.jx-cards-on) .jx-c-ctn .form-check-label {
    display: none;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-ctn {
    min-width: 46px;
    text-align: center;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-ctn .form-check.form-switch {
    justify-content: center;
}

/* --------------------------------------------------------------------------
   20. Order detail -- product list that never needs a column
   -------------------------------------------------------------------------- */
.jx-orderlist {
    display: flex;
    flex-direction: column;
}

.jx-orderitem {
    display: grid;
    grid-template-columns: 30px 56px minmax(0, 1fr);
    gap: .25rem .75rem;
    align-items: start;
    padding: .75rem 0;
    border-bottom: 1px solid var(--jx-border);
}

.jx-orderitem:first-child {
    padding-top: .25rem;
}

.jx-orderitem:last-child {
    border-bottom: 0;
}

.jx-orderitem-sr {
    grid-column: 1;
    grid-row: 1 / span 2;
    font-size: .75rem;
    font-weight: 600;
    color: var(--jx-muted);
    text-align: center;
    padding-top: .125rem;
}

.jx-orderitem-img {
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 56px;
    height: 56px;
    border-radius: var(--jx-radius-xs);
    border: 1px solid var(--jx-border);
    background-color: var(--jx-subtle-bg);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

.jx-orderitem-img img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.jx-orderitem-body {
    grid-column: 3;
    grid-row: 1;
    min-width: 0;
}

.jx-orderitem-title {
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--jx-heading);
    margin: 0 0 .125rem;
    overflow-wrap: anywhere;
}

.jx-orderitem-variant {
    font-size: .75rem;
    color: var(--jx-muted);
    margin: 0;
}

.jx-orderitem-meta {
    grid-column: 3;
    grid-row: 2;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
    gap: .25rem .75rem;
    margin-top: .375rem;
    min-width: 0;
}

.jx-meta {
    min-width: 0;
}

.jx-meta-label {
    display: block;
    font-size: .625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--jx-muted);
    line-height: 1.4;
}

.jx-meta-value {
    display: block;
    font-size: .8125rem;
    font-weight: 500;
    line-height: 1.35;
    color: var(--jx-text);
    overflow-wrap: anywhere;
}

.jx-meta-value-strong {
    font-weight: 700;
    color: var(--jx-heading);
}

.jx-order-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px dashed var(--jx-border);
}

.jx-order-total-label {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--jx-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.jx-order-total-value {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--jx-heading);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 575.98px) {
    .jx-orderitem {
        grid-template-columns: 24px 48px minmax(0, 1fr);
        gap: .25rem .5rem;
    }

    .jx-orderitem-img {
        width: 48px;
        height: 48px;
    }

    .jx-orderitem-meta {
        grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
    }
}

/* Side panel details must wrap, never widen the column. */
.jx-detail-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .625rem;
}

.jx-detail-list li {
    min-width: 0;
    overflow-wrap: anywhere;
    font-size: .8125rem;
    line-height: 1.45;
}

/* --------------------------------------------------------------------------
   17. Accessibility / motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

.card-animate:hover {
    transform: none;
}

/* --------------------------------------------------------------------------
   18. PRODUCTS TABLE - PRICE COLUMN
   The price cell holds an editable input. Its `min-width: 0` (needed so the
   input can follow the column) meant that when the table ran wider than the
   viewport, price was the only cell free to collapse - four-figure values got
   clipped mid-digit. Price now carries a hard floor, and the room comes from
   the three neighbouring columns whose content is fixed-size: the row number,
   the 4-digit serial, and the CTN switch.
   -------------------------------------------------------------------------- */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-price {
    width: 104px;
    min-width: 104px;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-price .form-control {
    min-width: 68px;
    padding-left: .375rem;
    padding-right: .375rem;
}

/* Reclaimed space: these hold short, fixed-size content, so trimming their
   padding costs nothing legible. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-serial {
    min-width: 44px;
    padding-left: .3125rem !important;
    padding-right: .3125rem !important;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-ctn {
    padding-left: .25rem !important;
    padding-right: .25rem !important;
    text-align: center;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-ctn .form-check.form-switch {
    padding-left: 2em;
    gap: 0;
}

/* --------------------------------------------------------------------------
   21. Pinned products -- pin button, remaining-time chip and row tint
   -------------------------------------------------------------------------- */
.table > tbody > tr.jx-row-pin > * {
    --bs-table-bg: #dbe7ff;
    --bs-table-accent-bg: #dbe7ff;
    background-color: #dbe7ff !important;
    color: #1c3d78 !important;
}

html[data-layout-mode="dark"] .table > tbody > tr.jx-row-pin > * {
    background-color: #24334f !important;
    color: #c3d5f5 !important;
}

.jx-pin-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .25rem;
}

/* The remaining time is a reading, not a control -- it stays quiet next to
   the two buttons and never stretches the column. */
.jx-pin-left {
    font-size: .625rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    padding: .1875rem .375rem;
    border-radius: 999px;
    background-color: rgba(64, 81, 137, .12);
    color: #405189;
}

html[data-layout-mode="dark"] .jx-pin-left {
    background-color: rgba(160, 185, 240, .16);
    color: #c3d5f5;
}

[data-jx-table]:not(.jx-cards-on) .jx-c-pin {
    width: 1%;
    white-space: nowrap;
    text-align: center;
}

[data-jx-table] .jx-c-pin .btn-sm {
    padding: .25rem .375rem;
    font-size: .6875rem;
    line-height: 1;
}

/* Card mode: the pin controls get their own strip above the action row. */
.jx-cards-on > tbody > tr > td.jx-c-pin::before {
    content: none;
}

.jx-cards-on > tbody > tr.jx-row-pin {
    border-left-width: 4px;
    border-left-color: #405189;
    background-color: rgba(64, 81, 137, .06);
}

.jx-cards-on > tbody > tr.jx-row-pin > * {
    background-color: transparent !important;
    color: inherit !important;
}

[data-jx-table="products"].jx-cards-on .jx-c-pin {
    grid-area: pin;
    justify-self: start;
    padding-top: .25rem !important;
}

[data-jx-table="products"].jx-cards-on .jx-c-pin .jx-pin-cell {
    justify-content: flex-start;
}

/* --------------------------------------------------------------------------
   22. PRODUCTS TABLE -- character-width columns, and no horizontal scrollbar
        at any width.

   The four text columns are sized in characters, as asked:

        Serial  6   Brand  11   Category  15   Title  24

   Two things make that hold. First, `table-layout: fixed`: the browser then
   takes every column width from the header row and never lets a long value
   push a column wider, so a row's content can only ever wrap, never spread.
   Second, the widths below are the only ones the table has -- Action is left
   unsized so it absorbs whatever is left over, which is what keeps the total
   pinned to the wrapper width instead of overflowing it.

   The widths are in rem, not ch, on purpose. Under fixed layout they are read
   off the <th>, which runs 11px bold while the cells run 13px regular, so a
   `ch` there is not a cell character; and Poppins is proportional, so a "0"
   (8.16px at 13px) is a fifth wider than the average character in a real
   product name (measured over the live titles: 6.3-7.1px, call it 6.6px).
   The numbers below are therefore characters x measured width:

        Serial     6 x 8.16px (digits, so the "0" width)   =  49px = 3.0625rem
        Brand     11 x 6.6px                               =  73px = 4.5625rem
        Category  15 x 6.6px                               =  99px = 6.1875rem
        Title     24 x 6.6px                               = 159px = 9.9375rem

   Being in rem they still follow the browser's text-size setting. Change the
   cell font size and these need re-measuring.
   -------------------------------------------------------------------------- */
[data-jx-table="products"]:not(.jx-cards-on) {
    table-layout: fixed;
    --jx-cell-pad: .3125rem;
}

/* One padding value across the table, so "N characters + padding" is exact
   and the pixels saved go to the Action column. */
[data-jx-table="products"]:not(.jx-cards-on) > thead th,
[data-jx-table="products"]:not(.jx-cards-on) > tbody td {
    padding: .375rem var(--jx-cell-pad) !important;
}

/* The character-count columns. box-sizing is border-box, so the horizontal
   padding is added back on top of the character budget. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-serial {
    width: calc(3.0625rem + var(--jx-cell-pad) * 2);
    min-width: 0;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-brand {
    width: calc(4.5625rem + var(--jx-cell-pad) * 2);
    min-width: 0;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-cat {
    width: calc(6.1875rem + var(--jx-cell-pad) * 2);
    min-width: 0;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-title {
    width: calc(9.9375rem + var(--jx-cell-pad) * 2);
    min-width: 0;
}

/* Fixed-size columns, trimmed to what their content actually needs so the
   text columns above can have their characters. Action is deliberately left
   without a width: under fixed layout it takes the remainder. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-chk   { width: 26px; min-width: 0; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-img   { width: 46px; min-width: 0; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-price { width: 76px; min-width: 0; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-ctn   { width: 44px; min-width: 0; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-pin   { width: 68px; min-width: 0; }

/* Action is the one column that must stay `auto`. Under fixed layout that is
   what makes it the remainder: every other column takes its stated width and
   Action absorbs the difference, which is why the table ends exactly at the
   wrapper. The shrink-to-content `width: 1%` it carries elsewhere would make
   it 1% of the table here and hand the surplus back to the other columns. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-act {
    width: auto;
    white-space: normal;
}

/* From 1280px up there is more width than the columns above ask for, and all
   of it was landing in Action as blank space beside the buttons. Past that
   point the buttons take the width they actually need and Title becomes the
   column that absorbs the slack -- it is the one that can use it. 1280px is
   where that swap is safe: below it Title would come out under its 24
   characters. The other three keep their character counts at every size.
   16.25rem is the action cluster measured on one line -- four icon buttons
   plus the widest status label, "Active/In Stock". */
@media (min-width: 1280px) {
    [data-jx-table="products"]:not(.jx-cards-on) .jx-c-act   { width: 16.25rem; }
    [data-jx-table="products"]:not(.jx-cards-on) .jx-c-title { width: auto; }
}

/* The row payload asks for a 50px thumbnail inline; at these column widths
   38px is the size that pays for itself. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-img img {
    width: 38px !important;
    height: 38px !important;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-price .form-control {
    min-width: 0;
    padding-left: .25rem;
    padding-right: .25rem;
}

/* Serial is one unbroken token, so it needs permission to break mid-value --
   that is what puts characters 7+ on the second line. The other three break
   at word boundaries first and only split a word when it cannot fit. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-serial {
    white-space: normal !important;
    text-align: left;
    line-height: 1.3;
}

[data-jx-table="products"] .jx-c-serial .jx-clamp {
    -webkit-line-clamp: 2;
    word-break: break-all;
    overflow-wrap: anywhere;
}

[data-jx-table="products"] .jx-c-title .jx-clamp,
[data-jx-table="products"] .jx-c-brand .jx-clamp,
[data-jx-table="products"] .jx-c-cat .jx-clamp {
    word-break: normal;
    overflow-wrap: break-word;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-title .jx-clamp { -webkit-line-clamp: 2; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-brand .jx-clamp { -webkit-line-clamp: 2; }
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-cat   .jx-clamp { -webkit-line-clamp: 3; }

/* CTN: the switch sits in the middle of its column. Bootstrap floats the
   input out of flow and hangs it in the wrapper's left padding -- with the
   "Ctn Only" label hidden in table mode there is nothing left in flow, so the
   padding alone decided where the switch landed and it came out pushed to the
   right. Taking the input back into flow lets the flex centring reach it. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-ctn .form-check.form-switch {
    display: flex;
    justify-content: center;
    padding-left: 0;
    gap: 0;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-ctn .form-check.form-switch .form-check-input {
    float: none;
    margin: 0;
}

/* Pin: the remaining-time chip drops under its buttons rather than widening
   the column -- the reading is kept, the width is not spent on it. It sits
   between the two buttons in the markup, so it is reordered last; otherwise
   wrapping would give each of the three its own line. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-pin .jx-pin-cell {
    flex-wrap: wrap;
    row-gap: .1875rem;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-pin .jx-pin-left {
    order: 1;
    flex-basis: 100%;
}

/* Action holds the leftover width, so its cluster is the one thing allowed to
   wrap onto a second line. Without this it would be the column that pushes
   the table past the wrapper and brings the scrollbar back. */
[data-jx-table="products"]:not(.jx-cards-on) .jx-c-act > div {
    flex-wrap: wrap !important;
    row-gap: .25rem;
    justify-content: flex-start;
}

[data-jx-table="products"]:not(.jx-cards-on) .jx-c-act .dropdown-toggle {
    white-space: normal;
    text-align: left;
    line-height: 1.2;
}

/* Header labels follow the same rule as the cells: wrap, never widen. */
[data-jx-table="products"]:not(.jx-cards-on) > thead th {
    white-space: normal;
    overflow-wrap: break-word;
}

/* The table is held to the wrapper regardless of what the markup asks for --
   the inline `width: 100%` on the element is the intent, and this keeps it
   true if that attribute is ever dropped or a plugin overwrites it. */
[data-jx-table="products"]:not(.jx-cards-on) {
    width: 100% !important;
    max-width: 100%;
}

/* --------------------------------------------------------------------------
   23. PRODUCT FORM -- size variant rows

   The variant rows used to be a bare Bootstrap .input-group: nine identical
   boxes telling you nothing but their placeholder, which disappears the
   moment a value is typed. They are a grid now so a header row can sit above
   them and stay aligned.

   Alignment only holds because every track except the eight text columns is a
   fixed size -- the header and each row are separate grid containers, so an
   `auto` track would resolve differently in each and the columns would drift.
   The buttons are stretched to fill their fixed track for the same reason.
   -------------------------------------------------------------------------- */
.jx-var-wrap {
    overflow-x: auto;
    padding-bottom: .25rem;
}

.jx-var-grid {
    display: grid;
    grid-template-columns:
        minmax(0, 2.2fr)            /* title -- the one you actually read */
        minmax(0, 1fr)              /* price */
        minmax(0, 0.7fr)            /* serial number */
        minmax(0, 1fr)              /* packing name */
        minmax(0, 0.6fr)            /* packing qty */
        5rem                        /* stock switch + "Out Of Stock" */
        4.25rem                     /* size status switch + "Inactive" */
        minmax(0, 0.7fr)            /* base unit */
        3.5rem                      /* ctn switch + "On"/"Off" */
        2.5rem 2.5rem;              /* colour, delete */
    gap: .375rem;
    align-items: center;
    min-width: 52rem;
}

/* Rows keep .input-group: existing scripts find them with
   closest('.input-group'). The grid replaces its flex layout, so the -1px
   seams and squared-off corners it puts between children are undone here.

   The width matters as much as the seams. Bootstrap sizes input-group
   children with `flex: 1 1 auto; width: 1%` -- the flex-grow is what opens
   them up, and it does nothing in a grid, so only the 1% survived and every
   box shrank to a sliver at the left of its (correctly sized) column. */
.jx-var-grid.input-group > * {
    width: 100%;
    min-width: 0;
    margin-left: 0 !important;
    border-radius: var(--vz-border-radius, .25rem) !important;
}

.jx-var-grid .btn {
    width: 100%;
    padding-left: 0;
    padding-right: 0;
}

.jx-var-head {
    font-size: .6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--jx-muted);
    margin-bottom: .3125rem;
}

.jx-var-head > span {
    overflow-wrap: break-word;
    line-height: 1.25;
}

.jx-var-head-switch {
    text-align: center;
}

/* Stock, Size Status and CTN are switches rather than boxes you type "Yes" or
   "No" into. Bootstrap floats the input and hangs it in the wrapper's left
   padding; taking it back into flow is what lets it sit in the middle of its
   column. */
.jx-var-switch.form-check {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .125rem;
    min-height: 0;
    margin: 0;
    padding-left: 0;
}

.jx-var-switch .form-check-input {
    float: none;
    margin: 0;
    cursor: pointer;
}

/* The switch says on or off; the caption under it says what on and off mean
   for that particular column. It is set from the wrapper's data-on-label /
   data-off-label so the row builder and the toggle handler cannot disagree
   about the wording. */
.jx-var-switch-label {
    font-size: .625rem;
    line-height: 1.1;
    color: var(--jx-muted);
    white-space: nowrap;
    text-align: center;
    user-select: none;
}

/* --------------------------------------------------------------------------
   24. USERS -- bulk password dialog

   The city list is as long as the customer base, so it scrolls inside the
   dialog rather than pushing the password field and the preview off screen.
   -------------------------------------------------------------------------- */
/* The dialog is taller than a laptop screen once a preview list is in it, so
   the body is the only part allowed to grow -- without this the footer, and
   with it the button that actually applies the change, ends up below the
   bottom of the window with no way to reach it. */
#bulkPasswordModal .modal-dialog {
    max-height: calc(100vh - 2rem);
}

#bulkPasswordModal .modal-content {
    max-height: calc(100vh - 2rem);
    overflow: hidden;
}

/* The <form> sits between .modal-content and .modal-body, so the column
   flexbox Bootstrap sets up on .modal-content stops at the form: the form is
   a plain block, grows to its content, and the footer inside it gets pushed
   past the clipped edge of the dialog. Carrying the flex column through the
   form is what lets the body shrink and scroll instead.

   min-height:0 on both is load-bearing -- a flex item defaults to
   min-height:auto and refuses to shrink below its own content. */
#bulkPasswordModal .modal-content > form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

#bulkPasswordModal .modal-body {
    overflow-y: auto;
    min-height: 0;
}

/* Select2 sits inside a modal here, so it has to clear the dialog's stacking
   context and match the height of the theme's own inputs. */
#bulkPasswordModal .select2-container {
    width: 100% !important;
}

#bulkPasswordModal .select2-container--default .select2-selection--multiple {
    border-color: var(--jx-border);
    min-height: 38px;
}

.select2-container--open {
    z-index: 1060;
}

#jxPreviewResult .table {
    font-size: .78125rem;
}

#jxPreviewResult .table-responsive {
    max-height: 15rem;
    overflow-y: auto;
}
