/**
 * CEV — shared verification popup design system.
 *
 * ONE stylesheet for every customer-facing verification surface: the signup
 * OTP popup, the login-authentication screen, the account-verify prompt and
 * the checkout verification popup. front.css and signup-style.css now only
 * carry their surface-specific extras and depend on this file.
 *
 * Styling is driven by CSS custom properties emitted once, server-side, by
 * CEV_Functions_Pro::popup_style_attr() on each popup's ROOT element. Every
 * token below carries a fallback so the card still renders correctly if the
 * attribute is absent (e.g. a Customizer preview iframe).
 *
 * Custom classes are cev-/otp- prefixed. Values live in tokens — do not
 * hardcode a colour or size that a merchant can configure.
 *
 * @package Customer_Email_Verification_Pro
 * @since   3.1.0
 */

/* ==========================================================================
   1. Tokens

   Declared on :root, NOT on the popup wrappers. This matters: the signup
   popup nests .cev-authorization-grid__visual inside a root that already
   carries the class. If the defaults were declared on those selectors, the
   NESTED element would match the rule, re-declare the defaults, and shadow
   the merchant's values inherited from the root's style attribute — the
   whole token layer would silently fall back to defaults.

   Declaring on :root means nothing between the popup root and the card
   re-declares a token, so the inline values from popup_style_attr() inherit
   all the way down. Every token is --cev-popup-* namespaced, so putting them
   on :root cannot collide with a theme.
   ========================================================================== */

:root {
	/* -- Merchant-configurable (overridden by popup_style_attr on the root) -- */
	--cev-popup-overlay: rgba( 15, 23, 42, 0.55 );
	--cev-popup-surface: #ffffff;
	--cev-popup-align: center;
	--cev-popup-width: 440px;
	--cev-popup-pad: 32px;
	--cev-popup-img-width: 80px;
	--cev-popup-heading-size: 20px;
	--cev-popup-accent: #4338ca;
	--cev-popup-on-accent: #ffffff;
	--cev-popup-btn-size: 15px;
	--cev-popup-btn-pad: 12px 20px;
	--cev-popup-btn-width: auto;

	/* -- Design tokens -- */
	--cev-popup-radius: 14px;
	--cev-popup-radius-sm: 9px;
	--cev-popup-border: rgba( 15, 23, 42, 0.08 );
	--cev-popup-text: #0f172a;
	--cev-popup-muted: #64748b;
	--cev-popup-danger: #dc2626;
	--cev-popup-danger-soft: #fef2f2;
	--cev-popup-success: #059669;
	--cev-popup-success-soft: #ecfdf5;
	--cev-popup-field-bg: #ffffff;
	--cev-popup-field-border: #d8dee9;
	/* Resting fill for OTP boxes / hover wells — the "empty" state. */
	--cev-popup-well: #f4f6fa;
	--cev-popup-chip-bg: #f1f5f9;

	/* Derived from --cev-popup-align so flex rows follow the merchant's
	   alignment setting; text-align alone cannot steer a flex container. */
	--cev-popup-justify: center;

	--cev-popup-shadow:
		0 1px 2px rgba( 15, 23, 42, 0.04 ),
		0 12px 32px -8px rgba( 15, 23, 42, 0.18 ),
		0 4px 12px -4px rgba( 15, 23, 42, 0.08 );
	--cev-popup-ring: 0 0 0 4px rgba( 67, 56, 202, 0.16 );

	--cev-popup-ease: cubic-bezier( 0.16, 1, 0.3, 1 );
}

/* ==========================================================================
   2. Overlay
   ========================================================================== */

.cev-authorization-grid__visual {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	height: 100%;
	width: 100%;
	z-index: 5000;
	background-color: var( --cev-popup-overlay );
	-webkit-backdrop-filter: blur( 3px );
	backdrop-filter: blur( 3px );
}

/* A nested overlay must never repaint the scrim — otherwise the tint stacks
   and the backdrop reads darker than the configured colour. */
.cev-authorization-grid__visual .cev-authorization-grid__visual {
	position: absolute;
	background-color: transparent;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
	z-index: auto;
}

.cev-authorization-grid__holder {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 1 1 0;
	height: 100%;
	padding: 24px 16px;
	position: relative;
	z-index: 100;
	box-sizing: border-box;
	overflow-y: auto;
}

.cev-authorization-grid__inner {
	max-width: var( --cev-popup-width );
	width: 100%;
}

/* ==========================================================================
   3. Card
   ========================================================================== */

.cev-authorization {
	border-radius: var( --cev-popup-radius );
	border: 1px solid var( --cev-popup-border );
	background-color: var( --cev-popup-surface );
	box-shadow: var( --cev-popup-shadow );
	overflow: hidden;
}

.cev-authorization__holder {
	padding: var( --cev-popup-pad );
	position: relative;
	text-align: var( --cev-popup-align );
	color: var( --cev-popup-muted );
	font-size: 15px;
	line-height: 1.55;
	box-sizing: border-box;
}

/* Header — the built-in mark.
   The default header. A logo lockup dominated the card and looked different on
   every store; a small accent tile anchors the eye without competing with the
   heading. Renders when no Header Image is set — see popup_uses_mark(). */
.cev-popup-mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border-radius: 12px;
	margin: 0 0 16px;
	background: var( --cev-popup-accent );
	color: var( --cev-popup-on-accent );
	flex: none;
}

.cev-popup-mark svg {
	width: 20px;
	height: 20px;
	display: block;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* Header — the merchant's own image, when they have set one. */
.popup_image {
	position: relative;
	display: inline-block;
	margin: 0 auto 16px;
	line-height: 0;
}

section.cev-authorization__holder .popup_image img,
.popup_image img {
	max-width: 100%;
	width: var( --cev-popup-img-width );
	height: auto;
}

/* ==========================================================================
   4. Typography
   ========================================================================== */

.cev-authorization__heading {
	position: relative;
}

.cev-authorization__title {
	display: block;
	color: var( --cev-popup-text );
	font-size: var( --cev-popup-heading-size );
	font-weight: 650;
	line-height: 1.25;
	letter-spacing: -0.018em;
	margin: 0 0 10px;
	text-wrap: balance;
}

.cev-authorization__description {
	display: block;
	margin: 0 0 10px;
	color: var( --cev-popup-muted );
	font-size: 13.5px;
	line-height: 1.5;
	text-align: var( --cev-popup-align );
}

.cev-authorization__description p,
.cev-authorization__description span,
.cev-authorization__description h1,
.cev-authorization__description h2,
.cev-authorization__description h3,
.cev-authorization__description h4,
.cev-authorization__description h5,
.cev-authorization__description h6 {
	margin: 0 0 6px;
}

/* The customer's email lands here as <strong> (the {customer_email} merge tag).
   Tinted rather than boxed: a bordered chip breaks badly when a long address
   wraps mid-sentence, and the message itself is merchant-editable prose.

   Horizontal padding is deliberately 0 with the tint bled outwards by a
   negative-margin-free box: padding pushed the following punctuation away from
   the chip, so "…@gmail.com." rendered as "…@gmail.com ." — which reads as a
   typo in the merchant's own copy. */
.cev-authorization__description strong,
.cev-authorization__description b {
	color: var( --cev-popup-text );
	font-weight: 600;
	background: var( --cev-popup-chip-bg );
	border-radius: 5px;
	box-shadow: 0 0 0 3px var( --cev-popup-chip-bg );
	word-break: break-word;
}

h5.required-filed,
h5.required-filed-email {
	font-size: 14px;
	text-align: initial;
	font-weight: 600;
	color: var( --cev-popup-text );
	margin: 0 0 8px;
}

/* ==========================================================================
   5. OTP input
   The single most-looked-at element in the plugin. Themes style bare inputs
   aggressively, so the box model and colours are defended with !important —
   the same defence the previous design used.
   ========================================================================== */

.otp-container {
	display: flex;
	justify-content: var( --cev-popup-justify );
	gap: 8px;
	margin: 0 0 4px;
	direction: ltr;
}

.otp-input,
.otp-input-login {
	width: 52px !important;
	height: 60px !important;
	margin: 0 !important;
	padding: 0 !important;
	font-size: 22px;
	font-weight: 650;
	font-variant-numeric: tabular-nums;
	text-align: center;
	color: var( --cev-popup-text );
	border: 1.5px solid var( --cev-popup-field-border ) !important;
	border-radius: var( --cev-popup-radius-sm ) !important;
	outline: none;
	/* Resting state is a filled well, so an empty box reads as "waiting" and a
	   typed one lifts to white. Without this the row is 4-6 identical outlines. */
	background: var( --cev-popup-well ) !important;
	box-shadow: none !important;
	box-sizing: border-box !important;
	transition:
		border-color 0.15s ease,
		background-color 0.15s ease,
		box-shadow 0.15s ease,
		transform 0.15s var( --cev-popup-ease );
	-moz-appearance: textfield;
}

.otp-input::-webkit-inner-spin-button,
.otp-input::-webkit-outer-spin-button,
.otp-input-login::-webkit-inner-spin-button,
.otp-input-login::-webkit-outer-spin-button {
	-webkit-appearance: none;
	appearance: none;
	margin: 0;
}

/* Filled — a digit has been entered.
   NOTE: this depends on the input carrying placeholder=" ". Without a
   placeholder attribute :placeholder-shown never matches, the negation is
   always true, and every box renders permanently "filled". */
.otp-input:not( :placeholder-shown ),
.otp-input-login:not( :placeholder-shown ) {
	background: var( --cev-popup-field-bg ) !important;
	border-color: var( --cev-popup-accent ) !important;
}

.otp-input:focus,
.otp-input-login:focus {
	background: var( --cev-popup-field-bg ) !important;
	border-color: var( --cev-popup-accent ) !important;
	box-shadow: var( --cev-popup-ring ) !important;
}

/* Error — set by JS alongside .error_mesg. */
.otp-container.is-error .otp-input,
.otp-container.is-error .otp-input-login,
.otp-input.is-error {
	border-color: var( --cev-popup-danger ) !important;
	animation: cev-popup-shake 0.4s var( --cev-popup-ease );
}

.otp-container.is-success .otp-input,
.otp-container.is-success .otp-input-login {
	border-color: var( --cev-popup-success ) !important;
}

/* ==========================================================================
   6. Buttons
   ========================================================================== */

.cev-button,
#verify-otp-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	border: none;
	outline: 0;
	position: relative;
	cursor: pointer;
	text-align: center;
	text-decoration: none;
	vertical-align: top;
	white-space: nowrap;
	margin: 0;
	/* Size / padding / full-width all come from the Customizer via tokens
	   (cev_popup_button_size + sample_toggle_switch_cev). */
	padding: var( --cev-popup-btn-pad );
	width: var( --cev-popup-btn-width );
	border-radius: var( --cev-popup-radius-sm );
	font-size: var( --cev-popup-btn-size );
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: 0;
	background-color: var( --cev-popup-accent );
	color: var( --cev-popup-on-accent );
	box-shadow: none;
	transition:
		background-color 0.15s ease,
		box-shadow 0.15s ease,
		transform 0.15s var( --cev-popup-ease ),
		opacity 0.15s ease;
}

.cev-button:hover,
#verify-otp-button:hover {
	transform: translateY( -1px );
	box-shadow: 0 6px 16px -4px rgba( 15, 23, 42, 0.24 );
}

.cev-button:active,
#verify-otp-button:active {
	transform: translateY( 0 );
}

.cev-button:focus-visible,
#verify-otp-button:focus-visible {
	box-shadow: var( --cev-popup-ring );
}

.cev-button:disabled,
#verify-otp-button:disabled {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
	box-shadow: none;
}

/* Width is NOT set here — it comes from --cev-popup-btn-width. This selector
   outranks the base .cev-button rule, so hardcoding a width here would pin every
   button to full-width and silently break the "auto" button setting. */
.cev-button:not( .cev-button-text-normal ) {
	text-transform: none;
	margin-bottom: 8px;
	line-height: 1.2;
}

/* Legacy modifier kept for markup that still emits it. */
.cev-button_color_success {
	background-color: var( --cev-popup-accent );
	color: var( --cev-popup-on-accent );
	font-size: 15px;
}

/* Text / link affordances */
.cev-link-try-again,
a.cev_already_verify {
	color: var( --cev-popup-accent );
	cursor: pointer;
	text-decoration: none;
	font-weight: 500;
}

.cev-link-try-again:hover,
a.cev_already_verify:hover {
	text-decoration: underline;
}

a.cev_already_verify {
	display: block;
	text-align: var( --cev-popup-align );
	font-size: 0.9em;
	padding: 0 0 10px;
}

/* Not actionable until a code has actually been sent. This was an inline
   "pointer-events: none; color: …" computed in PHP; it is session state, so it
   belongs in a class the stylesheet can own. */
a.cev_already_verify.cev-is-disabled {
	pointer-events: none;
	color: var( --cev-popup-muted );
	cursor: default;
}

.cev-try-again-disable {
	pointer-events: none;
	cursor: not-allowed;
	opacity: 0.5;
}

/* ==========================================================================
   7. States
   ========================================================================== */

.error_mesg {
	display: none;
	margin: 10px 0 0;
	color: var( --cev-popup-danger );
	font-size: 13px;
	line-height: 1.45;
	font-weight: 500;
}

.resend_sucsess {
	margin: 10px 0 0;
	color: var( --cev-popup-success );
	font-size: 13px;
	font-weight: 500;
}

/* Injected by signup-script.js after a successful verification. */
.cev-success-message {
	margin-top: 10px;
	text-align: center;
	color: var( --cev-popup-success, #059669 );
	font-size: 13px;
	font-weight: 500;
}

.cev_limit_message {
	color: var( --cev-popup-danger );
	font-size: 0.9em;
}

.cev_resend_timer {
	font-size: 12px;
	color: var( --cev-popup-muted );
}

.cev-alert {
	display: flex;
	align-items: center;
	overflow: hidden;
	padding: 12px 16px;
	position: relative;
	font-size: 13px;
	line-height: 1.5;
	border-radius: var( --cev-popup-radius-sm );
	margin-top: 12px;
}

.cev-alert_theme_red {
	background-color: var( --cev-popup-danger-soft );
	color: var( --cev-popup-danger );
}

.cev-alert_theme_green {
	background-color: var( --cev-popup-success-soft );
	color: var( --cev-popup-success );
}

.cev-pin-verification__failure {
	margin-bottom: 16px;
}

.cev-pin-verification__row {
	display: flex;
	justify-content: center;
}

.cev-pin-verification__events {
	position: relative;
	margin-bottom: 0;
}

.cev-field {
	box-sizing: border-box;
	display: block;
	width: 100%;
	position: relative;
	direction: ltr;
}

.cev-field_text_center input,
.cev-field_text_center textarea {
	text-align: center;
}

/* ==========================================================================
   7b. Resend affordance + account-verify message
   ========================================================================== */

.cev-av-msg {
	min-height: 18px;
	margin-top: 12px;
	font-size: 13px;
	line-height: 1.45;
	font-weight: 500;
	color: var( --cev-popup-muted );
}

.cev-av-msg.is-error {
	color: var( --cev-popup-danger );
}

.cev-av-msg.is-success {
	color: var( --cev-popup-success );
}

/* Account-verify keeps its timer and resend link together in one element, so
   the rail lives on the wrapper rather than on each child. */
.cev-resend-section {
	margin: 18px 0 0;
	padding: 14px 0 0;
	border-top: 1px solid var( --cev-popup-border );
	font-size: 12.5px;
}

.cev_resend_link_front {
	color: var( --cev-popup-accent );
	text-decoration: none;
	cursor: pointer;
	font-size: 13px;
	font-weight: 500;
}

.cev_resend_link_front:hover {
	text-decoration: underline;
}

.cev_resend_link_front:focus-visible {
	outline: none;
	box-shadow: var( --cev-popup-ring );
	border-radius: 4px;
}

/* ==========================================================================
   8. Footer
   ========================================================================== */

/* The footer rail.
   .cev-authorization__footer IS the resend control — signup-script.js grabs it
   as $resendButton, hides it during the countdown and reveals it after, while
   .cev_resend_timer shows in the meantime. Exactly one of the two is visible,
   so both carry the rail and the popup never shows an empty bordered strip. */
.cev-authorization__footer,
.cev-authorization__holder > .cev_resend_timer {
	display: block;
	margin: 18px 0 0;
	padding: 14px 0 0;
	border-top: 1px solid var( --cev-popup-border );
	color: var( --cev-popup-muted );
	font-size: 12.5px;
	line-height: 1.5;
	text-align: var( --cev-popup-align );
}

.cev-authorization__footer {
	cursor: pointer;
}

.cev-authorization__footer a {
	color: var( --cev-popup-accent );
	text-decoration: none;
	font-weight: 600;
}

.cev-authorization__footer a:hover {
	text-decoration: underline;
}

/* ==========================================================================
   9. Back / close control
   ========================================================================== */

/* Despite the name and its original back-arrow icon, .back_btn CLOSES the
   popup — signup-script.js and smart-form.js both hide the dialog on click.
   It now looks like what it does: a quiet ghost close control, out of the way
   in the top-right rather than colliding with the header image. */
.back_btn {
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	position: absolute;
	top: 12px;
	right: 12px;
	color: var( --cev-popup-muted );
	background-color: transparent;
	transition: color 0.15s ease, background-color 0.15s ease;
}

.back_btn:hover {
	color: var( --cev-popup-text );
	background-color: var( --cev-popup-well );
}

.back_btn:focus-visible {
	outline: none;
	box-shadow: var( --cev-popup-ring );
	color: var( --cev-popup-text );
}

.back_btn svg {
	width: 12px;
	height: 12px;
	display: block;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

/* ==========================================================================
   10. Loading
   ========================================================================== */

.cev_loading_overlay {
	display: none;
	position: fixed;
	inset: 0;
	top: 0;
	right: 0;
	left: 0;
	width: 100%;
	height: 100vh;
	z-index: 5001;
	background-color: rgba( 255, 255, 255, 0.6 );
	-webkit-backdrop-filter: blur( 2px );
	backdrop-filter: blur( 2px );
}

.cev_loading_overlay::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 28px;
	height: 28px;
	margin: -14px 0 0 -14px;
	border: 2.5px solid rgba( 15, 23, 42, 0.15 );
	border-top-color: var( --cev-popup-accent, #4338ca );
	border-radius: 50%;
	animation: cev-popup-spin 0.7s linear infinite;
}

/* ==========================================================================
   11. Motion
   ========================================================================== */

@keyframes cev-popup-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes cev-popup-rise {
	from { opacity: 0; transform: translateY( 8px ) scale( 0.98 ); }
	to   { opacity: 1; transform: translateY( 0 ) scale( 1 ); }
}

@keyframes cev-popup-shake {
	10%, 90% { transform: translateX( -1px ); }
	20%, 80% { transform: translateX( 2px ); }
	30%, 50%, 70% { transform: translateX( -4px ); }
	40%, 60% { transform: translateX( 4px ); }
}

@keyframes cev-popup-spin {
	to { transform: rotate( 360deg ); }
}

.cev-authorization-grid__visual {
	animation: cev-popup-fade 0.18s ease-out;
}

.cev-authorization {
	animation: cev-popup-rise 0.28s var( --cev-popup-ease );
}

@media ( prefers-reduced-motion: reduce ) {
	.cev-authorization-grid__visual,
	.cev-authorization,
	.otp-input,
	.otp-input-login,
	.cev-button,
	#verify-otp-button {
		animation: none !important;
		transition: none !important;
	}

	.otp-input:focus,
	.otp-input-login:focus,
	.cev-button:hover,
	#verify-otp-button:hover {
		transform: none;
	}

	.cev_loading_overlay::after {
		animation: cev-popup-spin 1.4s linear infinite;
	}
}

/* ==========================================================================
   12. Responsive
   Under 480px the card becomes a bottom sheet rather than a shrunken
   desktop card — it keeps the OTP row reachable above the keyboard.
   ========================================================================== */

@media ( max-width: 600px ) {
	.cev-authorization__holder {
		padding: clamp( 20px, 5vw, var( --cev-popup-pad ) );
	}

	.otp-container {
		gap: 8px;
	}

	.otp-input,
	.otp-input-login {
		width: 46px !important;
		height: 54px !important;
		font-size: 20px;
	}
}

@media ( max-width: 480px ) {
	.cev-authorization-grid__holder {
		align-items: flex-end;
		padding: 0;
	}

	.cev-authorization-grid__inner {
		max-width: 100%;
	}

	.cev-authorization {
		border-radius: var( --cev-popup-radius ) var( --cev-popup-radius ) 0 0;
		border-bottom: none;
		animation: cev-popup-sheet 0.28s var( --cev-popup-ease );
	}

	@keyframes cev-popup-sheet {
		from { transform: translateY( 16px ); opacity: 0; }
		to   { transform: translateY( 0 ); opacity: 1; }
	}
}

@media ( max-width: 360px ) {
	.otp-container {
		gap: 6px;
	}

	.otp-input,
	.otp-input-login {
		width: 40px !important;
		height: 48px !important;
		font-size: 18px;
	}
}
