/* ============================================================================
   MENU — shared compound (single source of truth).
   A MENU-BUTTON + dropdown PANEL: a trigger carrying arbitrary content on its
   face (an avatar + identity, a "⋯ more" glyph, an icon) that opens a floating
   panel of `role="menuitem"` actions — plus an optional custom panel head.

   This is the ACTION sibling of the combobox (`_select`): the combobox SELECTS a
   value (role=listbox, aria-activedescendant, value commits back to the trigger);
   the menu FIRES actions (role=menu, DOM focus moves to items, nothing commits to
   the face). They deliberately share the same floating-panel motion recipe.

   Pair with _menu.js (ARIA menu-button controller: open/close, roving focus,
   dismiss, viewport-flip) + _menu.config.js (FP_COMPOUNDS.menu — motion presets +
   the Inspector schema). Load AFTER colors_and_type.css.

   Structure:
     .menu[data-menu]                wrapper the controller wires (position anchor)
       .menu-trigger                 the button (aria-haspopup=menu, aria-expanded)
         …custom face…  .menu-trigger__chev   (optional rotating chevron)
       .menu-panel  [role=menu]      the floating panel
         .menu-panel__head           (optional custom header — identity, title…)
         .menu-item   [role=menuitem]   action (button OR <a>)
         .menu-sep    [role=separator]
   Modifiers:  .menu-item--danger (destructive) · .menu-panel--end / --start
   Motion:  data-menu-motion="slide|zoom|both|fade" on the wrapper (default slide)
   ============================================================================ */

@layer tokens {
  :root {
    /* Motion — read at play time; governor-scaled, Inspector-tunable. DEFAULT =
       the "deliberate" preset (slide + fade), settled Jun 2026. */
    --mnu-dur: 280ms;                              /* @kind other */  /* open */
    --mnu-close-dur: 180ms;                        /* @kind other */  /* close */
    --mnu-ease: cubic-bezier(0.22, 1, 0.36, 1);    /* @kind other */  /* open spring */
    --mnu-close-ease: cubic-bezier(0.4, 0, 1, 1);  /* @kind other */  /* close (accelerate) */
    --mnu-shift: 9px;        /* @kind spacing */
    --mnu-scale: 0.92;       /* @kind other */
  }
}

/* ── Wrapper ──────────────────────────────────────────────────────────────── */
.menu { position: relative; display: inline-flex; }

/* ── Trigger ──────────────────────────────────────────────────────────────── */
.menu-trigger {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 4px 8px 4px 5px;
  background: transparent;
  border: var(--bw-control, 1px) solid var(--color-border-default);
  border-radius: var(--radius-control, var(--radius-md));
  color: var(--color-fg-default);
  cursor: pointer; user-select: none; -webkit-user-select: none;
  /* box-shadow joins the base transition so the focus ring BLOOMS (system
     pattern); the spring easing comes from the focus rule below. */
  transition: background-color 120ms ease, border-color 120ms ease,
              box-shadow 140ms ease-out;
}
/* hover + forced hover share one rule (unified state model). */
.menu-trigger:hover:not(:disabled):not([data-state~="disabled"]),
.menu-trigger[data-state~="hover"] {
  background: var(--gov-color-neutral-100); border-color: var(--gov-color-neutral-300);
}
.menu-trigger:active:not(:disabled),
.menu-trigger[data-state~="pressed"] {
  background: var(--gov-color-neutral-200, var(--gov-color-neutral-100)); border-color: var(--gov-color-neutral-300);
}
/* open = anchored state (reads like hover, holds while the panel is up). */
.menu[data-open] > .menu-trigger { background: var(--gov-color-neutral-100); border-color: var(--gov-color-neutral-300); }
/* Focus-ring bloom — live :focus-visible, the forced [data-state~=focus] channel,
   AND the .is-focus modifier (added by _force-state.js FOCUS_TARGETS). */
.menu-trigger:focus-visible,
.menu-trigger[data-state~="focus"],
.menu-trigger.is-focus {
  outline: none;
  box-shadow: var(--shadow-focus, 0 0 0 3px rgba(35,98,162,0.35));
  border-color: var(--gov-color-primary-500);
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 140ms ease-out, background-color 120ms ease;
}
.menu-trigger:disabled,
.menu-trigger[data-state~="disabled"] { color: var(--color-fg-tertiary); cursor: not-allowed; opacity: 0.6; }

/* Chevron — composes the open-rotate + a focus/hover nudge through one
   `transform` list (always rotate+scale, same order, so it interpolates
   cleanly), mirroring the combobox chevron. */
.menu-trigger__chev {
  font-size: 11px; color: var(--color-fg-tertiary); flex: none; margin-left: 1px;
  transform: rotate(0deg) scale(1);
  -webkit-text-stroke: 0 currentColor;
  transition: color 120ms linear,
              transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
              -webkit-text-stroke-width 160ms ease-out;
}
.menu-trigger:hover:not(:disabled) .menu-trigger__chev,
.menu-trigger[data-state~="hover"] .menu-trigger__chev,
.menu-trigger:focus-visible .menu-trigger__chev,
.menu-trigger[data-state~="focus"] .menu-trigger__chev,
.menu-trigger.is-focus .menu-trigger__chev {
  color: var(--gov-color-primary-500);
  transform: rotate(0deg) scale(1.18);
  -webkit-text-stroke-width: 0.4px;
}
.menu[data-open] > .menu-trigger .menu-trigger__chev {
  color: var(--gov-color-primary-500);
  transform: rotate(180deg) scale(1.12);
  -webkit-text-stroke-width: 0.4px;
}

/* ── Panel ────────────────────────────────────────────────────────────────
   Stays in the layout when closed (display:block + opacity/visibility) so the
   CLOSE transition has an end-state to interpolate to. `visibility:hidden` with
   a delay == the close duration makes it non-interactive once faded out. The
   closed transform (`--_t`) is set per motion variant; the open state is always
   the resting transform (none). Mirrors the _select dropdown. */
.menu-panel {
  position: absolute; top: calc(100% + 8px); right: 0;
  min-width: 232px; max-width: min(92vw, 340px);
  background: var(--color-bg-surface, #fff);
  border: var(--bw-panel, 1px) solid var(--color-border-default);
  border-radius: var(--radius-overlay, var(--radius-lg));
  box-shadow: var(--shadow-3, 0 12px 32px rgba(12,24,56,0.16), 0 4px 10px rgba(12,24,56,0.08));
  padding: 6px;
  /* Floats above page content; the open state lifts higher still so a dropdown
     never sits under later static content (e.g. the spec page's inline panel).
     Stays BELOW the standalone chrome cluster (z 9999) + version badge (9000). */
  z-index: 1000;
  /* closed state */
  --_t: translateY(calc(-1 * var(--mnu-shift)));
  transform-origin: top right;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: var(--_t);
  transition: opacity var(--mnu-close-dur) var(--mnu-close-ease),
              transform var(--mnu-close-dur) var(--mnu-close-ease),
              visibility 0s linear var(--mnu-close-dur);
}
/* Author anchor preference (also read by _menu.js place() to seed data-h). */
.menu-panel--start { right: auto; left: 0; transform-origin: top left; }
.menu-panel--end   { right: 0; left: auto; }

/* Inline showcase variant — sits in normal flow (no floating / no motion gate),
   always visible, so a spec page can display the open panel + its item states
   without the open/close behaviour. Mirrors .modal-scrim--inline. */
.menu-panel--inline {
  position: static; min-width: 0;
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: none; transition: none;
}

/* Motion variants — only the CLOSED transform differs. */
.menu[data-menu-motion="fade"] .menu-panel { --_t: none; }
.menu[data-menu-motion="zoom"] .menu-panel { --_t: scale(var(--mnu-scale)); }
.menu[data-menu-motion="both"] .menu-panel { --_t: translateY(calc(-1 * var(--mnu-shift))) scale(var(--mnu-scale)); }

/* Open — lifts above all page content (below chrome). */
.menu[data-open] .menu-panel {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: none;
  z-index: 8000;
  transition: opacity var(--mnu-dur) var(--mnu-ease),
              transform var(--mnu-dur) var(--mnu-ease),
              visibility 0s linear 0s;
}

/* ── Resolved placement (set by _menu.js place() on open; KEPT through close so
   the close animation plays in the same spot + direction). data-h = anchor side,
   data-v = above/below. Drives position + transform-origin + slide direction.
   Horizontal + vertical flip keep the panel on-screen. ─────────────────────── */
.menu-panel[data-h="end"]   { right: 0; left: auto; }
.menu-panel[data-h="start"] { left: 0; right: auto; }
.menu-panel[data-v="down"]  { top: calc(100% + 8px); bottom: auto; }
.menu-panel[data-v="up"]    { top: auto; bottom: calc(100% + 8px); }
.menu-panel[data-v="down"][data-h="end"]   { transform-origin: top right; }
.menu-panel[data-v="down"][data-h="start"] { transform-origin: top left; }
.menu-panel[data-v="up"][data-h="end"]     { transform-origin: bottom right; }
.menu-panel[data-v="up"][data-h="start"]   { transform-origin: bottom left; }
/* Opening ABOVE — slide/zoom enters from BELOW (+shift) instead of above. */
.menu[data-menu-motion="slide"] .menu-panel[data-v="up"],
.menu[data-menu-motion="both"]  .menu-panel[data-v="up"] { --_t: translateY(var(--mnu-shift)) scale(var(--mnu-scale, 1)); }
.menu[data-menu-motion="slide"] .menu-panel[data-v="up"] { --_t: translateY(var(--mnu-shift)); }

/* ── Panel head (optional custom region) ────────────────────────────────── */
.menu-panel__head {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 10px 10px 12px;
  border-bottom: 1px solid var(--color-border-subtle, var(--color-border-default));
  margin-bottom: 6px;
}
/* Optional head typography helpers (identity blocks, titles). */
.menu-head__name { font-size: 13.5px; font-weight: 600; color: var(--color-fg-default); }
.menu-head__mail { font-size: 11.5px; color: var(--color-fg-tertiary); margin-top: 1px; }
.menu-head__meta { font-size: 11px; color: var(--color-fg-secondary); margin-top: 4px; display: flex; align-items: center; gap: 4px; }
.menu-head__meta i { color: var(--gov-color-success-500); }

/* ── Items ──────────────────────────────────────────────────────────────── */
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: 1px solid transparent; background: transparent;
  border-radius: var(--radius-sm);
  font: 400 13px/1.3 var(--font-sans); color: var(--color-fg-default);
  cursor: pointer; text-align: left; text-decoration: none;
  transition: background-color 120ms ease, color 120ms ease,
              box-shadow 140ms ease-out, border-color 140ms ease-out;
}
.menu-item > i.bi { color: var(--color-fg-tertiary); font-size: 15px; flex: none; }
.menu-item__label { flex: 1 1 auto; min-width: 0; }
/* trailing meta — a shortcut hint, a count, or a ›chevron for a submenu cue. */
.menu-item__meta { margin-left: auto; color: var(--color-fg-tertiary); font-size: 12px; flex: none; }
/* OS-aware keyboard-shortcut keycaps (filled by _menu.js keycaps()) — the shared
   system keycap look (tooltip recipe: currentColor-mix fill + a 2px bottom border
   for a subtle 3D key). The "+" is big + tight (negative margin) so a chord reads
   as one unit, matching the global keycap treatment. */
.menu-item__meta.kbd { display: inline-flex; align-items: center; gap: 3px; }
.menu-item__meta kbd {
  font: 600 10px/1 var(--font-mono, ui-monospace, monospace);
  min-width: 9px; text-align: center;
  padding: 2px 5px; border-radius: 4px;
  color: var(--color-fg-secondary);
  background: color-mix(in srgb, currentColor 14%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
  border-bottom-width: 2px;
}
.menu-item__kplus { color: var(--color-fg-tertiary); font: 700 12px/1 var(--font-sans); padding: 0; margin: 0 -2px; }

.menu-item:hover:not(:disabled):not([data-state~="disabled"]),
.menu-item[data-state~="hover"] { background: var(--gov-color-neutral-100); }
.menu-item:active:not(:disabled),
.menu-item[data-state~="pressed"] { background: var(--gov-color-neutral-200, var(--gov-color-neutral-100)); }
/* Focus-ring bloom (same recipe as the trigger). */
.menu-item:focus-visible,
.menu-item[data-state~="focus"],
.menu-item.is-focus {
  outline: none;
  background: var(--gov-color-neutral-100);
  box-shadow: var(--shadow-focus, 0 0 0 3px rgba(35,98,162,0.35));
  border-color: var(--gov-color-primary-500);
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 140ms ease-out, background-color 120ms ease;
}
.menu-item:disabled,
.menu-item[data-state~="disabled"] { color: var(--color-fg-tertiary); cursor: not-allowed; opacity: 0.55; }
.menu-item:disabled > i.bi { color: var(--color-fg-tertiary); }

/* Destructive item (e.g. sign-out). */
.menu-item--danger { color: var(--gov-color-error-600, var(--gov-color-error-500)); }
.menu-item--danger > i.bi { color: inherit; }
.menu-item--danger:hover:not(:disabled),
.menu-item--danger[data-state~="hover"],
.menu-item--danger:focus-visible,
.menu-item--danger[data-state~="focus"],
.menu-item--danger.is-focus { background: var(--gov-color-error-50, var(--gov-color-neutral-100)); }

/* Separator. */
.menu-sep { height: var(--bw-line, 1px); background: var(--color-border-subtle, var(--color-border-default)); margin: 6px 4px; border: 0; }

/* ── Dark theme — tokens already flip; nudge the focus background tint so the
   neutral-100 hover reads on the dark surface. ──────────────────────────── */
@layer theme {
  [data-theme="dark"] .menu-item--danger:hover,
  [data-theme="dark"] .menu-item--danger[data-state~="hover"],
  [data-theme="dark"] .menu-item--danger.is-focus {
    background: color-mix(in srgb, var(--gov-color-error-500) 14%, transparent);
  }
}

/* Reduced motion is collapsed system-wide (colors_and_type.css) — the chevron
   rotation + the panel open/close snap automatically. No local block. */
