/* CapstoneMultiselect — searchable multi-select with inline chips.
   Sibling of the autocomplete: it reuses the dropdown-list / item / active /
   empty / spinner / validation / read-error look (same CSS custom properties and
   dark-theme cues) and adds a flex chip box. Loaded by <capstone-head> after
   capstone-grid.css. */

.capstone-multiselect-wrap {
    position: relative;
}

.capstone-multiselect-label {
    margin-bottom: 0.25rem;
}

/* The chip box IS the form control: a flex container that wraps chips and the
   filter input, growing vertically as chips fill rows. min-height matches a
   default .form-control so an empty control lines up with sibling inputs. */
.capstone-multiselect-control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    min-height: calc(2.375rem + 2px);
    height: auto;
    padding: 0.25rem 2.5rem 0.25rem 0.5rem; /* right padding reserves the toggle slot */
    cursor: text;
}

/* Focus-within ring mirroring Bootstrap's .form-control:focus so the chip box
   reads as a single focusable field even though focus lives on the inner input. */
.capstone-multiselect-control:focus-within {
    border-color: #007055;
    outline: 0;
    box-shadow: 0 0 0 0.25rem rgba(0, 112, 85, 0.25);
}

/* Same per-theme split as .form-control:focus in capstone-bootstrap.css, so the
   chip box and the autocomplete beside it light up the same green in dark mode. */
[data-bs-theme="dark"] .capstone-multiselect-control:focus-within {
    border-color: #0a8d64;
    box-shadow: 0 0 0 0.25rem rgba(10, 141, 100, 0.25);
}

.capstone-multiselect-control.is-invalid {
    /* ReSharper disable once CssNotResolved */
    border-color: var(--bs-form-invalid-border-color, #dc3545);
}

.capstone-multiselect-control.is-valid {
    /* ReSharper disable once CssNotResolved */
    border-color: var(--bs-form-valid-border-color, #198754);
}

/* Focused validation states: the state border already survives :focus-within
   (these rules come after it), but the focus ring would stay brand-green —
   tint it to the state color instead, matching the autocomplete and plain
   fields. */
.capstone-multiselect-control.is-invalid:focus-within {
    /* ReSharper disable once CssNotResolved */
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb, 220, 53, 69), 0.25);
}

.capstone-multiselect-control.is-valid:focus-within {
    /* ReSharper disable once CssNotResolved */
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb, 25, 135, 84), 0.25);
}

/* Suppress Bootstrap's .form-control.is-valid / .is-invalid background-image icon
   on the chip box. The control carries the `form-control` class for sizing/border,
   so Bootstrap would otherwise paint its own exclamation-circle SVG pinned to the
   far-right edge — directly on top of the toggle chevron, with no way to reposition
   a background image. We suppress it and render our own validation icon (below) in
   a controlled slot just left of the toggle instead. Border/padding stay. */
.was-validated .capstone-multiselect-control.form-control:valid,
.was-validated .capstone-multiselect-control.form-control:invalid,
.capstone-multiselect-control.form-control.is-valid,
.capstone-multiselect-control.form-control.is-invalid {
    background-image: none;
}

/* Our own red exclamation-circle, shown by showValidation(). Sits to the LEFT of
   the toggle chevron (which stays at the edge as the dropdown affordance) so the
   two never overlap. Hidden until the control is flagged invalid. */
.capstone-multiselect-validation-icon {
    position: absolute;
    right: 2.25rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    display: none;
    align-items: center;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
    font-size: 1rem;
    line-height: 1;
    pointer-events: none;
}

.capstone-multiselect-control.is-invalid ~ .capstone-multiselect-validation-icon {
    display: inline-flex;
}

/* Validated-OK state (validate() passed): same slot, green check — the glyph
   swap overrides the ::before content the bi- icon class sets. Parity with
   the autocomplete's is-valid and aspnet-validation's green on plain fields. */
.capstone-multiselect-control.is-valid ~ .capstone-multiselect-validation-icon {
    display: inline-flex;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-valid-color, #198754);
}

.capstone-multiselect-control.is-valid ~ .capstone-multiselect-validation-icon .bi::before {
    content: "\f26a"; /* bi-check-circle-fill */
}

/* The count badge shares the right: 2.25rem slot with the validation icon —
   hide it while a validation state is showing (same convention as the
   loading and read-error states) so the two never stack. The valid state
   makes this collision routine: a validated-OK control usually has
   selections, so badge + green check would otherwise always coincide. */
.capstone-multiselect-control.is-invalid ~ .capstone-multiselect-count,
.capstone-multiselect-control.is-valid ~ .capstone-multiselect-count {
    display: none;
}

/* Reserve room for both the validation icon and the toggle so wrapped chips never
   slide underneath them while the control is flagged invalid or validated-OK. */
.capstone-multiselect-control.is-invalid,
.capstone-multiselect-control.is-valid {
    padding-right: 4rem;
}

/* Borderless search input that flexes to fill the remaining row width. */
.capstone-multiselect-input {
    flex: 1 1 6ch;
    min-width: 6ch;
    border: none;
    outline: none;
    background: transparent;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-body-color);
    padding: 0.25rem 0.15rem;
    font-size: 1rem;
    line-height: 1.4;
}

.capstone-multiselect-input:disabled {
    cursor: not-allowed;
}

/* ── Chips ───────────────────────────────────────────────────
   Neutral gray pill — NOT SRU gold / .text-bg-secondary (gold fails white-text
   contrast) and NOT outline-secondary (fails on dark). The secondary-bg token
   takes body-color text, which clears AA in both themes. */
.capstone-multiselect-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-secondary-bg, #e9ecef);
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-body-color);
    /* ReSharper disable once CssNotResolved */
    border: 1px solid var(--bs-border-color);
    border-radius: 1rem;
    padding: 0.1rem 0.25rem 0.1rem 0.6rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    max-width: 100%;
}

.capstone-multiselect-chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.capstone-multiselect-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
    font-size: 1rem;
    line-height: 1;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    cursor: pointer;
    padding: 0;
    transition: background-color 0.1s, color 0.1s;
}

.capstone-multiselect-chip-remove:hover,
.capstone-multiselect-chip-remove:focus {
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-tertiary-bg, #dee2e6);
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-body-color);
}

/* Keyboard focus needs a real ring — the tertiary-bg tint above is nearly
   invisible against the gray chip. Same 2px brand outline the file-upload
   chip remove uses; :focus-visible keeps it off mouse clicks. */
.capstone-multiselect-chip-remove:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 1px;
}

/* ── Count badge ─────────────────────────────────────────────
   Solid primary green — white-on-#007055 keeps 6.09:1 (the only brand surface
   safe with white text). Sits left of the toggle. */
.capstone-multiselect-count {
    position: absolute;
    right: 2.25rem;
    top: 50%;
    transform: translateY(-50%);
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-primary, #007055);
    color: #fff;
    font-size: 0.7rem;
    z-index: 5;
    pointer-events: none;
}

/* ── Toggle chevron ──────────────────────────────────────────*/
.capstone-multiselect-toggle {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: none;
    padding: 0.25rem 0.4rem;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-body-color);
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.15s;
    z-index: 5;
    line-height: 1;
    font-size: 0.875rem;
}

.capstone-multiselect-toggle:hover {
    opacity: 1;
}

/* ── Dropdown list ───────────────────────────────────────────
   Same shell as the autocomplete list so the two feel identical. */
.capstone-multiselect-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 99;
    /* ReSharper disable once CssNotResolved */
    background: var(--bs-body-bg);
    /* ReSharper disable once CssNotResolved */
    border: 1px solid var(--bs-border-color);
    border-top: none;
    border-radius: 0 0 0.375rem 0.375rem;
    max-height: 240px;
    overflow-y: auto;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* Select-all / Clear-all header row. */
.capstone-multiselect-actions {
    display: flex;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    /* ReSharper disable once CssNotResolved */
    border-bottom: 1px solid var(--bs-border-color);
}

.capstone-multiselect-actions .btn-link {
    padding: 0.15rem 0.25rem;
    font-size: 0.8125rem;
    text-decoration: none;
}

.capstone-multiselect-actions .btn-link:hover {
    text-decoration: underline;
}

.capstone-multiselect-item {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    font-size: 0.875rem;
    /* ReSharper disable once CssNotResolved */
    border-bottom: 1px solid var(--bs-border-color);
    transition: background-color 0.1s;
}

.capstone-multiselect-item:last-child {
    border-bottom: none;
}

.capstone-multiselect-item:hover {
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-secondary-bg);
}

/* Check mark — invisible until the option is selected, so all rows align. */
.capstone-multiselect-check {
    visibility: hidden;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-primary, #007055);
    flex: 0 0 auto;
}

/* --bs-primary is pinned to #007055 in both themes for button contrast, which
   leaves the selected-item tick at ~2.5:1 on the dark list. Use the .text-brand
   dark shade (~6.5:1). The active (keyboard-highlighted) row paints white on
   green and overrides this. */
[data-bs-theme="dark"] .capstone-multiselect-check {
    color: #5cbc94;
}

.capstone-multiselect-item.is-selected .capstone-multiselect-check {
    visibility: visible;
}

.capstone-multiselect-item.is-selected {
    font-weight: 500;
}

.capstone-multiselect-item.is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.capstone-multiselect-item-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Keyboard-focus highlight (arrow navigation). */
.capstone-multiselect-active {
    color: #ffffff;
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-primary, #007055);
}

[data-bs-theme="dark"] .capstone-multiselect-active {
    background-color: #0a8d64;
}

/* Empty-state / no-match / max-hint rows — non-interactive, muted. */
.capstone-multiselect-empty,
.capstone-multiselect-hint {
    padding: 0.5rem 0.75rem;
    font-size: 0.8125rem;
    text-align: center;
    cursor: default;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
}

.capstone-multiselect-hint {
    /* ReSharper disable once CssNotResolved */
    border-top: 1px solid var(--bs-border-color);
}

/* Truncation footer — rendered as the last option entry when more items match
   than max-results allows. Muted + italic so it reads as a hint ("keep typing
   to narrow"), not a selectable row. Mirrors .capstone-autocomplete-more. */
.capstone-multiselect-more {
    padding: 0.375rem 0.75rem;
    font-size: 0.8125rem;
    font-style: italic;
    text-align: center;
    cursor: default;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
    /* ReSharper disable once CssNotResolved */
    border-top: 1px solid var(--bs-border-color);
}

/* ── Validation badge ────────────────────────────────────────*/
.capstone-multiselect-validation {
    position: absolute;
    top: 0;
    right: 0.5rem;
    transform: translateY(-50%);
    display: none;
    padding: 0.125rem 0.5rem;
    /* ReSharper disable once CssNotResolved */
    background: var(--bs-danger, #dc3545);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.2;
    border-radius: 0.25rem;
    z-index: 6;
    pointer-events: none;
    white-space: nowrap;
}

/* ── Loading spinner (read-url) ──────────────────────────────
   Same three-dot indicator and color cycle as the autocomplete. */
.capstone-multiselect-spinner {
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    display: none;
    align-items: center;
    gap: 0.3rem;
}

.capstone-multiselect[data-loading="true"] .capstone-multiselect-spinner {
    display: inline-flex;
}

.capstone-multiselect[data-loading="true"] .capstone-multiselect-toggle,
.capstone-multiselect[data-loading="true"] .capstone-multiselect-count {
    display: none;
}

/* Dot styling and color-cycle animation come from the shared "Loading dots"
   block in capstone-site.css (loaded by <capstone-head> before this file). */

/* ── Read-error state ────────────────────────────────────────*/
.capstone-multiselect-error-icon {
    position: absolute;
    right: 0.75rem;
    top: calc((2.375rem + 2px) / 2);
    transform: translateY(-50%);
    z-index: 5;
    display: none;
    align-items: center;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
    font-size: 1rem;
    line-height: 1;
    pointer-events: none;
}

.capstone-multiselect[data-read-error="true"] .capstone-multiselect-error-icon {
    display: inline-flex;
}

.capstone-multiselect[data-read-error="true"] .capstone-multiselect-toggle,
.capstone-multiselect[data-read-error="true"] .capstone-multiselect-count {
    display: none;
}

/* The read-error field is readonly + aria-disabled rather than `disabled`, so it
   stays focusable and its aria-describedby link to the message actually reaches
   assistive tech. Bootstrap only paints :disabled, so carry the non-interactive
   surface across ourselves — otherwise a control that refuses input still looks
   editable. Mirrors <capstone-autocomplete>. */
.capstone-multiselect[data-read-error="true"] .capstone-multiselect-control {
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-secondary-bg);
    opacity: 1;
    cursor: not-allowed;
}

.capstone-multiselect-error {
    display: none;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
    font-size: 0.875rem;
    line-height: 1.3;
}

.capstone-multiselect-error-message {
    flex: 0 1 auto;
}

.capstone-multiselect-error-retry {
    padding: 0;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
    font-size: 0.875rem;
    text-decoration: underline;
    line-height: 1.3;
}

.capstone-multiselect-error-retry:hover,
.capstone-multiselect-error-retry:focus {
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
    text-decoration: none;
}

/* ── Size variants ───────────────────────────────────────────
   Mirror Bootstrap's form-control-sm / -lg. Retune the control min-height, the
   font, and the chip/input scale; the toggle, count, and spinner center on
   top:50% so they follow the new height automatically. */
.capstone-multiselect-sm .capstone-multiselect-control {
    min-height: calc(2rem + 2px);
    font-size: 0.875rem;
    padding-top: 0.15rem;
    padding-bottom: 0.15rem;
}

.capstone-multiselect-sm .capstone-multiselect-input {
    font-size: 0.875rem;
}

.capstone-multiselect-sm .capstone-multiselect-chip {
    font-size: 0.75rem;
}

.capstone-multiselect-lg .capstone-multiselect-control {
    min-height: calc(3.5rem + 2px);
    font-size: 1.125rem;
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
}

.capstone-multiselect-lg .capstone-multiselect-input {
    font-size: 1.125rem;
}

.capstone-multiselect-lg .capstone-multiselect-chip {
    font-size: 0.9375rem;
}
