/* =========================================================
   Canonical menu/dropdown popover — THE one menu system (D50).
   Loaded globally from base.html. Covers the action/toggle menus
   (user, sidebar, kebab, report-row, download-split, rail filter);
   the SELECT pickers (.sel-*, .etp) are a separate component.
   Behavior helpers (flip-clamp placement, arrow-key nav) in
   static/js/ui_menu.js. Feature skins stay scoped in their files.
   ========================================================= */

.menu {
  position: absolute;            /* anchored under a relative trigger */
  min-width: 200px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);   /* card-tier radius (refresh Δ1) */
  box-shadow: var(--sh-2);
  padding: var(--sp-1);
  z-index: var(--z-menu);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--fg);
  animation: menu-in 140ms var(--ease);
}
.menu[hidden] { display: none; }
.menu--fixed { position: fixed; }        /* body-appended, JS-placed */
.menu--wide { min-width: 240px; }
/* Menus that can anchor INSIDE an open modal (the summary rows' ⋯ kebab)
   must clear --z-modal — scale-derived, same idiom as .modal--blocking. */
.menu--above-modal { z-index: calc(var(--z-modal) + 1); }
/* Picker-hosting menu (in-modal type change, shield_review.js): the panel wraps
   the .etp category combobox instead of menu__items. Roomy for the search input
   + grouped list; overflow visible so the .etp-list drops OUT of the panel
   (the known .etp-list clip gotcha). */
.menu--picker { min-width: 264px; padding: var(--sp-2); overflow: visible; }
/* Flyout submenu (2026-07-21). A MODIFIER on the canonical menu, never a second
   menu system: it inherits the field, radius, shadow, padding and item grammar
   and adds only placement. `window.UIMenu.placeSub` side-places it beside its
   parent row and flips left when the right edge runs out.

   Above the inline breakpoint it is fixed like any body-placed popover. It must
   also out-stack its PARENT menu, which already sits at --z-menu — a submenu
   that renders behind the menu it belongs to is invisible. Same scale-derived
   idiom as --above-modal; still never a bare integer. */
.menu--sub {
  /* ABSOLUTE, not fixed, and anchored to `.user-menu-sub-host`. The parent
     `.menu` animates with `transform: translateY()`, and a transformed ancestor
     becomes the containing block for a fixed descendant — a fixed flyout would
     silently resolve against the menu instead of the viewport and land off
     screen. Absolute against the host is immune to that AND rides the parent's
     open animation instead of detaching from it. */
  position: absolute;
  top: 0;
  left: calc(100% + var(--sp-2));
  min-width: 200px;
  z-index: calc(var(--z-menu) + 1);
}
/* Flip side when the right edge runs out (JS sets the attribute). */
.menu--sub[data-sub-side="left"] {
  left: auto;
  right: calc(100% + var(--sp-2));
}
/* ≤900px: nothing to fly out INTO beside the rail, so the same element opens
   inline as an accordion under its trigger. position:static makes the JS-written
   top/left inert (placeSub also clears them), the shadow would be wrong on a
   nested panel, and the inset field + rule tie the group to its parent row. */
@media (max-width: 900px) {
  .menu--sub,
  .menu--sub[data-sub-side="left"] {
    position: static;
    inset: auto;
    min-width: 0;
    margin: var(--sp-1) 0 var(--sp-1) var(--sp-5);
    border: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    padding: 0;
    animation: none;
  }
}
@keyframes menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .menu { animation: none; }
}

.menu__item {
  appearance: none;
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  text-align: left;
  color: var(--fg);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.menu__item:hover { background: var(--surface-muted); }
.menu__item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.menu__item--danger { color: var(--danger); }
.menu__item--danger:hover { background: var(--danger-soft-bg); }
.menu__item svg { flex: none; color: var(--fg-3); }

/* Toggle items (filter/sort menus): leading check slot shown when checked. */
.menu__check { width: 16px; flex: none; visibility: hidden; }
.menu__item[aria-checked="true"] .menu__check { visibility: visible; }

.menu__sep {
  height: 1px;
  background: var(--border);
  margin: var(--sp-1) 0;
  border: 0;
}
.menu__label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-3);
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
}
.menu__sub {
  display: block;
  font-size: var(--fs-micro);
  color: var(--fg-3);
  margin-top: 2px;
}
.menu__count {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--fg-3);
}

/* Trailing keyboard-shortcut slot (pattern study O3, D52): right-aligned mono
   hint on power-tool items. Capability only — no product menu adopts it yet;
   specimen lives on /styleguide. */
.menu__kbd {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg-3);
  letter-spacing: 0.04em;
}
