/**
 * Dropdown Menu Visibility Fixes
 * 
 * This stylesheet fixes issues with dropdown menus being clipped or hidden
 * by parent containers with overflow: hidden or lower z-index values.
 */

/* Ensure dropdown menus are always on top.

   NOTE: deliberately does NOT set `position`. Dropdown menus are positioned by
   Popper, which application.js configures with `strategy: 'fixed'` app-wide so a
   menu escapes any scrolling ancestor on its own. Popper writes `position: fixed`
   as an INLINE style, so a `position: absolute !important` here would win the
   cascade and re-trap every menu inside its scroll container while keeping the
   viewport-relative coordinates Popper computed — i.e. menus land in the wrong
   place. Leave positioning to Popper. */
.dropdown-menu {
  z-index: 1050 !important;
  /* Higher than most content but below modals */
}

/* A dropdown taller than the viewport is UNREACHABLE, not merely ugly
   (ISS-20260902-397-54DE04).

   Bootstrap puts no height cap on `.dropdown-menu`, and this app positions every
   menu with Popper's `strategy: 'fixed'` (application.js). A `position: fixed`
   box is laid out against the viewport and contributes nothing to page scroll —
   so once a menu is taller than the viewport, the overflowing items cannot be
   reached at all: the page will not scroll to them and the menu itself does not
   scroll. Measured on /admin/approval_workflows, whose "Create Workflow" picker
   lists every active marketplace app: 91 items, 3243px tall in a 900px viewport,
   with the last 2522px permanently off-screen.

   This rule is the FLOOR, not the whole fix. `capDropdownMenuHeight` in
   application.js runs on `shown.bs.dropdown` and writes the room the toggle
   actually has as an inline max-height, which outranks this rule. That measured
   value is what keeps ordinary menus whole: the navbar user menu is 13 items /
   612px and sits at the top of the page with ~840px below it, so it still
   renders in full.

   Half the viewport is the right static floor because Popper's `flip` puts the
   menu on whichever side of the toggle has room, and the space above plus the
   space below always sums to roughly the viewport height — so one side always
   offers at least ~50vh, making "the menu fits on screen" true for EVERY toggle
   position. A more generous static cap (say 100vh - 4rem) would still leave a
   mid-page toggle with a tall menu hanging off one end, which is the same
   unreachable bug in a narrower window.

   `overflow-y: auto` shows no scrollbar until the cap is hit, so short menus —
   the overwhelming majority — are pixel-identical. Bootstrap's arrow-key
   navigation focuses items, and focusing an item inside a scroll container
   scrolls it into view natively, so the keyboard path reaches the bottom too.
   Safe to clip: no `.dropdown-menu` in app/views contains an absolutely
   positioned child, and Bootstrap's own nested popovers/tooltips are positioned
   `fixed` by the same Popper default, which an `overflow` ancestor cannot clip.

   Intentionally NOT `!important`, so both the inline value written by
   application.js and the tighter per-view opt-ins that predate this rule (the
   shift coverage dashboard's 400px, the wiki icon picker's 350px, the
   availability-calendar block below) keep winning over it. */
.dropdown-menu {
  max-height: calc(50vh - 3rem);
  overflow-y: auto;
}

.card {
  overflow: visible !important;
}

/* ...but a card that explicitly writes `.overflow-hidden` is asking to clip on
   purpose, and the blanket rule above silently took that away app-wide: same
   specificity (0,1,0) as Bootstrap's `.overflow-hidden`, both !important, and
   this file loads later, so it won.

   The visible damage is the card's rounded corners. In CSS painting order a
   child's background paints over its parent's border, and at a rounded corner
   the child's SQUARE box corner sticks out past the parent's curve — so an
   opaque square-cornered child (a flush list group, a media block, a tinted
   panel) paints across the corner arc and the card reads as square/clipped
   along that edge while the other corners stay round. `overflow: hidden` is
   what clips it back, which is exactly why those cards opt in.

   Two-class specificity (0,2,0) so the deliberate opt-in outranks the blanket
   rule while every card that never asked for clipping keeps it. Safe for
   dropdowns: application.js configures Popper with `strategy: 'fixed'`, so a
   menu is not clipped by an ancestor's overflow (see the note above), and no
   `.card.overflow-hidden` in app/views contains a dropdown toggle today. */
.card.overflow-hidden {
  overflow: hidden !important;
}

/* Fix for any parent containers that might clip dropdowns */
.container-fluid,
.container,
.row,
.col,
[class^="col-"] {
  overflow: visible !important;
}

/* Ensure dropdown toggle buttons have proper position context */
.dropdown,
.dropend,
.dropstart,
.dropup {
  position: relative !important;
}

/* Fix for card headers and footers with dropdowns - ensure they don't clip menu */
.card-header,
.card-footer {
  overflow: visible !important;
}

/* Fix for main content area - ensure dropdowns can escape boundaries */
.main,
main.content {
  overflow: visible !important;
}

/* Ensure dropdown menus in card headers and footers have high enough z-index to appear above sticky nav */
.card-header .dropdown-menu,
.card-footer .dropdown-menu {
  z-index: 1055 !important;
}

/* Fix for availability calendar page dropdown specifically.
   `position` is intentionally omitted — see the note on `.dropdown-menu` above. */
.availability-calendar + .alert + .dropdown .dropdown-menu,
.card-header .dropdown .dropdown-menu,
.card-footer .dropdown .dropdown-menu {
  z-index: 1055 !important;
}

/* Fix for team availability show_user_availability page - 
   Prevents dropdown and buttons from being clipped or misaligned */
[data-controller="availability-calendar"] .card-header {
  position: relative !important;
  overflow: visible !important;
  z-index: auto !important;
}

[data-controller="availability-calendar"] .card-header .dropdown {
  position: relative !important;
  z-index: 1 !important;
}

[data-controller="availability-calendar"] .card-header .dropdown-menu {
  z-index: 1060 !important;
  /* `position` intentionally omitted — see the note on `.dropdown-menu` above. */
  /* Ensure the dropdown menu doesn't get clipped at page boundaries */
  max-height: calc(100vh - 200px) !important;
  overflow-y: auto !important;
}

/* Ensure the card actions button group aligns properly within card header */
[data-controller="availability-calendar"] .card-header .d-flex.align-items-center.gap-2 {
  flex-shrink: 0 !important;
  /* Prevent action buttons from being compressed */
}

/* Ensure wrapper and main container don't clip dropdown content */
.wrapper,
.main {
  overflow: visible !important;
}

/* AdminKit's dropdownAnimation animated `transform` (translateY at 0%, translate(0)
   at 100%). Per CSS spec, an animation's keyframe transform overrides inline styles
   for the animated property — and with animation-fill-mode: forwards, that override
   persists. The result: Popper's `transform: translate(x, y)` (set inline to position
   the menu below the toggle) was getting frozen at translate(0,0), making the menu
   overlap its toggle button. Redefining the keyframes to animate only opacity keeps
   the fade-in effect without breaking Popper positioning. */
@keyframes dropdownAnimation {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
/* ---------------------------------------------------------------------------
   A row/card that becomes a STACKING CONTEXT while you use its ⋮ menu drags the
   menu down with it (ISS-20260902-524-0A7219).

   `.dropdown-menu { z-index: 1050 }` at the top of this file only means 1050
   *within the menu's own stacking context*. The moment an ancestor establishes
   one, that 1050 is re-based against the ANCESTOR's z-index, and the menu can no
   longer out-stack anything painted in the root context — the fixed app sidebar
   (z-index 998) or the fixed navbar (1030).

   Two ancestors in this app do exactly that, and both only while the row is in
   use, which is what produced the reported flicker:

   - Bootstrap's own list rows. `.list-group-item { position: relative }` plus
     `.list-group-item-action:hover, :focus { z-index: 1 }` (and
     `.list-group-item.active { z-index: 2 }`) makes the row a stacking context
     for as long as the pointer is on it. On My Tasks (List) the ⋮ sits at the
     row's left edge and `dropdown-menu-end` opens the menu leftwards, straight
     over the sidebar: menu behind the sidebar while the row is hovered, in front
     the instant the pointer leaves it. Moving from the button to a menu item
     crosses that boundary, so the menu flickers between the two.

   - `.kanban-task-card:hover, :focus-within` (custom.css) adds `z-index: 20` AND
     a `transform`. The transform is the worse half: it makes the card the
     containing block for `position: fixed` descendants, and every dropdown in
     this app is positioned by Popper with `strategy: 'fixed'` in VIEWPORT
     coordinates (see application.js) — so the menu is laid out against the card
     instead. `:focus-within` holds both for the whole time the menu is open,
     because the toggle keeps focus.

   Release the trap only while a menu inside is actually open: the hover
   elevation and the card lift are untouched at every other moment. Keyed on
   `.show` rather than `:hover` so the keyboard path (`:focus`, `:focus-within`)
   is covered by the same rule.

   Specificity is (0,3,0) — `:has()` takes its most specific argument — so these
   beat the (0,2,0) rules above from light.css and custom.css no matter which
   file loads last. No !important needed; do not add one. */
.list-group-item:has(.dropdown-menu.show) {
  z-index: auto;
}

.kanban-task-card:has(.dropdown-menu.show) {
  z-index: auto;
  transform: none;
  /* The transform TRANSITION has to go with it, and this line is load-bearing.
     `.kanban-task-card` transitions `transform` over 0.2s, so `transform: none`
     alone only STARTS an animation — the computed value stays a matrix, the card
     stays the containing block, Popper (which positions on a microtask, after
     `.show` lands) still resolves against the card, and the menu then jumps by the
     card's full offset when the transition finishes. Measured on My Tasks/Kanban:
     836px right and 286px up from its own toggle. Dropping the transform from the
     transition list makes the release instant, so Popper reads `none` and computes
     viewport coordinates as intended; box-shadow keeps its ease. */
  transition: box-shadow 0.2s ease, opacity 0.2s ease;
}
