/* Payment-method pill row + mode-based field visibility for the donation forms
   (form 10 — /give and /donate-to-help-hope-live). */
/* The pill row (#hhl-pay-method) sits at the top of the payment card inside GF's
   fields grid, so grid-column:1/-1 makes it span the full row (else it collapses
   to one column — the HHLTB-2543 zero/narrow-width hazard). The wallet button
   (#hhl-express-checkout) is anchored to .gform_footer instead (apple-pay-ece.js
   ensureMarkup(), plus forms.js wrapDonationCards() on the theme side) and lives
   in the terms/submit card next to Give Now, not under the pills here — it is
   the submit control for the wallet path, same as Give Now is for the card
   path. Its grid-column is kept only as a defensive no-op for the rare fallback
   that lands it inside GF's fields grid instead. */
#hhl-pay-method { margin: 0 0 1.25rem; grid-column: 1 / -1; }
#hhl-pay-method .hhl-pay-legend { font-weight: 600; margin-bottom: .5rem; display: block; }
#hhl-pay-method[hidden] { display: none !important; }

/* Wallet mode: hide the donor/card fields the wallet supplies. Email (field 9)
   stays visible as the receipt destination. The credit-card field is targeted
   by its GF type class, NOT a numeric id — that id is re-created per
   environment (local 17, dev 59, live may differ again). The billing address is
   targeted by its marker class for the same reason (its id differs per env by
   construction) — the wallet supplies the address via applyBackfill(). */
.hhl-mode-applepay #field_10_7,
.hhl-mode-googlepay #field_10_7,
.hhl-mode-applepay #field_10_23,
.hhl-mode-googlepay #field_10_23,
.hhl-mode-applepay .hhl-billing-address,
.hhl-mode-googlepay .hhl-billing-address,
.hhl-mode-applepay .gfield--type-stripe_creditcard,
.hhl-mode-googlepay .gfield--type-stripe_creditcard,
.hhl-mode-applepay #field_10_49,
.hhl-mode-googlepay #field_10_49 { display: none !important; }

/* In wallet mode the only completion path is the wallet button, so hide GF's
   footer — otherwise a donor can submit into validation errors on hidden
   required fields. */
.hhl-mode-applepay .gform_footer,
.hhl-mode-googlepay .gform_footer { display: none !important; }

/* Card mode (covers both card and ACH — Stripe's own Payment Element tabs
   pick between them) uses GF's Payment Element; hide the wallet button. */
.hhl-mode-card #hhl-express-checkout { display: none; }

/* ---------------------------------------------------------------------------
   The payment-resolution mask (HHLTB-2735).

   The form renders with no mode class, so GF Stripe's Payment Element and its
   Card/Bank/Link tabs used to be on screen and interactive from first paint —
   then vanished seconds later when the ECE `ready` event finally reported a
   wallet and the preselect hid them, mid-typing. Nothing may be offered before
   the mode is known, so the Payment Element run is masked until it is.

   `visibility`, never `display` — the same rule the wallet mount lives by
   below. The mask must not change what any Stripe element measures at mount:
   `display: none` pins the measured width to 0 forever (HHLTB-2543), while
   visibility keeps the real layout box and merely stops the subtree painting.
   It also takes the hidden Payment Element out of the tab order, so the
   keyboard route into "typing into fields that are about to disappear" closes
   with the visual one. Re-asserted `visible` on the loading box below, which
   is a child of the hidden subtree.

   The reserved min-height is roughly a mounted Payment Element's height, so
   the card does not jump when the mask lifts onto one.

   The animation is the backstop that makes this mask safe to ship: it reveals
   the payment fields on its own, so they cannot stay hidden behind a spinner
   whatever happens to the JavaScript — blocked, 404, or throwing before its
   timer is armed. A permanently masked payment area costs the donation
   outright, so the reveal must not depend on JS at all. Verified by blocking
   apple-pay-ece.js outright: the fields stayed masked at a reserved 220px and
   real width, then came back with min-height released and no script having run.

   The 4s delay deliberately EQUALS apple-pay-ece.js's MASK_TIMEOUT_MS instead
   of sitting behind it, and the ordering still holds because the two clocks
   differ: an animation delay runs from the moment the element starts animating
   (its first render), while that script's budget runs from navigation start. So
   this rule can only ever expire at or after the script's cap — locally, JS
   lifted at 4.03s and this rule at 5.39s off a field first rendered at 1.39s.
   Should the script run so late that this wins anyway, its budget is by then
   spent, which leaves it able to resolve only 'timeout' — never 'ready' — so
   the revealed fields still cannot be pulled back out (HHLTB-2735). Change one
   delay and change the other, or that argument breaks.

   Note this reveals the FIELDS while the body class stays until the script
   removes it — which is why the loading box below is only ever injected inside
   a live window; a stale one would otherwise sit over the revealed fields. */
body.hhl-pay-resolving .gform_wrapper .gfield--type-stripe_creditcard {
	position: relative;
	min-height: 13.75rem;
	visibility: hidden;
	animation: hhl-pay-mask-expire 1ms linear 4s forwards;
}
@keyframes hhl-pay-mask-expire { to { visibility: visible; min-height: 0; } }

/* The loading box (apple-pay-ece.js installLoadingBox()) only ever shows
   inside that window: keying its display off the body class means a stale node
   cannot outlive the mask even if JS fails to remove it. */
.hhl-pay-loading { display: none; }
body.hhl-pay-resolving .gform_wrapper .hhl-pay-loading {
	display: flex;
	visibility: visible;
	position: absolute;
	inset: 0;
	align-items: center;
	justify-content: center;
	gap: .625rem;
	color: #495057;
}
.hhl-pay-loading__spinner {
	flex: 0 0 auto;
	width: 1.25rem;
	height: 1.25rem;
	border: 3px solid #c1e8e8;
	border-top-color: #00aeb3;
	border-radius: 50%;
	animation: hhl-wallet-spin .8s linear infinite;
}
@media ( prefers-reduced-motion: reduce ) {
	.hhl-pay-loading__spinner { animation: none; }
}

/* The wallet button stays invisible until apple-pay-ece.js has confirmed the
   mounted Express Checkout Element is restricted to the wallet the donor's pill
   actually selects (HHLTB-2699). The very first mount is deliberately
   unrestricted — it is how the page discovers which wallets the device has —
   and would otherwise show Apple Pay AND Google Pay for the moment before the
   restricted rebuild lands.

   `visibility`, never `display`: ECE measures its container width once at mount
   and a zero-width mount produces a 0-height button that never recovers
   (HHLTB-2543), so this box must keep its real width the whole time.

   The reserved min-height matches Stripe's default 44px wallet button so the
   card below does not jump while an element is being destroyed and rebuilt
   (visibility keeps the box, but a destroyed element leaves it empty). It is a
   MIN only, and height is not what ECE measures at mount (width is), so it
   cannot reintroduce HHLTB-2543. */
#hhl-express-checkout { visibility: hidden; min-height: 44px; }
#hhl-express-checkout.is-wallet-ready { visibility: visible; }

/* Form 10's three section breaks (34, 44, 48) exist as structural anchors, not
   as headings — 34 is where the payment pill row is injected, 44 is the card-2
   boundary. GF still renders each one's title as <h3 class="gsection_title">,
   and an EMPTY h3 keeps a full heading's worth of height. Collapse those so the
   sections contribute only their separator rule. */
#gform_wrapper_10 .gsection_title:empty { display: none; }

/* Section 34 sits between the pill row and the Payment Element. In wallet mode
   the Payment Element is hidden, which would leave 34's separator rule and its
   margin stranded at the bottom of the payment card with nothing beneath them.
   Hide the whole section in wallet mode. Safe for the pill row: the pills are
   inserted BEFORE this node and stay where they are, and getElementById (which
   apple-pay-ece.js uses to find the anchor) is unaffected by display. */
.hhl-mode-applepay #field_10_34,
.hhl-mode-googlepay #field_10_34 { display: none !important; }

/* Pills. Mirrors the theme's .inline-buttons treatment used by the amount,
   tip and frequency pills (_forms.scss:121-162). */
#hhl-pay-method .hhl-pay-options { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.hhl-pay-pill {
	border: 1.5px solid #ced4da;
	border-radius: 50px;
	background: #fff;
	padding: .5rem 1.25rem;
	font-weight: 600;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color .15s, border-color .15s;
}
.hhl-pay-pill.is-selected { border-color: #00aeb3; background-color: #c1e8e8; color: #003d3f; }

/* The order total is a computed display value, not an input. Strip the border/
   background GF's gravity-theme gives it so donors don't read it as an editable
   field (applies to both Total fields on the donation forms). Scoped to the
   gravity-theme wrapper to match the theme's own total rule specificity. */
.gform_wrapper.gravity-theme .ginput_container_total,
.gform_wrapper.gravity-theme .ginput_total {
	padding: 0 !important;
	border: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}

/* The wallet "processing" overlay (apple-pay-ece.js showProcessing()). Raised
   the instant the donor authorizes the Apple Pay / Google Pay sheet and held
   until the page navigates to the confirmation, so the multi-second gap between
   Face ID and the thank-you page is not a silent, untouched-looking form that
   invites a second tap, a back swipe or a refresh. Being fixed and full-viewport
   is load-bearing, not decoration: it physically covers the wallet button,
   backing up the walletPaymentCompleted re-tap refusal. The element is injected
   into <body> because the donation cards/GF grid could otherwise trap a fixed
   child in a containing block. */
.hhl-wallet-processing {
	position: fixed;
	inset: 0;
	/* Above GF/theme overlays and the sticky header, and deliberately NOWHERE
	   NEAR max int: confirmPayment() can still raise Stripe's 3DS challenge
	   (unusual for Apple Pay, reachable via Google Pay) while this overlay is
	   up, and Stripe pins that challenge at the maximum z-index. Covering it
	   would strand the donor mid-authentication with no way to finish paying.
	   Do not raise this to 2147483647. */
	z-index: 100000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
	background: rgba( 255, 255, 255, .95 );
	text-align: center;
}
.hhl-wallet-processing[hidden] { display: none; }
.hhl-wallet-processing__box { max-width: 22rem; }
.hhl-wallet-processing__spinner {
	width: 2.75rem;
	height: 2.75rem;
	margin: 0 auto 1.25rem;
	border: 4px solid #c1e8e8;
	border-top-color: #00aeb3;
	border-radius: 50%;
	animation: hhl-wallet-spin .8s linear infinite;
}
.hhl-wallet-processing__title {
	margin: 0 0 .5rem;
	font-size: 1.25rem;
	font-weight: 700;
	color: #003d3f;
}
.hhl-wallet-processing__note { margin: 0; color: #495057; }
.hhl-wallet-processing__slow { margin: .75rem 0 0; font-size: .875rem; color: #6c757d; }
.hhl-wallet-processing__slow[hidden] { display: none; }

@keyframes hhl-wallet-spin { to { transform: rotate( 360deg ); } }

/* No spin for donors who asked for less motion — the overlay's copy is what
   actually carries the "don't touch anything" message, so losing the animation
   costs nothing. */
@media ( prefers-reduced-motion: reduce ) {
	.hhl-wallet-processing__spinner { animation: none; }
}
