  /* Homepage-specific styles. Site-wide element rules, the colour-cycle
     keyframes, box-sizing and design tokens now live in css/ (linked
     above); see docs/css-systems/AUDIT.md. */

  /* Search overlay: command-palette style, opened by the search button or Cmd/Ctrl-P */
  .search-overlay {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    /* viewport-fit=cover lets this fixed layer slide under the status
       bar / notch, so the card must clear the top safe-area inset or its
       header is hidden behind the chrome. --safe-top is defined in
       css/tokens.css and overridable per-element via inline style in tests. */
    padding: max(10vh, calc(var(--safe-top) + 1rem)) 1rem 1rem;
    /* A glassy veil instead of a flat black sheet: the site's gradient
       and stars stay visible, just blurred and quietened. Engines
       without backdrop-filter get a darker plain scrim instead (see
       the @supports block below). */
    background: rgba(12, 6, 28, 0.55);
    backdrop-filter: blur(9px) saturate(1.2);
    -webkit-backdrop-filter: blur(9px) saturate(1.2);
    opacity: 1;
    /* The veil fades and the panel springs in/out around the hidden
       attribute. The second declaration upgrades the first where
       display can transition discretely; engines without allow-discrete
       drop it and keep today's instant toggle, losing only the exit
       fade. Focus restore and inert toggling stay synchronous in the
       JS either way - the exit animation is purely cosmetic. */
    transition: opacity 240ms ease;
    transition: opacity 240ms ease, display 340ms allow-discrete;
  }

  .search-overlay[hidden] {
    display: none;
    opacity: 0;
  }

  @starting-style {
    .search-overlay {
      opacity: 0;
    }
  }

  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .search-overlay {
      background: rgba(12, 6, 28, 0.35);
    }
  }

  /* The panel is tinted by --square-colour when a nav square opened it
     (set inline from the square's frozen swatch) and falls back to the
     site cyan for the search palette, so both overlays read as part of
     the same warm, glowing world rather than a foreign grey box. */
  .homepage-search {
    position: relative;
    width: 100%;
    max-width: 36rem;
    margin: 0;
    text-align: left;
    /* Plain fallbacks first: engines without color-mix() drop the
       tinted declarations and keep these readable defaults */
    background: rgba(20, 20, 35, 0.92);
    background: color-mix(in oklab, var(--square-colour, #18C1F3) 16%, rgb(26 16 40 / 0.88));
    border: 1px solid rgba(255, 255, 255, 0.35);
    border: 1px solid color-mix(in oklab, var(--square-colour, #18C1F3) 55%, transparent);
    border-radius: 0.75rem;
    padding: 0.85rem;
    color: #fff;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45);
    box-shadow:
      0 10px 40px rgba(0, 0, 0, 0.35),
      0 0 60px color-mix(in oklab, var(--square-colour, #18C1F3) 25%, transparent);
    transform: none;
    /* Springy arrival (slight overshoot), brisk departure */
    transition:
      transform 340ms cubic-bezier(0.34, 1.3, 0.64, 1),
      opacity 220ms ease-out;
  }

  /* Where the panel flies from / shrinks back to: the square info card
     sets --card-from in JS to the tapped square's exact position and
     size, so the card visibly IS that square expanding. The search
     palette keeps the gentle default rise. */
  .search-overlay[hidden] .homepage-search {
    transform: var(--card-from, scale(0.94) translateY(14px));
    opacity: 0.25;
    transition:
      transform 200ms cubic-bezier(0.55, 0, 0.85, 0.4),
      opacity 200ms ease-in;
  }

  @starting-style {
    .search-overlay .homepage-search {
      transform: var(--card-from, scale(0.94) translateY(14px));
      opacity: 0.25;
    }
  }

  .search-overlay-close {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border: 1px solid color-mix(in oklab, var(--square-colour, #18C1F3) 45%, transparent);
    border-radius: 0.45rem;
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 1rem;
    line-height: 1;
    padding: 0.35rem 0.5rem;
    cursor: pointer;
    transition: background-color 150ms ease, transform 150ms ease;
  }

  .search-overlay-close:hover {
    background: rgba(24, 193, 243, 0.35);
    background: color-mix(in oklab, var(--square-colour, #18C1F3) 35%, transparent);
  }

  .search-overlay-close:active,
  .square-info-card .square-info-link:active {
    transform: scale(0.95);
  }

  /* Tighter gutters for the overlays on small screens */
  @media (max-width: 480px) {
    .search-overlay {
      padding: max(7vh, calc(var(--safe-top) + 1rem)) 0.75rem 1rem;
    }
  }

  .homepage-search label {
    display: block;
    font-weight: 700;
    margin-bottom: 0.35rem;
    padding: 0;
  }

  .homepage-search input {
    width: 100%;
    border-radius: 0.5rem;
    border: 1px solid rgba(255, 255, 255, 0.5);
    background: rgba(17, 17, 17, 0.75);
    color: #fff;
    padding: 0.55rem 0.65rem;
  }

  .homepage-search-status {
    min-height: 1.25rem;
    margin: 0.5rem 0 0;
    padding: 0;
    color: #fef3aa;
    font-size: 0.95rem;
  }

  .homepage-search-results {
    list-style: none;
    margin: 0.4rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.3rem;
    max-height: 50vh;
    overflow-y: auto;
  }

  .homepage-search-results a {
    display: block;
    border-radius: 0.45rem;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.05);
    color: #fff;
    text-decoration: none;
    padding: 0.45rem 0.55rem;
    font-weight: 600;
  }

  .homepage-search-results a small {
    display: block;
    margin-top: 0.2rem;
    color: rgba(255, 255, 255, 0.8);
    font-weight: 400;
  }

  .homepage-search-results a.is-active,
  .homepage-search-results a:hover {
    border-color: rgba(255, 255, 255, 0.75);
    background: rgba(24, 193, 243, 0.35);
  }


