/*!
 * HAF Core — shared form styles.
 *
 * Only loaded on sites whose theme does NOT declare
 * add_theme_support( 'haf-core-forms' ). SHOP's theme styles these classes
 * itself (with polish that must not be overwritten — see class-assets.php),
 * so in practice this file ships to MAIN only.
 *
 * Written against Bootstrap 5 utilities/variables that BOTH themes already
 * load, but with no SCSS dependency: this is plain CSS on purpose so it needs
 * no build step on a host we do not run a compiler on.
 */

/* ── Bot trap ───────────────────────────────────────────────────────────── */

/*
 * Off-canvas rather than display:none — some bots deliberately skip
 * display:none fields because that is the obvious tell. Kept out of the
 * accessibility tree by aria-hidden and out of tab order by tabindex="-1".
 */
.haf-core-trap {
	position: absolute !important;
	left: -9999px !important;
	top: auto !important;
	width: 1px !important;
	height: 1px !important;
	overflow: hidden !important;
}

/* ── Inline field tips ──────────────────────────────────────────────────── */

.haf-core-field {
	position: relative;
	/* The field is normally a Bootstrap grid column, i.e. already a flex
	   child, and flex children default to min-width:auto — a long
	   validation message would widen the field and reflow the whole row.
	   No flex sizing here on purpose: the grid owns the widths, and a
	   `flex: 1 1 0` at this specificity beat the .col-md-6 columns (this
	   file prints in the footer, after main.css) and collapsed the
	   contact form's three rows onto one. */
	min-width: 0;
}

.haf-core-tip {
	position: absolute;
	top: 100%;
	left: 0;
	margin: 2px 0 0;
	font-size: 12px;
	line-height: 1.3;
	font-weight: 700;
	/*
	 * #dc3232, NOT the theme's $danger. In this brand $danger is #9A1F07, a
	 * deep maroon that disappears against the dark footer the signup form sits
	 * on. #dc3232 is the red the old CF7 plugin used and the one the user
	 * recognises as "the error red".
	 */
	color: #dc3232;
	animation: haf-core-fade-in 0.3s ease;
}

@keyframes haf-core-fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

/* ── Inline form layout ─────────────────────────────────────────────────── */

.haf-core-form {
	display: flex;
	flex-flow: row wrap;
	gap: 0.5rem;
	position: relative;
}

/*
 * Reserve the validation-icon gutter AT ALL TIMES, not just in .is-invalid.
 * Applying it only on error shifts the input's text and — where the column
 * is not clamping — resizes the whole form the instant a message appears.
 */
.haf-core-form .form-control {
	padding-right: 2.5rem;
}

.haf-core-form .form-control::placeholder {
	color: #ced4da;
	opacity: 1;
}

/*
 * The disclosure line is long. In a shrink-to-fit flex form it would stretch
 * the form to its own width (measured 300px -> 396px on the shop footer), so
 * it is forced onto its own full-width row that contributes zero to the
 * intrinsic width calculation.
 */
.haf-core-form .haf-recaptcha-disclosure {
	flex: 0 0 100%;
	width: 0;
	min-width: 100%;
	margin-top: 1.25rem;
	margin-bottom: 0;
	font-size: 11px;
	line-height: 1.4;
	opacity: 0.75;
}

/* Google's badge is hidden, so this branding line is REQUIRED by their terms.
   If the disclosure ever stops rendering, the hide rule below must go too. */
.grecaptcha-badge {
	visibility: hidden;
}

/* ── Submit button loading state ────────────────────────────────────────── */

.haf-core-form button.is-loading {
	position: relative;
	color: transparent !important;
}

.haf-core-form button.is-loading::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 1em;
	height: 1em;
	margin: -0.5em 0 0 -0.5em;
	border: 2px solid currentColor;
	border-right-color: transparent;
	border-radius: 50%;
	color: #fff;
	animation: haf-core-spin 0.75s linear infinite;
}

@keyframes haf-core-spin {
	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.haf-core-tip {
		animation: none;
	}
	.haf-core-form button.is-loading::after {
		animation-duration: 2s;
	}
}

/* ── Fallback toasts (only used where the theme has no toast system) ────── */

.haf-core-toasts {
	position: fixed;
	z-index: 1080;
	left: 50%;
	bottom: 1.5rem;
	transform: translateX(-50%);
	width: min(92vw, 420px);
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	pointer-events: none;
}

.haf-core-toast {
	pointer-events: auto;
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	padding: 0.75rem 1rem;
	border-left: 4px solid currentColor;
	background: #fff;
	color: #1c1421;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
	font-size: 14px;
	line-height: 1.45;
	animation: haf-core-toast-in 0.3s ease;
}

.haf-core-toast--success {
	border-left-color: #7ac143;
}

.haf-core-toast--error {
	border-left-color: #dc3232;
}

.haf-core-toast.is-leaving {
	animation: haf-core-toast-out 0.3s ease forwards;
}

.haf-core-toast__close {
	margin-left: auto;
	border: 0;
	background: none;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	color: inherit;
	opacity: 0.6;
}

.haf-core-toast__close:hover,
.haf-core-toast__close:focus-visible {
	opacity: 1;
}

@keyframes haf-core-toast-in {
	from {
		opacity: 0;
		transform: translateY(8px);
	}
}

@keyframes haf-core-toast-out {
	to {
		opacity: 0;
		transform: translateY(8px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.haf-core-toast,
	.haf-core-toast.is-leaving {
		animation: none;
	}
}

/* ── Grid-column fields ─────────────────────────────────────────────────── */

/*
 * On the contact form the field wrapper IS the Bootstrap column, and a
 * column's padding box starts half a gutter to the left of the control it
 * holds. Anchored at left:0 the tip therefore printed ~8px outside the
 * input's edge — reported on hashandflowers.com the day the form went live.
 * Both themes compile Bootstrap with the `haf` variable prefix; the
 * fallbacks cover a stock build.
 */
.row > .haf-core-field > .haf-core-tip {
	left: calc(var(--haf-gutter-x, var(--bs-gutter-x, 1.5rem)) * 0.5);
}

/*
 * Bootstrap recolours the whole consent sentence in the invalid colour the
 * moment the checkbox is flagged. The box and the tip beneath already carry
 * the state; the CF7 form this replaced never touched the label, and the
 * user asked for that back.
 */
.haf-core-field .form-check-input.is-invalid ~ .form-check-label {
	color: inherit;
}
