/* List controls sit between the header and the table. Both hosts are empty on
   non-list routes, so the row collapses with no reserved space. The filter
   host takes the free width (its chips wrap inside it) and the sort control
   holds its natural size at the end of the row. */
.list-controls {
    max-width: 1200px;
    margin: 0 auto 0.75rem;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
}

.filter-bar-host:empty,
.sort-control-host:empty {
    display: none;
}

.filter-bar-host {
    flex: 1 1 auto;
}

.sort-control-host {
    flex: 0 0 auto;
}

.filter-bar {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* Neutral surface button so it reads as a control, not the primary brand
   action (the add-species + confirm buttons own the brand color). */
.filter-toggle {
    background: var(--surface-4);
    color: var(--surface-9);
    border: 1px solid var(--surface-6);
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.filter-toggle:hover {
    background: var(--surface-5);
}

.filter-badge {
    background: var(--brand-2);
    color: var(--surface-9);
    border-radius: 999px;
    font-size: 0.75rem;
    min-width: 1.25rem;
    padding: 0 0.4rem;
    text-align: center;
}

.filter-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.filter-chip {
    background: var(--surface-3);
    color: var(--surface-9);
    border: 1px solid var(--surface-5);
    border-radius: 999px;
    font-weight: normal;
    padding: 0.25rem 0.7rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.filter-chip:hover {
    background: var(--surface-4);
}

.filter-clear-all {
    background: none;
    color: var(--brand-3);
    font-weight: normal;
    padding: 0.25rem 0.5rem;
}

.filter-clear-all:hover {
    background: none;
    text-decoration: underline;
}

/* Popover panel. Absolute so it overlays the table rather than shoving it
   down. Fixed width (not max-width) so expanding a section with long labels
   can't resize the panel from one interaction to the next. On narrow screens
   it stretches full-width (see the media query). A single stacked column of
   collapsible sections; when the expanded sections overflow, the whole panel
   scrolls within its max-height rather than each section scrolling on its own. */
.filter-panel {
    position: absolute;
    top: calc(100% + 0.4rem);
    left: 0;
    z-index: 20;
    background: var(--surface-2);
    border: 1px solid var(--surface-5);
    border-radius: 0.5rem;
    padding: 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    width: min(92vw, 320px);
    max-height: 70vh;
    overflow-y: auto;
    box-shadow: 0 8px 24px var(--modal-overlay);
}

.filter-group {
    border: none;
    margin: 0;
    padding: 0;
}

/* Accordion header — full-width, neutral until hover; the whole row toggles
   its section. Brand-colored bold to read as the group title the legend was. */
.filter-group-toggle {
    width: 100%;
    background: none;
    color: var(--brand-3);
    font-weight: bold;
    text-align: left;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.4rem;
    border-radius: 0.35rem;
}

.filter-group-toggle:hover {
    background: var(--surface-3);
}

/* Fixed caret width so labels line up whether a section is open or closed. */
.filter-group-toggle .fa-solid {
    width: 0.9rem;
    text-align: center;
    font-size: 0.8em;
}

.filter-group-label {
    flex: 1 1 auto;
}

/* Selection-count pill on the header, mirroring .filter-badge so a *collapsed*
   section still reads as active. */
.filter-group-count {
    background: var(--brand-2);
    color: var(--surface-9);
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: normal;
    min-width: 1.25rem;
    padding: 0 0.4rem;
    text-align: center;
}

/* Options of an expanded section, indented under the label past the caret.
   Uncapped — a long facet grows the panel, which scrolls as a whole
   (see .filter-panel) rather than each section scrolling on its own. */
.filter-options {
    display: flex;
    flex-direction: column;
    padding: 0.1rem 0 0.3rem 1.4rem;
}

.filter-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.15rem 0;
    cursor: pointer;
}

.filter-option input {
    padding: 0;
    margin: 0;
}

/* Live match count beside each option; muted so the value still leads. */
.filter-count {
    color: var(--surface-7);
    font-size: 0.85em;
}

/* Zero-count options are unreachable given the other selections — grey them
   and show they can't be picked. A checked option is never disabled. */
.filter-option.is-disabled {
    opacity: 0.45;
    cursor: default;
}

@media (max-width: 480px) {
    /* Hand the panel's containing block to the control row so left/right:0
       stretch it edge-to-edge. Anchoring to .filter-bar instead would size the
       panel to a flex item whose width swings twice over: it shares the row
       with the sort control, and its own chips can grow it past the line and
       wrap the row — so the panel resized itself mid-interaction, the moment a
       first value was checked. The row is the stable full-width box. */
    .list-controls {
        position: relative;
    }

    .filter-bar {
        position: static;
    }

    /* Hang the panel off the toggle's height rather than the row's, so it opens
       directly under the button and overlays the chips and sort control that
       wrap beneath it — those are what the panel is replacing while it's open,
       so being pushed below them stranded it far from the control that opened
       it. The height is published by FilterBar.render() because the button's
       box follows the font's normal line box, so there is no constant to
       hardcode that wouldn't drift; the fallback only has to cover first paint. */
    .filter-panel {
        top: calc(var(--filter-toggle-height, 2.5rem) + 0.4rem);
        left: 0;
        right: 0;
        width: auto;
    }
}

/* Sort control. Deliberately styled as a sibling of the filter toggle — they
   are peers in the same row and should read as one control group. */
.sort-control {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.sort-toggle,
.sort-direction {
    background: var(--surface-4);
    color: var(--surface-9);
    border: 1px solid var(--surface-6);
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.sort-toggle:hover,
.sort-direction:hover {
    background: var(--surface-5);
}

/* Popover menu, mirroring .filter-panel so the two read as one system. */
.sort-menu {
    position: absolute;
    top: calc(100% + 0.4rem);
    right: 0;
    z-index: 20;
    background: var(--surface-2);
    border: 1px solid var(--surface-5);
    border-radius: 0.5rem;
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    min-width: 10rem;
    box-shadow: 0 8px 24px var(--modal-overlay);
}

.sort-option {
    background: none;
    color: var(--surface-9);
    font-weight: normal;
    text-align: left;
    padding: 0.35rem 0.6rem;
    border-radius: 0.35rem;
}

.sort-option:hover {
    background: var(--surface-4);
}

/* The active key needs to be visible without opening the menu's aria state. */
.sort-option[aria-checked="true"] {
    color: var(--brand-3);
    font-weight: bold;
}

/* Divider between the sort keys and the Hide-unmeasured toggle. */
.sort-menu-divider {
    height: 1px;
    background: var(--surface-5);
    margin: 0.3rem 0;
}

/* Checkbox-style menu item; greyed + inert while the active sort isn't a
   measurement, where hiding unmeasured species has no meaning. */
.sort-hide-toggle {
    background: none;
    color: var(--surface-9);
    font-weight: normal;
    text-align: left;
    padding: 0.35rem 0.6rem;
    border-radius: 0.35rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.sort-hide-toggle:hover:not(:disabled) {
    background: var(--surface-4);
}

.sort-hide-toggle:disabled {
    opacity: 0.45;
    cursor: default;
}
