/* 1🌱 Floating Images — front end */

.osfi-stage {
	position: relative;
	width: 100%;
	min-height: 400px;
	overflow: visible;
}

.osfi-stage .osfi-item {
	position: absolute;
	left: 0;
	top: 0;
	width: 200px;
	animation-duration: 6s;
	animation-delay: 0s;
	animation-iteration-count: infinite;
	animation-timing-function: ease-in-out;
	animation-fill-mode: both;
	will-change: transform;
	line-height: 0;
	/*
	 * Position and timing are written out per image as literal values, never as CSS custom
	 * properties. Firefox refuses to run an animation on the compositor when its properties
	 * depend on a variable — the variable could change at any time — so a var()-driven
	 * animation falls back to the main thread and snaps to whole pixels. The Divi Sensei
	 * module writes literals, and is smooth. Measured 2026-09-22.
	 */
	transform-style: preserve-3d;
	-webkit-transform-style: preserve-3d;
	display: inline-block;
	margin: 0;
}

.osfi-stage .osfi-item img {
	display: block;
	width: 100%;
	height: auto;
}

/* Someone who has asked their system to reduce motion sees the images placed, but still. */
@media (prefers-reduced-motion: reduce) {
	.osfi-stage .osfi-item {
		animation: none !important;
	}
}

.osfi-stage .osfi-effect-floatUpDown    { animation-name: osfi-float-up-down; }
.osfi-stage .osfi-effect-floatLeftRight { animation-name: osfi-float-left-right; }
.osfi-stage .osfi-effect-floatDiagonal  { animation-name: osfi-float-diagonal; }
.osfi-stage .osfi-effect-sway           { animation-name: osfi-sway; }
.osfi-stage .osfi-effect-rock           { animation-name: osfi-rock; }
.osfi-stage .osfi-effect-pulse          { animation-name: osfi-pulse; }
.osfi-stage .osfi-effect-orbit          { animation-name: osfi-orbit; animation-timing-function: linear; }
.osfi-stage .osfi-effect-drift          { animation-name: osfi-drift; }
.osfi-stage .osfi-effect-tilt           { animation-name: osfi-tilt; }
.osfi-stage .osfi-effect-wobble         { animation-name: osfi-wobble; }
.osfi-stage .osfi-effect-zoomDrift      { animation-name: osfi-zoom-drift; }

@keyframes osfi-float-up-down {
	0%, 100% { transform: translateY(0); }
	50%      { transform: translateY(-20px); }
}

@keyframes osfi-float-left-right {
	0%, 100% { transform: translateX(0); }
	50%      { transform: translateX(-20px); }
}

@keyframes osfi-float-diagonal {
	0%, 100% { transform: translate(0, 0); }
	50%      { transform: translate(-16px, -16px); }
}

@keyframes osfi-sway {
	0%, 100% { transform: translateX(0) rotate(-2deg); }
	50%      { transform: translateX(14px) rotate(2deg); }
}

@keyframes osfi-rock {
	0%, 100% { transform: rotate(-4deg); }
	50%      { transform: rotate(4deg); }
}

@keyframes osfi-pulse {
	0%, 100% { transform: scale(1); }
	50%      { transform: scale(1.08); }
}

@keyframes osfi-orbit {
	0%   { transform: translate(0, 0); }
	25%  { transform: translate(14px, -14px); }
	50%  { transform: translate(0, -28px); }
	75%  { transform: translate(-14px, -14px); }
	100% { transform: translate(0, 0); }
}

@keyframes osfi-drift {
	0%, 100% { transform: translate(0, 0) rotate(0deg); }
	33%      { transform: translate(12px, -10px) rotate(2deg); }
	66%      { transform: translate(-10px, -18px) rotate(-2deg); }
}

@keyframes osfi-tilt {
	0%, 100% { transform: perspective(600px) rotateY(-8deg); }
	50%      { transform: perspective(600px) rotateY(8deg); }
}

@keyframes osfi-wobble {
	0%, 100% { transform: translateY(0) rotate(0deg); }
	25%      { transform: translateY(-10px) rotate(3deg); }
	75%      { transform: translateY(-10px) rotate(-3deg); }
}

@keyframes osfi-zoom-drift {
	0%, 100% { transform: scale(1) translateY(0); }
	50%      { transform: scale(1.06) translateY(-16px); }
}

/* Builder-only: an image slot with nothing chosen yet. */
.osfi-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 120px;
	padding: 12px;
	border: 1px dashed rgba(0, 0, 0, 0.35);
	border-radius: 4px;
	background: rgba(255, 255, 255, 0.6);
	font-size: 13px;
	line-height: 1.3;
	text-align: center;
	color: #333;
}


/* --------------------------------------------------------------------------
 * Glide effects: a plain A-to-B slide with a slight zoom, played back and
 * forth. No rotation — a rotating image reads as rolling rather than drifting.
 * Values measured from the four motions already in use on the Timber home page
 * (2026-09-22) so the two look alike side by side.
 * -------------------------------------------------------------------------- */

.osfi-stage .osfi-effect-glideUpDown,
.osfi-stage .osfi-effect-glideLeftRight,
.osfi-stage .osfi-effect-glideDiagonal,
.osfi-stage .osfi-effect-glideZoom {
	animation-direction: alternate;
	animation-fill-mode: none;
}

.osfi-stage .osfi-effect-glideUpDown    { animation-name: osfi-glide-up-down; }
.osfi-stage .osfi-effect-glideLeftRight { animation-name: osfi-glide-left-right; }
.osfi-stage .osfi-effect-glideDiagonal  { animation-name: osfi-glide-diagonal; }
.osfi-stage .osfi-effect-glideZoom      { animation-name: osfi-glide-zoom; }

@keyframes osfi-glide-up-down {
	0%   { transform: translate3d(0, 10px, 0) scale3d(0.99, 0.99, 1) rotate3d(0, 0, 0, 0deg); }
	100% { transform: translate3d(0, -10px, 0) scale3d(1, 1, 1) rotate3d(0, 0, 0, 0deg); }
}

@keyframes osfi-glide-left-right {
	0%   { transform: translate3d(10px, 0, 0) scale3d(0.99, 0.99, 1) rotate3d(0, 0, 0, 0deg); }
	100% { transform: translate3d(-10px, 0, 0) scale3d(1, 1, 1) rotate3d(0, 0, 0, 0deg); }
}

@keyframes osfi-glide-diagonal {
	0%   { transform: translate3d(-10px, -10px, 0) scale3d(0.95, 0.95, 1) rotate3d(1, 0, 0, 0deg); }
	100% { transform: translate3d(10px, 10px, 0) scale3d(1, 1, 1) rotate3d(0, 0, 0, 0deg); }
}

@keyframes osfi-glide-zoom {
	0%   { transform: translate3d(0, -10px, 0) scale3d(0.95, 0.95, 1) rotate3d(0, 0, 0, 0deg); }
	100% { transform: translate3d(0, 10px, 0) scale3d(1, 1, 1) rotate3d(0, 0, 0, 0deg); }
}
