/* ============================================================================
   theme_v2 - UTILITY LAYER
   ----------------------------------------------------------------------------
   theme_v2 loads bootstrap's JS bundle but NOT its stylesheet, and the page
   templates carry roughly ten thousand bootstrap utility classes. Every one of
   them was doing nothing, which is why layouts collapsed into a full-width
   stack: `d-flex` did not make a row, `collapse` did not hide anything, and
   `gap-2` added no gap.

   This file implements the utilities those templates actually use - 175 of
   them, taken from a scan of themes/theme_v2/templates - mapped onto the
   design tokens in global.css rather than bootstrap's palette. So `text-muted`
   is the theme's muted colour in both light and dark, not bootstrap's grey.

   Loaded LAST, after components.css, because a utility on an element is meant
   to win over the component's own rule. That is the whole contract of a
   utility class.

   Two deliberate improvements over bootstrap:
     - the directional spacing helpers (me-*, ms-*, ps-*, pe-*, text-start,
       text-end, float-*) use logical properties, so they flip correctly in
       Arabic instead of staying pinned to the left.
     - the colour helpers follow the light/dark scheme.

   This layer exists to make the not-yet-ported pages correct. New markup
   should use the components in boxs/ui/ - do not reach for these to build
   something a component already covers.

   Spacing scale (bootstrap's): 0 = 0, 1 = 4px, 2 = 8px, 3 = 16px,
                                4 = 24px, 5 = 48px
   ========================================================================= */


/* ==========================================================================
   display
   ========================================================================== */

.d-none          { display: none !important; }
.d-block         { display: block !important; }
.d-inline        { display: inline !important; }
.d-inline-block  { display: inline-block !important; }
.d-flex          { display: flex !important; }
.d-inline-flex   { display: inline-flex !important; }
.d-grid          { display: grid !important; }

@media (min-width: 576px) { .d-sm-flex { display: flex !important; } }
@media (min-width: 768px) { .d-md-flex { display: flex !important; } }

/* bootstrap's collapse is display:none until .show is added by its JS. Without
   this the "More" filters and every other collapsible render permanently open,
   below the control that claims to be hiding them. */
.collapse:not(.show) { display: none; }

.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}


/* ==========================================================================
   flex
   ========================================================================== */

.flex-column   { flex-direction: column !important; }
.flex-wrap     { flex-wrap: wrap !important; }
.flex-nowrap   { flex-wrap: nowrap !important; }
.flex-fill     { flex: 1 1 auto !important; }
.flex-grow-1   { flex-grow: 1 !important; }
.flex-shrink-0 { flex-shrink: 0 !important; }

.align-items-center  { align-items: center !important; }
.align-items-start   { align-items: flex-start !important; }
.align-items-end     { align-items: flex-end !important; }
.align-items-stretch { align-items: stretch !important; }

.justify-content-center  { justify-content: center !important; }
.justify-content-between { justify-content: space-between !important; }
.justify-content-end     { justify-content: flex-end !important; }

.gap-1 { gap: 4px !important; }
.gap-2 { gap: 8px !important; }
.gap-3 { gap: 16px !important; }
.gap-4 { gap: 24px !important; }


/* ==========================================================================
   spacing
   Directional helpers use logical properties so Arabic mirrors correctly.
   ========================================================================== */

.m-0 { margin: 0 !important; }

.mt-0 { margin-top: 0 !important; }
.mt-1 { margin-top: 4px !important; }
.mt-2 { margin-top: 8px !important; }
.mt-3 { margin-top: 16px !important; }
.mt-4 { margin-top: 24px !important; }

.mb-0  { margin-bottom: 0 !important; }
.mb-1  { margin-bottom: 4px !important; }
.mb-2  { margin-bottom: 8px !important; }
.mb-3  { margin-bottom: 16px !important; }
.mb-4  { margin-bottom: 24px !important; }
.mb-5  { margin-bottom: 48px !important; }
.mb-10 { margin-bottom: 40px !important; }

.ms-1    { margin-inline-start: 4px !important; }
.ms-2    { margin-inline-start: 8px !important; }
.ms-auto { margin-inline-start: auto !important; }

.me-1 { margin-inline-end: 4px !important; }
.me-2 { margin-inline-end: 8px !important; }
.me-3 { margin-inline-end: 16px !important; }

.mx-1    { margin-inline: 4px !important; }
.mx-auto { margin-inline: auto !important; }

.my-1 { margin-block: 4px !important; }
.my-2 { margin-block: 8px !important; }
.my-4 { margin-block: 24px !important; }
.my-5 { margin-block: 48px !important; }

.p-0 { padding: 0 !important; }
.p-1 { padding: 4px !important; }
.p-2 { padding: 8px !important; }
.p-3 { padding: 16px !important; }
.p-5 { padding: 48px !important; }

.pt-1 { padding-top: 4px !important; }
.pt-2 { padding-top: 8px !important; }
.pt-3 { padding-top: 16px !important; }
.pt-5 { padding-top: 48px !important; }

.pb-1 { padding-bottom: 4px !important; }
.pb-2 { padding-bottom: 8px !important; }
.pb-3 { padding-bottom: 16px !important; }
.pb-4 { padding-bottom: 24px !important; }

.ps-0 { padding-inline-start: 0 !important; }
.ps-3 { padding-inline-start: 16px !important; }

.pe-0 { padding-inline-end: 0 !important; }
.pe-3 { padding-inline-end: 16px !important; }

.px-0 { padding-inline: 0 !important; }
.px-1 { padding-inline: 4px !important; }
.px-2 { padding-inline: 8px !important; }
.px-3 { padding-inline: 16px !important; }
.px-4 { padding-inline: 24px !important; }
.px-5 { padding-inline: 48px !important; }

.py-0 { padding-block: 0 !important; }
.py-1 { padding-block: 4px !important; }
.py-2 { padding-block: 8px !important; }
.py-3 { padding-block: 16px !important; }
.py-5 { padding-block: 48px !important; }


/* ==========================================================================
   sizing
   ========================================================================== */

.w-100 { width: 100% !important; }
.h-100 { height: 100% !important; }

.overflow-auto     { overflow: auto !important; }
.overflow-hidden   { overflow: hidden !important; }
.overflow-x-auto   { overflow-x: auto !important; }


/* ==========================================================================
   position
   ========================================================================== */

.position-relative { position: relative !important; }
.position-absolute { position: absolute !important; }

.top-0     { top: 0 !important; }
.top-100   { top: 100% !important; }
.top-50    { top: 50% !important; }
.bottom-0  { bottom: 0 !important; }
.start-0   { inset-inline-start: 0 !important; }
.start-50  { inset-inline-start: 50% !important; }
.end-0     { inset-inline-end: 0 !important; }


/* ==========================================================================
   typography
   ========================================================================== */

.small { font-size: 11.5px !important; }

.fs-1 { font-size: 30px !important; }
.fs-2 { font-size: 25px !important; }
.fs-3 { font-size: 21px !important; }
.fs-5 { font-size: 16px !important; }
.fs-6 { font-size: 13px !important; }

.fw-normal   { font-weight: 400 !important; }
.fw-500      { font-weight: 500 !important; }
.fw-semibold { font-weight: 600 !important; }
.fw-bold     { font-weight: 700 !important; }

.lh-lg { line-height: 1.7 !important; }

.text-start  { text-align: start !important; }
.text-end    { text-align: end !important; }
.text-right  { text-align: end !important; }
.text-center { text-align: center !important; }

.text-uppercase  { text-transform: uppercase !important; }
.text-capitalize { text-transform: capitalize !important; }

.text-decoration-none      { text-decoration: none !important; }
.text-decoration-underline { text-decoration: underline !important; }

.text-break { word-break: break-word !important; }

.text-truncate {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
}

.align-middle { vertical-align: middle !important; }

.user-select-all { user-select: all !important; }


/* ==========================================================================
   colour - follows the light / dark scheme
   ========================================================================== */

.text-muted     { color: var(--text-3) !important; }
.text-secondary { color: var(--text-3) !important; }
.text-dark      { color: var(--text) !important; }
.text-light     { color: var(--text-4) !important; }
.text-white     { color: #fff !important; }
.text-primary   { color: var(--accent) !important; }
.text-success   { color: var(--good) !important; }
.text-danger    { color: var(--bad) !important; }
.text-warning   { color: var(--warn) !important; }
.text-info      { color: var(--info) !important; }

.bg-white       { background-color: var(--surface) !important; }
.bg-light       { background-color: var(--surface-2) !important; }
.bg-dark        { background-color: var(--text) !important; color: var(--surface) !important; }
.bg-transparent { background-color: transparent !important; }

.bg-primary-subtle { background-color: var(--accent-soft) !important; }
.bg-success-subtle { background-color: var(--good-soft) !important; }
.bg-danger-subtle  { background-color: var(--bad-soft) !important; }
.bg-warning-subtle { background-color: var(--warn-soft) !important; }
.bg-info-subtle    { background-color: var(--info-soft) !important; }

.bg-opacity-10 { opacity: 1 !important; }

/* the gradient badge classes the v1 templates use - drawn as solid tokens so
   they read the same in both schemes */
.bg-gradient,
.bg-grd-primary  { background-image: none !important; background-color: var(--accent) !important; color: #fff !important; }
.bg-grd-success,
.bg-gradient-success { background-image: none !important; background-color: var(--good) !important; color: #fff !important; }
.bg-grd-danger   { background-image: none !important; background-color: var(--bad) !important; color: #fff !important; }
.bg-grd-warning,
.bg-gradient-warning { background-image: none !important; background-color: var(--warn) !important; color: #fff !important; }
.bg-grd-info,
.bg-gradient-info { background-image: none !important; background-color: var(--info) !important; color: #fff !important; }
.bg-grd-royal,
.bg-gradient-purple,
.bg-purple       { background-image: none !important; background-color: var(--accent-2, var(--accent)) !important; color: #fff !important; }


/* ==========================================================================
   border + radius + shadow
   ========================================================================== */

.border          { border: 1px solid var(--border) !important; }
.border-0        { border: 0 !important; }
.border-2        { border-width: 2px !important; }
.border-3        { border-width: 3px !important; }
.border-4        { border-width: 4px !important; }
.border-top      { border-top: 1px solid var(--border) !important; }
.border-bottom   { border-bottom: 1px solid var(--border) !important; }
.border-bottom-0 { border-bottom: 0 !important; }
.border-end      { border-inline-end: 1px solid var(--border) !important; }

.border-light           { border-color: var(--border-2) !important; }
.border-white           { border-color: var(--surface) !important; }
.border-primary         { border-color: var(--accent) !important; }
.border-secondary       { border-color: var(--border) !important; }
.border-warning         { border-color: var(--warn) !important; }
.border-primary-subtle  { border-color: var(--accent-soft) !important; }
.border-success-subtle  { border-color: var(--good-soft) !important; }
.border-danger-subtle   { border-color: var(--bad-soft) !important; }
.border-warning-subtle  { border-color: var(--warn-soft) !important; }
.border-info-subtle     { border-color: var(--info-soft) !important; }
.border-gradient-1      { border-color: var(--accent) !important; }

.rounded          { border-radius: var(--r-md) !important; }
.rounded-1        { border-radius: var(--r-sm) !important; }
.rounded-2        { border-radius: var(--r-md) !important; }
.rounded-3        { border-radius: var(--r-lg) !important; }
.rounded-4        { border-radius: var(--r-xl) !important; }
.rounded-5        { border-radius: 20px !important; }
.rounded-circle   { border-radius: 50% !important; }
.rounded-pill     { border-radius: 999px !important; }

.shadow    { box-shadow: var(--sh-lg) !important; }
.shadow-sm { box-shadow: var(--sh-sm) !important; }


/* ==========================================================================
   TABLE FILTER BAR
   The markup is boxs/table/table_container_v2.html. With the utilities above
   in place its flex row works again; these rules give it the theme's look
   rather than bootstrap's, and stop the label/field pairs sprawling.
   ========================================================================== */

/* Kept deliberately compact: a filter bar is chrome above the data, not the
   point of the page. The label sits inside the control as its placeholder
   rather than on a line of its own, which is what made the bar three rows
   tall on a list with four filters. */
[id^="fb_main_"],
[id^="fb_extragrid_"] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.fb-item {
    display: flex;
    flex-direction: column;
    gap: 0;
    flex: 1 1 170px;
    min-width: 0;
    max-width: 240px;
}

/* the visible label is the placeholder; this stays for screen readers */
.fb-item > label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* the icon + control pair, drawn like the picker control in components.css */
.fb-item .input-group {
    display: flex;
    align-items: stretch;
    height: 34px;
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: var(--r-md);
    overflow: hidden;
    flex-wrap: nowrap;
}

.fb-item .input-group:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.fb-item .input-group-text {
    display: grid;
    place-items: center;
    flex: none;
    width: 34px;
    height: 100%;
    padding: 0;
    border: 0;
    border-inline-end: 1px solid var(--border);
    background: var(--surface-3);
    color: var(--text-3);
}

.fb-item .input-group-text .material-icons-outlined { font-size: 16px; }

.fb-item .input-group > .form-control,
.fb-item .input-group > .form-select {
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    padding: 0 10px;
    font-size: 12.5px;
    color: var(--text);
    outline: none;
}

.fb-item .input-group > .form-control:focus,
.fb-item .input-group > .form-select:focus { box-shadow: none; outline: none; }

.fb-item .input-group > .form-control::placeholder { color: var(--text-4); }

/* More / Apply / Export sit at the end of the row, not mid-stack */
[id^="fb_main_"] > .d-flex {
    flex: 0 0 auto;
    margin-inline-start: auto;
    align-self: flex-end;
    gap: 7px;
}

@media (max-width: 620px) {
    .fb-item { flex: 1 1 100%; max-width: none; }
    [id^="fb_main_"] > .d-flex { margin-inline-start: 0; width: 100%; }
}


/* ==========================================================================
   BOOTSTRAP GRID
   Another name collision, the same shape as .modal was: global.css defines
   `.row` as the template's own HORIZONTAL flex row, while the page templates
   use `.row` as bootstrap's grid row holding .col-* children. So a
   `<div class="row"><div class="col-12">A</div><div class="col-12">B</div></div>`
   put A and B side by side instead of stacking - which is what pushed the
   E-Invoice nav and its content panel apart on the entity view.

   Scoped with :has() so only a .row that actually contains columns behaves as
   a grid; the template's own .row keeps its meaning.
   ========================================================================== */

.row:has(> [class*="col-"]) {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0;
    margin-inline: -8px;
    width: auto;
}

.row:has(> [class*="col-"]) > [class*="col-"] {
    padding-inline: 8px;
    min-width: 0;
    margin-bottom: 16px;
}

[class*="col-"] { flex: 0 0 100%; max-width: 100%; }

.col-1  { flex: 0 0 8.3333%;  max-width: 8.3333%; }
.col-2  { flex: 0 0 16.6667%; max-width: 16.6667%; }
.col-3  { flex: 0 0 25%;      max-width: 25%; }
.col-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
.col-6  { flex: 0 0 50%;      max-width: 50%; }
.col-8  { flex: 0 0 66.6667%; max-width: 66.6667%; }
.col-9  { flex: 0 0 75%;      max-width: 75%; }
.col-12 { flex: 0 0 100%;     max-width: 100%; }

/* the responsive tiers are min-width in bootstrap: below the breakpoint a
   column is full width, above it takes its share */
@media (min-width: 576px) {
    .col-sm-3  { flex: 0 0 25%;      max-width: 25%; }
    .col-sm-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
    .col-sm-6  { flex: 0 0 50%;      max-width: 50%; }
    .col-sm-12 { flex: 0 0 100%;     max-width: 100%; }
}

@media (min-width: 768px) {
    .col-md-2  { flex: 0 0 16.6667%; max-width: 16.6667%; }
    .col-md-3  { flex: 0 0 25%;      max-width: 25%; }
    .col-md-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
    .col-md-5  { flex: 0 0 41.6667%; max-width: 41.6667%; }
    .col-md-6  { flex: 0 0 50%;      max-width: 50%; }
    .col-md-7  { flex: 0 0 58.3333%; max-width: 58.3333%; }
    .col-md-8  { flex: 0 0 66.6667%; max-width: 66.6667%; }
    .col-md-9  { flex: 0 0 75%;      max-width: 75%; }
    .col-md-12 { flex: 0 0 100%;     max-width: 100%; }
}

@media (min-width: 992px) {
    .col-lg-3  { flex: 0 0 25%;      max-width: 25%; }
    .col-lg-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
    .col-lg-6  { flex: 0 0 50%;      max-width: 50%; }
    .col-lg-8  { flex: 0 0 66.6667%; max-width: 66.6667%; }
    .col-lg-12 { flex: 0 0 100%;     max-width: 100%; }
}

@media (min-width: 1200px) {
    .col-xl-3  { flex: 0 0 25%;      max-width: 25%; }
    .col-xl-4  { flex: 0 0 33.3333%; max-width: 33.3333%; }
    .col-xl-6  { flex: 0 0 50%;      max-width: 50%; }
    .col-xl-8  { flex: 0 0 66.6667%; max-width: 66.6667%; }
    .col-xl-9  { flex: 0 0 75%;      max-width: 75%; }
    .col-xl-12 { flex: 0 0 100%;     max-width: 100%; }
}


/* ==========================================================================
   FILTER BAR - presentation
   The controls used to float loose on the card, which read as unfinished and
   gave no boundary between "narrow the list" and the list itself. They now sit
   on their own surface, so the bar is one object rather than four stray boxes.
   ========================================================================== */

[id^="fb_section_"] {
    background: var(--surface-2);
    border: 1px solid var(--border-2);
    border-radius: var(--r-lg);
    padding: 11px 12px;
    margin-bottom: 4px;
}

.fb-item .input-group { background: var(--surface); }

/* the icon reads as part of the field, not a separate button */
.fb-item .input-group-text {
    background: transparent;
    border-inline-end: 0;
    width: 30px;
}

.fb-item .input-group > .form-control,
.fb-item .input-group > .form-select { padding-inline-start: 2px; }

.fb-item .input-group > .form-control::placeholder { text-transform: capitalize; }

/* Apply is the primary action; Reset is quiet until you need it */
[id^="fb_main_"] .btn { height: 34px; }

[id^="fb_main_"] .btn-outline-secondary {
    background: transparent;
    border-color: var(--border);
    color: var(--text-3);
}

[id^="fb_main_"] .btn-outline-secondary:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--surface);
}

/* Columns / Cards belong with the filters, not floating above them */
.table-container > .card-header > .d-flex.justify-content-end { margin-bottom: 8px; }
