/* HYPERPART: search-select */
/* Promoted from Dazzle fragments.css (Tier F4b, fleet convergence).
 * One deliberate delta: the results panel's visibility moved from
 * Alpine x-show/x-cloak onto state-in-DOM — the input SSRs
 * aria-expanded="false", controllers/dz-search-select.js flips it on
 * focusin/focusout, and the sibling rule below hides the panel off
 * the attribute. */

/* ─────────────────────────── search_select fragment ─────────────
 * Debounced search with dropdown results. Standard form input
 * chrome + spinner + ARIA combobox listbox panel below. Error
 * state (border colour) keyed off `aria-invalid="true"` — same
 * convention as form.css. */

.dz-search-select {
  position: relative;
  width: 100%;
}

.dz-search-select-input {
  width: 100%;
  /* Match .dz-form-input box model (border-box + min-height 2.5rem). */
  box-sizing: border-box;
  height: auto;
  min-height: 2.5rem;
  line-height: 1.4;
  padding-block: var(--space-sm);
  padding-inline-start: var(--space-md);
  padding-inline-end: 2rem; /* room for the spinner */
  border-radius: var(--radius-sm);
  background: var(--colour-surface);
  border: 1px solid var(--colour-border);
  font-size: var(--text-sm);
  color: var(--colour-text);
  outline: none;
  transition:
    box-shadow var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}

.dz-search-select-input::placeholder {
  color: var(--colour-text-muted);
}

.dz-search-select-input:focus-visible {
  box-shadow: 0 0 0 1px var(--colour-brand);
  border-color: var(--colour-brand);
}

.dz-search-select-input[aria-invalid="true"] {
  border-color: var(--colour-danger);
}

.dz-search-select-input[aria-invalid="true"]:focus-visible {
  box-shadow: 0 0 0 1px var(--colour-danger);
}

.dz-search-select-spinner {
  position: absolute;
  inset-inline-end: var(--space-md);
  inset-block-start: 50%;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  color: var(--colour-text-muted);
}

.dz-search-select-spinner-icon {
  width: 1rem;
  height: 1rem;
  animation: dz-spin 1s linear infinite;
}

.dz-search-select-results {
  position: absolute;
  z-index: 50;
  width: 100%;
  margin-block-start: 0.25rem;
  max-height: 15rem;
  overflow-y: auto;
  background: var(--colour-surface);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}

.dz-search-select-prompt {
  padding-inline: var(--space-md);
  padding-block: var(--space-md);
  font-size: var(--text-sm);
  color: var(--colour-text-muted);
}

/* Results visibility rides `data-dz-open` on the ROOT (set by
 * dz-search-select.js) — closed at SSR (attribute absent), open on
 * focus, closed 200ms after focus leaves the widget (the grace lets a
 * result-row click land before the panel hides). Root-keyed, NOT
 * input-keyed: the select exchange OOB-replaces the input element, so
 * an input-anchored sibling rule would wedge the panel open after a
 * successful selection. aria-expanded on the input is the a11y mirror. */
.dz-search-select:not([data-dz-open="true"]) .dz-search-select-results {
  display: none;
}
