/* npsp-middleware-wp — donate widgets
 * BEM-namespaced (.npsp-donate__*) so it never collides with theme styles.
 *
 * COLOR RESOLUTION
 *   Fonts and most colors are NOT set here — they inherit from the active WP
 *   theme via normal CSS inheritance. The CTA background is the only color we
 *   care about strongly enough to opt into a fallback chain:
 *
 *     1. --npsp-primary       (set by Settings → "CTA color override", if any)
 *     2. --wp--preset--color--accent-1   (block-theme convention, e.g. TT4)
 *     3. --wp--preset--color--accent
 *     4. --wp--preset--color--primary
 *     5. #d63131  (hardcoded red fallback)
 *
 *   Hover is auto-derived as "primary darkened 15%" via color-mix(). To force
 *   a different palette site-wide without admin: drop a `:root { --npsp-primary: #yourcolor }`
 *   into the theme's CSS — it wins over everything except the explicit Settings override.
 */

:root {
    --npsp-on-primary: #ffffff;
    --npsp-card-bg: #ffffff;
    --npsp-card-text: #1f1f1f;
    --npsp-card-muted: #4a4a4a;
    --npsp-card-border: #e2e2e2;
    --npsp-overlay-bg: rgba(15, 15, 15, 0.7);
    --npsp-radius: 8px;
    --npsp-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
}

/* ─── CTA (button + card) ──────────────────────────────────────────────── */

.npsp-donate__cta {
    /* Resolved primary color — see chain in the file header. Defined locally
       on the CTA so theme variables (which live on body, not :root) are
       reachable via inheritance. */
    --npsp-resolved-primary: var(--npsp-primary,
                              var(--wp--preset--color--accent-1,
                              var(--wp--preset--color--accent,
                              var(--wp--preset--color--primary,
                              #d63131))));
    box-sizing: border-box;
    display: inline-block;
    padding: 0.75em 1.4em;
    /* Properties below use !important to defend the button look against the
       theme's link styles. Themes commonly attach .entry-content a / a:hover
       rules with higher specificity than ours; this neutralizes them so the
       CTA renders consistently regardless of theme. To allow the theme to
       drive a property, just remove the !important on that line. */
    background: var(--npsp-resolved-primary) !important;
    color: var(--npsp-on-primary) !important;
    border: 0 !important;
    border-radius: var(--npsp-radius);
    font-weight: 600 !important;
    font-style: normal !important;
    font-size: 1rem;
    line-height: 1.2;
    text-decoration: none !important;
    text-shadow: none !important;
    text-transform: none !important;
    cursor: pointer;
    transition: background-color 120ms ease;
}

/* Cover every interactive state — themes target most of these, especially
   :hover and :visited. */
.npsp-donate__cta:link,
.npsp-donate__cta:visited,
.npsp-donate__cta:hover,
.npsp-donate__cta:focus,
.npsp-donate__cta:focus-visible,
.npsp-donate__cta:active {
    color: var(--npsp-on-primary) !important;
    text-decoration: none !important;
    border-color: transparent !important;
}

.npsp-donate__cta:hover,
.npsp-donate__cta:focus-visible {
    /* color-mix has ~95% browser support; falls back to plain primary on the
       handful of browsers that don't (Safari pre-16.4, etc.). */
    background: color-mix(in srgb, var(--npsp-resolved-primary), black 15%) !important;
}

.npsp-donate__cta:focus-visible {
    outline: 3px solid var(--npsp-resolved-primary);
    outline-offset: 3px;
}

.npsp-donate__cta--card {
    width: 100%;
    text-align: center;
}

/* Standalone button — wrap matches the surrounding paragraph rhythm so it
   doesn't sit flush against the block container's left edge. */
.npsp-donate__button-wrap {
    margin: 1em 0;
}

/* ─── Inline card (text overlaid on image) ─────────────────────────────── */

.npsp-donate__card {
    position: relative;
    display: block;
    width: 100%;
    /* Always fill the container's content width — no fixed cap.
       The aspect-ratio scales the height proportionally. */
    aspect-ratio: 8 / 5;
    overflow: hidden;
    border-radius: var(--npsp-radius);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
    background: #1a1a1a;
    color: #ffffff;
    box-sizing: border-box;
}

.npsp-donate__card *,
.npsp-donate__card *::before,
.npsp-donate__card *::after {
    box-sizing: border-box;
}

.npsp-donate__card-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    z-index: 0;
}

.npsp-donate__card-logo {
    width: 40px;
    height: 40px;
    object-fit: contain;
    align-self: flex-start;
    margin-bottom: 0.1rem;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}

.npsp-donate__card-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 1rem;
    background: linear-gradient(180deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0.55) 40%,
        rgba(0, 0, 0, 0.92) 100%);
    color: #ffffff;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.npsp-donate__card-overlay.has-text {
    padding-top: 1.5rem;
}

/* Same defense-against-theme-rules as the CTA. The card text sits on a dark
   image gradient and MUST stay light/readable. Themes that style h3 or p
   inside .entry-content would otherwise win on specificity and ruin contrast. */
.npsp-donate__card-headline {
    margin: 0 !important;
    color: #ffffff !important;
    font-size: 1.25rem !important;
    font-weight: 700 !important;
    font-style: normal !important;
    line-height: 1.25 !important;
    text-decoration: none !important;
    text-transform: none !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45) !important;
}

.npsp-donate__card-text {
    margin: 0 !important;
    color: rgba(255, 255, 255, 0.95) !important;
    font-size: 1rem !important;
    font-style: normal !important;
    line-height: 1.4 !important;
    text-decoration: none !important;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4) !important;
}

/* ─── Card on mobile ───────────────────────────────────────────────────
   The 8:5 landscape aspect on phone widths squeezes the overlay so the logo
   (top of the overlay's flex column) gets clipped by overflow:hidden. Keep
   the same overlay-on-image layout (image as backdrop, gradient + text at
   the bottom) but switch to a portrait 4:5 aspect under 600px so the card
   is tall enough to fit logo + headline + body + CTA without any clipping. */
@media (max-width: 600px) {
    .npsp-donate__card {
        aspect-ratio: 4 / 5;
    }
}

/* ─── Modal: native <dialog> element ────────────────────────────────────
   The modal is a real <dialog> opened with .showModal(). That places it in
   the browser's "top layer" — above the entire DOM tree including iframes —
   so hit-testing routes events to the close button deterministically across
   every browser. ESC, focus trap, body scroll lock, and dialog accessibility
   semantics are handled natively. */
.npsp-donate__dialog {
    /* Reset native <dialog> defaults: white bg, padding, default border. */
    border: 0;
    padding: 0;
    background: transparent;
    color: inherit;
    /* Fixed-size dialog: never grows or shrinks based on iframe content.
       The iframe inside fills the dialog and scrolls its own content
       internally (Stripe Checkout / YouTube modal pattern). With a fixed
       footprint, the close button at position:absolute stays pinned to
       the dialog's top-right corner forever. */
    width: calc(100% - 2rem);
    max-width: 720px;
    height: 90vh;
    max-height: 90vh;
    margin: auto;
    overflow: hidden;
    border-radius: var(--npsp-radius);
    display: flex;
    flex-direction: column;
}

.npsp-donate__dialog::backdrop {
    background: var(--npsp-overlay-bg);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

/* On small viewports, fill the screen edge-to-edge. `100dvh` (dynamic
   viewport height) tracks the iOS address-bar collapse so the dialog
   doesn't end up taller than the visible area. */
@media (max-width: 640px) {
    .npsp-donate__dialog {
        width: 100%;
        max-width: 100%;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
    }
    /* Pre-iOS-15.4 / pre-Firefox-101 fallback. */
    @supports not (height: 100dvh) {
        .npsp-donate__dialog {
            height: 100vh;
            max-height: 100vh;
        }
    }
}

/* Close button is back inside the dialog. Top-layer placement (via showModal)
   makes its hit-test reliable across browsers — no fixed-positioning workaround
   or z-index gymnastics needed. */
.npsp-donate__close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    width: 2.75rem;
    height: 2.75rem;
    border: 0;
    background: rgba(0, 0, 0, 0.6);
    color: #ffffff;
    font-size: 1.5rem;
    line-height: 1;
    border-radius: 999px;
    cursor: pointer;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    transition: background-color 120ms ease;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.npsp-donate__close:hover,
.npsp-donate__close:focus-visible {
    background: rgba(0, 0, 0, 0.78);
    outline: 2px solid rgba(255, 255, 255, 0.55);
    outline-offset: 2px;
}

.npsp-donate__frame {
    /* Fills the dialog's remaining height (after the absolute-positioned
       close button). Form scrolls inside the iframe via its own native
       scrollbar — we no longer derive iframe height from postMessage. */
    width: 100%;
    flex: 1;
    border: 0;
    background: transparent;
    display: block;
}

/* Admin-only notice when base URL isn't configured */
.npsp-donate__notice {
    padding: 0.75rem 1rem;
    background: #fff8e1;
    border-left: 4px solid #ffb300;
    color: #663c00;
    font-size: 0.9rem;
    margin: 0.5rem 0;
}
