/*
 * DavidSW Theme - Home slider motion (Flatsome banners)
 *
 * Loaded only on pages whose content contains "dsw-motion"
 * (inc/frontend/motion.php). Printed at wp_head 102, after dsw-custom.css.
 *
 * UX Builder setup, per banner:
 *   Slider  -> Class "dsw-motion-slider" (true crossfade between slides).
 *   Banner  -> Class "dsw-motion" (add "dsw-halloween" for the seasonal look),
 *              Slide effect None, Background position 50% 50% (Flatsome prints
 *              bg_pos as an #id rule we cannot override, and the layers are
 *              aligned to a centred background).
 *   Layers  -> one Image per exported layer, in order ghost, watch, type, badge:
 *              Class "dsw-layer dsw-layer-ghost|watch|type|badge", Animate None,
 *              no link (the banner link stays clickable through the layers).
 *
 * Each layer image is cropped to its own pixels and carries its position in its
 * filename (-x{left}-y{top}-w{width}, in 1/10000ths of the background).
 * dsw-motion.js reads that and places it on a stage that covers the banner the
 * way the background image does (object-fit: cover), so layers line up at any
 * screen size.
 *
 * Depends on Flatsome's banner markup (.banner-inner, .banner-bg, .banner-layers,
 * .img > .img-inner > img) and slider classes (.slider-type-fade,
 * .flickity-slider, .is-selected). Re-test after Flatsome updates.
 */

/* ---------- Units and stage ---------- */

/* --dsw-u is 1% of the banner width. Banners are full width, so 1vw is a close
 * fallback; dsw-motion.js refines it with the measured width (--dsw-bw) where
 * container queries are missing (Safari < 16). */
.dsw-motion {
	--dsw-ar: 1.5; /* background aspect ratio; dsw-motion.js sets the real one */
	--dsw-cx: 0;   /* smoothed pointer / idle drift, -1..1, set by dsw-motion.js */
	--dsw-cy: 0;
	--dsw-u: calc(var(--dsw-bw, 100vw) / 100);
	--dsw-uh: calc(var(--dsw-bh, 100vh) / 100);
}

.dsw-motion .banner-inner {
	overflow: hidden;
}

@supports (container-type: size) {
	.dsw-motion {
		--dsw-u: 1cqw;
		--dsw-uh: 1cqh;
	}

	/* Absolutely positioned (.fill), so its size never depends on its content. */
	.dsw-motion .banner-inner {
		container-type: size;
	}
}

/* The layer stage: covers the banner like object-fit: cover, centred. Beats
 * Flatsome's .banner-layers max-height:100%, .container padding/max-width and the
 * phone overflow:auto. */
.dsw-motion .banner-inner .banner-layers {
	position: absolute;
	max-width: none;
	max-height: none;
	margin: 0;
	padding: 0;
	overflow: visible;
	width: max(calc(100 * var(--dsw-u)), calc(100 * var(--dsw-uh) * var(--dsw-ar)));
	height: max(calc(100 * var(--dsw-uh)), calc(100 * var(--dsw-u) / var(--dsw-ar)));
	left: calc((100 * var(--dsw-u) - max(calc(100 * var(--dsw-u)), calc(100 * var(--dsw-uh) * var(--dsw-ar)))) / 2);
	top: calc((100 * var(--dsw-uh) - max(calc(100 * var(--dsw-uh)), calc(100 * var(--dsw-u) / var(--dsw-ar)))) / 2);
}

/* Layers. transform !important + this specificity beats Flatsome's
 * md-x50 / lg-x50 / md-y50 position classes, which are also !important. */
.dsw-motion .banner-layers .dsw-layer {
	position: absolute;
	left: var(--dsw-x, 0);
	top: var(--dsw-y, 0);
	right: auto;
	bottom: auto;
	width: var(--dsw-w, 100%) !important;
	pointer-events: none;
	transform:
		perspective(1600px)
		translate3d(calc(var(--dsw-cx) * var(--dsw-depth, 0px)), calc(var(--dsw-cy) * var(--dsw-depth, 0px)), 0)
		rotateX(calc(var(--dsw-cy) * var(--dsw-tilt, 0deg) * -1))
		rotateY(calc(var(--dsw-cx) * var(--dsw-tilt, 0deg))) !important;
}

/* UX Builder must be able to select layers on its canvas. */
.ux-builder-iframe .dsw-motion .banner-layers .dsw-layer {
	pointer-events: auto;
}

/* Hidden while dsw-motion.js (footer) has not placed the layer yet. Inside a
 * slider the not-yet-ready rule below already hides layers before the script
 * runs; outside one they can show unplaced for that moment. */
.dsw-js .dsw-motion .dsw-layer:not(.dsw-placed) {
	visibility: hidden;
}

/* A layer whose file name carries no -x-y-w position cannot be placed; hide it
 * rather than draw it at full size (dsw-motion.js logs which file). */
.dsw-motion .dsw-layer.dsw-unplaced {
	display: none;
}

.dsw-motion .dsw-layer .img-inner {
	position: relative;
	overflow: visible; /* float and tilt must not clip the cropped image */
}

.dsw-motion .dsw-layer img {
	display: block;
	width: 100%;
	height: auto;
}

.dsw-motion .dsw-layer-ghost { --dsw-depth: calc(-.7 * var(--dsw-u)); --dsw-tilt: -2deg; }
.dsw-motion .dsw-layer-type  { --dsw-depth: calc(.25 * var(--dsw-u)); }
.dsw-motion .dsw-layer-watch { --dsw-depth: calc(.9 * var(--dsw-u)); --dsw-tilt: 7deg; }
.dsw-motion .dsw-layer-badge { --dsw-depth: calc(.55 * var(--dsw-u)); --dsw-tilt: 4deg; }

/* Keyboard users can see where the banner link is (Flatsome draws no focus ring
 * on its full-banner link). The link spans the cover stage, which can be larger
 * than the banner and clipped, so the ring is drawn on the banner itself. */
.dsw-motion .banner-layers > a.fill:focus-visible {
	outline: none;
}

.dsw-motion:has(.banner-layers > a.fill:focus-visible) {
	outline: 2px solid rgba(255, 255, 255, .85);
	outline-offset: -6px;
}

/* A Flatsome slide effect left on a motion banner would fight the background
 * animation below. */
.slider .dsw-motion.has-slide-effect .bg {
	opacity: 1;
	transition: none;
}

/* ---------- Slides: a true crossfade ----------
 * Flatsome's fade fades both slides at once over .6s, so the picture dips to the
 * background mid-change. In a slider marked dsw-motion-slider the incoming slide
 * fades in over the outgoing one, which holds until the fade completes. */
.dsw-motion-slider .slider-type-fade .flickity-slider > * {
	transition: opacity .9s ease;
}

.dsw-motion-slider .slider-type-fade .flickity-slider > :not(.is-selected) {
	transition: opacity 0s .9s;
}

/* ---------- Studio light: a soft key light that drifts with the pointer ----------
 * z-index lifts it above the background image, which is also absolutely
 * positioned and would otherwise paint over it. */
.dsw-motion .banner-bg::before {
	content: "";
	position: absolute;
	inset: -20%;
	z-index: 1;
	pointer-events: none;
	background: radial-gradient(ellipse 30% 34% at 50% 46%, rgba(255, 255, 255, .34), rgba(255, 255, 255, .1) 45%, transparent 72%);
	mix-blend-mode: soft-light;
	transform: translate3d(calc(var(--dsw-cx) * 12 * var(--dsw-u)), calc(var(--dsw-cy) * 7 * var(--dsw-uh)), 0);
}

/* Dust motes hanging in that light. */
.dsw-motion .banner-bg::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		radial-gradient(circle, rgba(255, 255, 255, .9) 0 .7px, transparent 1.6px),
		radial-gradient(circle, rgba(255, 255, 255, .7) 0 1px, transparent 2.2px),
		radial-gradient(circle, rgba(255, 250, 240, .55) 0 1.4px, transparent 3px);
	background-size: 190px 230px, 270px 310px, 380px 420px;
	-webkit-mask: radial-gradient(ellipse 30% 42% at 50% 48%, #000 15%, transparent 70%);
	mask: radial-gradient(ellipse 30% 42% at 50% 48%, #000 15%, transparent 70%);
	mix-blend-mode: screen;
	opacity: .45;
	animation: dsw-motes 60s linear infinite;
}

/* ---------- Entrance ----------
 * Replayed every time Flickity selects the slide, once its layer images have
 * actually arrived (.dsw-ready), so nothing pops in late on a slow connection. */
.slider .dsw-motion:not(.dsw-ready) .dsw-layer .img-inner {
	opacity: 0;
}

.dsw-motion.is-selected.dsw-ready .bg,
.dsw-motion.dsw-leaving.dsw-ready .bg {
	animation: dsw-push 3.4s cubic-bezier(.16, 1, .3, 1) both, dsw-breathe 16s 3.4s ease-in-out infinite;
}

.dsw-motion.is-selected.dsw-ready .dsw-layer-ghost .img-inner {
	animation: dsw-ghost-in 3.2s .05s cubic-bezier(.16, 1, .3, 1) both;
}

.dsw-motion.is-selected.dsw-ready .dsw-layer-watch .img-inner {
	animation: dsw-watch-in 2.2s .2s cubic-bezier(.16, 1, .3, 1) both;
}

/* Headline: a soft-edged reveal opening outwards from the centre. */
.dsw-motion.is-selected.dsw-ready .dsw-layer-type .img-inner {
	-webkit-mask: linear-gradient(90deg, transparent, #000 25%, #000 75%, transparent) 50% 50% / 300% 100% no-repeat;
	mask: linear-gradient(90deg, transparent, #000 25%, #000 75%, transparent) 50% 50% / 300% 100% no-repeat;
	animation: dsw-reveal 1.9s .6s cubic-bezier(.22, 1, .36, 1) both;
}

.dsw-motion.is-selected.dsw-ready .dsw-layer-badge .img-inner {
	transform-origin: 50% 0;
	animation: dsw-badge-in 1.2s 1.5s cubic-bezier(.34, 1.4, .64, 1) both;
}

/* Leaving slides fade and soften while the next slide fades in over them
 * (.dsw-leaving is set by dsw-motion.js for the length of the crossfade). The
 * background animation stays matched above, so it carries on rather than
 * snapping back to its resting size. */
.slider .dsw-motion:not(.is-selected) .dsw-layer .img-inner {
	opacity: 0;
}

.slider .dsw-motion.dsw-leaving .dsw-layer .img-inner {
	animation: dsw-leave .7s ease both;
}

/* ---------- Ambient ---------- */
.dsw-motion .dsw-layer-watch img {
	animation: dsw-float 9s ease-in-out infinite;
}

.dsw-motion .dsw-layer-ghost img {
	animation: dsw-drift 18s ease-in-out infinite;
}

/* The watch catches the light: a highlight that follows the pointer, plus an
 * occasional glint across the crystal, both clipped to the watch's own alpha
 * (mask set by dsw-motion.js from the image). */
.dsw-motion .dsw-layer-watch .img-inner {
	--dsw-mask: linear-gradient(transparent, transparent);
}

.dsw-motion .dsw-layer-watch .img-inner::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(circle at calc(50% + var(--dsw-cx) * 38%) calc(38% + var(--dsw-cy) * 28%), var(--dsw-sheen, rgba(255, 255, 255, .3)), transparent 36%),
		linear-gradient(105deg, transparent 42%, var(--dsw-shine, rgba(255, 255, 255, .55)) 50%, transparent 58%);
	background-size: 100% 100%, 300% 100%;
	background-position: 0 0, 100% 0;
	background-repeat: no-repeat;
	-webkit-mask: var(--dsw-mask) 50% 50% / 100% 100% no-repeat;
	mask: var(--dsw-mask) 50% 50% / 100% 100% no-repeat;
	mix-blend-mode: screen;
}

/* The glint across the crystal runs only while dsw-motion.js has the banner
 * marked .dsw-glint (about every 9 s), so nothing repaints between glints. */
.dsw-motion.dsw-glint .dsw-layer-watch .img-inner::after {
	animation: dsw-sweep 1.8s cubic-bezier(.65, 0, .35, 1) both;
}

/* Nothing animates on slides nobody can see, or when the visitor paused it. */
.slider .dsw-motion:not(.is-selected):not(.dsw-leaving) *,
.slider .dsw-motion:not(.is-selected):not(.dsw-leaving) *::before,
.slider .dsw-motion:not(.is-selected):not(.dsw-leaving) *::after,
.dsw-motion.dsw-offscreen *,
.dsw-motion.dsw-offscreen *::before,
.dsw-motion.dsw-offscreen *::after,
.dsw-paused .dsw-motion *,
.dsw-paused .dsw-motion *::before,
.dsw-paused .dsw-motion *::after {
	animation-play-state: paused !important;
}

/* ---------- Pause control (added by dsw-motion.js to each slider) ---------- */
.dsw-motion-pause {
	position: absolute;
	right: 14px;
	bottom: 14px;
	z-index: 20;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, .55);
	border-radius: 50%;
	background: rgba(0, 0, 0, .35);
	color: #fff;
	opacity: .65;
	cursor: pointer;
	transition: opacity .2s;
}

.dsw-motion-pause:hover,
.dsw-motion-pause:focus-visible {
	opacity: 1;
}

.dsw-motion-pause:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

.dsw-motion-pause svg {
	width: 14px;
	height: 14px;
	fill: currentColor;
}

.dsw-motion-pause .dsw-i-play,
.dsw-motion-pause[aria-pressed="true"] .dsw-i-pause {
	display: none;
}

.dsw-motion-pause[aria-pressed="true"] .dsw-i-play {
	display: block;
}

@keyframes dsw-push { from { transform: scale(1.09); } to { transform: scale(1); } }
@keyframes dsw-breathe { 50% { transform: scale(1.025); } }
@keyframes dsw-ghost-in { from { opacity: 0; transform: scale(1.18); } }
@keyframes dsw-watch-in {
	from { opacity: 0; transform: translateY(5%) scale(.93); filter: blur(14px); }
	55% { filter: blur(0); }
	to { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes dsw-reveal {
	from { opacity: 0; -webkit-mask-size: 0% 100%; mask-size: 0% 100%; filter: blur(6px); }
	35% { opacity: 1; }
	to { opacity: 1; -webkit-mask-size: 300% 100%; mask-size: 300% 100%; filter: blur(0); }
}
@keyframes dsw-leave { to { opacity: 0; filter: blur(6px); transform: scale(.98); } }
@keyframes dsw-badge-in { from { opacity: 0; transform: perspective(700px) rotateX(-75deg) translateY(-6%); } }
@keyframes dsw-float { 50% { translate: 0 -1%; } }
@keyframes dsw-drift { 50% { scale: 1.035; rotate: -1.2deg; } }
@keyframes dsw-sweep {
	from { background-position: 0 0, 100% 0; }
	to { background-position: 0 0, 0 0; }
}
@keyframes dsw-motes { to { background-position: 190px -460px, -270px -620px, 380px -840px; } }

/* =====================================================================
 * Halloween: candlelit, misty, moonlit. Add "dsw-halloween" next to
 * "dsw-motion" on the banner; no new images needed.
 * ===================================================================== */
.dsw-halloween {
	--dsw-shine: rgba(255, 206, 150, .6);
	--dsw-sheen: rgba(255, 186, 110, .3);
	background-color: #0b0908;
}

/* A painted candlelit backdrop replaces Andrey's colours, so every slide matches
 * (filtering his background instead showed its glow edges as hard seams). The
 * image is not displayed at all, so Flatsome's lazy loader never downloads it
 * and nothing animates it; dsw-motion.js still reads its width/height
 * attributes for the layer stage. */
.dsw-halloween .bg {
	display: none;
}

.dsw-halloween .banner-bg {
	background:
		radial-gradient(ellipse 55% 65% at 50% 60%, #2a1912 0%, #150e0b 48%, #070605 100%);
}

/* Candle glow behind the watch, with an irregular flicker. */
.dsw-halloween .banner-bg::before {
	content: "";
	position: absolute;
	inset: 0;
	transform: none;
	z-index: 1;
	pointer-events: none;
	background:
		radial-gradient(ellipse 30% 46% at 50% 54%, rgba(232, 132, 48, .42), rgba(150, 52, 14, .16) 50%, transparent 72%),
		radial-gradient(ellipse 80% 70% at 50% 60%, rgba(60, 18, 40, .35), transparent 70%);
	mix-blend-mode: screen;
	animation: dsw-flicker 5.3s steps(1, end) infinite, dsw-glow 7s ease-in-out infinite;
}

/* Low mist drifting across, plus a vignette. */
.dsw-halloween .banner-bg::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background:
		radial-gradient(ellipse 45% 18% at 25% 88%, rgba(214, 208, 222, .14), transparent 70%),
		radial-gradient(ellipse 40% 16% at 75% 82%, rgba(214, 208, 222, .10), transparent 70%),
		radial-gradient(ellipse 35% 14% at 50% 96%, rgba(214, 208, 222, .12), transparent 70%);
	background-size: 160% 100%;
	box-shadow: inset 0 0 calc(18 * var(--dsw-u)) calc(4 * var(--dsw-u)) rgba(0, 0, 0, .75);
	-webkit-mask: none;
	mask: none;
	mix-blend-mode: normal;
	opacity: 1;
	animation: dsw-mist 38s linear infinite alternate;
}

/* ---------- Halloween extras, built by dsw-motion.js ----------
 * Both sit on .banner-inner, the visible banner (the layer stage can be
 * larger and cropped). .dsw-fx-back is behind the PSD layers (under the
 * mist), .dsw-fx-front in front of them. Sizes use --dsw-u (1% of the banner width) so they scale with it. */
.dsw-fx {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
}

.dsw-fx-back { z-index: 0; }
.dsw-fx-front { z-index: 2; }

.dsw-fx svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/* Starfield, upper sky only. */
.dsw-fx-stars {
	position: absolute;
	inset: 0 0 50% 0;
	background-image:
		radial-gradient(circle, rgba(255, 246, 230, .9) 0 1px, transparent 1.6px),
		radial-gradient(circle, rgba(255, 236, 210, .7) 0 .8px, transparent 1.4px),
		radial-gradient(circle, rgba(220, 225, 255, .6) 0 1px, transparent 1.6px);
	background-size: 173px 97px, 241px 131px, 317px 163px;
	background-position: 11px 7px, 90px 40px, 200px 70px;
	-webkit-mask: linear-gradient(#000 30%, transparent);
	mask: linear-gradient(#000 30%, transparent);
	animation: dsw-twinkle 4.7s ease-in-out infinite alternate;
}

.dsw-fx-stars + .dsw-fx-stars {
	background-size: 211px 113px, 283px 151px;
	background-position: 60px 30px, 170px 10px;
	animation-duration: 6.1s;
	animation-delay: -2s;
}

/* Moon: detailed SVG, with a halo, drifting cloud wisps and passing bats. */
.dsw-fx-moon {
	position: absolute;
	top: 8%;
	right: 11%;
	width: calc(10 * var(--dsw-u));
	filter: drop-shadow(0 0 calc(1.4 * var(--dsw-u)) rgba(250, 232, 190, .35)) drop-shadow(0 0 calc(5 * var(--dsw-u)) rgba(250, 232, 190, .14));
	animation: dsw-moon 3s .2s cubic-bezier(.16, 1, .3, 1) both;
}

.dsw-fx-clouds {
	position: absolute;
	top: 7%;
	right: 3%;
	width: calc(30 * var(--dsw-u));
	opacity: .75;
	animation: dsw-clouds 46s ease-in-out infinite alternate;
}

.dsw-fx-bat {
	position: absolute;
	top: 21%;
	right: 25%;
	width: calc(3.4 * var(--dsw-u));
	opacity: 0;
	animation: dsw-bat 17s 3s linear infinite;
}

.dsw-fx-bat-2 { width: calc(2.5 * var(--dsw-u)); top: 25%; animation-delay: 3.7s; animation-duration: 17.6s; }
.dsw-fx-bat-3 { width: calc(1.9 * var(--dsw-u)); top: 17%; animation-delay: 4.5s; animation-duration: 16.4s; }

/* Each wing hinges at the shoulder: up-stroke spread, down-stroke folded under. */
.dsw-fx-bat .dsw-bat-wl,
.dsw-fx-bat .dsw-bat-wr {
	transform-box: view-box;
	animation: dsw-wing-l .26s ease-in-out infinite;
}

.dsw-fx-bat .dsw-bat-wl { transform-origin: 56px 27px; }
.dsw-fx-bat .dsw-bat-wr { transform-origin: 64px 27px; animation-name: dsw-wing-r; }
.dsw-fx-bat .dsw-bat-body { transform-box: view-box; animation: dsw-bat-bob .26s ease-in-out infinite; }
.dsw-fx-bat-2 :is(.dsw-bat-wl, .dsw-bat-wr, .dsw-bat-body) { animation-duration: .22s; }
.dsw-fx-bat-3 :is(.dsw-bat-wl, .dsw-bat-wr, .dsw-bat-body) { animation-duration: .19s; }

/* Gold spider web in the top-left corner; its spider climbs up and down. */
.dsw-fx-web {
	position: absolute;
	top: 0;
	left: 0;
	width: calc(16 * var(--dsw-u));
	opacity: .85;
}

.dsw-fx-web .dsw-web-shine {
	opacity: .2;
	animation: dsw-web-shine 7s ease-in-out infinite alternate;
}

.dsw-fx-web .dsw-spider {
	animation: dsw-spider 9s ease-in-out infinite;
}

/* Jack-o'-lanterns on the floor, bottom left. */
.dsw-fx-pumpkins {
	position: absolute;
	left: 3.5%;
	bottom: 4%;
	width: calc(12 * var(--dsw-u));
	animation: dsw-rise-in 1.6s 1.2s cubic-bezier(.16, 1, .3, 1) both;
}

.dsw-fx-pumpkins .dsw-pk-glow {
	animation: dsw-flicker 3.7s steps(1, end) infinite;
}

/* The ghost: follows the pointer on desktop, wanders on its own on phones. */
.dsw-fx-ghost {
	position: absolute;
	top: 0;
	left: 0;
	width: calc(3.4 * var(--dsw-u));
	opacity: 0;
	transition: opacity 1s;
	will-change: transform;
}

.dsw-fx-ghost.is-on {
	opacity: .92;
}

.dsw-fx-ghost svg {
	filter: drop-shadow(0 0 calc(.7 * var(--dsw-u)) rgba(255, 240, 222, .55));
	animation: dsw-bob 2.6s ease-in-out infinite;
}

/* Phone banners: headlines top and bottom, so a lighter set of extras. */
@media (max-width: 549px) {
	.dsw-fx-moon,
	.dsw-fx-clouds,
	.dsw-fx-bat {
		display: none;
	}

	.dsw-fx-web { width: calc(26 * var(--dsw-u)); opacity: .6; }
	.dsw-fx-pumpkins { width: calc(22 * var(--dsw-u)); left: 2%; bottom: 1.5%; }
	.dsw-fx-ghost { width: calc(11 * var(--dsw-u)); }
}

/* Embers rising past the watch. */
.dsw-halloween .banner-layers::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		radial-gradient(circle, rgba(255, 170, 80, .95) 0 1.5px, transparent 3px),
		radial-gradient(circle, rgba(255, 140, 50, .8) 0 2px, transparent 3.5px),
		radial-gradient(circle, rgba(255, 200, 120, .7) 0 1.2px, transparent 2.5px);
	background-size: 230px 340px, 310px 420px, 170px 260px;
	background-position: 20px 0, 140px 90px, 80px 200px;
	-webkit-mask: radial-gradient(ellipse 34% 60% at 50% 60%, #000 30%, transparent 75%);
	mask: radial-gradient(ellipse 34% 60% at 50% 60%, #000 30%, transparent 75%);
	opacity: .8;
	animation: dsw-embers 22s linear infinite;
}

/* Champagne type, amber ghost, warm rim light on the watch. */
.dsw-halloween .dsw-layer-type img {
	filter: sepia(.45) saturate(1.3) brightness(.96);
}

.dsw-halloween .dsw-layer-ghost img {
	filter: sepia(1) saturate(3) hue-rotate(-12deg) brightness(1.15);
}

.dsw-halloween .dsw-layer-watch img {
	filter: drop-shadow(0 0 calc(2.2 * var(--dsw-u)) rgba(240, 130, 50, .32)) drop-shadow(0 calc(1.2 * var(--dsw-u)) calc(2 * var(--dsw-u)) rgba(0, 0, 0, .6));
}

.dsw-halloween .dsw-layer-type,
.dsw-halloween .dsw-layer-ghost,
.dsw-halloween .dsw-layer-watch,
.dsw-halloween .dsw-layer-badge {
	z-index: 1;
}

@keyframes dsw-flicker {
	0%, 100% { opacity: 1; }
	12% { opacity: .9; }
	15% { opacity: 1; }
	41% { opacity: .86; }
	44% { opacity: .97; }
	71% { opacity: .92; }
	74% { opacity: 1; }
}
@keyframes dsw-glow { 50% { transform: scale(1.06); } }
@keyframes dsw-mist { to { background-position: 100% 0, 0 0, 60% 0; } }
@keyframes dsw-moon { from { opacity: 0; transform: translateY(25%); } }
@keyframes dsw-twinkle { from { opacity: .35; } to { opacity: 1; } }
@keyframes dsw-clouds { from { transform: translateX(-12%); } to { transform: translateX(14%); } }
/* Erratic, fluttering flight across the moon, banking as it turns. */
@keyframes dsw-bat {
	0% { opacity: 0; transform: translate(calc(-6 * var(--dsw-u)), calc(4 * var(--dsw-u))) rotate(-10deg) scale(.6); }
	2% { opacity: 1; }
	4% { transform: translate(calc(-3 * var(--dsw-u)), calc(2.2 * var(--dsw-u))) rotate(4deg) scale(.68); }
	6.5% { transform: translate(0, calc(2.8 * var(--dsw-u))) rotate(-6deg) scale(.75); }
	9% { transform: translate(calc(3.5 * var(--dsw-u)), calc(.6 * var(--dsw-u))) rotate(8deg) scale(.82); }
	11.5% { transform: translate(calc(6.5 * var(--dsw-u)), calc(1.4 * var(--dsw-u))) rotate(-5deg) scale(.88); }
	14% { transform: translate(calc(10 * var(--dsw-u)), calc(-1 * var(--dsw-u))) rotate(7deg) scale(.94); }
	16.5% { transform: translate(calc(13.5 * var(--dsw-u)), calc(-.4 * var(--dsw-u))) rotate(-4deg) scale(.98); }
	19% { opacity: 1; transform: translate(calc(17 * var(--dsw-u)), calc(-3 * var(--dsw-u))) rotate(6deg) scale(1); }
	21%, 100% { opacity: 0; transform: translate(calc(19.5 * var(--dsw-u)), calc(-4.5 * var(--dsw-u))) rotate(0) scale(1); }
}
@keyframes dsw-wing-l {
	0%, 100% { transform: rotate(32deg) scaleY(.9); }
	50% { transform: rotate(-24deg) scaleY(.6); }
}
@keyframes dsw-wing-r {
	0%, 100% { transform: rotate(-32deg) scaleY(.9); }
	50% { transform: rotate(24deg) scaleY(.6); }
}
@keyframes dsw-bat-bob { 50% { transform: translateY(-3px); } }
@keyframes dsw-rise-in { from { opacity: 0; transform: translateY(20%); } }
@keyframes dsw-bob { 50% { transform: translateY(-9%) rotate(-3deg); } }
@keyframes dsw-web-shine { to { opacity: .75; } }
@keyframes dsw-spider {
	35%, 65% { transform: translateY(46px); }
	50% { transform: translateY(30px); }
}
@keyframes dsw-embers {
	to { background-position: 20px -340px, 140px -330px, 80px -60px; }
}

/* ---------- Reduced motion: keep the finished look, drop the movement ---------- */
@media (prefers-reduced-motion: reduce) {
	.dsw-motion .bg,
	.dsw-motion .dsw-layer .img-inner,
	.dsw-motion .dsw-layer img,
	.dsw-motion .dsw-layer .img-inner::after,
	.dsw-motion .banner-bg::before,
	.dsw-motion .banner-bg::after,
	.dsw-halloween .banner-layers::after,
	.dsw-fx * {
		animation: none !important;
		transition: none !important;
	}

	.dsw-motion-slider .slider-type-fade .flickity-slider > * {
		transition: none;
	}

	.dsw-fx-bat,
	.dsw-fx-ghost {
		display: none;
	}
}
