/* ═══════════════════════════════════════════════════════════════
   TOAST-N — Notification popup with auto-dismiss.
   ═══════════════════════════════════════════════════════════════ */

/* Safari 17.x bug: `:scope[data-open]` and `:scope[data-closing]`
   (Flavor B — attribute-removal restyle) don't reliably restyle on
   attribute toggling inside `@scope`. Selectors moved out as plain
   `toast-ui[data-…]` rules. See docs/BROWSER-COMPAT.md §3a. */
toast-ui[data-open] {
  transition: transform var(--toast-duration) var(--toast-easing),
              opacity var(--toast-duration) var(--toast-easing);
  transform: translateY(0);
  opacity: 1;
}
toast-ui[data-closing] {
  transition: transform var(--toast-duration) var(--toast-easing),
              opacity var(--toast-duration) var(--toast-easing);
  opacity: 0;
}
toast-ui[data-closing],
toast-ui[data-closing][position="bottom-right"],
toast-ui[data-closing][position="bottom-left"] {
  transform: translateY(1rem);
}
toast-ui[data-closing][position="top-right"],
toast-ui[data-closing][position="top-left"] {
  transform: translateY(-1rem);
}

@scope (toast-ui) {
  :where(:scope) {
    --toast-bg:       var(--a-bg-subtle);
    --toast-fg:       var(--a-fg);
    --toast-radius:   var(--a-radius-md);
    --toast-shadow:   var(--a-shadow-lg);
    --toast-duration: var(--a-duration);
    --toast-easing:   var(--a-easing-out);
    --toast-pad-x:    var(--a-space-4);
    --toast-pad-y:    var(--a-space-3);
    --toast-border:   var(--a-border-subtle);
    --toast-max-width: 24rem;
    --toast-gap:      var(--a-space-3);

    /* ── Typography ── */
    --toast-font:     var(--a-font-family);
    --toast-size:     var(--a-ui-md);

    /* ── Position offset ── */
    --toast-offset:   var(--a-space-4);

    /* ── Close button ── */
    --toast-close-duration: var(--a-duration-fast);
    --toast-close-easing:   var(--a-easing);
    --toast-focus-ring:     var(--a-focus-ring);
    --toast-focus-radius:   var(--a-radius-sm);
  }

  :scope {
    box-sizing: border-box;
    position: fixed;
    z-index: 9999;
    display: flex;
    align-items: center;
    gap: var(--toast-gap);
    max-width: var(--toast-max-width);
    padding: var(--toast-pad-y) var(--toast-pad-x);
    background: var(--toast-bg);
    color: var(--toast-fg);
    font-family: var(--toast-font);
    font-size: var(--toast-size);
    border: 1px solid var(--toast-border);
    border-radius: var(--toast-radius);
    box-shadow: var(--toast-shadow);
    opacity: 0;
    pointer-events: auto;
  }

  /* ── Position variants ── */

  :where(:scope),
  :where(:scope[position="bottom-right"]) {
    bottom: var(--toast-offset);
    right: var(--toast-offset);
    transform: translateY(1rem);
  }
  :where(:scope[position="bottom-left"]) {
    bottom: var(--toast-offset);
    left: var(--toast-offset);
    right: auto;
    transform: translateY(1rem);
  }
  :where(:scope[position="top-right"]) {
    top: var(--toast-offset);
    right: var(--toast-offset);
    bottom: auto;
    transform: translateY(-1rem);
  }
  :where(:scope[position="top-left"]) {
    top: var(--toast-offset);
    left: var(--toast-offset);
    right: auto;
    bottom: auto;
    transform: translateY(-1rem);
  }

  /* Enter / exit animation rules ([data-open] / [data-closing]) moved
     outside @scope — see Safari 17.x bug note at top of file. */

  /* ── Variants ──
     `--variant-muted` flips light↔dark with scheme, so the fg token
     paired with it must do the same. Use `--a-{variant}-text` (the
     light-dark scheme-aware token), NOT `--a-{variant}-text-strong`
     (the latter is locked dark for warning + light for the others —
     designed for solid `--variant-strong` fills, where the bg never
     flips). Mirrors alert.css's variant wiring. */

  :where(:scope),
  :where(:scope[variant="info"]) {
    --toast-bg:     var(--a-info-muted);
    --toast-fg:     var(--a-info-text);
    --toast-border: var(--a-info-border-subtle);
  }
  :where(:scope[variant="success"]) {
    --toast-bg:     var(--a-success-muted);
    --toast-fg:     var(--a-success-text);
    --toast-border: var(--a-success-border-subtle);
  }
  :where(:scope[variant="warning"]) {
    --toast-bg:     var(--a-warning-muted);
    --toast-fg:     var(--a-warning-text);
    --toast-border: var(--a-warning-border-subtle);
  }
  :where(:scope[variant="danger"]) {
    --toast-bg:     var(--a-danger-muted);
    --toast-fg:     var(--a-danger-text);
    --toast-border: var(--a-danger-border-subtle);
  }

  /* `primary` is the accent-filled variant — solid bg + on-accent text
     for "branded" toasts (welcome banners, feature-launch nudges)
     where the message should read as a brand stamp rather than tinted
     status chrome. Tracks the same accent-strong source as button-ui's
     primary; border picks up `--a-accent-border-subtle` since there's
     no `--a-primary-border-subtle` token. */
  :where(:scope[variant="primary"]) {
    --toast-bg:     var(--a-primary-bg);
    --toast-fg:     var(--a-primary-fg);
    --toast-border: var(--a-accent-border-subtle);
  }

  /* `muted` and `neutral` are semantic aliases of the base canvas
     surface — same tokens as the unstyled `:scope`, declared explicitly
     so the yaml enum and the CSS contract agree. Use cases: quiet
     status nudges that shouldn't carry tonal weight (e.g. "Draft
     saved" without success-green). Mirrors alert-ui's pattern. */
  :where(:scope[variant="muted"]),
  :where(:scope[variant="neutral"]) {
    --toast-bg:     var(--a-bg-subtle);
    --toast-fg:     var(--a-fg);
    --toast-border: var(--a-border-subtle);
  }

  /* ── Message slot ── */

  [slot="message"] {
    flex: 1;
    min-width: 0;
  }

  /* ── Close button ──
     A real <button-ui icon="x" variant="ghost" size="sm"> stamped by
     toast.js — brings the system focus ring + hover transition + a
     properly-sized icon-ui glyph. The `align-self: start` keeps the
     button on the first line of multi-line toast bodies, matching the
     alert-ui pattern. */
  [slot="close"] {
    flex-shrink: 0;
    align-self: start;
    color: currentColor;
  }

  /* Inside a container: drop fixed positioning */
  [data-toast-container] > :scope {
    position: relative;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
  }
}

/* ── Toast lane container ──
   Per-position singleton, attached to `document.body`. Promoted to the
   browser's top-layer via the Popover API — `[popover="manual"]` on the
   element + `showPopover()` on first post. The native popover stack
   means multiple lanes (e.g. top-right + bottom-center) coexist
   without z-index collisions, and the lane sits above ALL page chrome
   (modals included, since both ride the top-layer in document order).

   Reset the UA `[popover]` defaults (centred, white panel, border).
   The lane is a transparent flex column anchored to a viewport corner;
   the toast cards inside paint themselves. `pointer-events: none` on
   the lane + `auto` on each toast lets clicks pass through empty
   space between cards. */
[data-toast-container] {
  position: fixed;
  inset: unset;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  overflow: visible;
  width: max-content;
  max-width: 100vw;
  z-index: 9999;             /* fallback for envs without Popover API */
  display: flex;
  gap: var(--a-space-2);
  pointer-events: none;
}
[data-toast-container]:popover-open {
  /* Native top-layer; component-level z-index above is moot here but kept
     for fallback. */
  display: flex;
}

/* Top lanes — newest at top, columns flow downward. */
[data-toast-container="top-right"],
[data-toast-container="top-center"],
[data-toast-container="top-left"] {
  top: var(--a-space-4);
  flex-direction: column;
}
/* Bottom lanes — newest at bottom, columns reverse so post() lands at
   the visually-newest position. */
[data-toast-container="bottom-right"],
[data-toast-container="bottom-center"],
[data-toast-container="bottom-left"] {
  bottom: var(--a-space-4);
  flex-direction: column-reverse;
}

[data-toast-container="bottom-right"],
[data-toast-container="top-right"] {
  right: var(--a-space-4);
  align-items: flex-end;
}
[data-toast-container="bottom-left"],
[data-toast-container="top-left"] {
  left: var(--a-space-4);
  align-items: flex-start;
}
[data-toast-container="top-center"],
[data-toast-container="bottom-center"] {
  left: 50%;
  transform: translateX(-50%);
  align-items: center;
}
