/*
 * KISS 3D + Web AR — 3D Showcase (inline viewer + hotspots).
 * Kept separate from the AR launcher CSS since it's a different context.
 */

.kiss-webar-showcase {
	position: relative;
	width: 100%;
	align-self: stretch; /* if the container centers its items, still fill width */
	--kiss-webar-showcase-height: 60vh;
}

/*
 * Critical: when the widget sits in a flex container whose items are
 * CENTERED (a very common "center this on the page" setup), a width:100%
 * child collapses to zero width in the shrink-to-fit context — which makes
 * <model-viewer> an invisible 0-wide sliver that never loads. Forcing the
 * Elementor widget wrapper to full width keeps it from collapsing.
 */
.elementor-widget-kiss_webar_showcase {
	width: 100%;
}

.kiss-webar-showcase model-viewer {
	width: 100%;
	height: var(--kiss-webar-showcase-height);
	min-height: 360px;
	/* background-color is set inline (transparent or a solid color). */
	--poster-color: transparent;
	/*
	 * Default to the gesture split that lets the visitor scroll PAST the model:
	 * a vertical swipe scrolls the page, a horizontal drag rotates.
	 *
	 * model-viewer mirrors its own `touch-action` attribute to an inline style,
	 * but ONLY once interaction is enabled — before that the inline value is
	 * empty and this rule decides, so it must match the attribute (pan-y).
	 */
	touch-action: pan-y;
}

/*
 * Mobile/tablet portrait: a wide, shallow boat lift auto-frames to the narrow
 * width, so a tall (60–70vh) viewer leaves a big empty band above the model and
 * pushes the AR button / instructions off the bottom of the screen. Cap the
 * height so the model fills the frame and the controls stay visible. max-height
 * caps the inline height the runtime sets, and the 360px min-height floor still
 * applies. (Verified against the real model at 412px wide: ~46–50vh frames the
 * lift with balanced margins vs ~48% empty at 70vh.)
 */
/* NOTE: the mobile height is chosen by the runtime (pickHeight) and written as
   an inline style, because an inline height beats any media query. The old
   hardcoded `max-height: 50vh` cap lived here and would have overridden — and
   silently capped — the "Viewer height (mobile)" setting, so it's gone. */

/* Loader ------------------------------------------------------------- */
/* Transparent-friendly: no dark panel, just the tumbling wireframe cube
   so it reads cleanly on light OR dark backgrounds. */

.kiss-webar-sc-loader {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	background: transparent;
}

/* Download percentage shown under the cube (replaces model-viewer's default
   top progress bar, which we suppress with an empty progress-bar slot). */
.kiss-webar-sc-progress {
	min-height: 1em;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--kw-loader, #8a8f98);
}

.kiss-webar-sc-cube-scene {
	width: 64px;
	height: 64px;
	perspective: 400px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.kiss-webar-sc-cube {
	width: 46px;
	height: 46px;
	position: relative;
	transform-style: preserve-3d;
	animation: kw-sc-spin 3.2s cubic-bezier(0.55, 0.1, 0.45, 0.9) infinite;
}

.kiss-webar-sc-side {
	position: absolute;
	inset: 0;
	border: 2px solid var(--kw-loader, #8a8f98);
	background: transparent;
}

.kiss-webar-sc-side--front  { transform: translateZ(23px); }
.kiss-webar-sc-side--back   { transform: rotateY(180deg) translateZ(23px); }
.kiss-webar-sc-side--top    { transform: rotateX(90deg) translateZ(23px); }
.kiss-webar-sc-side--bottom { transform: rotateX(-90deg) translateZ(23px); }
.kiss-webar-sc-side--left   { transform: rotateY(-90deg) translateZ(23px); }
.kiss-webar-sc-side--right  { transform: rotateY(90deg) translateZ(23px); }

@keyframes kw-sc-spin {
	0%   { transform: rotateX(-20deg) rotateY(0deg); }
	50%  { transform: rotateX(20deg) rotateY(180deg); }
	100% { transform: rotateX(-20deg) rotateY(360deg); }
}

@media (prefers-reduced-motion: reduce) {
	.kiss-webar-sc-cube { animation-duration: 8s; }
}

/* Recovery cover (1.20.4): after an app/tab-switch recovery reload, the
   whole page waits behind the cube until the 3D section has settled (see
   startRecoveryCover). Above everything, the pre-AR intro included. */
.kiss-webar-sc-recover {
	position: fixed;
	inset: 0;
	z-index: 100001;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--kw-recover-bg, #ffffff);
	transition: opacity 0.3s ease;
}
.kiss-webar-sc-recover.is-done {
	opacity: 0;
	pointer-events: none;
}

/* Hotspots ----------------------------------------------------------- */

.kiss-webar-hotspot {
	appearance: none;
	background: transparent;
	border: 0;
	padding: 0;
	margin: 0;
	cursor: default;
}

/* Neutralize the host theme's <button>/link hover + focus styling (Hello
   Elementor paints a colored square behind the dot on rollover). !important
   is needed to beat the theme; the dot's own hover state is handled below. */
.kiss-webar-hotspot,
.kiss-webar-hotspot:hover,
.kiss-webar-hotspot:focus,
.kiss-webar-hotspot:active {
	background: transparent !important;
	box-shadow: none !important;
	outline: none !important;
	text-decoration: none !important;
	/* The theme's button box too (Hello Elementor: 1px #c36 border, padding,
	   radius). Our plain rule above only wins when this stylesheet happens to
	   load after the theme's; padding would also shift the dot off its point. */
	border: 0 !important;
	padding: 0 !important;
	border-radius: 0 !important;
	min-width: 0 !important;
	min-height: 0 !important;
}

/* Keyboard focus still gets a clean ring — on the dot, not a theme square. */
.kiss-webar-hotspot:focus-visible .kiss-webar-hotspot-dot {
	outline: 2px solid var(--kw-hotspot, #ffcc33);
	outline-offset: 2px;
}

.kiss-webar-hotspot.has-content {
	cursor: pointer;
}

.kiss-webar-hotspot-dot {
	position: relative;
	display: block;
	/* The size is the WHOLE dot, white ring included, as with the Scroll
	   Assembly's step markers, so the same number gives the same dot (1.19.3;
	   it used to be the inside, 6px smaller than drawn). 32 = the old default
	   26 + the ring: unset dots look as before. */
	box-sizing: border-box;
	width: var(--kw-hotspot-size, 32px);
	height: var(--kw-hotspot-size, 32px);
	border-radius: 50%;
	background: var(--kw-hotspot, #ffcc33);
	border: 3px solid #fff;
	box-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
	transition: transform 120ms ease, opacity 160ms ease;
}

/* Touch: a dot can be tiny (a site may set 12px), but a finger needs about
   44px. An invisible circle around the dot takes the tap; the dot looks the
   same. It's on the dot (not the button) so it switches off with the dot:
   hidden siblings, Test playing, the lift lowered. Callout dots only, and
   only for coarse pointers: a mouse is precise, and a bare marker shouldn't
   swallow a drag. */
@media (pointer: coarse) {
	.kiss-webar-hotspot.has-content .kiss-webar-hotspot-dot::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: max(44px, 100%);
		height: max(44px, 100%);
		transform: translate(-50%, -50%);
		border-radius: 50%;
		background: transparent;
	}
}

/* When a callout is open, HIDE the other dots. model-viewer stacks hotspots
   by camera depth on their shadow-DOM <slot>, so a nearer dot renders on top
   of the open popover no matter what z-index our button carries — even a
   dimmed (semi-transparent) dot still paints over the callout. Fully hiding
   the siblings is the only reliable way to keep the open modal unobstructed.
   Class toggled on the container by the runtime. */
.kiss-webar-showcase.kw-has-open-callout .kiss-webar-hotspot:not(.is-open) .kiss-webar-hotspot-dot {
	opacity: 0;
	pointer-events: none;
}
.kiss-webar-showcase.kw-has-open-callout .kiss-webar-hotspot:not(.is-open) .kiss-webar-hotspot-dot::before {
	animation: none;
	opacity: 0;
}

/* Gentle attention pulse so the callouts read as interactive points without
   a big opaque marker hiding the model. Only on hotspots that have copy. */
.kiss-webar-hotspot.has-content .kiss-webar-hotspot-dot::before {
	content: "";
	position: absolute;
	inset: -5px;
	border-radius: 50%;
	border: 2px solid var(--kw-hotspot, #ffcc33);
	pointer-events: none;
	animation: kw-hotspot-pulse 2.4s ease-out infinite;
}

@keyframes kw-hotspot-pulse {
	0%   { transform: scale(0.7); opacity: 0.7; }
	70%  { transform: scale(1.6); opacity: 0; }
	100% { transform: scale(1.6); opacity: 0; }
}

/* Stop the pulse once a callout is open (it would fight the popover). */
.kiss-webar-hotspot.is-open .kiss-webar-hotspot-dot::before {
	animation: none;
	opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-webar-hotspot.has-content .kiss-webar-hotspot-dot::before {
		animation: none;
		opacity: 0;
	}
}

/* An open callout (and its dot) must sit above sibling hotspots. model-viewer
   assigns each hotspot an inline z-index by depth, so a dot nearer the camera
   would otherwise cover an open popover — !important beats that inline value. */
.kiss-webar-hotspot.is-open {
	z-index: 10000 !important;
}

.kiss-webar-hotspot.has-content:hover .kiss-webar-hotspot-dot,
.kiss-webar-hotspot.is-open .kiss-webar-hotspot-dot {
	transform: scale(1.18);
}

/* Hover fill: defaults to the dot's own color (no visible change beyond the
   scale) unless a hover color is set in Settings. This replaces the theme's
   pink rollover, which is neutralized above. */
.kiss-webar-hotspot.has-content:hover .kiss-webar-hotspot-dot {
	background: var(--kw-hotspot-hover, var(--kw-hotspot, #ffcc33));
}

.kiss-webar-hotspot.is-empty .kiss-webar-hotspot-dot {
	opacity: 0.55;
}

.kiss-webar-hotspot-content {
	box-sizing: border-box;
	position: absolute;
	left: 50%;
	bottom: calc(100% + 12px);
	transform: translateX(calc(-50% + var(--kw-callout-dx, 0px))) translateY(6px);
	width: max-content;
	max-width: 280px;
	background: var(--kw-callout-bg, #1e232a);
	color: var(--kw-callout-fg, #fff);
	border-radius: 10px;
	padding: 14px 16px;
	box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
	opacity: 0;
	pointer-events: none;
	transition: opacity 140ms ease, transform 140ms ease;
	z-index: 2;
	text-align: left;
}

/* Reset inherited theme spacing so the container padding is the ONLY outer
   spacing — guarantees uniform padding on all four sides regardless of the
   host theme's <p>/<ul>/<strong> margins. */
.kiss-webar-hotspot-content,
.kiss-webar-hotspot-content * {
	box-sizing: border-box;
}
.kiss-webar-hotspot-content > *:first-child {
	margin-top: 0;
}
.kiss-webar-hotspot-content > *:last-child {
	margin-bottom: 0;
}

.kiss-webar-hotspot.is-open .kiss-webar-hotspot-content {
	opacity: 1;
	transform: translateX(calc(-50% + var(--kw-callout-dx, 0px))) translateY(0);
	pointer-events: auto;
}

.kiss-webar-hotspot-content::after {
	content: "";
	position: absolute;
	top: 100%;
	/* Counter the box's horizontal nudge so the arrow keeps pointing at the
	   dot even when the callout has slid sideways to stay in frame. */
	left: calc(50% - var(--kw-callout-dx, 0px));
	transform: translateX(-50%);
	border: 7px solid transparent;
	border-top-color: var(--kw-callout-bg, #1e232a);
}

/*
 * Flip below the dot when there isn't room above.
 *
 * model-viewer clips slotted content at its own box, so a callout on a hotspot
 * near the top of the canvas was simply cut off. The runtime measures on open
 * (and as the model rotates) and adds .kw-flip-down when the space above can't
 * fit the box — the standard popover collision behavior. A taller viewer only
 * postpones the problem: rotate the model and the hotspot returns to the edge.
 */
.kiss-webar-hotspot.kw-flip-down .kiss-webar-hotspot-content {
	bottom: auto;
	top: calc(100% + 12px);
	transform: translateX(calc(-50% + var(--kw-callout-dx, 0px))) translateY(-6px);
}
.kiss-webar-hotspot.kw-flip-down.is-open .kiss-webar-hotspot-content {
	transform: translateX(calc(-50% + var(--kw-callout-dx, 0px))) translateY(0);
}
.kiss-webar-hotspot.kw-flip-down .kiss-webar-hotspot-content::after {
	top: auto;
	bottom: 100%;
	border-top-color: transparent;
	border-bottom-color: var(--kw-callout-bg, #1e232a);
}

.kiss-webar-hotspot-title {
	display: block;
	margin: 0;
	font-size: 14px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--kw-callout-fg, #fff);
}

.kiss-webar-hotspot-body {
	margin: 8px 0 0;
	font-size: 13px;
	line-height: 1.45;
	color: var(--kw-callout-fg, #fff);
	opacity: 0.9;
	/* Wrap long tokens instead of overflowing the rounded box. */
	overflow-wrap: anywhere;
	word-break: break-word;
}

/* Vertical lists — the "one item per line" callout the designer wants. */
.kiss-webar-hotspot-body ul,
.kiss-webar-hotspot-body ol {
	margin: 0;
	padding-left: 1.15em;
	list-style-position: outside;
}
.kiss-webar-hotspot-body li {
	margin: 3px 0;
}
.kiss-webar-hotspot-body p {
	margin: 0 0 6px;
}
.kiss-webar-hotspot-body p:last-child {
	margin-bottom: 0;
}
.kiss-webar-hotspot-body a {
	color: inherit;
	text-decoration: underline;
}

/* Instructions chip -------------------------------------------------- */

.kiss-webar-sc-instr {
	position: absolute;
	/*
	 * Laid out as a BAND (left+right) rather than left:50% + translateX, so the
	 * chip centers inside whatever horizontal space is actually free. When the
	 * zoom rail is present the band stops short of it (see .kw-has-zoom below)
	 * and the chip simply re-centers in the remainder — it can never run under
	 * the +/−/reset buttons the way a viewport-centered box did.
	 */
	left: 12px;
	right: 12px;
	bottom: 16px;
	margin: 0 auto; /* centers the max-content box within the band */
	display: inline-flex;
	align-items: center;
	gap: 8px;
	/* Size to content up to the max-width. Without this, an absolutely-
	   positioned shrink-to-fit box can only use part of the container during
	   layout, so long instruction text wrapped into a narrow, squished column.
	   max-content lets it take the full available width and stay on 1–2 lines. */
	width: max-content;
	/* NOTE: a percentage max-width on an absolutely-positioned box resolves
	   against the CONTAINING BLOCK, not the left/right band — so the cap has to
	   subtract the band insets explicitly or the chip overflows the gutter. */
	max-width: calc(100% - 24px);
	box-sizing: border-box;
	background: var(--kw-instr-bg, rgba(20, 24, 28, 0.86));
	color: #fff;
	font-size: 13px;
	line-height: 1.2;
	padding: 9px 10px 9px 16px;
	border-radius: 999px;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
	z-index: 3;
	transition: opacity 160ms ease;
}

.kiss-webar-sc-instr-text {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.kiss-webar-sc-instr.is-hidden {
	opacity: 0;
	pointer-events: none;
}

.kiss-webar-sc-instr-close {
	appearance: none;
	box-sizing: border-box;
	background: rgba(255, 255, 255, 0.18);
	color: #fff;
	border: 0;
	/* Lock to a circle — the host theme's button padding / min-width would
	   otherwise stretch it into an oval. */
	width: 22px !important;
	height: 22px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	padding: 0 !important;
	border-radius: 50%;
	cursor: pointer;
	font-size: 12px;
	line-height: 1;
	flex: 0 0 22px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.kiss-webar-sc-instr-close:hover {
	background: rgba(255, 255, 255, 0.3);
}

/* On narrow viewports the text has to wrap, so drop the pill shape (a
   999px radius on multi-line text reads as a squished oval blob) and use a
   proper rounded-rectangle toast: left-aligned text, comfortable line
   spacing, and the close button pinned to the top-right. */
@media (max-width: 600px) {
	.kiss-webar-sc-instr {
		align-items: flex-start;
		gap: 10px;
		padding: 11px 12px 11px 14px;
		border-radius: 14px;
		line-height: 1.38;
	}
	.kiss-webar-sc-instr-text {
		white-space: normal;
		text-align: left;
	}
	.kiss-webar-sc-instr-close {
		margin-top: 1px;
	}
}

/* AR Quick View button ----------------------------------------------- */

/* Bottom-center CTA over the viewer. Hidden until the runtime confirms the
   device can activate AR (adds .kw-ar-ready on the container), so it never
   shows on desktop. Explicit colors + resets so the host theme's button
   styling can't repaint or reshape it. */
.kiss-webar-sc-ar {
	position: absolute;
	left: 50%;
	/* Sits as low as it can without touching the frame edge, so it overlaps as
	   little of the model's base as possible (the model auto-frames to fill the
	   viewer, so any floating CTA covers something). */
	bottom: 10px;
	transform: translateX(-50%);
	z-index: 4;
	display: none;
	appearance: none;
	background: var(--kw-ar-bg, #ffcc33) !important;
	color: var(--kw-ar-fg, #1a1a1a) !important;
	border: 0 !important;
	padding: 12px 22px !important;
	font-weight: 700;
	font-size: 15px;
	line-height: 1.1;
	border-radius: 999px !important;
	cursor: pointer;
	white-space: nowrap;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.kiss-webar-sc-ar:hover {
	filter: brightness(0.94);
}

.kiss-webar-showcase.kw-ar-ready .kiss-webar-sc-ar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* When the AR button is present, lift the instructions chip above it so the
   two don't stack on the same bottom edge. */
.kiss-webar-showcase.kw-ar-ready .kiss-webar-sc-instr {
	bottom: 74px;
}

/*
 * Reserve a gutter for the zoom rail.
 *
 * The rail is ~36px wide and ~120px tall anchored bottom-right, so it occupies
 * the same vertical band as the lifted instructions chip. Ending the chip's
 * band (and capping the AR button) before the rail is what keeps the chip's
 * close button from landing under the "+". The runtime adds .kw-has-zoom only
 * when the controls actually render, so a showcase with them switched off
 * still uses the full width.
 */
.kiss-webar-showcase.kw-has-zoom .kiss-webar-sc-instr {
	right: 60px;
	max-width: calc(100% - 72px); /* left 12 + right 60 */
}
.kiss-webar-showcase.kw-has-zoom .kiss-webar-sc-ar {
	max-width: calc(100% - 112px);
}
@media (max-width: 480px) {
	.kiss-webar-showcase.kw-has-zoom .kiss-webar-sc-instr {
		right: 50px;
		max-width: calc(100% - 62px); /* left 12 + right 50 */
	}
	.kiss-webar-showcase.kw-has-zoom .kiss-webar-sc-ar {
		max-width: calc(100% - 96px);
	}
}

/* Pre-AR intro modal (shown before the showcase AR button fires) ------- */
/* Appended to <body> as a fixed full-screen overlay so it centers on the
   phone regardless of where the showcase sits/scrolls. On-brand dark panel
   with forced light text (theme-proof), matching the AR launcher's modal. */

.kiss-webar-sc-intro-modal {
	position: fixed;
	inset: 0;
	z-index: 100000;
	background: rgba(10, 15, 20, 0.85);
	display: none;
	align-items: center;
	justify-content: center;
	padding: 20px;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	font-family: inherit;
}

.kiss-webar-sc-intro-modal.is-open {
	display: flex;
}

.kiss-webar-sc-intro-panel {
	background: #1e232a;
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.12);
	border-radius: 14px;
	padding: 22px 22px 20px;
	max-width: 520px;
	width: 100%;
	max-height: 90vh;
	overflow-y: auto;
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.55);
	display: flex;
	flex-direction: column;
	gap: 16px;
}

/* Author-written instructions: dark panel is authoritative, so force light
   text regardless of the theme's paragraph/heading colors. */
.kiss-webar-sc-intro-body {
	font-size: 15px;
	line-height: 1.55;
	overflow-wrap: break-word;
}
.kiss-webar-sc-intro-body,
.kiss-webar-sc-intro-body * {
	color: #fff !important;
}
.kiss-webar-sc-intro-body a,
.kiss-webar-sc-intro-body a * {
	color: #ffcc33 !important;
	text-decoration: underline;
}
.kiss-webar-sc-intro-body :first-child { margin-top: 0; }
.kiss-webar-sc-intro-body :last-child  { margin-bottom: 0; }
.kiss-webar-sc-intro-body h2 { font-size: 20px; }
.kiss-webar-sc-intro-body h3 { font-size: 17px; }
.kiss-webar-sc-intro-body ul,
.kiss-webar-sc-intro-body ol { padding-left: 1.2em; margin: 0.5em 0; }
.kiss-webar-sc-intro-body li { margin: 0.3em 0; }

.kiss-webar-sc-intro-skip {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
	color: rgba(255, 255, 255, 0.8) !important;
	cursor: pointer;
}

.kiss-webar-sc-intro-skip input {
	accent-color: #ffcc33;
	width: 16px;
	height: 16px;
	margin: 0;
}

/* Mobile-first: stacked, primary (Continue) on top and full-width for a big
   tap target; Cancel below. Widen to a right-aligned row on larger screens. */
.kiss-webar-sc-intro-actions {
	display: flex;
	flex-direction: column-reverse;
	gap: 10px;
}

.kiss-webar-sc-intro-continue,
.kiss-webar-sc-intro-cancel {
	-webkit-appearance: none;
	appearance: none;
	box-sizing: border-box;
	width: 100%;
	padding: 14px 20px !important;
	border-radius: 999px !important;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.1;
	cursor: pointer;
	box-shadow: none !important;
	white-space: normal;
}

.kiss-webar-sc-intro-continue {
	background: #ffcc33 !important;
	color: #1a1a1a !important;
	border: 0 !important;
}
.kiss-webar-sc-intro-continue:hover { filter: brightness(0.94); }

/* The only way forward, so nothing may repaint it: a site's theme or kit
   styles every <button> (Hello Elementor, Elementor kit buttons, site CSS),
   sometimes with !important and in :hover/:focus/:active, and on a client's
   Pixel the Continue button rendered as dark text on the dark panel; it
   looked disabled, so AR never launched. Higher specificity + !important,
   every state. The AR button colors arrive as --kw-intro-cta-* (set inline
   by the runtime). */
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-continue,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-continue:hover,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-continue:focus,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-continue:focus-visible,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-continue:active {
	display: block !important;
	visibility: visible !important;
	opacity: 1 !important;
	background: var(--kw-intro-cta-bg, #ffcc33) !important;
	background-image: none !important;
	color: var(--kw-intro-cta-fg, #1a1a1a) !important;
	-webkit-text-fill-color: var(--kw-intro-cta-fg, #1a1a1a) !important;
	border: 0 !important;
	text-shadow: none !important;
	pointer-events: auto !important;
}
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-cancel,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-cancel:focus,
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-cancel:active {
	opacity: 1 !important;
	background: transparent !important;
	background-image: none !important;
	color: #fff !important;
	-webkit-text-fill-color: #fff !important;
	border: 1px solid rgba(255, 255, 255, 0.28) !important;
}
.kiss-webar-sc-intro-modal .kiss-webar-sc-intro-actions button.kiss-webar-sc-intro-cancel:hover {
	background: rgba(255, 255, 255, 0.08) !important;
}

.kiss-webar-sc-intro-cancel {
	background: transparent !important;
	color: #fff !important;
	border: 1px solid rgba(255, 255, 255, 0.28) !important;
	font-weight: 500;
}
.kiss-webar-sc-intro-cancel:hover { background: rgba(255, 255, 255, 0.08) !important; }

@media (min-width: 480px) {
	.kiss-webar-sc-intro-actions {
		flex-direction: row;
		justify-content: flex-end;
	}
	.kiss-webar-sc-intro-continue,
	.kiss-webar-sc-intro-cancel {
		width: auto;
	}
}

/*
 * Zoom controls (+ / − / reset).
 *
 * Once the mouse wheel belongs to the page (the default "page" scroll mode),
 * these buttons are the discoverable way to zoom — the same role the +/−
 * controls play on an embedded map. They're real <button>s, so they're
 * keyboard/AT accessible; every visual property is reset with !important
 * because host themes (Hello Elementor et al) style bare `button` aggressively
 * (pink borders, yellow fills, big radii) and would otherwise bleed in.
 */
.kiss-webar-sc-zoom {
	position: absolute;
	/* Center children on a common axis: the pan pad is a 3-column cross and so
	   much wider than the single buttons, which would otherwise left-align
	   against it and read as two separate clusters. */
	align-items: center;
	right: 12px;
	/* Clears the AR button row; the chip's band stops short of this rail
	   (see .kw-has-zoom) so the two can never collide. */
	bottom: 64px;
	z-index: 4;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.kiss-webar-sc-zoom-btn {
	appearance: none;
	-webkit-appearance: none;
	width: 36px !important;
	height: 36px !important;
	min-width: 36px !important;
	padding: 0 !important;
	margin: 0 !important;
	display: flex !important;
	align-items: center;
	justify-content: center;
	background: rgba(20, 24, 30, 0.72) !important;
	color: #fff !important;
	border: 1px solid rgba(255, 255, 255, 0.18) !important;
	border-radius: 8px !important;
	font-size: 18px !important;
	font-weight: 700;
	line-height: 1 !important;
	cursor: pointer;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
	transition: background-color 0.15s ease, transform 0.1s ease;
}
.kiss-webar-sc-zoom-btn:hover,
.kiss-webar-sc-zoom-btn:focus {
	background: rgba(20, 24, 30, 0.92) !important;
	color: #fff !important;
	outline: none !important;
}
.kiss-webar-sc-zoom-btn:focus-visible {
	outline: 2px solid var(--kw-hotspot, #ffcc33) !important;
	outline-offset: 2px;
}
.kiss-webar-sc-zoom-btn:active {
	transform: scale(0.94);
}
.kiss-webar-sc-zoom-reset {
	font-size: 15px !important;
}

/* Keep the zoom stack clear of the centered AR button on narrow screens. */
@media (max-width: 480px) {
	.kiss-webar-sc-zoom {
		right: 8px;
		bottom: 12px;
	}
	.kiss-webar-sc-zoom-btn {
		width: 32px !important;
		height: 32px !important;
		min-width: 32px !important;
		font-size: 16px !important;
	}
}

/*
 * "Hold Ctrl (⌘) and scroll to zoom" — the transient affordance shown when the
 * visitor wheels over the model without the modifier. A hint, never a gate:
 * pointer-events stay off so it can't swallow a drag, and it fades itself out.
 */
.kiss-webar-sc-wheelhint {
	position: absolute;
	inset: 0;
	z-index: 5;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	text-align: center;
	/* Settings → Showcase controls → Scroll-to-zoom overlay (color, opacity, text). */
	background: var(--kw-wheel-bg, rgba(12, 15, 20, 0.55));
	color: var(--kw-wheel-fg, #fff) !important;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.35;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.18s ease;
}
.kiss-webar-sc-wheelhint.is-visible {
	opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
	.kiss-webar-sc-wheelhint {
		transition: none;
	}
}

/*
 * AR button BELOW the model (Settings → AR button position).
 *
 * The model auto-frames to fill the viewer, so a floating CTA always covers
 * some of it — and it can't simply be pushed lower, because it's already at
 * the frame's bottom edge. Taking it out of the overlay and letting it flow
 * under the viewer is the only placement that leaves the model completely
 * clear. The container becomes a column so the button stacks beneath the
 * canvas; the chip drops back to the frame's bottom edge since nothing is
 * floating there any more.
 */
.kiss-webar-showcase.kw-ar-below {
	display: flex;
	flex-direction: column;
}
.kiss-webar-showcase.kw-ar-below .kiss-webar-sc-ar {
	position: static;
	transform: none;
	margin: 14px auto 2px;
	max-width: none;
}
.kiss-webar-showcase.kw-ar-below.kw-ar-ready .kiss-webar-sc-ar {
	display: inline-flex;
}
/* Nothing floats at the bottom edge now, so the chip doesn't need lifting. */
.kiss-webar-showcase.kw-ar-below.kw-ar-ready .kiss-webar-sc-instr {
	bottom: 16px;
}
/* The rail can drop back down too — the AR row is outside the canvas. */
.kiss-webar-showcase.kw-ar-below .kiss-webar-sc-zoom {
	bottom: 16px;
}

/*
 * Stage — the positioning context for everything that floats over the model.
 *
 * Overlays (instructions chip, control rail, wheel hint) anchor to the CANVAS,
 * not to the outer container. That matters when the AR button is placed BELOW
 * the model: the container then grows to include that button, so a `bottom:`
 * overlay measured from the container would sit behind the button. The stage
 * wraps only the canvas + its overlays, so their `bottom` is always the
 * canvas's bottom.
 */
.kiss-webar-sc-stage {
	position: relative;
	width: 100%;
}

/* Rail buttons are brandable: set the three colors in Settings → 3D Showcase
   (or per placement on the Elementor widget). Defaults keep the neutral dark
   translucent look that reads on both light and dark models. */
.kiss-webar-sc-zoom-btn {
	background: var(--kw-ctrl-bg, rgba(20, 24, 30, 0.72)) !important;
	color: var(--kw-ctrl-fg, #fff) !important;
}
.kiss-webar-sc-zoom-btn:hover,
.kiss-webar-sc-zoom-btn:focus {
	background: var(--kw-ctrl-hover-bg, var(--kw-ctrl-bg, rgba(20, 24, 30, 0.92))) !important;
	/* Falls back to the normal icon color, but is settable on its own: a brand
	   whose hover background equals its icon color (e.g. yellow on yellow)
	   would otherwise render an invisible glyph. */
	color: var(--kw-ctrl-hover-fg, var(--kw-ctrl-fg, #fff)) !important;
}
/* The info glyph is the circled-i character (U+24D8), so it needs no faux
   styling — just a slightly larger optical size to match the +/−/↻ weights. */
/* The instructions button uses an inline SVG rather than the ⓘ character: a
   glyph sits wherever the font's metrics put it (the circled-i rode high in
   its button), and the font here comes from the host theme, so a hardcoded
   nudge would be wrong elsewhere. `display:block` takes the SVG off the text
   baseline so the button's flex centering lands it exactly. */
.kiss-webar-sc-zoom-info svg {
	display: block;
}

/* Breathing room under the AR button when it sits below the model, so it
   doesn't collide with whatever section follows. */
.kiss-webar-showcase.kw-ar-below .kiss-webar-sc-ar {
	margin-bottom: 16px;
}
@media (max-width: 768px) {
	.kiss-webar-showcase.kw-ar-below .kiss-webar-sc-ar {
		margin-bottom: 22px;
	}
}

/*
 * Rail tooltips — ours, not the browser's.
 *
 * A native `title` is positioned by the browser to the lower-RIGHT of the
 * cursor, so on a rail hugging the right edge of the viewer it runs off the
 * page. This one opens to the LEFT of the button, so it always resolves
 * inside the layout. Pointer devices only: on touch there's no hover state
 * worth showing, and a sticky :hover after a tap would leave it stuck open.
 */
.kiss-webar-sc-zoom-btn {
	position: relative;
}

@media (hover: hover) and (pointer: fine) {
	/* The card colors (Settings → 3D Showcase → Callouts & cards), and none
	   of the theme's button lettering (uppercase, tracking) that the
	   pseudo-element would otherwise inherit from the button. */
	.kiss-webar-sc-zoom-btn::after {
		content: attr(data-kw-tip);
		position: absolute;
		right: calc(100% + 8px);
		top: 50%;
		transform: translateY(-50%);
		z-index: 6;
		padding: 5px 9px;
		border-radius: 6px;
		background: var(--kw-callout-bg, #1e232a);
		color: var(--kw-callout-fg, #fff);
		box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
		font-size: 12px;
		font-weight: 600;
		font-style: normal;
		line-height: 1.2;
		text-transform: none;
		letter-spacing: normal;
		white-space: nowrap;
		pointer-events: none;
		opacity: 0;
		transition: opacity 120ms ease;
	}
	.kiss-webar-sc-zoom-btn:hover::after,
	.kiss-webar-sc-zoom-btn:focus-visible::after {
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.kiss-webar-sc-zoom-btn::after {
		transition: none;
	}
}

/*
 * Pan pad — a compact 3×3 cross so ← ↑ ↓ → cost about the height of two rail
 * buttons instead of four. Two-finger drag already pans on touch, but that
 * gesture is easy to miss and some visitors avoid gestures entirely.
 */
.kiss-webar-sc-pan {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-template-rows: repeat(3, auto);
	gap: 2px;
	margin-top: 2px;
}
.kiss-webar-sc-pan .kw-pan-up    { grid-area: 1 / 2 / 2 / 3; }
.kiss-webar-sc-pan .kw-pan-left  { grid-area: 2 / 1 / 3 / 2; }
.kiss-webar-sc-pan .kw-pan-right { grid-area: 2 / 3 / 3 / 4; }
.kiss-webar-sc-pan .kw-pan-down  { grid-area: 3 / 2 / 4 / 3; }

.kiss-webar-sc-pan-btn {
	width: 30px !important;
	height: 30px !important;
	min-width: 30px !important;
	font-size: 15px !important;
}
@media (max-width: 480px) {
	.kiss-webar-sc-pan-btn {
		width: 28px !important;
		height: 28px !important;
		min-width: 28px !important;
		font-size: 14px !important;
	}
}

/*
 * The pan pad makes the rail ~94px wide instead of ~36px, so the gutter that
 * keeps the instructions chip and AR button clear of the rail has to grow to
 * match — otherwise the chip runs under the arrows.
 */
.kiss-webar-showcase.kw-has-pan .kiss-webar-sc-instr {
	right: 118px;
	max-width: calc(100% - 130px);
}
.kiss-webar-showcase.kw-has-pan .kiss-webar-sc-ar {
	max-width: calc(100% - 170px);
}
@media (max-width: 480px) {
	.kiss-webar-showcase.kw-has-pan .kiss-webar-sc-instr {
		right: 104px;
		max-width: calc(100% - 116px);
	}
	.kiss-webar-showcase.kw-has-pan .kiss-webar-sc-ar {
		max-width: calc(100% - 150px);
	}
}

/*
 * Controls docked as a BAR under the canvas (Settings → Controls position).
 *
 * A floating rail always costs canvas, and on a phone eight buttons stacked
 * down the right edge sit squarely on the model. Docking them below removes
 * the overlap entirely rather than trading one crowded corner for another —
 * which is also why this is preferred over hiding them behind a toggle: the
 * pan pad exists precisely because the gesture wasn't discoverable.
 */
.kiss-webar-showcase.kw-ctrl-bar {
	display: flex;
	flex-direction: column;
}
.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom {
	position: static;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 6px;
	margin: 10px auto 2px;
	padding: 0 8px;
}
/* The cross becomes a row here: ← ↑ ↓ → reads naturally left-to-right. */
.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-pan {
	display: flex;
	flex-direction: row;
	gap: 6px;
	margin-top: 0;
	/* A hairline separator keeps the movement group legible next to the
	   zoom/reset/info cluster without adding another element. */
	padding-left: 8px;
	border-left: 1px solid var(--kw-ctrl-bg, rgba(20, 24, 30, 0.28));
}
.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-pan > * {
	grid-area: auto;
}
.kiss-webar-showcase.kw-ctrl-bar .kw-pan-left  { order: 1; }
.kiss-webar-showcase.kw-ctrl-bar .kw-pan-up    { order: 2; }
.kiss-webar-showcase.kw-ctrl-bar .kw-pan-down  { order: 3; }
.kiss-webar-showcase.kw-ctrl-bar .kw-pan-right { order: 4; }
.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-pan-btn {
	width: 36px !important;
	height: 36px !important;
	min-width: 36px !important;
	font-size: 16px !important;
}
/* Tooltips open upward from a docked bar, centered on the button, except
   near a screen edge: there they line up with the button's edge instead, so
   they stay on screen (kw-tip-start / kw-tip-end, set on hover in script). */
@media (hover: hover) and (pointer: fine) {
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom-btn::after {
		right: auto;
		left: 50%;
		top: auto;
		bottom: calc(100% + 8px);
		transform: translateX(-50%);
	}
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom-btn.kw-tip-start::after {
		left: 0;
		transform: none;
	}
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom-btn.kw-tip-end::after {
		left: auto;
		right: 0;
		transform: none;
	}
}
@media (max-width: 480px) {
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom {
		gap: 5px;
	}
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-zoom-btn,
	.kiss-webar-showcase.kw-ctrl-bar .kiss-webar-sc-pan-btn {
		width: 34px !important;
		height: 34px !important;
		min-width: 34px !important;
	}
}

/* Leader line -------------------------------------------------------------
   From a marker on the model to the edge of its card (card callouts here, and
   the Scroll Assembly's step cards — the assembly loads this stylesheet). One
   SVG over the stage, under the card, never taking input; drawn in when a new
   marker/card pair appears. Color: --kw-leader (Settings → 3D Showcase →
   Callouts), else the assembly accent, else the hotspot color. */
.kw-leader {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	overflow: visible;
	pointer-events: none;
	z-index: 3;
	opacity: 0;
	transition: opacity 0.2s ease;
}

.kw-leader.is-on {
	opacity: 1;
}

.kw-leader-path {
	fill: none;
	stroke: var(--kw-leader, var(--kw-asm-accent, var(--kw-hotspot, #ffcc33)));
	stroke-width: var(--kw-leader-width, 2px);
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-dasharray: 1;
	stroke-dashoffset: 0;
	filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}

.kw-leader-end {
	fill: var(--kw-leader, var(--kw-asm-accent, var(--kw-hotspot, #ffcc33)));
}

.kw-leader.is-drawing .kw-leader-path {
	animation: kw-leader-draw 0.5s ease-out both;
}

@keyframes kw-leader-draw {
	from { stroke-dashoffset: 1; }
	to   { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.kw-leader.is-drawing .kw-leader-path { animation: none; }
}

/* Card callouts (Callout style: Card) -------------------------------------
   The open hotspot's copy in a card docked at the side of the frame — on the
   side away from the dot — or along the bottom on phones, compact. Same look
   as the Scroll Assembly's step cards. The bubble popovers are switched off
   in this mode; the other dots stay visible (dimmed) so visitors can hop
   between them — no popover sits over them, so there's nothing to hide. */
.kiss-webar-showcase.kw-callouts-card .kiss-webar-hotspot-content {
	display: none !important;
}

.kiss-webar-showcase.kw-callouts-card.kw-has-open-callout .kiss-webar-hotspot:not(.is-open) .kiss-webar-hotspot-dot {
	opacity: 0.55;
	pointer-events: auto;
}

.kiss-webar-showcase.kw-callouts-card.kw-has-open-callout .kiss-webar-hotspot:not(.is-open) .kiss-webar-hotspot-dot::before {
	animation: none;
	opacity: 0;
}

.kiss-webar-showcase.kw-callouts-card.kw-has-open-callout .kiss-webar-sc-instr {
	opacity: 0 !important;
	visibility: hidden;
	pointer-events: none;
}

.kiss-webar-showcase .kiss-webar-sc-card {
	position: absolute;
	z-index: 4;
	left: clamp(16px, 3vw, 40px);
	top: 50%;
	transform: translateY(-50%);
	width: min(var(--kw-card-w, 340px), 40%);
	max-height: calc(100% - 32px);
	overflow: auto;
	box-sizing: border-box;
	padding: 18px 20px 20px;
	border-radius: 10px;
	background: var(--kw-callout-bg, #1e232a);
	color: var(--kw-callout-fg, #ffffff);
	box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
	text-align: left;
}

.kiss-webar-showcase .kiss-webar-sc-card[hidden] {
	display: none !important;
}

.kiss-webar-showcase .kiss-webar-sc-card.is-right {
	left: auto;
	right: clamp(16px, 3vw, 40px);
}

.kiss-webar-showcase.kw-has-zoom .kiss-webar-sc-card.is-right { right: 64px; }
.kiss-webar-showcase.kw-has-pan .kiss-webar-sc-card.is-right { right: 124px; }

.kiss-webar-showcase .kiss-webar-sc-card.is-in {
	animation: kw-sc-card-in 0.3s ease both;
}

@keyframes kw-sc-card-in {
	from { opacity: 0; transform: translateY(calc(-50% + 8px)); }
	to   { opacity: 1; transform: translateY(-50%); }
}

/* Placed by the runtime: docked on the side nearest the dot, level with it
   (left/top set inline), so no centering transform. */
.kiss-webar-showcase .kiss-webar-sc-card.is-placed {
	right: auto;
	transform: none;
}

.kiss-webar-showcase .kiss-webar-sc-card.is-placed.is-in {
	animation-name: kw-sc-card-in-p;
}

@keyframes kw-sc-card-in-p {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: none; }
}

.kiss-webar-showcase .kiss-webar-sc-card-close {
	position: absolute;
	top: 8px;
	right: 8px;
	display: flex !important;
	align-items: center;
	justify-content: center;
	width: 28px !important;
	height: 28px !important;
	min-width: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 50% !important;
	background: transparent !important;
	color: inherit !important;
	font-size: 20px !important;
	line-height: 1 !important;
	opacity: 0.7;
	cursor: pointer;
	box-shadow: none !important;
}

.kiss-webar-showcase .kiss-webar-sc-card-close:hover,
.kiss-webar-showcase .kiss-webar-sc-card-close:focus-visible {
	opacity: 1;
	background: rgba(255, 255, 255, 0.12) !important;
}

.kiss-webar-showcase .kiss-webar-sc-card-title {
	margin: 0 !important;
	padding: 0 28px 0 0 !important;
	font-size: clamp(17px, 1.5vw, 21px);
	font-weight: 700;
	line-height: 1.25;
	color: var(--kw-callout-fg, #ffffff) !important;
	text-transform: none;
	letter-spacing: normal;
}

.kiss-webar-showcase .kiss-webar-sc-card-body {
	margin: 8px 0 0 !important;
	font-size: 14px;
	line-height: 1.55;
	color: var(--kw-callout-fg, #ffffff) !important;
	opacity: 0.88;
}

.kiss-webar-showcase .kiss-webar-sc-card-body > *:first-child { margin-top: 0 !important; }
.kiss-webar-showcase .kiss-webar-sc-card-body > *:last-child { margin-bottom: 0 !important; }
.kiss-webar-showcase .kiss-webar-sc-card-body p,
.kiss-webar-showcase .kiss-webar-sc-card-body ul,
.kiss-webar-showcase .kiss-webar-sc-card-body ol { margin: 0 0 8px !important; color: inherit !important; }
.kiss-webar-showcase .kiss-webar-sc-card-body ul,
.kiss-webar-showcase .kiss-webar-sc-card-body ol { padding-left: 1.2em !important; }
.kiss-webar-showcase .kiss-webar-sc-card-body li { color: inherit !important; }
.kiss-webar-showcase .kiss-webar-sc-card-body a { color: inherit !important; text-decoration: underline !important; }

/* Phones: a compact sheet along the bottom of the frame, above the floating
   AR button when there is one, so "View in Real World" is never covered. */
@media (max-width: 768px) {
	.kiss-webar-showcase .kiss-webar-sc-card,
	.kiss-webar-showcase .kiss-webar-sc-card.is-right {
		left: 10px;
		right: 10px;
		top: auto;
		bottom: 10px;
		transform: none;
		width: auto;
		max-height: 50%;
		padding: 12px 14px 14px;
	}
	.kiss-webar-showcase.kw-ar-ready:not(.kw-ar-below) .kiss-webar-sc-card {
		bottom: 62px;
	}
	.kiss-webar-showcase .kiss-webar-sc-card.is-in {
		animation-name: kw-sc-card-in-m;
	}
	@keyframes kw-sc-card-in-m {
		from { opacity: 0; transform: translateY(8px); }
		to   { opacity: 1; transform: none; }
	}
	.kiss-webar-showcase .kiss-webar-sc-card-title {
		font-size: 16px;
	}
	.kiss-webar-showcase .kiss-webar-sc-card-body {
		margin-top: 6px !important;
		font-size: 13.5px;
		line-height: 1.5;
	}
}

/* Scroll-to-zoom hint as a small pill instead of an overlay across the model. */
.kiss-webar-showcase.kw-wheel-pill .kiss-webar-sc-wheelhint {
	inset: auto;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: max-content;
	max-width: calc(100% - 32px);
	padding: 10px 18px;
	border-radius: 999px;
	font-size: 14px;
}

/* Card accent (1.15.0) ----------------------------------------------------
   An optional colored bar across the top of each card (Settings → Callouts
   & cards → Card accent, or per widget). The width variable is only set
   when there's an accent, so cards without one keep no border at all. */
.kiss-webar-showcase .kiss-webar-sc-card {
	border-top: var(--kw-card-accent-w, 0px) solid var(--kw-card-accent, transparent);
}

/* Play button (1.15.0) ----------------------------------------------------
   Plays one of the model file's animations once ("Test the lift"). Top
   center, clear of the AR button and the instructions bar at the bottom.
   Only added when the loaded file actually has an animation. Two looks: the
   site's own buttons (--theme plus its button classes; the default since
   1.18.0) or the plugin's pill below. */
.kiss-webar-sc-play {
	position: absolute;
	top: 12px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 4;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	white-space: nowrap;
	cursor: pointer;
}
.kiss-webar-sc-play:disabled {
	cursor: default;
}
/* Your theme's buttons: as on the Scroll Assembly's, take off the 1px #c36
   border Hello Elementor puts on every <button>, below the kit's own. */
:where(.kiss-webar-showcase) .kiss-webar-sc-play--theme {
	border: 0;
}
.kiss-webar-sc-play:not(.kiss-webar-sc-play--theme) {
	appearance: none;
	background: var(--kw-play-bg, var(--kw-ar-bg, #ffcc33)) !important;
	color: var(--kw-play-fg, var(--kw-ar-fg, #1a1a1a)) !important;
	border: 0 !important;
	border-radius: 999px !important;
	padding: 10px 18px !important;
	font-weight: 800;
	font-size: 13px;
	line-height: 1.1;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}
.kiss-webar-sc-play:not(.kiss-webar-sc-play--theme):hover,
.kiss-webar-sc-play:not(.kiss-webar-sc-play--theme):focus {
	background: var(--kw-play-bg, var(--kw-ar-bg, #ffcc33)) !important;
	color: var(--kw-play-fg, var(--kw-ar-fg, #1a1a1a)) !important;
	filter: brightness(0.95);
}
.kiss-webar-sc-play:not(.kiss-webar-sc-play--theme):disabled {
	filter: none;
}
.kiss-webar-sc-play-icon {
	width: 0;
	height: 0;
	border-left: 8px solid currentColor;
	border-top: 5px solid transparent;
	border-bottom: 5px solid transparent;
}
.kiss-webar-sc-play.is-playing .kiss-webar-sc-play-icon {
	width: 8px;
	height: 8px;
	border: 0;
	border-radius: 50%;
	background: currentColor;
	animation: kw-play-pulse 1s ease-in-out infinite;
}
@keyframes kw-play-pulse {
	50% { opacity: 0.3; }
}

/* While the animation plays, the hotspots would hang where the parts STOOD:
   hide them until it's done. The AR button and the how-to bar step aside
   too: on a phone they sit over the bottom of the model, which is exactly
   where a lift being lowered goes. */
.kiss-webar-showcase.kw-playing .kiss-webar-hotspot,
.kiss-webar-showcase.kw-playing .kiss-webar-sc-ar,
.kiss-webar-showcase.kw-playing .kiss-webar-sc-instr {
	opacity: 0 !important;
	pointer-events: none !important;
}
.kiss-webar-showcase .kiss-webar-sc-ar {
	transition: opacity 0.25s ease;
}

@media (prefers-reduced-motion: reduce) {
	.kiss-webar-sc-play.is-playing .kiss-webar-sc-play-icon { animation: none; }
}

/* Controls: the light look (1.15.0, the default) ---------------------------
   One frosted pill with dark, thin glyphs instead of a stack of dark tiles.
   Settings → Showcase controls → Controls look ("Classic" keeps the dark
   buttons and their brand colors). Same buttons, same order; only the
   paint changes. */
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-zoom {
	gap: 0;
	padding: 4px;
	border-radius: 999px;
	background: var(--kw-ctrl-light-bg, rgba(255, 255, 255, 0.74));
	-webkit-backdrop-filter: blur(10px) saturate(1.3);
	backdrop-filter: blur(10px) saturate(1.3);
	border: 1px solid rgba(255, 255, 255, 0.65);
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 8px 24px rgba(16, 24, 40, 0.12);
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-zoom-btn {
	width: 32px !important;
	height: 32px !important;
	min-width: 32px !important;
	background: transparent !important;
	color: var(--kw-ctrl-light-fg, #2a3340) !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none;
	font-size: 17px !important;
	font-weight: 400;
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-zoom-btn:hover,
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-zoom-btn:focus {
	background: rgba(16, 24, 40, 0.08) !important;
	color: #0f141a !important;
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-zoom-reset {
	font-size: 15px !important;
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-pan {
	gap: 0;
	margin-top: 3px;
	padding-top: 3px;
	border-top: 1px solid rgba(16, 24, 40, 0.1);
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-pan-btn {
	width: 26px !important;
	height: 26px !important;
	min-width: 26px !important;
	font-size: 12px !important;
}
/* Docked under the model (phones): the same pill, horizontal and centered. */
.kiss-webar-showcase.kw-ctrl-light.kw-ctrl-bar .kiss-webar-sc-zoom {
	align-self: center;
	gap: 0;
	padding: 3px 6px;
	max-width: calc(100% - 16px);
	box-sizing: border-box;
}
.kiss-webar-showcase.kw-ctrl-light.kw-ctrl-bar .kiss-webar-sc-pan {
	gap: 0;
	margin: 0 0 0 4px;
	padding: 0 0 0 4px;
	border-top: 0;
	border-left: 1px solid rgba(16, 24, 40, 0.1);
}
.kiss-webar-showcase.kw-ctrl-light.kw-ctrl-bar .kiss-webar-sc-zoom-btn,
.kiss-webar-showcase.kw-ctrl-light.kw-ctrl-bar .kiss-webar-sc-pan-btn {
	width: 34px !important;
	height: 34px !important;
	min-width: 34px !important;
}

/* Up / Stop / Down (1.19.0) -----------------------------------------------
   The visitor drives the lift through its "Lift travel" animation. A small
   vertical remote on the left edge, opposite the camera controls, in the
   same paint as the controls (the light pill).
   While the model is off its starting pose (kw-moved), whatever is pinned to
   where the parts stood steps aside, as during the play button's run. The
   how-to bar isn't pinned to the parts: pressing Up or Down puts it away,
   and (i) brings it back at any pose (1.21.1). */
.kiss-webar-sc-travel {
	position: absolute;
	left: 12px;
	top: 50%;
	transform: translateY(-50%);
	/* Under the card callout (4): a card being read wins if the two touch. */
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	transition: opacity 0.25s ease;
}
/* Phones dock the card callout along the bottom of the viewer, and the remote
   floats at mid-height on the left: a tall card ran under it (the client's
   Pixel: "Gearbox Options" read "rbox Options"). While a card is open the
   remote steps aside, as the other markers do, and is back on close. Wide
   screens place the card by script, clear of the remote (placeCard). */
@media (max-width: 768px) {
	.kiss-webar-showcase.kw-callouts-card.kw-has-open-callout .kiss-webar-sc-travel {
		opacity: 0;
		pointer-events: none;
	}
}
/* …and it waits for the how-to bar to go (kw-instr-open, set by the runtime
   while the bar shows): the two met at the bottom-left of a phone. The bar
   auto-hides, hides on the first drag, or is tapped away. */
.kiss-webar-showcase.kw-instr-open .kiss-webar-sc-travel {
	opacity: 0;
	pointer-events: none;
}
/* The remote sits at the middle of the viewer's left edge on wide screens,
   and in the bottom-left corner on phones and portrait tablets, where
   mid-height lands on the model's posts and the corner is empty (the
   client's Pixel phone and tablet). */
@media (max-width: 768px), (orientation: portrait) and (max-width: 1100px) {
	.kiss-webar-sc-travel {
		top: auto;
		bottom: 14px;
		transform: none;
	}
}
.kiss-webar-sc-travel-btn {
	position: relative;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	width: 36px !important;
	height: 36px !important;
	min-width: 36px !important;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 8px !important;
	background: var(--kw-ctrl-bg, rgba(20, 24, 30, 0.82)) !important;
	color: var(--kw-ctrl-fg, #fff) !important;
	box-shadow: none !important;
	line-height: 1;
	cursor: pointer;
	transition: opacity 0.2s ease, background-color 0.15s ease;
}
.kiss-webar-sc-travel-btn:hover:not(:disabled),
.kiss-webar-sc-travel-btn:focus-visible {
	background: var(--kw-ctrl-hover-bg, rgba(20, 24, 30, 0.95)) !important;
}
.kiss-webar-sc-travel-btn svg {
	display: block;
}
/* The theme's focus ring only for the keyboard, as on the camera controls. */
.kiss-webar-sc-travel-btn:focus {
	outline: none !important;
}
.kiss-webar-sc-travel-btn:focus-visible {
	outline: 2px solid var(--kw-hotspot, #ffcc33) !important;
	outline-offset: 2px;
}
.kiss-webar-sc-travel-btn:disabled {
	opacity: 0.35;
	cursor: default;
}
.kiss-webar-sc-travel-btn.is-active {
	box-shadow: inset 0 0 0 2px currentColor !important;
}
/* The light look: one frosted vertical pill, like the camera controls. */
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-travel {
	gap: 0;
	padding: 4px;
	border-radius: 999px;
	background: var(--kw-ctrl-light-bg, rgba(255, 255, 255, 0.74));
	-webkit-backdrop-filter: blur(10px) saturate(1.3);
	backdrop-filter: blur(10px) saturate(1.3);
	border: 1px solid rgba(255, 255, 255, 0.65);
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 8px 24px rgba(16, 24, 40, 0.12);
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-travel-btn {
	width: 34px !important;
	height: 34px !important;
	min-width: 34px !important;
	border-radius: 999px !important;
	background: transparent !important;
	color: var(--kw-ctrl-light-fg, #2a3340) !important;
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-travel-btn:hover:not(:disabled),
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-travel-btn:focus-visible {
	background: rgba(16, 24, 40, 0.08) !important;
	color: #0f141a !important;
}
.kiss-webar-showcase.kw-ctrl-light .kiss-webar-sc-travel-btn.is-active {
	background: rgba(16, 24, 40, 0.1) !important;
	box-shadow: none !important;
}
/* Mouse only, opening to the right (the remote hugs the left edge); the
   same card colors and plain lettering as the camera controls' tooltips. */
@media (hover: hover) and (pointer: fine) {
	.kiss-webar-sc-travel-btn::after {
		content: attr(data-kw-tip);
		position: absolute;
		left: calc(100% + 10px);
		top: 50%;
		transform: translateY(-50%);
		z-index: 6;
		padding: 5px 9px;
		border-radius: 6px;
		background: var(--kw-callout-bg, #1e232a);
		color: var(--kw-callout-fg, #fff);
		box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
		font-size: 12px;
		font-weight: 600;
		font-style: normal;
		line-height: 1.2;
		text-transform: none;
		letter-spacing: normal;
		white-space: nowrap;
		pointer-events: none;
		opacity: 0;
		transition: opacity 120ms ease;
	}
	.kiss-webar-sc-travel-btn:hover:not(:disabled)::after,
	.kiss-webar-sc-travel-btn:focus-visible::after {
		opacity: 1;
	}
}
/* While the play button runs its animation, the remote waits. */
.kiss-webar-showcase.kw-playing .kiss-webar-sc-travel {
	opacity: 0.4;
	pointer-events: none;
}
.kiss-webar-showcase.kw-moved .kiss-webar-hotspot,
.kiss-webar-showcase.kw-moved .kiss-webar-sc-ar {
	opacity: 0 !important;
	pointer-events: none !important;
}
@media (prefers-reduced-motion: reduce) {
	.kiss-webar-sc-travel-btn,
	.kiss-webar-sc-travel-btn::after {
		transition: none;
	}
}
