/* Slick Filters - Default Styles */

.slick-table-container {
    width: 100%;
    /*
     * ⚑ `min-width: 0` BREAKS THE SIZING CYCLE. Without it the container's `width: 100%`
     * resolves against its CONTENT — a wide table — so the container grows to the table and
     * then cannot constrain it. Measured in card mode: a 3484px container holding a 3452px
     * table with three 1140px "columns" marching off the page.
     *
     * The scroll wrapper inside still handles a genuinely wide grid; this only stops the
     * container itself from being sized by what it contains.
     */
    min-width: 0;
    max-width: 100%;
    margin: 0 auto;
    padding: 1rem;
}

/* Search Bar */
.slick-table-search {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.slick-search-input {
    flex: 1;
    padding: 0.5rem 0.75rem;
    border: 1px solid #d1d5db;
    border-radius: 0.375rem;
    font-size: 0.875rem;
}

.slick-search-input:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.slick-clear-search {
    padding: 0.5rem 1rem;
    background-color: #ef4444;
    color: white;
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.875rem;
}

.slick-clear-search:hover {
    background-color: #dc2626;
}

/* Active Filters */
.slick-table-active-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    padding: 0.75rem;
    background-color: #f3f4f6;
    border-radius: 0.375rem;
    margin-bottom: 1rem;
}

.slick-filters-label {
    font-weight: 600;
    font-size: 0.875rem;
    color: #374151;
}

.slick-filter-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem;
    background-color: #3b82f6;
    color: white;
    border-radius: 9999px;
    font-size: 0.875rem;
}

.slick-filter-remove {
    background: none;
    border: none;
    color: white;
    cursor: pointer;
    font-size: 1.25rem;
    line-height: 1;
    padding: 0;
    margin-left: 0.25rem;
}

.slick-filter-remove:hover {
    opacity: 0.8;
}

.slick-clear-all-filters {
    padding: 0.25rem 0.75rem;
    background-color: #ef4444;
    color: white;
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    font-size: 0.875rem;
}

.slick-clear-all-filters:hover {
    background-color: #dc2626;
}

/* Table Wrapper */
.slick-table-wrapper {
    overflow-x: auto;
    border: 1px solid #e5e7eb;
    border-radius: 0.5rem;
    margin-bottom: 1rem;
}

/* Table */
.slick-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

/* Header */
.slick-table-header-cell {
    background-color: #f9fafb;
    padding: 0.75rem 1rem;
    text-align: left;
    font-weight: 600;
    color: #374151;
    border-bottom: 2px solid #e5e7eb;
}

.slick-header-content {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.slick-sort-button {
    background: none;
    border: none;
    cursor: pointer;
    font-weight: 600;
    color: #374151;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0;
}

.slick-sort-button:hover {
    color: #3b82f6;
}

.slick-sort-icon {
    font-size: 1rem;
    color: #3b82f6;
}

/* Filter Row */
.slick-table-filter-cell {
    background-color: #ffffff;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid #e5e7eb;
}

/* Filter Inputs */
.slick-filter-input {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid #d1d5db;
    border-radius: 0.375rem;
    font-size: 0.875rem;
}

.slick-filter-input:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* Select Filter */
.slick-filter-select {
    background-color: white;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
    background-position: right 0.5rem center;
    background-repeat: no-repeat;
    background-size: 1.5em 1.5em;
    padding-right: 2.5rem;
}

.slick-filter-select[multiple] {
    background-image: none;
    padding-right: 0.75rem;
}

/* Range Filters */
.slick-filter-range {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.slick-filter-range input {
    flex: 1;
    min-width: 0;
}

.slick-range-separator {
    color: #9ca3af;
    font-weight: 500;
}

/* Table Body */
.slick-table-row {
    border-bottom: 1px solid #e5e7eb;
}

.slick-table-row:hover {
    background-color: #f9fafb;
}

.slick-table-cell {
    padding: 0.75rem 1rem;
    color: #374151;
}

.slick-table-empty {
    padding: 2rem;
    text-align: center;
    color: #9ca3af;
    font-style: italic;
}

/* Footer */
.slick-table-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    padding: 0.75rem 0;
}

.slick-per-page {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    color: #374151;
}

.slick-per-page-select {
    padding: 0.375rem 0.5rem;
    border: 1px solid #d1d5db;
    border-radius: 0.375rem;
    font-size: 0.875rem;
}

.slick-per-page-select:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

/* Responsive */
@media (max-width: 640px) {
    .slick-table-container {
        padding: 0.5rem;
    }

    .slick-table-header-cell,
    .slick-table-filter-cell,
    .slick-table-cell {
        padding: 0.5rem;
    }

    .slick-table-footer {
        flex-direction: column;
        align-items: flex-start;
    }

    .slick-filter-range {
        flex-direction: column;
    }

    .slick-range-separator {
        display: none;
    }
}


/* =========================================================================
   CARD VIEW — the same table, each row rendered as a card.

   ⚑ PRESENTATION ONLY. The markup is an ordinary <table>: same query, same
   filters, same sort, same pager. Only `display` changes, so a board cannot
   drift from the table it is a view of.

   ⚑ THE HEADER ROW IS HIDDEN and each cell carries its own label instead,
   from `data-label`. A card whose values have no names is a card nobody can
   read.
   ========================================================================= */
.slick-table.is-cards,
.slick-table.is-cards thead,
.slick-table.is-cards tbody,
.slick-table.is-cards tr,
.slick-table.is-cards td {
    display: block;
}

/* The filter row stays a row — it is controls, not content. */
.slick-table.is-cards thead tr:first-child {
    display: none;
}

/*
 * ⚑ THE TABLE MUST BE WIDTH-CONSTRAINED FOR THE GRID TO WORK.
 *
 * The package wraps every table in `overflow-x: auto`, which is right for a wide grid — it
 * scrolls rather than squashing. But it gives the table UNBOUNDED width, so `1fr` resolves
 * against the content and each card column came out full-width (measured: 1140px × 3, cards
 * overflowing instead of sitting side by side).
 *
 * In card mode there is nothing to scroll horizontally: a card wraps its own content. So the
 * table is pinned to its container and the grid resolves against the viewport.
 */
.slick-table.is-cards {
    width: 100%;
    max-width: 100%;
    table-layout: fixed;
}

.slick-table.is-cards tbody {
    display: grid;
    gap: 1rem;
    width: 100%;
}

/* ⚑ COLUMN COUNTS MATCH BOOTSTRAP'S BREAKPOINTS rather than inventing new ones. */
@media (min-width: 768px) {
    .slick-table.is-cards-2 tbody { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .slick-table.is-cards-3 tbody { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .slick-table.is-cards-4 tbody { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
    .slick-table.is-cards-3 tbody { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .slick-table.is-cards-4 tbody { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.slick-table.is-cards tbody tr.slick-table-row {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius, 0.375rem);
    padding: 0.75rem 1rem;
    background: var(--bs-body-bg, #fff);
}

.slick-table.is-cards tbody td.slick-table-cell {
    border: 0;
    padding: 0.25rem 0;
}

/* The field label, so a value is never anonymous. */
.slick-table.is-cards tbody td.slick-table-cell[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--bs-secondary-color, #6c757d);
}

/* A group header spans the whole grid rather than sitting in one cell. */
.slick-table.is-cards tbody tr.slick-table-group-header {
    grid-column: 1 / -1;
    border: 0;
    padding: 0.5rem 0 0;
    background: transparent;
}


/* Grid mode: a wide table scrolls rather than squashing. */
.slick-table-scroll {
    overflow-x: auto;
}

/*
 * ⚑⚑ THE ROW-ACTIONS MENU MUST ESCAPE THE SCROLL BOX ABOVE.
 *
 * Measured 2026-08-12 on Plantings: a four-item ⋮ menu rendered ONE-AND-A-HALF items. Setting
 * `overflow-x` computes `overflow-y` to `auto` as well, so the wrapper clips vertically — and
 * every action below the box's edge was unreachable without first scrolling the page. A menu you
 * have to scroll INTO is a menu an operator concludes is broken; the walk that found this
 * reported the lot's menu as holding only three actions.
 *
 * ⚑ `position: fixed` ON THE OPEN MENU IS THE NARROWEST FIX THAT WORKS. A fixed element is
 * positioned against the VIEWPORT, so no ancestor's overflow can clip it. `data-bs-strategy`
 * was tried first and did not take, because the data-API had already initialised the dropdown.
 *
 * ⚑ SCOPED TO `.show` AND TO THIS PACKAGE'S OWN MENUS, so a closed menu keeps Bootstrap's normal
 * absolute layout and no other dropdown on the page is affected.
 *
 * ⚑ THE DECLARATION ITSELF NOW LIVES WITH THE COMPOUND SELECTOR BELOW, beside the animation rule
 * it depends on. Both override the same theme declaration and both were relying on source order;
 * keeping them together is what stops the next reader from fixing one and leaving the other.
 */

/*
 * ⚑⚑ AND THE RULE ABOVE IS ONLY SAFE WITH THIS ONE — WITHOUT IT THE MENU OPENS 649px AWAY.
 *
 * Found on an operator walk 2026-08-13: clicking ⋮ on a row at y=627 opened its menu at y=0 —
 * the top-right of the page, beside the account avatar. With twenty lots on screen an operator
 * cannot tell WHICH row's menu they opened, and because nothing happens near the cursor they
 * click again. A menu that acts on the wrong row is a wrong record.
 *
 * ⚑ THE CAUSE IS THE THEME'S ANIMATION, NOT THE POSITIONING. AdminKit animates every
 * `.dropdown-menu` with `dropdownAnimation`, whose final keyframe is `transform: translate(0)`,
 * under `animation-fill-mode: forwards`. A finished forwards-filling animation BEATS INLINE
 * STYLE in the cascade — so Popper writes `translate(-280px, 651px)` on the element and the
 * keyframe silently overwrites it with the identity. Measured: `menu.style.transform` read
 * `translate(-280px, 651px)` while `getComputedStyle(...).transform` read `matrix(1,0,0,1,0,0)`.
 *
 * ⚑ WHY IT SURFACED ONLY NOW. Under Bootstrap's default ABSOLUTE strategy, losing the transform
 * is survivable: `inset: 0 0 auto auto` still resolves against the `position-relative` wrapper,
 * so the menu lands roughly beside its own row and nobody files a bug. Under `fixed` the SAME
 * inset resolves against the VIEWPORT — `top: 0; right: 0`. The clipping fix above did not
 * introduce this defect; it converted a harmless misalignment into a 649px one.
 *
 * ⚑ THE OPACITY FADE IS KEPT AND ONLY THE TRANSFORM IS SURRENDERED. An 8px slide is decoration;
 * a menu positioned against the correct row is the feature. Re-declaring the keyframes without
 * the transform leaves the fade intact and hands geometry back to Popper, which is the only
 * thing that knows where the toggle actually is.
 *
 * ⚑⚑ THE SELECTOR MUST CARRY `.show`, AND THAT IS THE WHOLE REASON THE FIRST ATTEMPT FAILED.
 * The theme's rule is `.dropdown .dropdown-menu.show` — three classes. Overriding it from
 * `.slick-actions-dropdown .dropdown-menu` (two) loses on specificity **on exactly the element
 * that matters**, the OPEN one. It read as fixed when measured closed and still opened at the
 * page corner, which is the kind of near-miss worth naming: the computed style of a closed menu
 * says nothing about the rule that governs it once it opens.
 *
 * ⚑⚑ AND THE FIX FOR THAT SHIPPED A SELECTOR THAT CAN NEVER MATCH — CORRECTED 2026-08-13.
 *
 * `.dropdown .slick-actions-dropdown .dropdown-menu.show` describes a `.slick-actions-dropdown`
 * nested INSIDE a separate `.dropdown` ancestor. No such element exists: the component puts BOTH
 * classes on the SAME div (`actions-dropdown.blade.php`), so a DESCENDANT combinator can never
 * bind. Measured on the live Plantings board — `document.querySelectorAll` returns **0** for that
 * selector and 1 for the compound below.
 *
 * ⚑ SO THE OVERRIDE WAS BEING CARRIED ENTIRELY BY THE THIRD SELECTOR, WHICH ONLY TIES. The
 * theme is (0,3,0) and `.slick-actions-dropdown .dropdown-menu.show` is also (0,3,0) — equal
 * specificity, decided purely by which stylesheet loads last. That worked, and it is one
 * `<link>` reorder away from silently reverting to a menu 649px from its own row.
 *
 * ⚑ THE COMPOUND `.dropdown.slick-actions-dropdown` (no space) IS THE HONEST FORM — it says what
 * the markup actually is, and at (0,4,0) it WINS on specificity rather than on load order. The
 * dead descendant selector is removed rather than left beside it: a selector that cannot match is
 * not a harmless belt-and-braces, it is a false statement about the DOM that the next reader will
 * trust.
 *
 * Verified in the browser: button bottom 703, menu top 705 — a 2px gap, right edges flush for
 * `dropdown-menu-end`, not clipped below the fold.
 */
@keyframes slickActionsFade {
    0% {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.slick-actions-dropdown .dropdown-menu,
.dropdown.slick-actions-dropdown .dropdown-menu.show {
    animation-name: slickActionsFade;
}

/*
 * ⚑ THE SAME COMPOUND FOR THE GEOMETRY RULE ABOVE, for the same reason — `position: fixed` on the
 * open menu must not depend on source order either. Stated separately from the animation rule
 * because the two answer different theme declarations and a future reader may need only one.
 */
.dropdown.slick-actions-dropdown .dropdown-menu.show {
    position: fixed !important;
}

/*
 * ⚑⚑ ROW ACTION ICONS — the control that REPLACED the ⋮ menu, not a decoration beside it.
 *
 * A `btn-link` is styled for text: it carries the link colour and an underline on hover, and at
 * `btn-sm` it reserves horizontal padding for a word that is no longer there. These three rules
 * make an icon button read as a target — a square hit area, a hover state an operator can see
 * before committing, and no underline under an SVG.
 *
 * ⚑ THE HIT AREA IS THE ACCESSIBILITY POINT, NOT THE LOOK. The glyph is 16px; a bare 16px target
 * on a touch screen or a cold morning with gloves on is a miss, and a miss on a row of icons is
 * the WRONG action on the RIGHT record. 32px is the smallest square that is honestly pressable.
 */
.slick-action-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    min-height: 2rem;
    border-radius: 0.25rem;
    text-decoration: none;
    /**
     * ⚑⚑ A CONTROL'S NAME NEVER WRAPS — walk 15, measured at 1024px on Plantings.
     *
     * "Cut Lot" broke across two lines, which doubled the row height, halved how many controls
     * fit, and made a two-word label read as two separate things. The walker: *"five controls in
     * about 230 px, LABELS WRAPPED TO TWO LINES, icons unlabelled."*
     *
     * ⚑ THE LABEL IS THE NAMEABLE HALF of an icon-plus-word control (see the component's own
     * note — three walks converged on every inline action carrying its word). A name split
     * across lines is a name an operator has to reassemble, on the device where they can least
     * afford to.
     */
    white-space: nowrap;
}

.slick-action-button:hover,
.slick-action-button:focus-visible {
    background-color: var(--bs-secondary-bg, rgba(0, 0, 0, 0.06));
    color: var(--bs-body-color);
    text-decoration: none;
}

/*
 * ⚑⚑ A DESTRUCTIVE ROW ACTION KEEPS ITS COLOUR ON HOVER — task #154.
 *
 * The rule above resolves hover to `--bs-body-color` for every action button, which would strip
 * the danger tone at exactly the moment the pointer is ON the irreversible control. That is the
 * "silent fallback that produces something readable" shape: the button still looks fine, it just
 * stops warning. Measured on Plantings, where the destructive act sits one 32px square from a
 * safe one and the walker reported clicking to find out which was which.
 *
 * ⚑ THE TINT IS THE DANGER SUBTLE, NOT THE NEUTRAL GREY, so the hit area itself reads red.
 */
.slick-action-button.slick-action-danger:hover,
.slick-action-button.slick-action-danger:focus-visible {
    background-color: var(--bs-danger-bg-subtle, rgba(220, 53, 69, 0.12));
    color: var(--bs-danger-text-emphasis, var(--bs-danger));
}

/*
 * ⚑ CARD MODE: NO HORIZONTAL SCROLL. A card wraps its own content, so the wrapper stays
 * inside the page and the grid resolves against the viewport rather than the content.
 */
.slick-table-cards-wrap {
    width: 100%;
    max-width: 100%;
    overflow-x: hidden;
}
