/* ==========================================================================
   Animations
   1. Button shine  — .fl-module.greenbutton, Gravity Forms submit
   2. Type-in headline — .tw-type
   ========================================================================== */


/* 1. Button shine
   ========================================================================== */

.fl-module.greenbutton .fl-button,
.gform_wrapper .gform_footer button[type="submit"] {
	position: relative;
	overflow: hidden;
}

.fl-module.greenbutton .fl-button::before,
.gform_wrapper .gform_footer button[type="submit"]::before {
	content: '';
	position: absolute;
	top: -10%;
	bottom: -10%;
	left: 0;
	width: 45%;
	background: linear-gradient(225deg,
			rgba(255, 255, 255, 0)    40%,
			rgba(255, 255, 255, 0.45) 50%,
			rgba(255, 255, 255, 0)    60%);
	-webkit-transform: translateX(320%) skewX(-15deg);
	transform: translateX(320%) skewX(-15deg);
	-webkit-transition: -webkit-transform 0.8s cubic-bezier(0.65, 0, 0.35, 1);
	transition: -webkit-transform 0.8s cubic-bezier(0.65, 0, 0.35, 1);
	transition: transform 0.8s cubic-bezier(0.65, 0, 0.35, 1);
	transition: transform 0.8s cubic-bezier(0.65, 0, 0.35, 1), -webkit-transform 0.8s cubic-bezier(0.65, 0, 0.35, 1);
	pointer-events: none;
	z-index: 0;
}

.fl-module.greenbutton .fl-button:hover::before,
.fl-module.greenbutton .fl-button:focus-visible::before,
.gform_wrapper .gform_footer button[type="submit"]:hover::before,
.gform_wrapper .gform_footer button[type="submit"]:focus-visible::before {
	-webkit-transform: translateX(-120%) skewX(-15deg);
	transform: translateX(-120%) skewX(-15deg);
}

.fl-module.greenbutton .fl-button .fl-button-text,
.gform_wrapper .gform_footer button[type="submit"] span {
	position: relative;
	z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
	.fl-module.greenbutton .fl-button::before,
	.gform_wrapper .gform_footer button[type="submit"]::before {
		-webkit-transition: none;
		transition: none;
	}
}


/* 2. Type-in headline
   The untyped remainder stays in flow and is hidden with visibility,
   so the heading's line breaks never change while typing.
   ========================================================================== */

.tw-type .tw-hidden {
	visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
	.tw-type .tw-hidden {
		visibility: visible;
	}
}


/* 3. Mosaic reveal
   Solid tiles over a row background photo, faded out on a stagger.
   Set --mosaic-tile to whatever sits behind the row.
   ========================================================================== */

.mosaic-reveal {
	--mosaic-tile: #f3f0eb;
}

.mosaic-reveal .fl-row-content-wrap {
	position: relative;
}

/* Pre-cover, painted from the very first frame — before any script runs.
   Without this the photo is visible until JS appends the tiles, which
   reads as a flash of image, then a blackout, then the mosaic. Same
   colour as the tiles, so the swap to the real grid is invisible. */
.mosaic-reveal .fl-row-content-wrap::before {
	content: '';
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background: var(--mosaic-tile, #f3f0eb);
	pointer-events: none;
	z-index: 1;
	/* Failsafe: if the script never runs, the cover clears itself rather
	   than hiding the photo permanently. Cancelled below once JS loads. */
	-webkit-animation: mosaic-failsafe 0s linear 4s forwards;
	animation: mosaic-failsafe 0s linear 4s forwards;
}

@-webkit-keyframes mosaic-failsafe {
	to {
		opacity: 0;
		visibility: hidden;
	}
}

@keyframes mosaic-failsafe {
	to {
		opacity: 0;
		visibility: hidden;
	}
}

/* The script sets this on <html> as soon as it executes. */
.mosaic-js .mosaic-reveal .fl-row-content-wrap::before {
	-webkit-animation: none;
	animation: none;
}

/* Set once the real tile grid is in place and has taken over. */
.mosaic-reveal.mosaic-armed .fl-row-content-wrap::before {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.mosaic-reveal .fl-row-content-wrap::before {
		display: none;
	}
}

.mosaic-reveal .fl-row-content {
	position: relative;
	z-index: 2;
}

.mosaic-grid {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	display: grid;
	grid-template-columns: repeat(var(--cols, 12), 1fr);
	grid-template-rows: repeat(var(--rows, 6), 1fr);
	pointer-events: none;
	z-index: 1;
}

.mosaic-grid i {
	display: block;
	background: var(--mosaic-tile, #f3f0eb);
	opacity: 1;
	-webkit-transform: scale(1.02);
	transform: scale(1.02);
	-webkit-transition:
		opacity var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1),
		-webkit-transform var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1);
	transition:
		opacity var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1),
		-webkit-transform var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1);
	transition:
		opacity var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1),
		transform var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1);
	transition:
		opacity var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1),
		transform var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1),
		-webkit-transform var(--dur, 420ms) cubic-bezier(0.4, 0, 0.2, 1);
}

.mosaic-grid.is-revealing i {
	opacity: 0;
	-webkit-transform: scale(1);
	transform: scale(1);
}


/* 4. Sun sweep
   A soft radial glow travelling across a photo at horizon height.
   Add .sunsweep to a BB Photo module, or to a Row for a background image.

   A radial gradient fading to transparent has no edge in any direction,
   so unlike a linear band there is nothing to soften — and animating
   background-position means no transformed box to clip.
   ========================================================================== */

.sunsweep {
	--sun-y: 38%;            /* height of the glow, as % of the image */
	--sun-size: 65%;         /* horizontal spread — tighter reads stronger */
	--sun-strength: 0.34;    /* peak intensity */
	--sun-warm: 255, 226, 176;   /* core colour */
	--sun-duration: 13s;     /* full cycle, including the pause */
}

.sunsweep .fl-photo-content,
.sunsweep.fl-row > .fl-row-content-wrap {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

/* Collapses the inline descender gap so the clip box matches the image
   exactly — otherwise the glow crosses bare background at the edges. */
.sunsweep .fl-photo-content {
	display: block;
	line-height: 0;
	font-size: 0;
}

.sunsweep .fl-photo-content img {
	display: block;
	width: 100%;
}

.sunsweep .fl-photo-content::after,
.sunsweep.fl-row > .fl-row-content-wrap::after {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: var(--sun-size);
	background:
		/* core — the sun itself */
		radial-gradient(ellipse 20% 55% at 50% var(--sun-y),
			rgba(var(--sun-warm), var(--sun-strength)) 0%,
			rgba(var(--sun-warm), calc(var(--sun-strength) * 0.5)) 40%,
			rgba(var(--sun-warm), 0) 72%),
		/* bloom — tall enough to span sky and field, so the effect never
		   terminates at the horizon and draw a visible edge */
		radial-gradient(ellipse 62% 190% at 50% var(--sun-y),
			rgba(var(--sun-warm), calc(var(--sun-strength) * 0.6)) 0%,
			rgba(var(--sun-warm), calc(var(--sun-strength) * 0.22)) 45%,
			rgba(var(--sun-warm), 0) 80%);
	background-repeat: no-repeat;
	background-size: 100% 100%;
	will-change: transform;
	/* screen, not soft-light: soft-light acts hardest on light tones, so
	   it lifts a pale sky to cream while barely touching dark foliage —
	   which makes the horizon read as a hard line. screen is biased the
	   other way and spreads the light evenly across both. */
	mix-blend-mode: screen;
	pointer-events: none;
	z-index: 1;
	-webkit-animation: sun-sweep var(--sun-duration) linear infinite;
	animation: sun-sweep var(--sun-duration) linear infinite;
}

/* The travel occupies the first 65% of the cycle; the rest is the pause
   before it comes round again.

   transform, not background-position: percentage background-position is
   computed against (container width - background width), so it does not
   travel proportionally and the glow never fully clears the frame — it
   stops while still visible, then snaps back. transform percentages are
   relative to the element's own width, so -110% is reliably off the left
   edge and 240% is reliably past the right. */
@-webkit-keyframes sun-sweep {
	0% {
		-webkit-transform: translateX(-110%);
		transform: translateX(-110%);
	}
	65%, 100% {
		-webkit-transform: translateX(240%);
		transform: translateX(240%);
	}
}
@keyframes sun-sweep {
	0% {
		-webkit-transform: translateX(-110%);
		transform: translateX(-110%);
	}
	65%, 100% {
		-webkit-transform: translateX(240%);
		transform: translateX(240%);
	}
}

@media (prefers-reduced-motion: reduce) {
	.sunsweep .fl-photo-content::after,
	.sunsweep.fl-row > .fl-row-content-wrap::after {
		-webkit-animation: none;
		animation: none;
		opacity: 0;
	}
}