/* ============================================
   <xm-overlay> — platform-native overlay foundation.

   The single surface that xm-dialog / xm-menu / xm-tooltip / xm-select /
   xm-autocomplete compose. Modal mode is a native <dialog> (its ::backdrop
   is the scrim); non-modal mode is a Popover-API element in the top layer,
   anchored with CSS anchor() / @position-try.

   Surface is the card tier — inverse-surface fill + inverse-on-surface ink
   (AD-13). Elevation level3 for popovers/menus, level4–5 for modals
   (DESIGN.md). Scrim is var(--md-sys-color-scrim) with alpha at this use
   site. No blur / backdrop-filter; no gradient.

   BEM block: `overlay`. Registered in scripts/check-bem.sh STRICT_BLOCKS.
   Modifiers: --modal / --non-modal · --tier-tooltip / --tier-menu /
   --tier-dialog. Elements: __dialog (native <dialog>), __popover (popover
   element), __surface (the card chrome), __body (content region).
   ============================================ */

/* ---------- Native <dialog> (modal) ---------- */
/* The <dialog> element is the positioning + top-layer host; its visible card
   is .overlay__surface inside it. The dialog box itself is transparent so the
   surface owns the chrome. */
.overlay__dialog {
  margin: auto;
  padding: 0;
  max-width: var(--xm-overlay-max-width, min(92vw, 560px));
  max-height: 86vh;
  border: none;
  background: transparent;
  color: var(--md-sys-color-inverse-on-surface);
  overflow: visible;
}

/* The scrim — flat token-alpha fill (DESIGN.md: scrim is pure black, alpha
   applied at the callsite). No blur. */
.overlay__dialog::backdrop {
  background: color-mix(in oklab, var(--md-sys-color-scrim) 48%, transparent);
  animation: overlay-fade var(--md-sys-motion-duration-short4)
    var(--md-sys-motion-easing-standard);
}

/* ---------- Popover (non-modal, anchored) ---------- */
.overlay__popover {
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--md-sys-color-inverse-on-surface);
  overflow: visible;
  /* Top-layer popover, positioned against the viewport. anchor() resolves
     against the per-instance position-anchor set inline. @position-try flips
     the popover when it would overflow the viewport. */
  position: fixed;
  position-try-fallbacks: flip-block, flip-inline;
}

/* Native anchor() path — used when the anchor element lives in the SAME tree
   scope as the popover (anchor-name is tree-scoped). data-placement is set by
   the element at open time; inset: auto resets so only the chosen edges bind. */
.overlay__popover[data-placement^="bottom"] {
  inset: auto;
  top: anchor(bottom);
  left: anchor(left);
  margin-block-start: var(--s-1);
}
.overlay__popover[data-placement^="top"] {
  inset: auto;
  bottom: anchor(top);
  left: anchor(left);
  margin-block-end: var(--s-1);
}
.overlay__popover[data-placement^="right"] {
  inset: auto;
  left: anchor(right);
  top: anchor(top);
  margin-inline-start: var(--s-1);
}
.overlay__popover[data-placement^="left"] {
  inset: auto;
  right: anchor(left);
  top: anchor(top);
  margin-inline-end: var(--s-1);
}

/* Cross-root fallback path — when the consumer's trigger is in ANOTHER shadow
   root, CSS anchor-name is NOT visible to this popover (tree-scoped). The
   element computes a fixed top/left from the trigger's bounding rect (no
   dependency) and pins them via these custom properties; anchor() is skipped.
   This is the built-in, dependency-free fallback — Floating UI (the heavier
   escape hatch) is only for deep/virtual cases, never the common cross-root
   one. */
.overlay__popover.overlay__popover--pinned {
  inset: auto;
  top: var(--xm-overlay-pin-top, 0);
  left: var(--xm-overlay-pin-left, 0);
  position-try-fallbacks: none;
  margin: 0;
}

/* ---------- The card surface (shared) ---------- */
.overlay__surface {
  display: flex;
  flex-direction: column;
  position: relative;
  min-width: 0;
  box-sizing: border-box;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  font:
    var(--md-sys-typescale-body-large-weight)
    var(--md-sys-typescale-body-large-size) /
    var(--md-sys-typescale-body-large-line-height)
    var(--md-sys-typescale-body-large-font);
}

/* Elevation per tier: dialogs lift highest (level5), menus/select-listbox
   sit at popover height (level3), tooltips are the quietest layer (level3
   too — they never cover a menu, but read as a raised chip). */
.overlay--modal .overlay__surface {
  box-shadow: var(--md-sys-elevation-level5);
  min-width: min(86vw, 320px);
}
.overlay--non-modal.overlay--tier-menu .overlay__surface {
  box-shadow: var(--md-sys-elevation-level3);
  min-width: 180px;
  border-radius: var(--md-sys-shape-corner-medium);
}

:host([match-anchor-width]) .overlay__surface {
  width: var(--xm-overlay-anchor-width, auto);
}
.overlay--non-modal.overlay--tier-dialog .overlay__surface {
  box-shadow: var(--md-sys-elevation-level3);
}
/* A tooltip shrink-wraps its copy: a three-word label stays on one line rather
   than wrapping ragged inside a fixed box, and only a long one reaches the cap
   and wraps. */
.overlay--tier-tooltip .overlay__surface {
  box-shadow: var(--md-sys-elevation-level3);
  border-radius: var(--md-sys-shape-corner-extra-small);
  width: max-content;
  max-width: 260px;
}

/* ---------- Pointer (opt-in, non-modal only) ----------
   A square rotated 45° whose centre sits on the surface edge facing the anchor:
   the inner half is hidden behind the opaque surface, the outer half reads as a
   triangle, and its two exposed sides carry the hairline so the outline stays
   continuous. Painted last so it covers the surface border along its base.

   The element positions it: `data-side` is the RESOLVED side (post-flip) and
   --xm-overlay-arrow-offset is the clamp delta that keeps it on the trigger. */
.overlay__arrow {
  position: absolute;
  width: var(--s-2);
  height: var(--s-2);
  background: var(--md-sys-color-inverse-surface);
  pointer-events: none;
}

.overlay__popover[data-side="top"] .overlay__arrow {
  bottom: calc(-1 * var(--s-1));
  left: calc(50% + var(--xm-overlay-arrow-offset, 0px));
  transform: translateX(-50%) rotate(45deg);
  border-right: 1px solid var(--md-sys-color-outline-variant);
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.overlay__popover[data-side="bottom"] .overlay__arrow {
  top: calc(-1 * var(--s-1));
  left: calc(50% + var(--xm-overlay-arrow-offset, 0px));
  transform: translateX(-50%) rotate(45deg);
  border-left: 1px solid var(--md-sys-color-outline-variant);
  border-top: 1px solid var(--md-sys-color-outline-variant);
}
.overlay__popover[data-side="left"] .overlay__arrow {
  right: calc(-1 * var(--s-1));
  top: calc(50% + var(--xm-overlay-arrow-offset, 0px));
  transform: translateY(-50%) rotate(45deg);
  border-right: 1px solid var(--md-sys-color-outline-variant);
  border-top: 1px solid var(--md-sys-color-outline-variant);
}
.overlay__popover[data-side="right"] .overlay__arrow {
  left: calc(-1 * var(--s-1));
  top: calc(50% + var(--xm-overlay-arrow-offset, 0px));
  transform: translateY(-50%) rotate(45deg);
  border-left: 1px solid var(--md-sys-color-outline-variant);
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}

/* ---------- Content region ---------- */
.overlay__body {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: auto;
  padding: var(--s-5);
}
.overlay--tier-menu .overlay__body {
  padding: var(--s-2);
}
/* The tooltip label owns its own padding (it is the whole content), so the
   body region adds none — otherwise the chip reads twice as tall as designed. */
.overlay--tier-tooltip .overlay__body {
  padding: 0;
  overflow: visible;
}

/* ---------- Open transition (short4, standard) ---------- */
@keyframes overlay-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.overlay__dialog[open],
.overlay__popover:popover-open {
  animation: overlay-fade var(--md-sys-motion-duration-short4)
    var(--md-sys-motion-easing-standard);
}

/* A tooltip grows out of its own pointer rather than fading in place: the
   origin is the arrow edge and the nudge runs along the anchor axis, so the
   label reads as belonging to the thing under the cursor. One keyframe set,
   steered per side by two custom properties, so reduced-motion has a single
   rule to switch off. */
@keyframes overlay-tip-in {
  from {
    opacity: 0;
    transform: translate(
        var(--xm-overlay-tip-dx, 0),
        var(--xm-overlay-tip-dy, 0)
      )
      scale(0.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.overlay--tier-tooltip.overlay__popover:popover-open {
  animation: overlay-tip-in var(--md-sys-motion-duration-short3)
    var(--md-sys-motion-easing-standard);
}
.overlay--tier-tooltip.overlay__popover[data-side="top"] {
  transform-origin: calc(50% + var(--xm-overlay-arrow-offset, 0px)) 100%;
  --xm-overlay-tip-dy: var(--s-1);
}
.overlay--tier-tooltip.overlay__popover[data-side="bottom"] {
  transform-origin: calc(50% + var(--xm-overlay-arrow-offset, 0px)) 0%;
  --xm-overlay-tip-dy: calc(-1 * var(--s-1));
}
.overlay--tier-tooltip.overlay__popover[data-side="left"] {
  transform-origin: 100% calc(50% + var(--xm-overlay-arrow-offset, 0px));
  --xm-overlay-tip-dx: var(--s-1);
}
.overlay--tier-tooltip.overlay__popover[data-side="right"] {
  transform-origin: 0% calc(50% + var(--xm-overlay-arrow-offset, 0px));
  --xm-overlay-tip-dx: calc(-1 * var(--s-1));
}

@media (prefers-reduced-motion: reduce) {
  .overlay__dialog[open],
  .overlay__popover:popover-open,
  .overlay--tier-tooltip.overlay__popover:popover-open,
  .overlay__dialog::backdrop {
    animation: none;
  }
}
