/* Search: the ⌘K dialog, the result rows, and the paged /search/ page.
   Loaded on every org page, so it is deliberately small and holds no styles for
   anything else.

   The dialog element is created by js/search.js on first open, which is why most of
   these selectors appear in no template. Everything is themed through the same
   variables as the rest of the site (see css/theme-terminal.css), so light, dark and
   the terminal skin come for free. */

/* ---- the nav trigger --------------------------------------------------- */

/* A compact icon button, not a mock text field. See the note in nav-org.html for
   the measurement: this bar had ~16px of slack at its widest, and a search box
   shaped like an input consumed all of it. */
.nav-search {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  padding: 7px 10px;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.nav-search:hover { border-color: var(--accent); color: var(--ink); }
.nav-search svg { flex: none; }
.nav-search__kbd {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 5px;
  font-size: 12px;
  line-height: 1.55;
}

/* Mobile drawer variant: the nav button is hidden below the breakpoint where the
   nav collapses, and this takes its place inside the drawer — where it is a
   full-width row with the word, because a lone icon in a list of text links reads
   as decoration. */
.mobile-nav .nav-search {
  width: 100%;
  justify-content: center;
  gap: 10px;
  margin: 10px 0 4px;
  padding: 11px 12px;
  background: var(--surface2);
}

/* ---- the dialog -------------------------------------------------------- */

.s-open, .s-open body { overflow: hidden; }

.s-dialog {
  width: min(760px, calc(100vw - 32px));
  max-height: min(680px, calc(100vh - 80px));
  margin: 8vh auto auto;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  /* TWO layers, not `background: var(--surface)`.
     On the terminal skin --surface is an opaque colour and either form looks the same. On
     flux it is `rgba(255,255,255,.045)` — a glass card designed to sit ON the page — so
     using it directly made the panel 4.5% white over whatever was behind it, and the
     pricing hero read straight through the results. Compositing the same translucent
     surface over the opaque page colour keeps each skin's intended tint while making the
     panel opaque, in light and dark, without hardcoding a colour or touching either theme. */
  background-color: var(--bg);
  background-image: linear-gradient(var(--surface), var(--surface));
  color: var(--ink);
  box-shadow: 0 30px 80px var(--shadow);
  overflow: hidden;
}

.s-dialog::backdrop { background: rgba(0, 0, 0, .62); backdrop-filter: blur(3px); }

.s-form { display: flex; flex-direction: column; max-height: inherit; min-height: 0; }

.s-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--line);
  flex: none;
}

.s-bar__icon { color: var(--muted); flex: none; }

.s-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  padding: 4px 0;
}

.s-input:focus { outline: none; }
.s-input::placeholder { color: var(--muted); }
/* The UA's own clear button duplicates Escape and sits under the close control. */
.s-input::-webkit-search-cancel-button { display: none; }

.s-close {
  flex: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 12.5px;
  padding: 3px 8px;
  cursor: pointer;
}

.s-close:hover { color: var(--ink); border-color: var(--accent); }

.s-results {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 8px 8px;
}

/* ---- groups ------------------------------------------------------------ */

.s-group__label {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 18px 10px 8px;
}

/* A rule above every group but the first: the groups are the primary structure of
   the list, and an uppercase label alone was not enough to see them. */
.s-group + .s-group .s-group__label {
  border-top: 1px solid var(--line);
  margin-top: 6px;
}

/* ---- one result -------------------------------------------------------- */

.s-hit {
  display: block;
  padding: 11px 10px 13px;
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
  border-bottom: none;
}

/* Hairline dividers rather than nothing: without them nine results read as one
   block of text. Inset via box-shadow so the divider does not move when the row
   below it gains the active background. */
.s-hit + .s-hit { box-shadow: inset 0 1px 0 var(--line); }

.s-hit:hover { background: var(--surface2); }

/* The active row is the one Enter follows, so it has to be unmistakable — the
   previous 1px inset ring was invisible against the panel. */
.s-hit.is-active {
  background: var(--surface2);
  box-shadow: inset 2px 0 0 var(--accent);
}

.s-hit.is-active + .s-hit { box-shadow: inset 0 1px 0 var(--line); }

/* Plain inline flow, NOT flex. Highlighting splits the title into several nodes
   ("IMQOptions." + <mark>safeDelivery</mark> + "Ttl"), and as a flex container every
   one of those became a flex item with the container's `gap` between them — the
   identifier rendered as "IMQOptions. safeDelivery Ttl", with spaces that are not
   in the name. Inline flow also wraps for free, which is what the badge needs on a
   375px screen. */
.s-hit__title {
  display: block;
  overflow-wrap: anywhere;
}

/* Prose titles are prose: sentence-shaped, read as sentences, and set in the body
   face. Mono is reserved for identifiers, where the character shapes carry meaning
   — which also makes the face itself a signal of which kind of result a row is. */
.s-hit--docs .s-hit__title,
.s-hit--answers .s-hit__title,
.s-hit--peer .s-hit__title {
  font-family: var(--font-body);
  font-size: 16.5px;
  font-weight: 600;
  line-height: 1.4;
}

.s-hit--api .s-hit__title {
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1.45;
}

.s-hit__kind {
  display: inline-block;
  margin-left: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 5px;
  white-space: nowrap;
  vertical-align: 1px;
}

.s-hit__crumbs {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
  overflow-wrap: anywhere;
}

.s-hit__text {
  display: -webkit-box;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--code);
  margin-top: 6px;
  /* Two lines, so a long answer cannot push the next result off the screen. */
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Highlighting, at two strengths. In a TITLE the match is why the row is here, so
   it gets the accent wash. In the SNIPPET the same treatment marked every
   occurrence of every term and turned the panel green — "redis queue" lit up half
   of it — so there it is weight and colour only. Same information, a tenth of the
   noise. */
.s-hit__title mark {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: inherit;
  border-radius: 2px;
  padding: 0;
}

.s-hit__text mark,
.s-hit__crumbs mark {
  background: none;
  color: var(--ink);
  font-weight: 600;
}

/* A result on the OTHER site. Marked with a left rule rather than a colour, so it reads
   as "elsewhere" without competing with the accent used for matches — and because the two
   editions have different accent colours, so anything hue-based would mean opposite things
   on the two sites. */
.s-hit--peer {
  border-left: 2px solid var(--line);
  padding-left: 12px;
}

.s-hit--peer .s-hit__crumbs { color: var(--muted); }

/* ---- "all N results" --------------------------------------------------- */

.s-more {
  display: block;
  padding: 9px 10px 4px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--accent);
  border-bottom: none;
}

.s-more:hover { text-decoration: underline; }

/* ---- panel furniture --------------------------------------------------- */

.s-empty, .s-hint, .s-status {
  margin: 0;
  padding: 16px 18px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
  flex: none;
}

.s-hint { border-top: 1px solid var(--line); }
.s-hint code {
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--surface2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}

.s-status {
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  padding: 10px 18px;
  min-height: 36px;
}

/* ---- /search/ ---------------------------------------------------------- */

.s-page { max-width: 820px; }

.s-page__form {
  display: flex;
  gap: 10px;
  margin-bottom: 26px;
}

.s-page__input {
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface2);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  padding: 12px 14px;
}

.s-page__input:focus { outline: none; border-color: var(--accent); }
.s-page__input::-webkit-search-cancel-button { display: none; }

.s-page__submit {
  flex: none;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 15px;
  padding: 0 20px;
  cursor: pointer;
}

.s-page__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.s-tab {
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 13px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}

.s-tab:hover { color: var(--ink); border-color: var(--accent); }
.s-tab.is-active {
  color: var(--on-accent);
  background: var(--accent);
  border-color: transparent;
}

.s-page .s-page__status {
  padding: 0 0 14px;
  border-top: 0;
  min-height: 0;
}

.s-page__results { border-top: 1px solid var(--line); }
.s-page__results .s-hit { padding: 16px 12px 18px; border-radius: 10px; }
.s-page__results .s-hit__text { -webkit-line-clamp: 3; }
.s-page .s-empty { padding: 20px 0; }

.s-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.s-pager__item {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 11px;
  font-family: var(--font-mono);
  font-size: 13.5px;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.s-pager__item:hover { border-color: var(--accent); }
.s-pager__item.is-current {
  background: var(--accent);
  color: var(--on-accent);
  border-color: transparent;
}
.s-pager__item.is-disabled { color: var(--muted); opacity: .5; }

/* ---- responsive -------------------------------------------------------- */

@media (max-width: 900px) {
  .nav-search { display: none; }

  /* …and back on for the drawer copy. The rule above hides both triggers, and the
     `.mobile-nav .nav-search` block at the top of this file restyles this one but
     never re-declares `display` — so the drawer row rendered 0x0 and a phone had no
     way into search at all: no header icon, no drawer row, and `/` needs a keyboard. */
  .mobile-nav .nav-search { display: inline-flex; }
}

/* Phones get the whole screen. `inset: 0` with `margin: 0` is the part that
   actually does it: a <dialog> is centred by `margin: auto` in the UA stylesheet,
   so setting only width/height leaves it laid out against the initial containing
   block and short of one edge. `dvh` after `vh` so the dialog is not taller than
   the visible area once a mobile browser's URL bar is showing. */
@media (max-width: 640px) {
  .s-dialog {
    inset: 0;
    margin: 0;
    width: 100%;
    max-width: none;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    border: 0;
    border-radius: 0;
  }

  .s-form { height: 100%; max-height: none; }

  /* The hint is two lines of instructions on a screen that has room for two more
     results instead. It is still shown before anything is typed. */
  .s-results:not(:empty) ~ .s-hint { display: none; }

  .s-page__form { flex-wrap: wrap; }
  .s-page__submit { width: 100%; padding: 12px 20px; }
}

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