/* ==========================================================================
   Shared primitives reused across multiple PCGU widgets. Ported verbatim
   from pestcontrolgroupusa_core_old (components.css / animations.css) —
   registered once via Assets_Manager, depended on by any widget that
   needs it, never duplicated per-widget.
   ========================================================================== */

/* ---- Icon base (Lucide-equivalent inline SVGs: stroke, not filled) ----
   Without this, every <svg class="icon"> in Icon_Library falls back to the
   browser default (solid black fill) instead of the intended thin-stroke
   outline style — this was missing and is why icons looked wrong. ---- */
.icon {
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
	flex-shrink: 0;
	display: inline-block;
	width: 1em;
	height: 1em;
}

/* ---- Generic bordered card (FAQ list now; reusable anywhere a plain
   bordered/shadowed surface is needed) ---- */
.card {
	border-radius: var(--radius-2xl);
	border: 1px solid var(--border);
	background-color: var(--card);
	box-shadow: var(--shadow-lift);
}

/* ---- Icon circle (phone-icon wraps at several sizes) ---- */
.icon-circle {
	position: relative;
	display: grid;
	place-items: center;
	border-radius: 9999px;
	background-color: rgba(255, 255, 255, 0.15);
	flex-shrink: 0;
}
.icon-circle--sm { height: 2rem; width: 2rem; }
.icon-circle--md { height: 2.25rem; width: 2.25rem; }
.icon-circle--lg { height: 2.5rem; width: 2.5rem; }
.icon-circle--xl { height: 2.75rem; width: 2.75rem; }

/* ---- Pulse ring (idle CSS animation, not GSAP-driven) ---- */
@keyframes pulse-ring {
	0% {
		box-shadow: 0 0 0 0 color-mix(in oklab, var(--secondary) 55%, transparent);
	}
	70% {
		box-shadow: 0 0 0 18px color-mix(in oklab, var(--secondary) 0%, transparent);
	}
	100% {
		box-shadow: 0 0 0 0 color-mix(in oklab, var(--secondary) 0%, transparent);
	}
}
.pulse-ring {
	animation: pulse-ring 2.2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* GSAP (assets/js/animations.js) sets inline transforms/opacity for these
   targets on load; these starting states prevent a flash-of-unanimated-
   content before JS runs. */
.js-blob,
.js-float {
	will-change: transform;
}

.js-fade-up {
	opacity: 0;
	transform: translateY(16px);
}

.js-ping-dot {
	will-change: transform, opacity;
}

/* ---- Active-link underline (nav links across Header/Footer widgets) ---- */
.nav-underline {
	position: relative;
}
.nav-underline::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -6px;
	height: 2px;
	background: var(--secondary);
	border-radius: 2px;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-underline:hover::after,
.nav-underline[data-active="true"]::after {
	transform: scaleX(1);
}

/* ---- Infinite marquee (Trust Badges now; Reviews/Team/Why-Choose-Us
   mobile reuse this same pattern later) — assets/js/marquee.js clones each
   .js-marquee-track's children once so this -50% translate loops with no
   visible seam. Kept as a CSS keyframe animation (not GSAP) since it's a
   constant-speed idle loop, not an entrance/interaction effect. ---- */
.marquee__viewport {
	overflow: hidden;
	padding-block: 0.75rem;
	-webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
	mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}
.marquee__track {
	display: flex;
	width: max-content;
	gap: 1.25rem;
}
@keyframes marquee-scroll {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}
@keyframes marquee-scroll-reverse {
	from { transform: translateX(-50%); }
	to { transform: translateX(0); }
}
.js-marquee-track {
	animation: marquee-scroll 42s linear infinite;
	will-change: transform;
}
.js-marquee-track.is-reverse {
	animation-name: marquee-scroll-reverse;
}
.js-marquee-track.is-slow {
	animation-duration: 110s;
}
.marquee__viewport:hover .js-marquee-track,
.marquee__viewport:focus-within .js-marquee-track {
	animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
	.js-marquee-track,
	.js-marquee-track.is-reverse,
	.js-marquee-track.is-slow,
	.js-marquee-track.is-reverse.is-slow {
		animation: none;
	}
}

/* ---- Scroll-triggered staggered reveal (Why Choose Us now; Common Pests,
   Service Areas, FAQ, Contact steps, Blog reuse the same pattern later) —
   assets/js/reveal.js fades/staggers a .js-reveal container's direct
   children in via GSAP once the container scrolls into view. This is the
   pre-JS starting state so there's no flash-of-unanimated-content. ---- */
.js-reveal > * {
	opacity: 0;
	transform: translateY(20px);
}

/* ---- Section-head component (eyebrow chip / title / copy, centered or
   left variant) — ported from pestcontrolgroupusa_core_old/typography.css.
   Services uses just the eyebrow; Why Choose Us now (and Common Pests,
   Process, Service Areas, FAQ later) use the full centered heading block. */
.section-head {
	max-width: 42rem; /* max-w-2xl */
}
.section-head--center {
	text-align: center;
	margin-inline: auto;
}
.section-head--left {
	text-align: left;
}
.section-head__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	border-radius: 9999px;
	border: 1px solid var(--border);
	background-color: var(--card);
	padding: 0.25rem 0.75rem;
	font-size: 0.6875rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--secondary);
}
.section-head__title {
	margin-top: 1rem;
	font-size: 1.875rem;
	font-weight: 800;
	letter-spacing: -0.02em;
	color: var(--foreground);
	font-family: var(--font-display);
}
.section-head__copy {
	margin-top: 0.75rem;
	font-size: 1rem;
	line-height: 1.625;
	color: var(--muted-foreground);
}
@media (min-width: 640px) {
	.section-head__title {
		font-size: 2.25rem;
	}
}

/* ---- Shared "call" CTA button (Services' bottom row now; Common Pests
   reuses the identical component later) — ported verbatim from
   components.css. Since this lives in shared.css it can't be prefixed
   with any one widget's wrapper class (it's reused by several), so the
   selector is self-doubled (".cta-call.cta-call", specificity 0,2,0)
   instead — a harmless way to reach the same "beat the theme/Elementor
   global <a> box-shadow reset" specificity every other CTA button in
   this plugin needs; see Hero/Header/About for the full writeup. */
.cta-call.cta-call {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	border-radius: var(--radius-2xl);
	background-image: var(--gradient-call);
	padding: 1rem 1.5rem;
	color: var(--primary-foreground);
	box-shadow: var(--shadow-call);
	transition: transform 300ms, filter 300ms;
}
.cta-call.cta-call:hover {
	transform: scale(1.02);
	filter: brightness(1.1);
}
.cta-call .icon-circle svg,
.cta-call .icon-circle i {
	color: #fff;
	height: 1.25rem;
	width: 1.25rem;
	font-size: 1.25rem;
}
.cta-call__text {
	display: flex;
	flex-direction: column;
	text-align: left;
	line-height: 1.2;
}
.cta-call__label {
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	color: rgba(255, 255, 255, 0.8);
}
.cta-call__number {
	font-size: 1.125rem;
	font-weight: 800;
}
