/* 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, and dialog accessibility semantics are
   handled natively; background page scroll is locked via .npsp-modal-open
   (see below) because native body-lock for showModal'd dialogs is
   inconsistent across browsers.

   Layout: a fixed-size dialog laid out as a vertical flex column —
     [ header bar (title + close) ]   ← flex: 0 0 auto, our chrome
     [ iframe                     ]   ← flex: 1, the donate form
   The header is OURS (parent page), so the close button lives in its own
   strip and can never overlap the cross-origin form content. The iframe
   fills the rest and scrolls its own content internally (Stripe Checkout /
   Donorbox modal pattern). */
.npsp-donate__dialog {
    /* Reset native <dialog> defaults: white bg, padding, default border. */
    border: 0;
    padding: 0;
    background: #ffffff;
    color: inherit;
    /* Fixed-size dialog: never grows or shrinks based on iframe content. */
    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);
}

/* Hard background-scroll lock while the modal is open. Applied as a class on
   <html> and <body> (by embed.js) so it wins over theme rules — a bare inline
   `overflow:hidden` can be defeated and lets the page's own scrollbar bleed
   through the dimmed backdrop at the viewport's right edge. `scrollbar-gutter:
   stable` is scoped to the open state so the gutter the now-hidden scrollbar
   used to occupy stays reserved — no sideways content jump on open/close. */
html.npsp-modal-open,
body.npsp-modal-open {
    overflow: hidden !important;
}
html.npsp-modal-open {
    scrollbar-gutter: stable;
}

/* 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;
        }
    }
}

/* Header bar — the modal's own chrome (title + close). Lives in the parent
   page, above the iframe, so the close button has dedicated real estate and
   never overlays the cross-origin donate form. flex:0 0 auto keeps it at its
   natural height while the iframe below takes the rest. */
.npsp-donate__header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 3rem;
    padding: 0.4rem 0.5rem 0.4rem 1rem;
    background: #ffffff;
    border-bottom: 1px solid var(--npsp-card-border);
    box-sizing: border-box;
}

.npsp-donate__title {
    font-size: 1rem;
    font-weight: 600;
    font-style: normal;
    line-height: 1.2;
    color: var(--npsp-card-text);
}

/* In-header close button: a light, modest control (not a heavy floating
   circle). 44px hit area for touch (Apple HIG / Material) with a transparent
   resting state so it reads as chrome, not an overlay. */
.npsp-donate__close {
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--npsp-card-muted);
    font-size: 1.5rem;
    line-height: 1;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 120ms ease, 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.08);
    color: var(--npsp-card-text);
    outline: 2px solid var(--npsp-primary, #d63131);
    outline-offset: 1px;
}

.npsp-donate__frame {
    /* Fills the dialog's remaining height below the header bar. 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;
}
