/* MonEx components. Every value comes from tokens.css. */

/* mx-shell: style-form.css locks html/body overflow app-wide, so every page needs its own scroll area. */
.mx-shell {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--mx-chrome-h));
}

.mx-shell__head {
    flex: 0 0 auto;
}

.mx-shell__body {
    flex: 1 1 auto;
    min-height: 0;
}

.mx-scroll {
    overflow-y: auto;
    min-height: 0;
}

/* page head */
.mx-page-head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;
    align-items: flex-start;
}

.mx-page-head__title {
    font-family: var(--mx-font-display);
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0;
}

.mx-page-head__sub {
    font-size: 0.85rem;
    color: var(--mx-muted);
    margin: 0.15rem 0 0;
}

/* section title */
.mx-section-title {
    font-family: var(--mx-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    text-align: left;
    margin: 2rem 0 1.25rem;
    padding-bottom: 0.65rem;
    border-bottom: 1px solid var(--mx-line);
}

.mx-section-title:first-child {
    margin-top: 0;
}

/* The :first-child reset above is for cards that open with a heading. A board body
   has no top padding of its own, so a title starting one needs the space back. */
.mx-board__body > .mx-section-title:first-child {
    margin-top: 1rem;
}

/* rail nav */
.mx-rail {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    border: 0;
}

.mx-rail .mx-rail__item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0.75rem;
    border: 0;
    border-radius: var(--mx-radius-sm);
    background: transparent;
    color: var(--mx-text);
    text-align: left;
    width: 100%;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.mx-rail .mx-rail__item:hover {
    background: var(--mx-surface-sub);
    color: var(--mx-text);
}

.mx-rail .mx-rail__item.active,
.mx-rail .mx-rail__item[aria-selected='true'] {
    background: var(--mx-brass-wash);
    color: var(--mx-brass);
    box-shadow: inset 3px 0 0 var(--mx-brass);
}

.mx-rail .mx-rail__ico {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--mx-radius-sm);
    background: var(--mx-surface-sub);
    color: var(--mx-muted);
    font-size: 0.9rem;
}

.mx-rail .mx-rail__item.active .mx-rail__ico,
.mx-rail .mx-rail__item[aria-selected='true'] .mx-rail__ico {
    background: var(--mx-brass);
    color: var(--mx-surface);
}

.mx-rail .mx-rail__label {
    font-weight: 500;
    font-size: 0.875rem;
    line-height: 1.2;
}

.mx-rail .mx-rail__label small {
    display: block;
    font-weight: 400;
    font-size: 0.72rem;
    color: var(--mx-muted);
    margin-top: 0.1rem;
}

.mx-rail .mx-rail__item.active .mx-rail__label small,
.mx-rail .mx-rail__item[aria-selected='true'] .mx-rail__label small {
    color: var(--mx-brass);
    opacity: 0.8;
}

/* fieldset */
.mx-fieldset {
    border: 1px solid var(--mx-line);
    border-radius: var(--mx-radius);
    padding: 1rem 1.25rem;
    background: var(--mx-surface);
}

.mx-fieldset + .mx-fieldset {
    margin-top: 1rem;
}

.mx-fieldset__head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.mx-fieldset__ico {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--mx-radius-sm);
    background: var(--mx-brass-wash);
    color: var(--mx-brass);
    font-size: 0.9rem;
}

.mx-fieldset__title {
    font-weight: 600;
    margin: 0;
    font-size: 0.95rem;
}

.mx-fieldset__desc {
    display: block;
    font-weight: 400;
    font-size: 0.78rem;
    color: var(--mx-muted);
}

.mx-fieldset label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--mx-muted);
    margin-bottom: 0.25rem;
}

/* pill */
.mx-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: var(--mx-surface-sub);
    color: var(--mx-muted);
}

.mx-pill--beli,
.mx-pill--ok {
    background: var(--mx-beli-wash);
    color: var(--mx-beli);
}

.mx-pill--jual,
.mx-pill--danger {
    background: var(--mx-jual-wash);
    color: var(--mx-jual);
}

.mx-pill--warn {
    background: var(--mx-warn-wash);
    color: var(--mx-warn);
}

/* form actions */
.mx-form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    border-top: 1px solid var(--mx-line);
    padding-top: 1rem;
    margin-top: 1.5rem;
}

/* mx-grid: Bootstrap draws a currentColor rule via .table > :not(:first-child) — zeroed once here. */
.mx-grid {
    width: 100%;
    border: 0;
    margin-bottom: 0;
}

.mx-grid > :not(:first-child) {
    border-top: 0 !important;
}

.mx-grid > thead > tr > th {
    background-color: var(--mx-surface-sub);
    border: 0;
    border-bottom: 1px solid var(--mx-line);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mx-muted);
    padding: 0.55rem 0.6rem;
}

.mx-grid > tbody > tr > td {
    border: 0;
    border-bottom: 1px solid var(--mx-line);
    background-color: var(--mx-surface);
    vertical-align: middle;
    padding: 0.45rem 0.6rem;
}

.mx-grid > tbody > tr:last-child > td {
    border-bottom: 0;
}

/* mx-grid--edit: the stock pages take input in their cells. Behind a modifier because
   eleven shipped views already use .mx-grid read-only and must not shift. */
.mx-grid--edit > thead > tr > th {
    position: sticky;
    top: 0;
    z-index: 2;
}

.mx-grid--edit > tbody > tr > td {
    padding: 0.3rem 0.5rem;
}

.mx-grid--edit .form-control,
.mx-grid--edit .form-select {
    font-size: 0.85rem;
    padding: 0.3rem 0.55rem;
    color: var(--mx-text);
    background: var(--mx-surface-sub);
    border: 1px solid var(--mx-line-strong);
    border-radius: var(--mx-radius-sm);
}

.mx-grid--edit .form-control:focus,
.mx-grid--edit .form-select:focus {
    background: var(--mx-surface);
    border-color: var(--mx-brass-bright);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--mx-brass) 18%, transparent);
}

.mx-grid--edit .mx-grid__num {
    font-family: var(--mx-font-mono);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* Replaces the inline style="background:#f8f9fa" the stock pages hand-roll today. */
.mx-grid--edit .form-control[readonly],
.mx-grid--edit .form-control:disabled,
.mx-grid--edit .form-select:disabled {
    color: var(--mx-text-soft);
    background: var(--mx-ground);
    border-color: var(--mx-line);
    cursor: default;
}

.mx-grid--edit .form-control.is-invalid,
.mx-grid--edit .form-select.is-invalid {
    background: var(--mx-jual-wash);
    background-image: none;
    border-color: var(--mx-jual);
    padding-right: 0.55rem;
}

.mx-grid--edit .input-group > .form-control,
.mx-grid--edit .input-group > .form-select {
    border-radius: var(--mx-radius-sm);
}

/* select2's bootstrap-5 theme hardcodes Bootstrap's stock blue instead of reading
   --bs-primary, so the token remap never reaches it. The theme's own selectors are
   five classes deep, so these have to match that depth to win. */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--highlighted {
    background-color: var(--mx-brass-wash);
    color: var(--mx-text);
}

.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option.select2-results__option--selected,
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[aria-selected='true']:not(.select2-results__option--highlighted) {
    background-color: var(--mx-brass);
    color: var(--mx-ink-contrast);
}

.select2-container--bootstrap-5.select2-container--focus .select2-selection,
.select2-container--bootstrap-5.select2-container--open .select2-selection {
    border-color: var(--mx-brass-bright);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--mx-brass) 18%, transparent);
}

.select2-container--bootstrap-5 .select2-dropdown {
    border-color: var(--mx-line-strong);
}

.select2-container--bootstrap-5 .select2-search__field:focus {
    border-color: var(--mx-brass-bright);
    box-shadow: none;
}

/* mx-skel: placeholder rows held in a grid while its data is in flight. The app DB
   is remote (~200ms a round trip) and these pages make several sequential calls, so
   a bare empty table reads as "no data" for seconds. */
.mx-skel__bar {
    display: block;
    height: 0.72rem;
    border-radius: 2px;
    background: linear-gradient(90deg,
            var(--mx-line) 25%,
            var(--mx-surface-sub) 37%,
            var(--mx-line) 63%);
    background-size: 400% 100%;
    animation: mx-skel-shimmer 1.4s ease-in-out infinite;
}

.mx-skel__bar--narrow {
    width: 40%;
}

/* Shape variants. A grid whose cells hold controls needs placeholders with the same
   box metrics as those controls, or the row height jumps when the data lands. Each
   variant mirrors one real control: --field a .form-control, --btn a .btn-sm. */
.mx-skel__field,
.mx-skel__btn {
    display: block;
    line-height: 1.5;
    border: 1px solid transparent;
    border-radius: var(--mx-radius-sm);
    background: linear-gradient(90deg,
            var(--mx-line) 25%,
            var(--mx-surface-sub) 37%,
            var(--mx-line) 63%);
    background-size: 400% 100%;
    animation: mx-skel-shimmer 1.4s ease-in-out infinite;
}

.mx-skel__field::before,
.mx-skel__btn::before {
    content: '\00a0';
}

/* matches .mx-grid--edit .form-control */
.mx-skel__field {
    font-size: 0.85rem;
    padding: 0.3rem 0.55rem;
}

/* matches .btn-sm */
.mx-skel__btn {
    width: 2.1rem;
    margin-inline: auto;
    font-size: 0.875rem;
    padding: 0.25rem 0.5rem;
}

.mx-skel__bar--mid {
    width: 65%;
}

@keyframes mx-skel-shimmer {
    0% {
        background-position: 100% 0;
    }

    100% {
        background-position: 0 0;
    }
}

/* A field whose value is still being fetched, once its row is already on screen. */
.mx-grid--edit .form-control.is-loading {
    color: transparent;
    background-image: linear-gradient(90deg,
            var(--mx-line) 25%,
            var(--mx-surface-sub) 37%,
            var(--mx-line) 63%);
    background-size: 400% 100%;
    animation: mx-skel-shimmer 1.4s ease-in-out infinite;
}

.mx-grid--edit .form-control.is-loading::placeholder {
    color: transparent;
}

@media (prefers-reduced-motion: reduce) {

    .mx-skel__bar,
    .mx-grid--edit .form-control.is-loading {
        animation: none;
    }
}

.mx-grid--edit .input-group-text {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mx-muted);
    background: var(--mx-surface-sub);
    border: 1px solid var(--mx-line-strong);
    border-radius: var(--mx-radius-sm);
}

/* mx-ledger */
.mx-ledger {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin-bottom: 0;
}

.mx-ledger > :not(:first-child) {
    border-top: 0 !important;
}

.mx-ledger > thead > tr > th {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--mx-ground);
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--mx-text-soft);
    border-bottom: 1.5px solid var(--mx-ink);
    padding: 0.85rem 0.75rem;
    box-shadow: none;
    white-space: nowrap;
}

.mx-ledger > tbody > tr > td {
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
    border: 0;
    border-bottom: 1px solid var(--mx-line);
    background: transparent;
    vertical-align: middle;
    overflow-wrap: anywhere;
}

.mx-ledger.table-striped > tbody > tr:nth-of-type(odd) > * {
    --bs-table-accent-bg: transparent;
    box-shadow: none;
}

.mx-ledger > tbody > tr > td.text-end,
.mx-ledger .mx-num {
    font-family: var(--mx-font-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

/* currency chip */
.mx-cc {
    display: inline-block;
    font-family: var(--mx-font-mono);
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    background: var(--mx-ink);
    color: var(--mx-ink-contrast);
    padding: 0.18rem 0.55rem;
}

/* expandable row + detail panel */
.mx-ledger__handle {
    width: 38px;
    padding: 0 !important;
}

.mx-ledger__handle-cell {
    padding: 0 !important;
    text-align: center;
    border-right: 1px solid var(--mx-line);
}

.mx-ledger__chev {
    display: inline-flex;
    width: 24px;
    height: 24px;
    align-items: center;
    justify-content: center;
    color: var(--mx-muted);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), color 0.25s ease;
}

.mx-ledger__row {
    cursor: pointer;
}

.mx-ledger__row:hover > td,
.mx-ledger__row.is-open > td {
    background: var(--mx-surface-sub);
}

.mx-ledger__row.is-open .mx-ledger__chev {
    transform: rotate(90deg);
    color: var(--mx-brass);
}

.mx-ledger__detail > td {
    padding: 0;
    background: var(--mx-surface);
}

.mx-panel {
    margin: 0 0 1rem 38px;
    background: var(--mx-ground);
    border: 1px solid var(--mx-line-strong);
    border-left: 3px solid var(--mx-brass-bright);
}

.mx-panel__head {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.65rem 1.1rem;
    border-bottom: 1px dashed var(--mx-line-strong);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--mx-text-soft);
    font-weight: 500;
}

.mx-panel__dot {
    width: 6px;
    height: 6px;
    background: var(--mx-brass-bright);
    border-radius: 50%;
    display: inline-block;
}

.mx-panel__body {
    padding: 0.35rem 1.1rem 1rem;
}

.mx-panel .mx-grid > thead > tr > th,
.mx-panel .mx-grid > tbody > tr > td {
    background: transparent;
}

.mx-panel .mx-grid > tbody > tr > td.text-end,
.mx-panel .mx-grid > tfoot > tr > td.text-end {
    font-family: var(--mx-font-mono);
    font-variant-numeric: tabular-nums;
}

.mx-panel .mx-grid > tfoot > tr > td {
    border-top: 1.5px solid var(--mx-ink);
    font-weight: 650;
    padding: 0.55rem 0.6rem;
}

/* group + subtotal row */
.mx-ledger__group > td {
    background: var(--mx-surface-sub) !important;
    border-bottom: 1px solid var(--mx-line-strong);
    cursor: pointer;
    font-weight: 600;
}

.mx-ledger__group .fa-chevron-right,
.mx-ledger__group .fa-chevron-down {
    font-size: 0.7rem;
    color: var(--mx-muted);
    width: 0.85rem;
}

.mx-ledger__group .fa-chevron-down {
    color: var(--mx-brass);
}

.mx-ledger__group:hover > td {
    background: color-mix(in srgb, var(--mx-surface-sub) 75%, var(--mx-line)) !important;
}

.mx-ledger__subtotal > td {
    border-top: 1px solid var(--mx-ink);
    border-bottom: 1.5px solid var(--mx-ink);
    font-weight: 650;
    background: transparent !important;
}

/* mx-board */
.mx-board {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--mx-chrome-h));
    min-height: 0;
    background: var(--mx-surface);
}

.mx-board__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 0.5rem var(--mx-board-pad) 1.1rem;
    border-bottom: 1px solid var(--mx-line-strong);
    position: relative;
}

.mx-board__head::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -3px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--mx-brass-bright) 30%, var(--mx-brass-bright) 70%, transparent);
    opacity: 0.35;
}

.mx-board__brand {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.mx-board__mark {
    font-family: var(--mx-font-display);
    font-size: 2.6rem;
    line-height: 1;
    color: var(--mx-brass-bright);
    font-weight: 700;
    transform: translateY(-2px);
}

.mx-board__mark .fa-solid {
    font-size: 1.75rem;
}

.mx-board__title {
    font-family: var(--mx-font-display);
    font-weight: 600;
    font-size: 1.55rem;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--mx-text);
    line-height: 1;
}

.mx-board__sub {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--mx-muted);
    margin: 0.35rem 0 0;
    font-weight: 400;
}

.mx-board__controls {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.mx-board__quota {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    align-self: center;
    margin-left: 0.35rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--mx-brass);
    background: var(--mx-brass-wash);
    color: var(--mx-brass);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
    border-radius: 2px;
}
.mx-board__quota--full {
    border-color: var(--mx-jual);
    background: var(--mx-jual-wash);
    color: var(--mx-jual);
}

.mx-board__filter {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.mx-board__entity {
    font-size: 0.8rem;
    color: var(--mx-text-soft);
    padding: 0.35rem 0.8rem;
    border: 1px solid var(--mx-line-strong);
    background: var(--mx-ground);
    border-radius: 2px;
    max-width: 32ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mx-board__select,
.mx-board__head .form-select {
    font-family: inherit;
    font-size: 0.85rem;
    border: 1px solid var(--mx-text);
    border-radius: 0;
    padding: 0.4rem 1.6rem 0.4rem 0.65rem;
    background: var(--mx-ground);
    color: var(--mx-text);
    cursor: pointer;
    letter-spacing: 0.02em;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%231a1714' stroke-width='3'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.55rem center;
}

.mx-board__select:focus,
.mx-board__head .form-select:focus,
.mx-board__head .form-control:focus {
    outline: 2px solid var(--mx-brass-bright);
    outline-offset: 1px;
    box-shadow: none;
    border-color: var(--mx-text);
}

.mx-board__actions {
    display: flex;
    gap: 0.5rem;
}

.mx-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    padding: 0.45rem 0.75rem;
    border-radius: 2px;
    border: 1px solid var(--mx-text);
    background: transparent;
    color: var(--mx-text);
    cursor: pointer;
    transition: all 0.15s ease;
    letter-spacing: 0.03em;
}

.mx-btn:hover {
    background: var(--mx-text);
    color: var(--mx-ground);
}

.mx-btn--ghost {
    border-color: var(--mx-line-strong);
    color: var(--mx-text-soft);
}

.mx-btn--ghost:hover {
    background: var(--mx-ground);
    color: var(--mx-text);
    border-color: var(--mx-text);
}

.mx-btn--ink {
    background: var(--mx-text);
    color: var(--mx-ground);
}

.mx-btn--ink:hover {
    background: var(--mx-brass);
    border-color: var(--mx-brass);
    color: var(--mx-ground);
}

/* Bootstrap controls pick up the board styling only inside this head */
.mx-board__head .form-control {
    font-size: 0.85rem;
    border: 1px solid var(--mx-line-strong);
    border-radius: 0;
    padding: 0.4rem 0.65rem;
    background: var(--mx-ground);
    color: var(--mx-text);
}

/* Presets lay their fields out on the Bootstrap grid, so a percentage column
   resolves against the squeezed head instead of the page. Size to content. */
.mx-board__head form {
    width: auto !important;
}

.mx-board__head .row > [class*='col-'] {
    flex: 0 0 auto;
    width: auto;
    max-width: none;
}

.mx-board__head .form-select {
    width: 12rem;
}

.mx-board__head .form-control[type='date'] {
    width: 9.75rem;
}

.mx-board__head .form-control[type='text'] {
    width: 13rem;
}

.mx-board__head .input-group-text {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    border: 0;
    background: transparent;
    color: var(--mx-muted);
    padding: 0.4rem 0.15rem;
}

.mx-board__head .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    padding: 0.45rem 0.75rem;
    border-radius: 2px;
    border: 1px solid var(--mx-line-strong);
    background: transparent;
    color: var(--mx-text-soft);
}

.mx-board__head .btn:hover {
    background: var(--mx-ground);
    color: var(--mx-text);
    border-color: var(--mx-text);
}

.mx-board__head .btn-dark {
    background: var(--mx-text);
    border-color: var(--mx-text);
    color: var(--mx-ground);
}

.mx-board__head .btn-dark:hover {
    background: var(--mx-brass);
    border-color: var(--mx-brass);
    color: var(--mx-ground);
}

.mx-board__head .btn i {
    font-size: 0.95rem !important;
}

.mx-board__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /* Cells carry 0.75rem of their own, so this lands ledger text on --mx-board-pad,
       flush with the header above it. */
    padding-inline: 0.25rem;
}

.mx-board__body::-webkit-scrollbar {
    width: 8px;
}

.mx-board__body::-webkit-scrollbar-track {
    background: transparent;
}

.mx-board__body::-webkit-scrollbar-thumb {
    background: var(--mx-line-strong);
    border-radius: 0;
}

@media (max-width: 991px) {
    .mx-board__head {
        flex-wrap: wrap;
        gap: 1rem;
    }

    .mx-board__controls {
        flex-wrap: wrap;
    }

    .mx-board__mark {
        font-size: 2rem;
    }

    .mx-board__title {
        font-size: 1.25rem;
    }
}

/* request overlay — still swallows clicks while a request is in flight, but stays
   transparent: washing out the whole page to open one modal read as a full-page load. */
.mx-loading {
    position: fixed;
    inset: var(--mx-navbar-h) 0 0 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
}

.mx-loading.is-active {
    opacity: 1;
    visibility: visible;
}


/* Idle animation still burns cycles behind visibility:hidden. */
.mx-loading:not(.is-active) .mx-loading__reel,
.mx-loading:not(.is-active) .mx-loading__tally::after {
    animation-play-state: paused;
}

.mx-loading__card {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 15rem;
    padding: 1.15rem 1.4rem 1.25rem;
    background: var(--mx-surface);
    border: 1px solid var(--mx-line-strong);
    border-left: 3px solid var(--mx-brass-bright);
    box-shadow: var(--mx-shadow);
}

.mx-loading__caption {
    font-family: var(--mx-font-sans);
    font-size: 0.65rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mx-muted);
}

/* A rate board mid-tick — the one motion this counter actually makes. */
.mx-loading__window {
    height: 2rem;
    overflow: hidden;
}

.mx-loading__reel {
    display: flex;
    flex-direction: column;
    animation: mxReel 3.6s steps(6) infinite;
}

.mx-loading__code {
    flex: 0 0 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-family: var(--mx-font-mono);
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--mx-text);
}

.mx-loading__code::before {
    content: '';
    width: 3px;
    height: 1rem;
    background: var(--mx-brass-bright);
}

@keyframes mxReel {
    to { transform: translateY(-12rem); }
}

.mx-loading__tally {
    height: 2px;
    overflow: hidden;
    background: var(--mx-line);
}

.mx-loading__tally::after {
    content: '';
    display: block;
    height: 100%;
    width: 40%;
    background: var(--mx-brass);
    animation: mxTally 1.15s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

@keyframes mxTally {
    from { transform: translateX(-100%); }
    to { transform: translateX(350%); }
}

@media (prefers-reduced-motion: reduce) {
    .mx-loading__reel { animation-duration: 9s; }
    .mx-loading__tally::after {
        animation: none;
        width: 100%;
        opacity: 0.5;
    }
}

/* SweetAlert dialogs — the shell comes from the --swal2-* remap in tokens.css.
   What is left is type and the footer band, which no variable reaches. */
/* No overflow:hidden here — several pages put wide tables in a popup and it
   clipped them. The actions band rounds its own corners instead. */
.swal2-popup:not(.swal2-toast) {
    box-shadow: var(--mx-shadow);
}

.swal2-popup:not(.swal2-toast) .swal2-title {
    font-family: var(--mx-font-display);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--mx-text);
    text-wrap: balance;
}

.swal2-popup:not(.swal2-toast) .swal2-html-container {
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--mx-text-soft);
    overflow-x: auto;
}

/* A confirm with no body text hides its (empty) html container, which was the
   thing supplying the gap — without this the title sits on the button band. */
.swal2-popup:not(.swal2-toast):not(:has(.swal2-html-container:not(:empty))) .swal2-title {
    padding-bottom: 1.25rem;
}

/* Same band as .mx-modal's footer, so alerts and modals read as one family. */
.swal2-popup:not(.swal2-toast) .swal2-actions {
    gap: 0.5rem;
    border-top: 1px solid var(--mx-line-strong);
    border-radius: 0 0 var(--mx-radius) var(--mx-radius);
}

/* showLoading() renders the spinner inside .swal2-actions, so the right-aligned
   button row would shove it off to one side. */
.swal2-popup.swal2-loading:not(.swal2-toast) .swal2-actions {
    justify-content: center;
    background: var(--mx-surface);
    border-top: 0;
}

.swal2-popup:not(.swal2-toast) .swal2-actions .btn {
    margin: 0;
}

.swal2-popup .swal2-icon.swal2-success {
    border-color: var(--mx-beli);
}

.swal2-popup .swal2-icon.swal2-success [class^='swal2-success-line'] {
    background-color: var(--mx-beli);
}

.swal2-popup .swal2-icon.swal2-success .swal2-success-ring {
    border-color: var(--mx-beli-wash);
}

.swal2-popup .swal2-icon.swal2-error {
    border-color: var(--mx-jual);
}

.swal2-popup .swal2-icon.swal2-error [class^='swal2-x-mark-line'] {
    background-color: var(--mx-jual);
}

.swal2-popup .swal2-icon.swal2-warning,
.swal2-popup .swal2-icon.swal2-info,
.swal2-popup .swal2-icon.swal2-question {
    border-color: var(--mx-brass-bright);
    color: var(--mx-brass);
}

.swal2-popup .swal2-loader {
    border-color: var(--mx-brass) rgba(0, 0, 0, 0) var(--mx-brass) rgba(0, 0, 0, 0);
}

/* Shows which document is already stored on a file input, which the browser
   itself will never display. */
.mx-file-current {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.72rem;
    color: var(--mx-muted);
    word-break: break-all;
}

/* Pagination and counters sit below the scroll area, not inside it, so they stay
   visible while the ledger scrolls. Three tracks rather than a centred flex row so the
   pager centres on the board: a wide "1234 Data" would otherwise shove it off-centre. */
.mx-board__foot {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1.75rem;
    padding: 0.6rem var(--mx-board-pad) 1rem;
    border-top: 1px solid var(--mx-line-strong);
}

/* grid-row pins both to the same row: without it auto-placement sees the counter claim
   column 3 first and drops the pager onto a second row. */
.mx-board__foot .total-data {
    grid-row: 1;
    grid-column: 3;
    justify-self: end;
    padding: 0 !important;
}

.mx-board__foot .total-data p {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--mx-muted);
}

.mx-board__foot .pagination-container {
    grid-row: 1;
    grid-column: 2;
    margin: 0 !important;
}

/* The stock pages close with Save/Cancel instead of counter + pagination. */
.mx-board__foot--actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* x-datatable.rows.detail-table emits flex divs with its own light-only colours;
   inside a panel they need to read as part of the ledger. */
.mx-panel .detail-table-head {
    background: var(--mx-surface-sub);
    border-bottom: 1px solid var(--mx-line-strong);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mx-muted);
}

.mx-panel .detail-table-row {
    border-bottom: 1px solid var(--mx-line);
}

.mx-panel .detail-table-row:last-child {
    border-bottom: none;
}

.mx-panel .detail-table-cell {
    padding: 0.45rem 0.6rem;
    font-size: 0.85rem;
    color: var(--mx-text);
}

/* Row action buttons are icon-only; they must never wrap their column. */
.mx-ledger__actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    white-space: nowrap;
}

/* Free text (addresses) would otherwise wrap to a dozen lines and make every
   row hundreds of pixels tall. Clamp it; the full value stays in the title. */
.mx-ledger__clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    cursor: pointer;
}

.mx-ledger__clamp.is-open {
    display: block;
    -webkit-line-clamp: unset;
}

/* style-form.css caps every detail area at 300px and scrolls it. Inside a board
   the panel sizes to its content instead, so nothing scrolls within a row. */
.mx-board .detail-container {
    max-height: none;
    overflow-y: visible;
    padding: 0;
    background-color: transparent;
}

/* A table with too many columns to fit reads better wide and scrolled than
   squeezed, where every cell wraps and rows grow tall. */
.mx-ledger--wide {
    width: max-content;
    min-width: 100%;
}

.mx-ledger--wide > thead > tr > th,
.mx-ledger--wide > tbody > tr > td {
    white-space: nowrap;
    overflow-wrap: normal;
}

/* dashboard KPI strip — one card per subject, its Beli/Jual split inline, so
   the headline number and its breakdown are read in one movement. */
.mx-kpi {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.75rem;
}

.mx-kpi__card {
    background: var(--mx-surface);
    border: 1px solid var(--mx-line);
    border-radius: var(--mx-radius);
    box-shadow: var(--mx-shadow);
    padding: 0.85rem 1rem;
}

.mx-kpi__label {
    margin: 0 0 0.25rem;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mx-muted);
}

.mx-kpi__value {
    margin: 0;
    font-family: var(--mx-font-display);
    font-size: 1.85rem;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--mx-text);
}

.mx-kpi__value small {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--mx-muted);
    margin-right: 0.15rem;
}

.mx-kpi__split {
    display: flex;
    gap: 1rem;
    margin: 0.7rem 0 0;
    padding-top: 0.6rem;
    border-top: 1px solid var(--mx-line);
}

.mx-kpi__leg {
    flex: 1;
    min-width: 0;
}

.mx-kpi__leg dt {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin: 0 0 0.1rem;
    font-size: 0.57rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.mx-kpi__leg dd {
    margin: 0;
    font-family: var(--mx-font-mono);
    font-size: 0.92rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.mx-dot {
    display: inline-block;
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 2px;
}

.mx-dot--beli { background: var(--mx-beli); }
.mx-dot--jual { background: var(--mx-jual); }
.mx-dot--warn { background: var(--mx-warn); }
.mx-dot--muted { background: var(--mx-muted); }

.mx-text-beli { color: var(--mx-beli); }
.mx-text-jual { color: var(--mx-jual); }

/* chart panels */
.mx-charts {
    display: grid;
    gap: 0.75rem;
}

.mx-charts--split { grid-template-columns: 2fr 1fr; }
.mx-charts--half { grid-template-columns: 1fr 1fr; }

.mx-chart {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--mx-surface);
    border: 1px solid var(--mx-line);
    border-radius: var(--mx-radius);
    box-shadow: var(--mx-shadow);
}

.mx-chart__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.55rem 0.9rem;
    background: var(--mx-surface-sub);
    border-bottom: 1px solid var(--mx-line);
}

.mx-chart__title {
    margin: 0;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mx-text-soft);
}

.mx-chart__legend {
    display: flex;
    gap: 0.7rem;
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--mx-muted);
}

.mx-chart__legend span {
    display: flex;
    align-items: center;
    gap: 0.28rem;
}

/* Chart.js sizes its canvas to the parent, so the parent must have a height of
   its own — otherwise a wide bar chart and a square doughnut in the same row
   resolve to different heights and one of them ends up half empty. */
.mx-chart__body {
    position: relative;
    height: 236px;
    padding: 0.7rem 0.8rem 0.8rem;
}

.mx-chart__body--short { height: 168px; }

@media (max-width: 991.98px) {
    .mx-kpi,
    .mx-charts--split,
    .mx-charts--half {
        grid-template-columns: 1fr;
    }
}

/* The export button ships wrapped (a form for the single variant, a div.dropdown for the
   other), so the wrapper is the flex item that stretches with its siblings while the
   button inside keeps its natural height. Making the wrapper a flex container passes the
   stretch through. The dropdown menu is position:absolute, so it stays out of the flow. */
.mx-board__actions > form,
.mx-board__actions > .dropdown {
    display: flex;
}

.mx-board__actions > form > *,
.mx-board__actions > .dropdown > .btn {
    flex: 1;
}

/* Labelled filter row for the Verifikasi pages. Unlike the stock and rate toolbars these
   carry visible labels: two bare date inputs do not say which is "from" and which is
   "to". Replaces the .filter-panel .form-label rule each page used to push itself. */
.mx-filter {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.mx-filter__field {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 9rem;
}

.mx-filter__label {
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mx-text-soft);
}

.mx-filter .form-select,
.mx-filter .form-control {
    font-size: 0.85rem;
}

.mx-filter__field--search {
    min-width: 18rem;
}
.mx-filter__field--search .btn {
    padding-block: 0;
    line-height: 1;
}

/* The customer detail/create/edit forms head their sections with
   <h3 class="text-center mt-5 mb-3"> — 86 of them across 44 blades. Restyling them here
   gives those sections the section-title treatment wherever a modal shows them, without
   editing the markup. Bootstrap's .text-center is !important, so the override must be. */
.mx-modal .modal-body h3.text-center {
    font-family: var(--mx-font-display);
    font-size: 1rem;
    font-weight: 600;
    text-align: left !important;
    margin: 1.75rem 0 1.1rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--mx-line);
}

.mx-modal .modal-body h3.text-center:first-child {
    margin-top: 0;
}

/* style-form.css appends " (opsional)" to every non-required floating label. In a
   read-only detail modal nothing is fillable, so it lands on every field as noise.
   Scoped to readonly/disabled fields so editable forms keep the hint. */
.mx-modal .modal-body .form-floating > input[readonly] ~ label::after,
.mx-modal .modal-body .form-floating > input[disabled] ~ label::after,
.mx-modal .modal-body .form-floating > textarea[readonly] ~ label::after,
.mx-modal .modal-body .form-floating > textarea[disabled] ~ label::after,
.mx-modal .modal-body .form-floating > select[disabled] ~ label::after {
    content: '';
}

/* Detail modals show a record, they are not a form to fill in, so they carry the
   denomination modal's density rather than Bootstrap's 3.5rem floating-label rows.
   Keyed off readonly/disabled so create and edit modals keep their full-size controls. */
.mx-modal .modal-body .form-floating > .form-control[readonly],
.mx-modal .modal-body .form-floating > .form-control[disabled],
.mx-modal .modal-body .form-floating > .form-select[disabled] {
    height: auto;
    min-height: 2.75rem;
    padding: 1.4rem 0.6rem 0.3rem;
    font-size: 0.85rem;
    line-height: 1.2;
}

/* The textarea component sets an inline height, which wins over min-height; the value
   still has to start below the label, so its top padding is pinned here. */
.mx-modal .modal-body .form-floating > textarea.form-control[readonly],
.mx-modal .modal-body .form-floating > textarea.form-control[disabled] {
    min-height: 3.7rem;
    padding-top: 1.5rem;
}

/* The label is painted over the control, so it has to clear the value's first line:
   it sits in the control's top padding, never on top of the text. */
.mx-modal .modal-body .form-floating > .form-control[readonly] ~ label,
.mx-modal .modal-body .form-floating > .form-control[disabled] ~ label,
.mx-modal .modal-body .form-floating > .form-select[disabled] ~ label {
    padding: 0.22rem 0.6rem;
    font-size: 0.72rem;
    line-height: 1.05;
    height: auto;
    opacity: 1;
    transform: scale(0.85) translateY(0) translateX(0.1rem);
}

/* Bootstrap's row gutter is what spaces the field grid; a record reads better tight. */
.mx-modal .modal-body .row {
    --bs-gutter-y: 0.35rem;
    --bs-gutter-x: 0.5rem;
}

.mx-modal .modal-body h3.text-center {
    margin: 1.15rem 0 0.7rem;
}

/* ── Risk Component (reusable badge & scorecard) ── */
.mx-risk-badge {
    cursor: pointer;
    user-select: none;
}

/* Row wrapper for tables */
.mx-risk-row > td {
    padding: 0.5rem !important;
    background: var(--mx-surface-sub);
}

.mx-risk {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.mx-risk__cell {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    min-width: 4.5rem;
    background: var(--mx-surface);
    border-radius: var(--mx-radius-sm);
    padding: 0.35rem 0.45rem;
    font-size: 0.72rem;
    line-height: 1.3;
}

.mx-risk__label {
    color: var(--mx-muted);
    margin-bottom: 0.2rem;
}

.mx-risk__value {
    font-weight: 650;
    font-family: var(--mx-font-mono);
    font-variant-numeric: tabular-nums;
    margin-top: auto;
}

.mx-risk__bar {
    height: 3px;
    border-radius: 2px;
    background: var(--mx-line);
    margin-top: 0.25rem;
    overflow: hidden;
}

.mx-risk__bar-fill {
    height: 100%;
    border-radius: 2px;
    transition: width 0.3s ease;
}

.mx-risk__bar-fill--low    { background: var(--bs-success); }
.mx-risk__bar-fill--medium { background: var(--bs-warning); }
.mx-risk__bar-fill--high   { background: var(--bs-danger);  }
.mx-risk__bar-fill--none   { background: var(--bs-secondary); }

.mx-risk__cell--final {
    flex-basis: 100%;
    border: 1px solid var(--mx-line);
}

.mx-risk__info {
    font-size: 0.6rem;
    color: var(--mx-muted);
    cursor: help;
    opacity: 0.7;
}

.mx-risk__info:hover {
    opacity: 1;
}

