/* Anchored Popover — app-wide anchored popover chrome (anchored_popover.js).
 *
 * Owns only the pop shell: the fixed/floating box, the height-morphing clip,
 * the loading skeleton, the caret, and the open/flip transitions. A body
 * brings its own internal layout. One #anchor-pop singleton lives in
 * <body>; the controller pins it to its trigger in viewport coords, so it is
 * never clipped by an overflow:hidden ancestor. */

.anchor-pop {
    position: fixed;
    z-index: 1080;
    width: 340px;
    background: var(--pop-bg, #0d1117);
    border: 1px solid var(--border-emphasis);
    border-radius: 12px;
    box-shadow: 0 22px 60px rgba(0, 0, 0, .6);
    font-size: 14px;
    line-height: 1.5;
    /* open/close is an opacity + lift fade, not a display toggle, so the pop
       eases in under its trigger; the controller pins its position */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-5px) scale(.985);
    transform-origin: top center;
    transition: opacity .13s ease, transform .13s ease, visibility 0s linear .13s;
    pointer-events: none;
}

.anchor-pop.open {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity .13s ease, transform .13s ease;
    pointer-events: auto;
}

/* flipped above its trigger: lift up from below, and (via the controller's
   pinned `bottom`) grow upward, so a height change never moves the caret */
.anchor-pop--up {
    transform-origin: bottom center;
    transform: translateY(5px) scale(.985);
}

.anchor-pop--up.open {
    transform: none;
}

/* `left`/`right` placement (controller positionHorizontal): pop beside the
   trigger, growing toward it from the facing edge. `centered-over`
   (positionCenteredOver): centred on the trigger, scaling up from its middle.
   The .open transform: none from .anchor-pop.open (higher specificity) lands
   all of these. */
.anchor-pop--right {
    transform-origin: left center;
    transform: translateX(-8px) scale(.985);
}

.anchor-pop--left {
    transform-origin: right center;
    transform: translateX(8px) scale(.985);
}

.anchor-pop--centered-over {
    transform-origin: center center;
    /* translateY(-50%) keeps the box centred on its trigger (controller pins top to
       the trigger's centre); as the body morphs in after load the -50% re-resolves
       against the new height, so it grows/shrinks evenly up and down. Closed it
       scales toward that centre for the fade-out. */
    transform: translateY(-50%) scale(.96);
}

/* open: a keyframe (not the shared transform transition) drives the scale-in so its
   explicit `from` can't be polluted by the class/position sequencing on first open
   — which otherwise slid it up from the default top-anchored transform. Both frames
   carry translateY(-50%), so it scales in place, centred, with no slide. */
.anchor-pop--centered-over.open {
    transform: translateY(-50%);
    animation: anchor-pop-centered-over-in .14s ease both;
}

@keyframes anchor-pop-centered-over-in {
    from {
        opacity: 0;
        transform: translateY(-50%) scale(.96);
    }
    to {
        opacity: 1;
        transform: translateY(-50%) scale(1);
    }
}

/* the clip morphs its height between the skeleton and the loaded body; the
   pinned anchor edge plus this transition make the unknown-size swap glide
   instead of jump. It also clips the body to rounded corners — the caret sits
   on .anchor-pop (outside this clip), so it is never cut off. */
.anchor-pop-clip {
    overflow: hidden;
    border-radius: inherit;
    transition: height .22s cubic-bezier(.4, 0, .2, 1);
}

/* each freshly-swapped body (skeleton, content, or a re-rendered error form)
   fades in, so the content change reads as a settle rather than a flash */
#anchor-pop-content > * {
    animation: anchor-pop-fade .18s ease both;
}

@keyframes anchor-pop-fade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* ---- loading skeleton: a compact form-shaped shimmer shown the instant the
        pop opens, kept shorter than any real body so the swap-in grows into
        place instead of shrinking (a shrink reads as a bounce) ---- */
.anchor-pop-sk-body {
    padding: 15px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.anchor-pop-sk-row {
    display: flex;
    gap: 10px;
}

.anchor-pop .sk-bar {
    display: block;
    border-radius: 6px;
    background: linear-gradient(100deg,
    rgba(255, 255, 255, .035) 30%,
    rgba(255, 255, 255, .09) 50%,
    rgba(255, 255, 255, .035) 70%) var(--surface-2, #1b1e27);
    background-size: 220% 100%;
    animation: anchor-pop-shimmer 1.3s ease-in-out infinite;
}

@keyframes anchor-pop-shimmer {
    from {
        background-position: 220% 0;
    }
    to {
        background-position: -120% 0;
    }
}

.anchor-pop .sk-label {
    width: 40%;
    height: 9px;
    margin-bottom: 8px;
}

.anchor-pop .sk-input {
    width: 100%;
    height: 36px;
}

.anchor-pop .sk-btn {
    width: 84px;
    height: 34px;
    border-radius: 7px;
}

/* caret aimed at the anchor: the controller sets --arrow-x (its x within the
   pop) and toggles --up when the pop is flipped above its trigger */
.anchor-pop::before {
    content: "";
    position: absolute;
    top: -7px;
    left: var(--arrow-x, 28px);
    margin-left: -6px;
    width: 12px;
    height: 12px;
    background: var(--pop-bg, #0d1117);
    border-left: 1px solid var(--border-emphasis);
    border-top: 1px solid var(--border-emphasis);
    transform: rotate(45deg);
}

.anchor-pop--up::before {
    top: auto;
    bottom: -7px;
    border-left: none;
    border-top: none;
    border-right: 1px solid var(--border-emphasis);
    border-bottom: 1px solid var(--border-emphasis);
}

/* sideways caret for left/right placement: on the edge facing the trigger, at
   --arrow-y (its y within the pop), pointing at the trigger's middle */
.anchor-pop--right::before,
.anchor-pop--left::before {
    top: var(--arrow-y, 28px);
    left: auto;
    margin-left: 0;
    margin-top: -6px;
    border: none;
}

.anchor-pop--right::before {
    left: -7px;
    border-left: 1px solid var(--border-emphasis);
    border-bottom: 1px solid var(--border-emphasis);
}

.anchor-pop--left::before {
    right: -7px;
    border-top: 1px solid var(--border-emphasis);
    border-right: 1px solid var(--border-emphasis);
}

/* centered-over sits on top of its trigger — no caret to tie it anywhere */
.anchor-pop--centered-over::before {
    display: none;
}

/* ---- confirm body ([data-popover-confirm]): icon tile + question, then an
        equal-width cancel/confirm row. Built client-side by the controller —
        no fetch, no skeleton. The --pc accent RGB follows the confirm style
        (the same class the confirm button gets), defaulting to danger. ---- */
.anchor-pop-confirm {
    --pc: var(--bs-danger-rgb);
    padding: 15px;
}

.anchor-pop-confirm--warning {
    --pc: var(--bs-warning-rgb);
}

.anchor-pop-confirm--primary {
    --pc: var(--bs-primary-rgb);
}

.anchor-pop-confirm--secondary {
    --pc: var(--bs-secondary-rgb);
}

.anchor-pop-confirm-head {
    display: flex;
    align-items: center;
    gap: 12px;
}

.anchor-pop-confirm-ic {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 9px;
    font-size: 15px;
    color: rgb(var(--pc));
    background: rgba(var(--pc), .14);
}

.anchor-pop-confirm-q {
    color: var(--text-primary);
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.45;
    text-wrap: pretty;
}

.anchor-pop-confirm-row {
    display: flex;
    gap: 9px;
    margin-top: 14px;
}

.anchor-pop-confirm-row .btn {
    flex: 1;
}

/* ---- optional header for a popover form body: a title (.ttl) + close-X (.x).
        Lay the flex/colour out with utilities in the markup; this owns only the
        bar's padding/border and the close button's red hover ---- */
.anchor-pop-head {
    padding: 13px 15px;
    border-bottom: 1px solid var(--border-subtle);
}

.anchor-pop-head .ttl {
    font-size: 12px;
    letter-spacing: .06em;
}

/* close-X is .text-muted in markup; red hover, no btn-link underline */
.anchor-pop-head .x:hover, .anchor-pop-head .x:focus {
    color: var(--color-red) !important;
    background: rgba(239, 68, 68, .12);
    text-decoration: none !important;
}

/* --- Light theme: the skeleton shimmer is white-alpha (invisible on the
   light --surface-2 base) — flip it to black-alpha. --- */
html[data-theme="light"] .anchor-pop .sk-bar {
    background: linear-gradient(100deg,
    rgba(0, 0, 0, .04) 30%,
    rgba(0, 0, 0, .09) 50%,
    rgba(0, 0, 0, .04) 70%) var(--surface-2, #eceef2);
    background-size: 220% 100%;
}
