@layer components {
  /* Command palette (J) — the app's primary navigation.
     The trigger keycap sits with the dock/sidebar toggles in the header; the
     panel is a native popover, so top layer, Esc and light-dismiss come free. */

  .palette__toggle {
    /* Real <button> like .dock__full-toggle: strip the chrome to a keycap. */
    align-items: center;
    anchor-name: --palette;
    background: none;
    border: 0;
    color: var(--color-ink);
    cursor: pointer;
    display: inline-flex;
    font: inherit;
    padding: 0;
    position: relative;
  }

  /* Unread/unseen indicator — the same dot the hamburger carried. */
  /* Brand mark + chevron trigger (BC-style): the K keycap pops in between on
     Shift. The favicon is a black disc — inverted for dark themes. */
  .palette__toggle img {
    block-size: 1.2em;
    border-radius: 50%;

    html[data-theme="dark"] & {
      filter: invert(1);
    }

    @media (prefers-color-scheme: dark) {
      html:not([data-theme]) & {
        filter: invert(1);
      }
    }
  }

  .palette__chevron {
    font-size: 0.55em;
  }

  .palette__toggle.has-news::after {
    --size: 0.5em;

    aspect-ratio: 1;
    background-color: var(--color-blue);
    border-radius: 50%;
    content: "";
    inline-size: var(--size);
    inset-block-start: -0.1em;
    inset-inline-end: -0.15em;
    position: absolute;
  }

  .palette {
    /* Drops open at the trigger keycap: the button sits under the panel's
       top-right corner, the way Fizzy's jump menu pops from its trigger. */
    position-anchor: --palette;
    margin: 0;
    inset: auto;
    inset-block-start: calc(anchor(top, 0.65rem) - 0.35rem);
    inset-inline-end: calc(anchor(right, var(--inline-space)) - 0.5ch);
    position-try-fallbacks: flip-inline;

    background: var(--color-bg);
    border: var(--border);
    border-radius: 1.25em;
    box-shadow:
      0 0 0 1px oklch(var(--lch-always-black) / 0.04),
      0 0.4em 1.2em -0.4em oklch(var(--lch-always-black) / 0.15),
      0 1em 3em -1em oklch(var(--lch-always-black) / 0.35);
    flex-direction: column;
    gap: var(--block-space-half);
    inline-size: min(52ch, 94vw);
    max-block-size: min(75dvh, 42rem);
    padding: var(--block-space) var(--inline-space);
    /* Closed, the inherited pointer-events guards the tiles' global number
       hotkeys: hotkey#click ignores elements computing pointer-events: none. */
    pointer-events: none;

    opacity: 0;
    transform: scale(0.95) translateY(-0.35rem);
    transform-origin: top right;
    transition: 0.2s allow-discrete;
    transition-property: display, opacity, overlay, transform;

    &:popover-open {
      display: flex;
      opacity: 1;
      pointer-events: auto;
      transform: none;
    }

    @starting-style {
      &:popover-open {
        opacity: 0;
        transform: scale(0.95) translateY(-0.35rem);
      }
    }

    /* Narrow screens: a top sheet spanning the viewport (Fizzy's jump menu),
       dvh-capped so the browser chrome never clips it — the list scrolls
       inside .palette__scroll. Explicit insets make the anchor() rules inert. */
    @media (max-width: 50rem) {
      inset-block-start: var(--block-space-half);
      inset-inline: var(--inline-space);
      inline-size: auto;
      max-block-size: calc(100dvh - var(--block-space));
      transform-origin: top center;
    }
  }

  /* Search + touch-only close. The bar opts out of the column flex shrink so
     the list scrolls, not the search field. */
  .palette__bar {
    align-items: center;
    display: flex;
    flex-shrink: 0;
    gap: var(--inline-space-half);
  }

  .palette__search {
    flex-grow: 1;
    min-inline-size: 0;
  }

  /* Only touch devices see the close button — pointer users have Esc and
     light-dismiss (Fizzy's nav__close media-query trick). */
  .palette__close {
    background: none;
    border: var(--border);
    border-radius: 50%;
    color: var(--color-ink);
    cursor: pointer;
    flex-shrink: 0;
    font-size: 1em;
    line-height: 1;
    padding: 0.55em;

    @media (any-hover: hover) {
      display: none;
    }
  }

  .palette__scroll {
    display: flex;
    flex-direction: column;
    gap: var(--block-space-half);
    min-block-size: 0;
    overflow-y: auto;
  }

  .palette turbo-frame {
    display: block;
  }

  .palette__tiles {
    --gap: 0.5rem;

    display: flex;
    flex-wrap: wrap;
    gap: var(--gap);

    /* Collapse the row once the filter hides every tile. */
    &:not(:has(.palette__tile:not([hidden]))) {
      display: none;
    }
  }

  .palette__tile {
    align-items: center;
    aspect-ratio: 5 / 3;
    background-color: var(--color-gray-light);
    border-radius: 0.5em;
    color: var(--color-ink-dark);
    display: flex;
    /* Fixed thirds (like Fizzy): a lone tile left by the filter keeps its
       size instead of stretching across the whole panel. */
    flex: 0 1 calc((100% - var(--gap) * 2) / 3);
    flex-direction: column;
    font-size: var(--font-small-responsive);
    gap: 0.4em;
    justify-content: center;
    min-inline-size: 0;
    position: relative;
    text-align: center;
    text-decoration: none;

    &[hidden] {
      display: none;
    }

    &:hover {
      background-color: var(--color-gray);
    }

    &[aria-selected] {
      background-color: var(--color-blue-light);
    }

    i {
      color: var(--color-gray-dark);
      font-size: 1.4em;
    }

    kbd {
      border-color: transparent;
      box-shadow: none;
      font-size: 0.7em;
      inset-block-start: 0.4em;
      inset-inline-end: 0.4em;
      opacity: 0.6;
      position: absolute;
    }
  }

  .palette__section {
    padding-block: var(--block-space-half);

    &:has(+ .palette__section) {
      border-block-end: var(--border);
    }

    /* Sections whose every row is filtered out disappear with them. */
    &:not(:has(.palette__item:not([hidden]))) {
      display: none;
    }
  }

  .palette__label {
    color: var(--color-gray-dark);
    display: block;
    font-size: var(--font-x-small-responsive);
    letter-spacing: 0.05em;
    margin-block-end: var(--block-space-third);
    text-transform: uppercase;
  }

  .palette__list {
    display: flex;
    flex-direction: column;
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .palette__item {
    border-radius: var(--border-radius);

    &:hover,
    /* Rows the browser focuses (e.g. the avatar menu's first link on open)
       highlight like hover instead of drawing the global focus ring. */
    &:has(:focus-visible) {
      background-color: var(--color-gray-light);
    }

    &[aria-selected] {
      background-color: var(--color-blue-light);
    }

    /* button covers button_to rows (avatar menu's Abmelden). */
    :is(a, button) {
      align-items: center;
      background: none;
      border: 0;
      color: var(--color-ink-dark);
      cursor: pointer;
      display: flex;
      font: inherit;
      gap: 1em;
      inline-size: 100%;
      min-inline-size: 0;
      padding: var(--block-space-third) var(--inline-space);
      text-align: start;
      text-decoration: none;

      &:focus-visible {
        outline: none;
      }
    }

    form {
      display: contents;
    }

    i {
      color: var(--color-gray-dark);
      flex-shrink: 0;
      inline-size: 1.5em;
      text-align: center;
    }
  }

  /* Cross-account rows: which Vergabestelle a hit belongs to. Capped so a long
     account name can never crowd out the record name. */
  .palette__context {
    color: var(--color-gray-dark);
    flex-shrink: 0;
    font-size: var(--font-x-small-responsive);
    margin-inline-start: auto;
    max-inline-size: 35%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .palette__dot {
    aspect-ratio: 1;
    background-color: var(--color-blue);
    border-radius: 50%;
    flex-shrink: 0;
    inline-size: 0.5em;
  }

  .palette__check {
    color: var(--color-green);
    margin-inline-start: auto;
  }

  .palette__blank-slate {
    color: var(--color-ink-muted);
    padding-block: var(--block-space);
    text-align: center;
  }

  /* The blank slate only surfaces when nothing at all matches the filter. */
  .palette:has(.palette__item:not([hidden])) .palette__blank-slate,
  .palette:has(.palette__tile:not([hidden])) .palette__blank-slate {
    display: none;
  }

  /* Theme switch for signed-out visitors (authenticated ones use the avatar
     menu), parked below the results with a hairline separator. */
  .palette__theme {
    display: flex;
    justify-content: center;
    padding-block-start: var(--block-space-half);
    border-block-start: var(--border);
  }
}
