/*
Menu: the content, items and parts DropdownMenu, ContextMenu and Menubar
share (the .menu family). Each root adds its own class to the content
(.dropdown-menu, .context-menu, .menubar-content).

<div class="menu" role="menu" popover="manual" data-menu-content data-state data-side data-align>
  <span class="menu-arrow">                    optional (DropdownMenu arrow)
  <div class="menu-label">                     MenuLabel
  <div class="menu-item" role="menuitem" data-highlighted data-disabled data-variant>
    <span class="menu-item-indicator">         checkbox and radio items
    ...label...
    <span class="menu-shortcut">               MenuShortcut
  <div role="group" class="menu-group">        MenuGroup, MenuRadioGroup
  <div class="menu-separator" role="separator">
  <div class="menu-sub" data-menu-sub>         display: contents
    <div class="menu-item menu-sub-trigger" data-state>  ... <span class="menu-sub-chevron">
    <div class="menu menu-sub-content" role="menu" popover="manual">

State never moves anything: highlight and open change the row's colors,
checked changes the indicator's visibility; the indicator column is
always reserved.
*/

@layer components {

.menu-sub,
.menu-trigger-wrap {
  display: contents;
}

.menu {
  --menu-indicator-width: var(--icon-size);

  box-sizing:       border-box;
  min-width:        var(--space-32);
  max-width:        var(--available-width, calc(100vw - 2 * var(--space-2)));
  max-height:       var(--available-height, none);
  overflow-x:       hidden;
  overflow-y:       auto;
  padding:          var(--overlay-padding);
  color:            var(--overlay-ink);
  background:       var(--overlay-bg);
  border:           var(--overlay-border-width) solid var(--overlay-border);
  border-radius:    var(--radius-overlay);
  box-shadow:       var(--overlay-shadow);
  font-family:      var(--font-ui);
  font-size:        var(--text-ui);
  font-weight:      var(--weight-body);
  letter-spacing:   var(--tracking-ui);
  line-height:      var(--leading-snug);
  outline:          none;
  transform-origin: var(--transform-origin);
}

/* With an arrow the content cannot clip its own overflow: the arrow sits
   outside its edge. The content keeps overflow visible and an inner
   .menu-body takes the padding and scrolls inside the room the menu has
   (Radix renders the Arrow beside the scrolling content). */
.menu:has(> .menu-arrow) {
  overflow:   visible;
  max-height: none;
}

.menu:has(> .menu-body) {
  padding: 0;
}

.menu-body {
  position:      relative;
  box-sizing:    border-box;
  max-height:    calc(var(--available-height, 100vh) - 2 * var(--overlay-border-width));
  padding:       var(--overlay-padding);
  overflow-x:    hidden;
  overflow-y:    auto;
  border-radius: inherit;
  outline:       none;
}

.menu:focus-visible {
  box-shadow: var(--overlay-shadow);
}

/* Items */

.menu-item {
  position:        relative;
  display:         flex;
  align-items:     center;
  gap:             var(--item-gap);
  box-sizing:      border-box;
  min-height:      var(--item-height);
  padding:         0 var(--item-padding-x);
  border-radius:   var(--radius-item);
  color:           inherit;
  text-decoration: none;
  text-transform:  none;
  cursor:          default;
  user-select:     none;
  outline:         none;
}

.menu-item > .icon {
  flex:   none;
  width:  var(--icon-size);
  height: var(--icon-size);
  color:  var(--ink-dim);
}

.menu-item[data-highlighted],
.menu-sub-trigger[data-state="open"] {
  background: var(--item-highlight);
  color:      var(--item-highlight-ink);
}

.menu-item[data-highlighted] > .icon {
  color: currentColor;
}

/* Keyboard focus on a highlighted row reads as the highlight; no ring, which
   would grow the row's paint past its neighbours. */
.menu-item:focus-visible {
  outline: none;
}

.menu-item[data-disabled] {
  color:  var(--ink-faint);
  cursor: not-allowed;
}

.menu-item[data-disabled][data-highlighted] {
  background: var(--item-highlight);
  color:      var(--ink-faint);
}

.menu-item[data-variant="destructive"] {
  color: var(--danger);
}

.menu-item[data-variant="destructive"] > .icon {
  color: currentColor;
}

.menu-item[data-variant="destructive"][data-highlighted] {
  background: var(--danger-soft);
  color:      var(--danger);
}

/* Inset rows and every checkbox or radio row keep the indicator column. */
.menu-item.is-inset,
.menu-label.is-inset,
.menu-item[data-menu-check] {
  padding-inline-start: calc(var(--item-padding-x) + var(--menu-indicator-width) + var(--item-gap));
}

.menu-item-indicator {
  position:        absolute;
  inset-inline-start: var(--item-padding-x);
  top:             0;
  bottom:          0;
  display:         flex;
  align-items:     center;
  justify-content: center;
  width:           var(--menu-indicator-width);
  visibility:      hidden;
  pointer-events:  none;
}

.menu-item-indicator .icon {
  width:  var(--icon-size);
  height: var(--icon-size);
}

/* Each indicator shows only its own state, so slotted custom indicators
   (one per state) work the same way. */
.menu-item-indicator > * {
  display: none;
}

.menu-item[data-state="checked"] > .menu-item-indicator,
.menu-item[data-state="indeterminate"] > .menu-item-indicator {
  visibility: visible;
}

.menu-item[data-state="checked"] > .menu-item-indicator > .is-checked,
.menu-item[data-state="indeterminate"] > .menu-item-indicator > .is-indeterminate {
  display: contents;
}

/* Base UI ItemIndicator data-ending-style: an indicator turning off keeps
   the glyph it is leaving until its exit transition ends. */
.menu-item-indicator[data-ending-style] {
  visibility: visible;
}

.menu-item-indicator[data-ending-style="checked"] > .is-checked,
.menu-item-indicator[data-ending-style="indeterminate"] > .is-indeterminate {
  display: contents;
}

.menu-item-label {
  flex:      1 1 auto;
  min-width: 0;
}

/* Sub Trigger */

.menu-sub-chevron {
  display:            inline-flex;
  margin-inline-start: auto;
  color:              var(--ink-dim);
}

.menu-sub-chevron .icon {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

.menu-sub-trigger:dir(rtl) .menu-sub-chevron {
  transform: scaleX(-1);
}

/* Label, Separator, Shortcut, Group */

.menu-label {
  display:        flex;
  align-items:    center;
  gap:            var(--item-gap);
  box-sizing:     border-box;
  min-height:     var(--item-height);
  padding:        0 var(--item-padding-x);
  color:          var(--ink-dim);
  font-size:      var(--text-ui-sm);
  font-weight:    var(--weight-strong);
  text-transform: var(--case-ui);
  user-select:    none;
}

.menu-separator {
  height:     var(--overlay-border-width);
  margin:     var(--overlay-padding) calc(var(--overlay-padding) * -1);
  background: var(--overlay-border);
}

.menu-shortcut {
  margin-inline-start: auto;
  padding-inline-start: var(--space-4);
  color:               var(--ink-dim);
  font-family:         var(--font-ui);
  font-size:           var(--text-ui-sm);
  letter-spacing:      var(--tracking-wide);
  white-space:         nowrap;
}

.menu-item[data-highlighted] .menu-shortcut {
  color: currentColor;
}

.menu-group {
  display: block;
}

/* A vertical rule, between items laid out in a row the caller builds. */
/* A horizontal menu (orientation="horizontal") lays its items in a row. */
.menu[data-orientation="horizontal"] {
  display:     flex;
  align-items: center;
  gap:         var(--item-gap);
}

.menu-separator[aria-orientation="vertical"] {
  align-self: stretch;
  width:      var(--overlay-border-width);
  height:     auto;
  margin:     0 var(--overlay-padding);
}

/* Filtering */

/* Rows the filter hides; their own display rules would otherwise win. */
.menu [hidden] {
  display: none;
}

.menu-input-row {
  display:       flex;
  align-items:   center;
  gap:           var(--item-gap);
  box-sizing:    border-box;
  min-height:    var(--item-height);
  margin:        calc(var(--overlay-padding) * -1) calc(var(--overlay-padding) * -1) var(--overlay-padding);
  padding:       0 calc(var(--item-padding-x) + var(--overlay-padding));
  border-bottom: var(--overlay-border-width) solid var(--overlay-border);
  color:         var(--ink-dim);
}

.menu-input-row > .icon {
  flex:   none;
  width:  var(--icon-size);
  height: var(--icon-size);
}

.menu-input {
  flex:           1 1 auto;
  min-width:      0;
  height:         var(--item-height);
  margin:         0;
  padding:        0;
  border:         0;
  background:     transparent;
  box-shadow:     none;
  color:          var(--overlay-ink);
  font:           inherit;
  letter-spacing: inherit;
  outline:        none;
}

.menu-input:focus,
.menu-input:focus-visible {
  border:     0;
  outline:    none;
  box-shadow: none;
}

.menu-input::placeholder {
  color:   var(--ink-dim);
  opacity: 1;
}

.menu-clear {
  display:         inline-flex;
  flex:            none;
  align-items:     center;
  justify-content: center;
  width:           var(--icon-size);
  height:          var(--icon-size);
  margin:          0;
  padding:         0;
  border:          0;
  border-radius:   var(--radius-item);
  background:      transparent;
  color:           var(--ink-dim);
  cursor:          default;
}

.menu-clear .icon {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

/* Nothing to clear: hidden but kept in layout, so the row never moves. */
.menu-clear:disabled {
  visibility: hidden;
}

.menu-clear:focus-visible {
  outline:    none;
  box-shadow: var(--focus-ring);
}

/* MenuList: the role=menu list beside a filter input; the content keeps the padding. */
.menu-list {
  display: block;
  outline: none;
}

/* Without a MenuList the controller adds an empty role=menu that owns the
   rows (aria-owns); it takes no space. */
.menu-owned-list {
  position: absolute;
  inset:    0 auto auto 0;
  width:    0;
  height:   0;
  overflow: hidden;
}

.menu-empty {
  display:     flex;
  align-items: center;
  justify-content: center;
  box-sizing:  border-box;
  min-height:  var(--item-height);
  padding:     0 var(--item-padding-x);
  color:       var(--ink-dim);
  font-size:   var(--text-ui-sm);
}

/* Arrow */

/* The arrow is a triangle arrowWidth wide along the menu's edge and
   arrowHeight tall away from it (Radix Arrow width and height), set inline as
   --menu-arrow-width and --menu-arrow-height. ::before is the border-colored
   triangle, ::after the fill one moved in by the border width, so the edge
   reads as the menu's border bending round the tip. */
.menu-arrow {
  /* Sized before float() places it, so the context menu can clear its tip. */
  position:       absolute;
  width:          var(--menu-arrow-width);
  height:         var(--menu-arrow-height);
  pointer-events: none;
}

.menu-arrow::before,
.menu-arrow::after {
  content:    "";
  position:   absolute;
  inset:      0;
  background: var(--overlay-border);
  clip-path:  polygon(0 100%, 50% 0, 100% 100%);
}

.menu-arrow::after {
  background: var(--overlay-bg);
  transform:  translateY(var(--overlay-border-width));
}

.menu-arrow[data-side="bottom"] {
  top: calc(-1 * var(--menu-arrow-height) - var(--overlay-border-width));
}

.menu-arrow[data-side="top"] {
  bottom: calc(-1 * var(--menu-arrow-height) - var(--overlay-border-width));
}

.menu-arrow[data-side="top"]::before,
.menu-arrow[data-side="top"]::after {
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

.menu-arrow[data-side="top"]::after {
  transform: translateY(calc(-1 * var(--overlay-border-width)));
}

.menu-arrow[data-side="left"],
.menu-arrow[data-side="right"] {
  width:  var(--menu-arrow-height);
  height: var(--menu-arrow-width);
}

.menu-arrow[data-side="right"] {
  left: calc(-1 * var(--menu-arrow-height) - var(--overlay-border-width));
}

.menu-arrow[data-side="right"]::before,
.menu-arrow[data-side="right"]::after {
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
}

.menu-arrow[data-side="right"]::after {
  transform: translateX(var(--overlay-border-width));
}

.menu-arrow[data-side="left"] {
  right: calc(-1 * var(--menu-arrow-height) - var(--overlay-border-width));
}

.menu-arrow[data-side="left"]::before,
.menu-arrow[data-side="left"]::after {
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.menu-arrow[data-side="left"]::after {
  transform: translateX(calc(-1 * var(--overlay-border-width)));
}

/* Motion */

.menu[data-state="open"] {
  animation: menu-in var(--duration-enter) var(--ease-enter);
}

.menu[data-state="closed"] {
  animation: menu-out var(--duration-exit) var(--ease-exit) forwards;
  pointer-events: none;
}

.menu[data-side="bottom"] { --menu-slide-x: 0; --menu-slide-y: calc(var(--enter-distance) * -1); }
.menu[data-side="top"]    { --menu-slide-x: 0; --menu-slide-y: var(--enter-distance); }
.menu[data-side="right"]  { --menu-slide-x: calc(var(--enter-distance) * -1); --menu-slide-y: 0; }
.menu[data-side="left"]   { --menu-slide-x: var(--enter-distance); --menu-slide-y: 0; }

/* Moving to another of the menu's triggers while open (Base UI Viewport):
   the controller animates the box; its rows stay clipped to it and fade in. */
.menu[data-morphing]:not(:has(> .menu-arrow)),
.menu[data-morphing] > .menu-body {
  overflow: hidden;
}

.menu[data-morphing] > :not(.menu-arrow, .menu-body),
.menu[data-morphing] > .menu-body > * {
  animation: menu-morph-in var(--duration-enter) var(--ease-enter);
}

@keyframes menu-morph-in {
  from { opacity: 0; }
}

@keyframes menu-in {
  from {
    opacity:   0;
    transform: translate(var(--menu-slide-x, 0), var(--menu-slide-y, 0)) scale(var(--enter-scale));
  }
}

@keyframes menu-out {
  to {
    opacity:   0;
    transform: scale(var(--enter-scale));
  }
}


/* Backdrop (backdrop) */

/* Base UI Menu.Backdrop: a top layer box under the menu, shown first so the
   menu stacks above it. It dims the page with the theme's backdrop and takes
   the press outside a modal menu that closes it. */
.menu-backdrop {
  position:   fixed;
  inset:      0;
  width:      auto;
  height:     auto;
  max-width:  none;
  max-height: none;
  margin:     0;
  padding:    0;
  border:     0;
  background: var(--backdrop);
  pointer-events: auto;
}

.menu-backdrop:not(:popover-open) {
  display: none;
}

.menu-backdrop[data-state="open"] {
  animation: menu-backdrop-in var(--duration-enter) var(--ease-enter);
}

.menu-backdrop[data-state="closed"] {
  animation: menu-backdrop-out var(--duration-exit) var(--ease-exit) forwards;
}

@keyframes menu-backdrop-in {
  from { opacity: 0; }
}

@keyframes menu-backdrop-out {
  to { opacity: 0; }
}

}


/* FORCED COLORS -------------------------------------------------------------
   High contrast paints every background Canvas and drops box-shadow, so the
   highlight fill would vanish and a keyboard user could not see which row
   Enter chooses. The highlighted row, and a sub trigger whose submenu is
   open, get a Highlight frame drawn inside the row (an outline: no layout
   effect, and the menu's overflow cannot clip it). */

@layer components {

@media (forced-colors: active) {
  .menu-item[data-highlighted],
  .menu-sub-trigger[data-state="open"] {
    outline:        var(--focus-ring-width) solid Highlight;
    outline-offset: calc(-1 * var(--focus-ring-width));
  }

  .menu-item[data-disabled] {
    color: GrayText;
  }
}

}
