/* =============================================================================
   search.css — header search trigger + overlay panel.
   Paired with js/search.js and the /search-index.json emitted by build.mjs.
   ============================================================================ */

/* ---- trigger (sits in the utility bar, right side) ---- */
/* Matches .utility-phone / .utility-catalog exactly. `color: inherit` does NOT
   work here: a <button> does not inherit the bar's white from an ancestor the
   way the sibling <a> elements do — it picked up the dark body text colour and
   rendered near-black (#0F172A) on navy (#061A34), about 1.2:1 contrast, i.e.
   invisible. Set the colour explicitly. */
.utility-search {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  color: #ffffff;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.utility-search .icon { color: #ffd9a3; flex-shrink: 0; }
.utility-search:hover { text-decoration: underline; }
/* Icon only on small screens — the utility bar overflows once Search, Campus
   Safety, Catalog and Portal all carry labels. The magnifier is understood
   without text, and aria-label on the button keeps it announced. */
.utility-search > span { display: none; }
@media (min-width: 560px) { .utility-search > span { display: inline; } }
.utility-search:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Campus Safety sits in the utility bar on wider screens. Below 900px it would
   overflow the bar, so it is hidden here and appears in the mobile menu
   instead (see the mobile-menu list in shell.mjs) — it stays reachable at
   every width, which is the whole point of surfacing it. */
.utility-safety {
  display: none;
  align-items: center;
  gap: 0.4rem;
  /* Explicit white for the same reason as .utility-search: without it this
     fell back to the default link blue (#2172C1), ~2.8:1 on navy, under the
     4.5:1 AA minimum and visibly out of step with its siblings. */
  color: #ffffff;
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.utility-safety .icon { color: #ffd9a3; flex-shrink: 0; }
.utility-safety:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.utility-safety:focus-visible { outline: 3px solid #ffffff; outline-offset: 2px; border-radius: var(--radius-sm); }
@media (min-width: 900px) { .utility-safety { display: inline-flex; } }

/* ---- overlay ---- */
.search-panel {
  position: fixed;
  inset: 0;
  /* Must sit above the sticky header (--z-header: 200) and the cookie banner
     (--z-cookie: 400). At 200 it tied with the header and lost on DOM order,
     which clipped the search input behind it. */
  z-index: var(--z-modal);
  background: rgba(11, 26, 51, .55);
  display: grid;
  align-items: start;
  justify-items: center;
  padding: clamp(var(--space-4), 8vh, var(--space-10)) var(--space-3) var(--space-4);
  overflow-y: auto;
}
.search-panel[hidden] { display: none; }
body.search-open { overflow: hidden; }

.search-dialog {
  width: min(680px, 100%);
  background: var(--color-bg, #fff);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}

.search-dialog__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.search-dialog__icon { color: var(--color-text-muted); flex: none; }

.search-input {
  flex: 1;
  font: inherit;
  font-size: var(--text-lg);
  border: 0;
  padding: .35rem 0;
  background: transparent;
  color: var(--color-text);
}
.search-input:focus { outline: none; }
.search-input::placeholder { color: var(--color-text-muted); }

.search-close {
  flex: none;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-sm);
  padding: .3rem .6rem;
  cursor: pointer;
}
.search-close:hover { background: var(--color-surface); color: var(--color-text); }
.search-close:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

.search-status {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  border-bottom: 1px solid var(--color-border);
}
.search-status:empty { display: none; }

.search-results {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: min(52vh, 460px);
  overflow-y: auto;
}
.search-results:empty { display: none; }
.search-results li + li { border-top: 1px solid var(--color-border); }

.search-results a {
  display: grid;
  gap: .2rem;
  padding: var(--space-3);
  text-decoration: none;
  color: var(--color-text);
}
.search-results a:hover,
.search-results li.is-active a { background: var(--color-surface); }
.search-results a:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }

.search-result__title {
  font-family: var(--font-headline);
  font-weight: 600;
  color: var(--color-primary);
}
.search-result__snippet {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: 1.45;
}
.search-result__path {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  opacity: .8;
}
.search-results mark {
  background: var(--color-orange-subtle, #ffe9d1);
  color: inherit;
  padding: 0 .1em;
  border-radius: 2px;
}

.search-hint {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
}

@media (prefers-reduced-motion: no-preference) {
  .search-dialog { animation: search-in .14s ease-out; }
  @keyframes search-in {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: none; }
  }
}
