/* ——— Popups ———
   A float that belongs to the control that opened it: the ⋯ menu on a card,
   the palette under the way anywhere. Always a popover, never a <dialog> — a
   thing belonging to one button must not dim the page, must close when you
   click away, and must hang off what you pressed. The first two come free with
   `popover`; the third is what the anchor gives.

   The trigger names itself (`style="anchor-name: --x"`) and the popup points
   back at it. That inline style is the one thing CSS cannot say for us: an
   anchor name identifies a single element, and there is a fresh one per card.

   Callers retune, they do not restate — a menu hangs off its button's end
   corner, the palette centres under its pill, and both say so in one custom
   property. */
@layer components {
  .popup {
    position: absolute;
    /* The UA sheet pins [popover] to inset: 0, which would stretch the popup
       across the whole placement area instead of sitting it inside.

       position-area, not a pair of anchor() insets: the logical anchor sides
       silently resolve to nothing in Chrome 140 and the popup drops to the
       page origin — which looks exactly like the centred-modal bug this
       replaced, so it is worth naming. */
    inset: auto;
    position-area: var(--popup-area, block-end);
    /* Near the bottom of the viewport it opens upwards instead; the tactic
       flips the margin with it, so the gap stays on the trigger's side. A
       caller that can also meet a side edge adds the inline flips through
       the property, as it sets its area. */
    position-try-fallbacks: var(--popup-try, flip-block);
    margin-block-start: var(--block-space-half);
    /* No popup outgrows the screen it hangs over — a phone first of all. */
    max-inline-size: calc(100dvw - var(--inline-space-double));
    max-block-size: 80dvh;
    overflow-y: auto;
    /* A float is denser than the sheet it covers, in both axes (user,
       2026-08-11 — the ⋯ menu read as body copy, then as too airy once it
       stopped). A menu row is a verb you are picking, not prose you are
       reading.

       The rhythm is retuned by the token, never by new padding rules — the
       mechanism .todos already uses, and the reason --block-space-half is
       derived per element rather than at :root. Halving it here tightens every
       row, separator and footer in one line and keeps them in proportion.

       Said once on .popup rather than per menu: the ⋯ dialog, the person
       picker, the combobox and the palette all wear it, and three
       near-identical font-size lines is precisely the drift this avoids. */
    --block-space: 0.5rem;

    padding: var(--block-space-half);
    color: var(--color-ink);
    font-size: var(--text-small);
    background-color: var(--color-canvas);
    border: var(--border);
    border-radius: var(--border-radius-float);
    box-shadow: var(--shadow);

    /* A popover's backdrop is transparent already, and stays that way: a popup
       is a way through the page, not an interruption of it.

       Dialog speed by HANSHI's clock. Both overlay and display have to be told
       to hold, or the fade out never gets to run. */
    opacity: 0;
    transition:
      opacity var(--speed-quick) var(--ease-out),
      overlay var(--speed-quick) allow-discrete,
      display var(--speed-quick) allow-discrete;

    &:popover-open {
      opacity: 1;

      @starting-style {
        opacity: 0;
      }
    }
  }

  /* Every popup hanging off the fixed bar — the trays, the avatar's account
     menu — lives in viewport coordinates like the bar itself. Absolute is
     document coordinates: right for a popup on page content, and a drift of
     exactly the scroll offset for one whose anchor holds still in fixed
     chrome. In this file and not layout.css because layout sits in the base
     layer and this must win in components — dialog.css makes the same move
     for the same menu's area. */
  #footer .popup {
    position: fixed;
  }

  /* Without anchor positioning there is nothing to hang from, so the popup
     stops pretending and centres itself. Everything it offers still works. */
  @supports not (anchor-name: --supported) {
    .popup {
      position: fixed;
      inset: 0;
      margin: auto;
      block-size: fit-content;
      inline-size: fit-content;
    }
  }

  /* A keyboard hint on a keyboardless screen: the ⋯ dialog's footer IS the
     dismiss line, and it stands down wherever no esc exists — said once here
     for both of the popups that draw one (user, 2026-08-24).

     `.action-dialog footer`, not `.popup footer`: the premise "a popup's
     footer is always the dismiss line" stopped being true when the tray grew
     a real one, so on a touch screen the rule took "See all my tasks" off
     my/_tray with it and the tray's only way through to the page was gone
     (user, 2026-08-29). The dismiss line has one home and this is it —
     shared/_action_dialog and chat_messages/_actions, which wears the same
     class; dialog.css styles it from inside the same scope. */
  @media (hover: none) {
    .action-dialog footer {
      display: none;
    }
  }
}
