/* =============================================================================
   DDG · components/search-autocomplete.css
   Live results panel under the header search field, plus the submit button's
   loading state.

   NOT @imported by main.css — this is enqueued separately in functions.php,
   because the autocomplete only exists under WordPress (it needs the
   ddg/v1/search route) and main.css is shared with the static build. It still
   declares @layer components, so it lands in the same cascade tier as
   header.css and needs no specificity games to sit on top of it.

   The panel markup is built by assets/js/search-autocomplete.js and appended
   inside .search-form, which header.css already makes position: relative.
   ========================================================================== */

@layer components {

  /* =========================================================================
     RESULTS PANEL
     Anchored to the field group, so it inherits the form's width for free:
     910px inside the desktop overlay, the drawer's width on mobile.
     max-height is set inline by the script — it depends on where the field has
     landed on screen, which CSS cannot know.
     ====================================================================== */
  .search-results {
    position: absolute;
    inset-inline: 0;
    inset-block-start: calc(100% + var(--space-8));
    z-index: 10;                      /* above the field group, inside the form */
    overflow-y: auto;
    overscroll-behavior: contain;     /* scrolling the list never scrolls the page */
    padding-block: var(--space-8);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: 0 12px 32px rgb(var(--ddg-navy-rgb) / 0.18);
    text-align: start;                /* the desktop overlay centres its form */
  }
  .search-results[hidden] { display: none; }

  /* Post type heading — "Posts", "Projects". Text comes from the post type's
     own registered label, so it follows a rename in ACF. */
  .search-results__group {
    margin: 0;
    padding: var(--space-12) var(--space-16) var(--space-8);
    font-size: 0.6875rem;             /* 11px */
    font-weight: var(--fw-extrabold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: rgb(var(--ddg-navy-rgb) / 0.5);
  }
  .search-results__group + .search-results__list { margin-block-start: 0; }

  .search-results__list { margin: 0; padding: 0; list-style: none; }
  .search-results__item { margin: 0; }

  .search-results__link {
    display: block;
    padding: var(--space-8) var(--space-16);
    font-size: var(--fs-14);
    font-weight: var(--fw-medium);
    line-height: 1.4;
    color: var(--color-text);
    text-decoration: none;
    transition: background var(--transition-fast), color var(--transition-fast);
  }

  /* Hover and keyboard focus land on the SAME visual state, so arrowing
     through the list looks identical to pointing at it. */
  .search-results__link:hover,
  .search-results__link.is-active,
  .search-results__link:focus-visible {
    background: rgb(var(--ddg-blue-rgb) / 0.08);
    color: var(--color-link-hover);
    outline: none;
  }

  /* The matched run, wrapped in <b> by the script. */
  .search-results__link b {
    font-weight: var(--fw-extrabold);
    color: var(--color-link-hover);
  }

  .search-results__empty {
    margin: 0;
    padding: var(--space-12) var(--space-16);
    font-size: var(--fs-14);
    font-weight: var(--fw-medium);
    color: rgb(var(--ddg-navy-rgb) / 0.6);
  }

  /* =========================================================================
     SUBMIT BUTTON — magnifier <-> spinner

     NO LAYOUT SHIFT, by construction: the icon never leaves the flow and the
     spinner never enters it. The <svg> keeps its box and only fades, while the
     spinner is absolutely centred on top of it. Nothing is measured, nothing
     reflows — the swap is two opacity transitions on the compositor.

     currentColor is what makes one rule serve both skins: the button is navy
     with a white icon in the drawer and white with a navy icon in the desktop
     overlay, and the ring follows automatically.
     ====================================================================== */
  .search-submit { position: relative; }

  .search-submit > svg {
    transition: opacity var(--transition-fast), transform var(--transition-fast);
  }
  .search-submit.is-loading > svg {
    opacity: 0;
    transform: scale(0.7);
  }

  /* header.css ships this span hidden; it becomes the ring here. Borrowing
     ddg-spin from components/spinner.css rather than declaring a second
     identical keyframe — @keyframes names are document-global. */
  .search-submit .search-loading-icon {
    display: block;
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    inline-size: 18px;
    block-size: 18px;
    margin-block-start: -9px;
    margin-inline-start: -9px;
    border: 2px solid currentColor;
    border-block-start-color: transparent;   /* the gap that reads as motion */
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition-fast);
  }
  .search-submit.is-loading .search-loading-icon {
    opacity: 1;
    animation: ddg-spin 700ms linear infinite;
  }

  /* Matches spinner.css's approach: stop rotating, pulse instead. */
  @media (prefers-reduced-motion: reduce) {
    .search-submit > svg,
    .search-submit .search-loading-icon { transition: none; }

    .search-submit.is-loading .search-loading-icon {
      border-block-start-color: currentColor;
      opacity: 0.5;
      animation: ddg-pulse 1.2s ease-in-out infinite;
    }
  }
}
