/*
 * BPBytes "Filter" search modal.
 * Targets include/SearchForm/tpls/headerPopup.tpl (the Bootstrap modal shell, #searchDialog,
 * appended straight to <body> like every other Bootstrap popup in this app — see components.css'
 * own modal-chrome comment) and the plain <table> field grid rendered inside it by
 * include/SearchForm/tpls/SearchFormGeneric.tpl (Quick Filter) and SearchFormGenericAdvanced.tpl
 * (Advanced Filter). CSS only, no template overrides — same approach as every other core view.
 */

/*
 * The "?" help icon's onclick opens a jQuery UI .dialog(), whose own z-index never accounts for
 * Bootstrap's #searchDialog (z-index:1050) or its backdrop (1040), so it opened behind the still-
 * open search modal. !important since jQuery UI sets z-index as an inline style via JS.
 */
.ui-dialog {
    z-index: 1200 !important;
}

.ui-widget-overlay {
    z-index: 1190 !important;
}

/*
 * headerPopup.tpl always renders a "Quick Filter"/"Advanced Filter" <h5 class="searchTabHeader
 * mobileOnly"> pair alongside the real clickable tabs, meant to swap in only on very narrow
 * screens (SuiteP hides these by default; BPBytes never defined that base rule).
 */
.searchTabHeader {
    display: none;
}

/*
 * Sized for the current label-above-field layout (4 columns * ~190px + gaps + padding ≈ 850px)
 * instead of the old label-beside-field math, which left a large unused strip on the right.
 */
#searchDialog .modal-lg {
    width: 860px;
    max-width: 95vw;
}

#searchDialog .module-title-text {
    margin: 0 0 16px;
    font-size: 20px;
    font-weight: 700;
    color: var(--bp-text);
}

/* Active tab gets the theme's accent color + underline; resting tabs get muted text and no
   competing border under the whole row. */
#searchDialog .nav-tabs {
    border-bottom: none;
}

#searchDialog .nav-tabs > li > a {
    color: var(--bp-text-muted);
    font-weight: 600;
    border: none;
    border-bottom: 2px solid transparent;
}

#searchDialog .nav-tabs > li > a:hover {
    color: var(--bp-text);
}

#searchDialog .nav-tabs > li.active > a {
    color: var(--bp-primary);
    border-bottom-color: var(--bp-primary);
}

/*
 * SearchFormGeneric.tpl / SearchFormGenericAdvanced.tpl render a plain
 * <table><td width='1%'>label</td><td width='1%'>{field}</td></table> grid, so auto table layout
 * was sizing each control down to its own minimal content. A real min-width forces the cell to
 * grow to fit it.
 */
#searchDialog #searchList label {
    display: block;
    margin: 0 0 6px;
    font-size: 13px;
    font-weight: 700;
    color: var(--bp-text);
    white-space: nowrap;
}

#searchDialog #searchList td {
    padding: 8px 12px;
    vertical-align: middle;
}

/*
 * Label-above-field layout instead of the original label-beside-field row: putting each <tr>
 * itself into CSS grid with 2 explicit rows and column auto-flow makes the source sequence
 * label1,field1,label2,field2,... fill column 1 (both rows) before moving to column 2, landing
 * each label directly above its field. :not(:has(...)) excludes every row that isn't a clean run
 * of label/field pairs (any td[colspan], or .sumbitButtons — Quick Filter's Search/Clear row when
 * it shares the last field pair's <tr>).
 *
 * This per-<tr> grid works fine for plain layout, but see the .sumbitButtons/colspan="20" blocks
 * further down for why it breaks once a multi-select dropdown or absolutely-positioned element is
 * involved — those cases get a different, table-level technique instead.
 */
#searchDialog #searchList table {
    width: 100%;
}

#searchDialog #searchList table tr:not(:has(td[colspan], .sumbitButtons)) {
    display: grid;
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    /*
     * Explicit tracks, not just grid-auto-columns: each <tr> is its own grid container here, so
     * grid-auto-columns alone would size every row's columns from that row's own field count,
     * leaving rows with fewer fields not lining up under rows with more. maxColumns is kept in
     * sync with maxColumnsBasic system-wide (SearchForm2.php::setup()), and comes out to 4 for
     * every module seen so far.
     */
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    grid-auto-columns: minmax(170px, 1fr);
    column-gap: 32px;
    row-gap: 0;
    justify-content: start;
    align-items: start;
    /* Containing block for .helpIcon further down. */
    position: relative;
}

/* flex-shrink:0 keeps a nowrap <td> ("Modify current filter:", etc.) from shrinking below its own
   text's width once it's a flex item, which would otherwise spill into the next cell. */
#searchDialog #searchList table tr:has(td[colspan]) {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-top: 8px;
    padding-top: 14px;
}

#searchDialog #searchList table tr:has(td[colspan]) > td {
    flex-shrink: 0;
}

/*
 * A module whose Quick Filter field count is an exact multiple of maxColumnsBasic never opens a
 * second <tr> for Search/Clear — .sumbitButtons/.helpIcon land as trailing cells in the SAME <tr>
 * as the last field pair, with no td[colspan] in that row.
 *
 * Gridding that <tr> directly (the per-row rule above) draws the fields correctly, but a
 * multi-select dropdown (.ms-drop, position:absolute) opened at the bottom of the WHOLE row
 * instead of under its own field — a <tr> overriding `display` to something grid-shaped while
 * still living in a real <table> confuses the browser's table-layout algorithm enough to throw off
 * .ms-drop's containing-block height. Fix: don't grid the <tr> — grid the <table> itself (a plain
 * block box with no table-layout quirks) and make the <tr> `display: contents` so its <td>s become
 * direct grid items. Safe to scope to the whole table here because this exact case (field count <=
 * maxColumns) only ever has the one <tr>.
 */
#searchDialog #searchList table:has(tr > .sumbitButtons) {
    display: grid;
    /*
     * Exactly 2 explicit rows: each field contributes 2 auto-flowed items (label, field), so
     * grid-auto-flow:column fills column 1's 2 rows before advancing. A 3rd explicit row here
     * would give auto-flow 3 slots per column, scrambling label/field pairs across the wrong
     * rows/columns. .sumbitButtons' own explicit grid-row:3 below still places it in an implicit
     * 3rd row without needing a matching explicit track here.
     */
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    grid-auto-columns: minmax(170px, 1fr);
    column-gap: 32px;
    row-gap: 0;
    justify-content: start;
    align-items: start;
    position: relative;
}

/* SearchFormGeneric.tpl writes a bare <table><tr> with no explicit <tbody> — the browser inserts
   one anyway, so both the implicit <tbody> AND the <tr> need display:contents for the <td>s to
   bubble up to the grid container (the table, styled above). */
#searchDialog #searchList table:has(tr > .sumbitButtons) > tbody,
#searchDialog #searchList table:has(tr > .sumbitButtons) tr {
    display: contents;
}

/*
 * SearchFormGeneric.tpl also wraps into a second <tr> once field count passes maxColumnsBasic —
 * Search/Clear then render into their own trailing <tr><td colspan="{$searchTableColumnCount}">,
 * not .sumbitButtons riding along with the last field pair, so the rule above never matches and
 * this table fell through to the general per-<tr> grid-auto-flow rule instead (the same family of
 * bug the Advanced Filter blocks below fix for their own template). #search_form_submit is Quick
 * Filter's own stable id regardless of wrapping — $searchTableColumnCount is a computed value, not
 * a fixed number to key a selector off. :not(:has(tr > .sumbitButtons)) excludes the single-row
 * case already handled above.
 */
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) {
    display: grid;
    grid-template-rows: auto auto;
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    column-gap: 32px;
    row-gap: 0;
    justify-content: start;
    align-items: start;
    position: relative;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody {
    display: contents;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) {
    display: contents;
}

/*
 * Every field <td> gets an explicit grid-column/grid-row instead of relying on auto-flow: mixing
 * auto-placed items with the trailing row's grid-column:1/-1 (row left auto) placed that row
 * ahead of the fields regardless of DOM order, and once it was given an explicit row too, the
 * auto-flow cursor for the fields started skipping cells that row had claimed. Explicit placement
 * for both removes the ambiguity. nth-child(1..8) covers up to 4 pairs per row (maxColumnsBasic).
 */
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(1),
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(2) {
    grid-column: 1;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(3),
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(4) {
    grid-column: 2;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(5),
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(6) {
    grid-column: 3;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(7),
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(8) {
    grid-column: 4;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) {
    grid-row: 1;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(even) {
    grid-row: 2;
}

/* A second field-tr (more fields than one row holds) needs its own row pair — nth-child counts
   per its own <tr>, so without this it would land in exactly the same cells as the first row's. */
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) {
    grid-row: 3;
}

#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(even) {
    grid-row: 4;
}

/* The trailing Search/Clear(+helpIcon) row: full-span, pinned below the field row(s) instead of
   competing with them for a grid cell via auto-placement. */
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:has(td[colspan]) {
    grid-column: 1 / -1;
    grid-row: 3;
}

/* When a second field-tr exists it occupies rows 3-4, so the trailing row needs pushing to row 5.
   Anchored via `~` (general sibling) on the second field-tr rather than a table:has() wrapping
   another :has() — :has() can't nest inside :has(), so that combination is simply invalid CSS and
   silently matches nothing. */
#searchDialog #searchList table:has(#search_form_submit):not(:has(tr > .sumbitButtons)) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) ~ tr:has(td[colspan]) {
    grid-row: 5;
}

/*
 * SearchFormGeneric.tpl writes Search and Clear as `...id="search_form_submit">&nbsp;<input
 * ...id="search_form_clear"...` — a literal &nbsp; between them, which becomes its own anonymous
 * flex item rather than collapsing away. Zeroing the column-gap leaves that &nbsp; as the only
 * thing spacing them, matching the single-whitespace-character gap Save/Cancel get elsewhere.
 */
#searchDialog #searchList table:has(tr > .sumbitButtons) .sumbitButtons {
    grid-column: 1 / -1;
    grid-row: 3;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 0;
    margin-top: 8px;
    padding-top: 14px;
}

/*
 * SearchFormGenericAdvanced.tpl never shares its field row's <tr> with Search/Clear — that's
 * always a separate row further down — so it never matches table:has(tr > .sumbitButtons) above
 * and falls through to the same per-<tr> grid-auto-flow bug. The row-wrap spacer
 * (<tr><td colspan='20'>) always immediately follows the field row(s), so "a <tr> immediately
 * followed by that spacer" reliably identifies them regardless of field count. Same table-is-the-
 * grid-container/tr-is-contents fix, but scoped to just the field row(s) since this table also has
 * real sibling rows (the spacer, saved-search, Search/Clear) that need to keep spanning full width.
 */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) {
    display: grid;
    grid-template-rows: auto auto;
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    column-gap: 32px;
    row-gap: 0;
    justify-content: start;
    align-items: start;
    position: relative;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody {
    display: contents;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) {
    display: contents;
}

/* Explicit grid-column/grid-row per field <td> — see the matching Quick Filter comment above for
   why auto-placement doesn't mix safely with the trailing rows' explicit placement. */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(1),
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(2) {
    grid-column: 1;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(3),
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(4) {
    grid-column: 2;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) {
    min-width: 170px;
    min-height: 0;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) label {
    width: auto;
    max-width: 100%;
    min-width: 0;
    white-space: normal;
    overflow-wrap: break-word;
    word-break: normal;
    line-height: 1.25;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(5),
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(6) {
    grid-column: 3;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(7),
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(8) {
    grid-column: 4;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) {
    grid-row: 1;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(even) {
    grid-row: 2;
}

/* A second field-tr — same reasoning as the identical Quick Filter rule above. `tr:not(...) +
   tr:not(...)` (a field-tr immediately preceded by another field-tr) is more specific than the
   plain tr:not(...) selector above it, so it wins for just that row's cells. */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(odd) {
    grid-row: 3;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) > td:nth-child(even) {
    grid-row: 4;
}

/*
 * Every other row (the spacer, saved-search rows, Search/Clear) keeps its own display (flex, or
 * none for the spacer) but needs an explicit grid-column/grid-row now that nothing is left on
 * auto-placement. SearchFormGenericAdvanced.tpl only ever renders these three, in this fixed
 * order, after the field row(s): the spacer (hidden), the optional "Layout Options"/"Save filter
 * as" row (colspan='2'), the optional inline saved-search row (colspan='6'), then Search/Clear
 * (colspan='5'). An absent row just leaves its numbered slot empty.
 */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan], .sumbitButtons) {
    grid-column: 1 / -1;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan="2"]) {
    grid-row: 3;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan="6"]) {
    grid-row: 4;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan="5"]) {
    grid-row: 5;
}

/* When a second field-tr exists (rows 3-4), the trailing rows shift to 5/6/7. Anchored via `~`
   on the second field-tr rather than nesting :has() inside :has() (invalid CSS — see the Quick
   Filter comment above for the same issue). */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) ~ tr:has(td[colspan="2"]) {
    grid-row: 5;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) ~ tr:has(td[colspan="6"]) {
    grid-row: 6;
}

#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:not(:has(td[colspan], .sumbitButtons)) + tr:not(:has(td[colspan], .sumbitButtons)) ~ tr:has(td[colspan="5"]) {
    grid-row: 7;
}

/* The generic divider rule's margin-top/padding-top (22px) is sized for a single divider —
   Advanced Filter stacks up to three of these rows, so that compounds into a large dead gap.
   Tightened here, scoped to this table only; other search-form dividers elsewhere keep the
   original size. */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan], .sumbitButtons) {
    margin-top: 4px !important;
    padding-top: 6px !important;
}

/* modules/SavedSearch/SavedSearchForm.tpl (the "Order by column"/"Direction" widget) is its own
   nested <table> — the #searchDialog #searchList td padding above has no descendant restriction,
   so it was reaching this inner table's small controls too. Scoped down to match their size. */
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) #inlineSavedSearch td {
    padding: 2px 8px;
}

/* The row-wrap spacer (<tr><td colspan='20'>&nbsp;</td></tr>) has no real content, but its
   td[colspan] still matches the divider rule above, stacking its own margin/padding directly
   against the very next row's. colspan="20" is unique to this spacer (every other colspan in the
   template is 2, 5, or 6), so it's a safe way to remove just this one row. */
#searchDialog #searchList table tr:has(td[colspan="20"]) {
    display: none;
}

/* "Layout Options", "Save filter as:", and "Modify current filter:" are three unrelated controls
   sharing one row as plain sibling <td>s — a left border on each group's first cell (2nd/4th
   child of the colspan="2" row) marks where a new group starts. */
#searchDialog #searchList table tr:has(td[colspan="2"]) > td:nth-child(2),
#searchDialog #searchList table tr:has(td[colspan="2"]) > td:nth-child(4) {
    margin-left: 6px;
    padding-left: 20px;
    border-left: 1px solid var(--bp-border);
}

#searchDialog #searchList select,
#searchDialog #searchList input[type="text"] {
    min-width: 130px;
    padding: 7px 10px;
    border: 1px solid var(--bp-border);
    border-radius: var(--bp-radius);
    font-size: 13px;
    color: var(--bp-text);
    background: var(--bp-surface);
}

#searchDialog #searchList select:focus,
#searchDialog #searchList input[type="text"]:focus {
    outline: none;
    border-color: var(--bp-primary);
    box-shadow: 0 0 0 3px var(--bp-primary-soft);
}

/* A bool-type search field renders as a plain <select> with no multi-select-plugin replacement;
   editview.css's native-select chevron treatment is scoped to #content, which never reaches this
   Bootstrap modal appended to <body>. */
#searchDialog #searchList select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 32px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b667a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 12px;
    cursor: pointer;
}

/* Datetimecombo.js appends an hour/minute/meridiem <select> trio that only ever needs two
   characters each — the generic select rule above would force all three to its 130px+ width. */
#searchDialog #searchList select.datetimecombo_time {
    min-width: 0;
    width: auto;
    padding: 7px 22px 7px 8px;
    background-position: right 6px center;
    background-size: 10px;
}

/* Multi-select enum fields render through custom/js/multiple-select.min.js, whose own CSS hard-
   codes .ms-parent to width:60% !important of its cell — collapsing to almost nothing once that
   cell has no other real width driving it. */
#searchDialog #searchList .ms-parent {
    width: 160px !important;
    min-width: 160px !important;
}

#searchDialog #searchList .ms-choice {
    min-width: 160px;
}

/* The multiselect init passes no maxHeight, so .ms-drop ul's own overflow:auto never has a height
   to actually clip against — the dropdown just grows to list every option. Capping the height
   gives that overflow:auto something to scroll. */
#searchDialog #searchList .ms-drop ul {
    max-height: 240px;
}

/* The "Save filter as:" text field sits in a nowrap cell right next to the Save button — needs a
   fixed size, not width:100%, or the button has no room and visually overflows. */
#searchDialog #searchList input[name="saved_search_name"] {
    min-width: 160px;
    width: 160px;
}

/* overflow-x:auto with overflow-y unset forces both axes into a clipping context, which was
   clipping the multi-select dropdown panel instead of letting it float below the field. Visible
   on both axes so dropdowns can float freely; the page's own scroll is the fallback if a row is
   ever genuinely too wide. */
#searchDialog .modal-body {
    max-width: 100%;
    overflow: visible;
}

/* bootstrap.min.css gives #searchDialog itself (the outer .modal, a real scroll container sized
   to its own rendered height, not the viewport) its own overflow-y:auto the moment the modal is
   open — a dropdown opening near the bottom of a shorter modal still got clipped there even with
   modal-body already visible. Same "let it float, don't clip" rationale, one ancestor further out. */
#searchDialog {
    overflow: visible !important;
}

.ms-drop {
    z-index: 1100 !important;
}

#searchDialog #searchList img {
    vertical-align: middle;
}

/*
 * Search/Clear already get their filled/primary vs plain look from the shared button rules in
 * components.css (same treatment as EditView/DetailView's Save/Cancel). What they were missing is
 * the closure a form's action bar gets elsewhere — components.css' .modal-footer pattern
 * (padding, border-top) — since these buttons render as a plain grid row inside .modal-body's own
 * flow, with no <div class="modal-footer"> to sit in. Negative side/bottom margins matching
 * .modal-body's own 24px padding bleed this row to the modal's real edges, with matching corner
 * radius so it still follows modal-content's rounded bottom corners.
 */
#searchDialog .sumbitButtons,
#searchDialog #searchList table:has(tr + tr > td[colspan="20"]) > tbody > tr:has(td[colspan="5"]) {
    margin: 24px -24px -24px !important;
    padding: 16px 24px !important;
    border-top: 1px solid var(--bp-border);
    border-bottom-left-radius: var(--bp-radius-lg);
    border-bottom-right-radius: var(--bp-radius-lg);
}

/* This row also inherits gap:10px 20px from the generic divider rule above (needed for the OTHER
   controls sharing it — the Basic Filter link, the My Filters dropdown), so the shared gap can't
   just be lowered. Dropping just Search's own redundant margin-right brings it and Clear down to
   a tight, Save/Cancel-style gap without touching the rest of the row. */
#searchDialog #search_form_submit_advanced {
    margin-right: 0;
}

/* input.button's margin-right is the only thing spacing "Save filter as:"'s Save button from its
   neighbour (it's not itself a flex row) — Quick Filter's Search/Clear is the one place this
   doubles up with the flex gap above, stripped back to 0 there specifically. */
#searchDialog input.button {
    margin-right: 8px;
}

#searchDialog .sumbitButtons input.button {
    margin-right: 0;
}

/* "Layout Options" and "Quick Filter" (Advanced Filter's bottom row) are plain <a> tags that
   otherwise fall back to Bootstrap's default link color. */
#searchDialog .tabFormAdvLink,
#searchDialog #basic_search_link {
    color: var(--bp-primary);
    font-weight: 600;
    text-decoration: none;
}

#searchDialog .tabFormAdvLink:hover,
#searchDialog #basic_search_link:hover {
    color: var(--bp-primary-hover);
    text-decoration: underline;
}

/* "| My Filters [dropdown]" sits right after "Quick Filter" with only &nbsp; for spacing — a left
   border marks it as its own group. */
#searchDialog .white-space {
    margin-left: 8px;
    padding-left: 16px;
    border-left: 1px solid var(--bp-border);
}

/*
 * The help-icon cell lands as a grid item with no explicit placement of its own. Even with
 * position:absolute taking it out of flow, it still gets auto-placed into a real column track,
 * and that track's width leaks into its own used width — so right:0 resolves against a box a
 * whole column wide, landing its visible corner one column short of the table's true right edge
 * and overlapping whichever field is last. Forcing the width back to content size sidesteps the
 * grid placement entirely.
 */
#searchDialog .helpIcon {
    position: absolute;
    top: 0;
    right: 0;
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
    padding-left: 0 !important;
}

#searchDialog .helpIcon img {
    width: 18px;
    height: 18px;
    opacity: 0.55;
    vertical-align: middle;
}

#searchDialog .helpIcon img:hover {
    opacity: 0.85;
}

/* Date filter: the operator and the date box line up with the other 160px by 40px filter fields. */
#searchDialog #searchList select[id$="_range_choice"] {
    width: 160px !important;
    max-width: none;
    height: var(--bp-control-h);
}

#searchDialog #searchList input.dateRangeInput {
    width: 116px;
    min-width: 116px;
    height: var(--bp-control-h);
}

#searchDialog #searchList button[id$="_trigger"] {
    width: var(--bp-control-h);
    height: var(--bp-control-h);
}

#searchDialog #searchList .ms-choice > div.icon-caret,
#searchDialog #searchList .ms-choice > div.icon-caret.open {
    border: 0;
    margin-top: 0;
    top: 0;
    right: 0;
    width: 32px;
    height: 100%;
    background: var(--bp-chevron) no-repeat right 10px center / 12px;
}
