/* =============================================================================
   App utilities
   ============================================================================= */

/* Active filter field highlight */
.filter-active {
    border-color: var(--bs-primary) !important;
    box-shadow: 0 0 0 .15rem rgba(var(--bs-primary-rgb), .15) !important;
}

/* =============================================================================
   Components
   ============================================================================= */

/* Text truncation for table cells (<td>). The cell keeps its content on one
   line and clips it with an ellipsis, so no single long value can widen the
   column or add height to the row. The full text is exposed via a title
   tooltip set in core/tables.py. */
.cell-truncate-sm,
.cell-truncate-md,
.cell-truncate-lg {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.cell-truncate-sm {
    max-width: 90px;
}

.cell-truncate-md {
    max-width: 130px;
}

/* Sized so the full 18-column table fits a 1920px viewport without
   horizontal scrolling, with room to spare for a scrollbar. The three
   widest columns all sit at this cap, so it is the lever that decides
   whether the table fits. */
.cell-truncate-lg {
    max-width: 175px;
}

/* Short values (codes, dates, amounts) that should never wrap onto a second
   line; without a max-width they still size to their content. */
.cell-nowrap {
    white-space: nowrap;
}

/* Reserve the width the badge grid needs. Without this the table layout is
   free to squeeze the cell when the table overflows, which makes the badges
   wrap one per line and blows the row up to eight lines tall. */
.cell-controllo {
    min-width: 9.25rem;
}

/* Lifecycle flags in the appalti table: eight abbreviated badges, capped so
   they wrap to two rows of four instead of stretching the column. */
.controllo-grid {
    display: flex;
    flex-wrap: wrap;
    gap: .15rem;
    max-width: 9rem;
}

.controllo-badge {
    min-width: 2.05rem;
    padding: .2rem .25rem;
    font-size: .65rem;
    font-weight: 600;
    cursor: default;
}

.controllo-badge-off {
    background-color: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
}

/* Appalti list table: constrain height so the container scrolls vertically,
   which is required for position:sticky on thead and td:first-child to work
   (position:sticky is relative to the nearest scroll ancestor).

   The budget subtracted from the viewport covers the page header, the filter
   toolbar and the pagination bar, which sits outside this scroll container
   (see core/templates/core/appalti_table.html). */
.appalti-table-scroll {
    max-height: calc(100dvh - 15rem);
    overflow-y: auto;
}

.appalti-table {
    font-size: .8125rem;
}

/* Headers are allowed to wrap. Forcing them onto one line would make each
   column at least as wide as its label, and several labels are wider than the
   data underneath them; the cost is a taller thead, which is a single row. */
.appalti-table thead th {
    vertical-align: bottom;
}

.appalti-table-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: var(--bs-table-bg, var(--bs-body-bg));
}

.appalti-table-scroll th:first-child,
.appalti-table-scroll td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background-color: var(--bs-body-bg);
    box-shadow: 2px 0 4px rgba(0, 0, 0, .06);
}

/* Intersection cell (sticky on both axes): must sit above both */
.appalti-table-scroll thead th:first-child {
    z-index: 3;
    background-color: var(--bs-table-bg, var(--bs-body-bg));
}

/* The sticky first column paints its own opaque background (so scrolled rows
   do not show through), which would otherwise swallow table-hover. Repaint it
   on hover so the whole row highlights as one. */
.appalti-table-scroll tbody tr:hover > td:first-child {
    background-color: var(--bs-tertiary-bg);
}

/* Pagination sits below the scroll container, always visible */
.appalti-table-wrapper .pagination {
    margin-top: .75rem;
    margin-bottom: .25rem;
}

.controllo-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .1rem .6rem;
}

/* =============================================================================
   Third-party overrides: Select2
   Match Select2's default theme to Bootstrap 5 form-select-sm appearance.
   ============================================================================= */

/* Override Select2's inline width so it fills its column */
.select2-container {
    width: 100% !important;
}

.select2-container--default .select2-selection--single {
    border-color: var(--bs-border-color);
    border-radius: var(--bs-border-radius-sm);
    /* Matches Bootstrap's form-select-sm height: padding-y * 2 + line-height + borders */
    height: calc(1.5em + .5rem + 2px);
    font-size: .875rem;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    padding-left: .5rem;
    padding-right: 1.5rem;
    color: var(--bs-body-color);
    line-height: calc(1.5em + .5rem);
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 100%;
    top: 0;
    right: .5rem;
}

.select2-container--default .select2-selection--single .select2-selection__placeholder {
    color: var(--bs-secondary-color);
}

.select2-dropdown {
    border-color: var(--bs-border-color);
    border-radius: var(--bs-border-radius-sm);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    border-color: var(--bs-border-color);
    border-radius: var(--bs-border-radius-sm);
}

.select2-container--default .select2-results__option--highlighted[aria-selected] {
    background-color: var(--bs-primary);
}
