/* ==========================================================================
   JHR Hotspot Hero
   --------------------------------------------------------------------------
   The frame is sized by JS to exactly the cover-cropped artwork rectangle.
   Everything that has to line up with the painting lives inside it, so the
   artwork is the one and only coordinate system.
   ========================================================================== */

.jhr-hh {
	--jhr-hh-reveal-duration: 700ms;
	--jhr-hh-reveal-easing: cubic-bezier(.22, .61, .36, 1);
	--jhr-hh-reveal-scale: 1.02;
	--jhr-hh-reveal-glow: rgba(196, 161, 14, .35);
	--jhr-hh-reveal-glow-size: 24px;

	--jhr-hh-dot-size: 9px;
	--jhr-hh-dot-border: rgba(255, 255, 255, .55);
	--jhr-hh-dot-bg: transparent;
	--jhr-hh-dot-active: #e5cb68;
	--jhr-hh-dot-glow: rgba(225, 198, 90, .7);
	--jhr-hh-dot-scale: 1.5;
	--jhr-hh-dots-offset: 48px;

	--jhr-hh-caption-x: 56px;
	--jhr-hh-caption-y: 44px;

	--jhr-hh-indicator: #e5cb68;
	--jhr-hh-indicator-size: 8px;
	--jhr-hh-cursor: pointer;
}

.jhr-hh__hero {
	position: relative;
	width: 100%;
	height: 100svh;
	min-height: 620px;
	overflow: hidden;
	isolation: isolate;
	background: #07111c;
}

.jhr-hh__stage {
	position: absolute;
	inset: 0;
	overflow: hidden;
}

/* --------------------------------------------------------------------------
   The art frame. JS sizes it to the exact cover-crop geometry, and parallax
   transforms this element and nothing inside it, so art, masks and hit areas
   can never drift apart.

   The 100%/100% here is the state BEFORE that happens. Without it the frame is
   a zero-sized box — it has no intrinsic size and only inline styles from
   layout() ever gave it one — so the artwork had nowhere to paint until the
   script ran, however early the browser fetched it. layout()'s inline width,
   height, left and top override these the moment it takes over.
   -------------------------------------------------------------------------- */
.jhr-hh__frame {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	transform-origin: 50% 50%;
	will-change: transform;
	transition: transform .9s cubic-bezier(.22, .61, .36, 1);
}

/* Placeholder thumbnail, behind the artwork. Blurred hard and scaled slightly
   past the edges so the blur has no visible border. background-size matches the
   artwork's object-fit: fill, so the two distort identically and the sharp
   image lands exactly where the blurred one was. */
.jhr-hh__lqip {
	position: absolute;
	inset: 0;
	background-position: 50% 50%;
	background-repeat: no-repeat;
	background-size: cover;
	filter: blur(22px);
	transform: scale(1.08);
}

.jhr-hh.is-laid-out .jhr-hh__lqip {
	background-size: 100% 100%;
}

/* Aspect mode: the hero is exactly the artwork's shape. layout() sets that as
   an inline pixel height, but only once it runs — this holds the right height
   from first paint, so the page does not reflow under the visitor when the
   script catches up. */
.jhr-hh--h-aspect .jhr-hh__hero {
	height: auto;
	min-height: 0;
	aspect-ratio: var(--jhr-hh-art-ratio, 1920 / 980);
}

.jhr-hh__picture {
	/* No box of its own: the <img> inside is absolutely positioned against the
	   frame, exactly as it is when there is no <picture> wrapper. */
	display: contents;
}

/* Primed by the inline marker in the markup, before first paint, and cleared
   by the runtime the moment it builds the stack. Without it the slides paint
   as ordinary blocks one under another until the script catches up. */
.jhr-hh.is-scene-follower {
	display: none;
}

.jhr-hh__base,
.jhr-hh__paint {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

.jhr-hh__base {
	/* Before layout() runs, the frame is the whole hero and the artwork has to
	   crop itself to fit it — the same centred cover crop the script will
	   compute, so the handover is invisible. Afterwards the frame carries the
	   artwork's own aspect ratio and any fitting would be a second, wrong crop
	   on top of the first. */
	object-fit: cover;
}

.jhr-hh.is-laid-out .jhr-hh__base {
	object-fit: fill;
}

/* --------------------------------------------------------------------------
   Load gate
   --------------------------------------------------------------------------
   is-loading is set by the inline primer during parse — before first paint —
   and only while the artwork is still downloading. The artwork stays
   transparent over the blurred placeholder instead of painting in strips or
   popping on, then fades in once it has decoded. Only JavaScript ever adds the
   class, and it always releases it (load, error or timeout), so the artwork can
   never be left hidden.
   -------------------------------------------------------------------------- */
.jhr-hh__base {
	transition: opacity .7s cubic-bezier(.22, .61, .36, 1);
}

.jhr-hh.is-loading .jhr-hh__base {
	opacity: 0;
}

.jhr-hh__loader {
	--jhr-hh-loader-size: 38px;

	position: absolute;
	inset: 0;
	z-index: 9;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
	opacity: 0;
	visibility: hidden;
	transition: opacity .35s ease, visibility 0s linear .35s;
}

/* Fades in only after a short delay, so a fast or cached load never shows a
   spinner at all — it just appears for loads slow enough to need one. */
.jhr-hh.is-loading .jhr-hh__loader {
	visibility: visible;
	animation: jhr-hh-loader-in .4s ease .35s both;
}

.jhr-hh__spinner {
	width: var(--jhr-hh-loader-size);
	height: var(--jhr-hh-loader-size);
	border-radius: 50%;
	border: 2px solid rgba(255, 255, 255, .18);
	border-top-color: var(--jhr-hh-loader-color, var(--jhr-hh-indicator, #e5cb68));
	animation: jhr-hh-spin .9s linear infinite;
}

@keyframes jhr-hh-loader-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes jhr-hh-spin {
	to { transform: rotate(360deg); }
}

.jhr-hh__paint {
	overflow: visible;
}

.jhr-hh__reveal {
	opacity: 0;
	transition:
		opacity var(--jhr-hh-reveal-duration) var(--jhr-hh-reveal-easing),
		transform var(--jhr-hh-reveal-duration) var(--jhr-hh-reveal-easing),
		filter var(--jhr-hh-reveal-duration) var(--jhr-hh-reveal-easing);
	transform-box: fill-box;
	transform-origin: 50% 50%;
	pointer-events: none;
}

.jhr-hh__reveal.is-active {
	opacity: 1;
}

.jhr-hh--reveal-fade-scale .jhr-hh__reveal {
	transform: scale(var(--jhr-hh-reveal-scale));
}

.jhr-hh--reveal-fade-scale .jhr-hh__reveal.is-active {
	transform: scale(1);
}

.jhr-hh--reveal-rise .jhr-hh__reveal {
	transform: translateY(1.4%);
}

.jhr-hh--reveal-rise .jhr-hh__reveal.is-active {
	transform: translateY(0);
}

.jhr-hh--reveal-glow .jhr-hh__reveal.is-active {
	filter: drop-shadow(0 0 var(--jhr-hh-reveal-glow-size) var(--jhr-hh-reveal-glow));
}

/* Hit areas ---------------------------------------------------------------- */
.jhr-hh__hit {
	cursor: var(--jhr-hh-cursor);
	outline: none;
}

/* "fill" not "all": these paths live in a scaled 0..1 space where the default
   1-unit stroke is as wide as the whole artwork, and "all" would make that
   invisible band hit-testable. */
.jhr-hh__hit path {
	fill: none;
	stroke: none;
	stroke-width: 0;
	pointer-events: fill;
}

.jhr-hh--indicator-outline .jhr-hh__hit path {
	stroke: var(--jhr-hh-indicator);
	stroke-width: 1.2;
	stroke-opacity: .35;
	vector-effect: non-scaling-stroke;
	transition: stroke-opacity .3s ease;
}

.jhr-hh--indicator-outline .jhr-hh__hit:hover path,
.jhr-hh--indicator-outline .jhr-hh__hit:focus-visible path {
	stroke-opacity: .9;
}

.jhr-hh--debug .jhr-hh__hit path {
	fill: rgba(255, 0, 200, .22);
	stroke: #ff00c8;
	stroke-width: 1.5px;
	vector-effect: non-scaling-stroke;
}

.jhr-hh__hit:focus-visible path {
	stroke: var(--jhr-hh-indicator);
	stroke-width: 2px;
	vector-effect: non-scaling-stroke;
	stroke-opacity: 1;
}

/* Pulsing indicator dots --------------------------------------------------- */
.jhr-hh__pulse {
	position: absolute;
	width: var(--jhr-hh-indicator-size);
	height: var(--jhr-hh-indicator-size);
	margin: calc(var(--jhr-hh-indicator-size) / -2) 0 0 calc(var(--jhr-hh-indicator-size) / -2);
	border-radius: 50%;
	background: var(--jhr-hh-indicator);
	pointer-events: none;
	opacity: .85;
	animation: jhr-hh-pulse 2.4s ease-out infinite;
}

.jhr-hh__pulse::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	box-shadow: 0 0 0 0 var(--jhr-hh-indicator);
	animation: jhr-hh-ring 2.4s ease-out infinite;
}

.jhr-hh__pulse.is-hidden {
	opacity: 0;
	animation-play-state: paused;
}

@keyframes jhr-hh-pulse {
	0%, 100% { transform: scale(.85); opacity: .55; }
	50%      { transform: scale(1.15); opacity: .95; }
}

@keyframes jhr-hh-ring {
	0%   { box-shadow: 0 0 0 0 currentColor; opacity: .5; }
	70%  { box-shadow: 0 0 0 14px transparent; opacity: 0; }
	100% { box-shadow: 0 0 0 0 transparent; opacity: 0; }
}

/* Static text overlays and anchored captions -------------------------------- */
/* Mirror of the artwork frame, stacked above the scrim so overlay text and
   anchored captions are not dimmed by it. Sized and transformed in lockstep
   with the artwork frame, so it shares the same artwork coordinate space. */
.jhr-hh__frame--over {
	z-index: 6;
	pointer-events: none;
}

.jhr-hh__text,
.jhr-hh__anchored {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.jhr-hh__text-item {
	position: absolute;
	margin: 0;
	/* Overlays sit above the hit areas. Left clickable, a wide headline would
	   swallow hovers meant for the artwork underneath, so only real links in
	   the overlay take pointer events. */
	pointer-events: none;
}

.jhr-hh__text-item a {
	pointer-events: auto;
}

.jhr-hh__text-item.is-hidden {
	display: none;
}

/* Accent line ---------------------------------------------------------------
   A block row holding one inline-block bar. Being inline, the bar obeys the
   item's text-align, so it sits under left, centred or right-aligned text
   without an alignment control of its own. The row's line box is collapsed
   so only the bar and its margin take up space. */
.jhr-hh__accent {
	display: block;
	margin-top: var(--jhr-hh-accent-gap, 18px);
	line-height: 0;
	font-size: 0;
}

.jhr-hh__accent::before {
	content: "";
	display: inline-block;
	vertical-align: top;
	width: var(--jhr-hh-accent-width, 100px);
	max-width: 100%;
	height: var(--jhr-hh-accent-height, 3px);
	background: var(--jhr-hh-accent-color, #caa938);
}

/* Logo ---------------------------------------------------------------------- */
.jhr-hh__el--logo {
	line-height: 0;
}

.jhr-hh__logo {
	display: inline-block;
	width: 180px;
	max-width: 100%;
	height: auto;
	vertical-align: top;
}

/* Pinned logo — "Show on All Slides (Fixed)". A layer outside the artwork
   frame, so parallax never moves it; in a slideshow the runtime lifts it onto
   the shared container, above every slide, so transitions never move it
   either. The in-slide original is kept only as the style source. */
.jhr-hh--logo-pinned .jhr-hh__el--logo {
	display: none !important;
}

.jhr-hh__pinned {
	position: absolute;
	inset: 0;
	z-index: 8;
	overflow: hidden;
	pointer-events: none;
}

/* Above the slides, under the slideshow arrows and dots (12). */
.jhr-hh__pinned--scenes {
	z-index: 11;
}

/* A slide whose own pinned layer was not chosen as the slideshow's. Scoped to
   real slides, so a hero sharing the container without being part of the
   group keeps its own logo. */
.jhr-hh-scene .jhr-hh__hero > .jhr-hh__pinned {
	display: none;
}

.jhr-hh__pinned-item {
	position: absolute;
	width: max-content;
	height: max-content;
	line-height: 0;
}

.jhr-hh__pinned-item.is-hidden {
	display: none;
}

.jhr-hh__pinned .jhr-hh__logo {
	max-width: none;
}

.jhr-hh__logo-link {
	display: inline-block;
	pointer-events: auto;
}

/* Button --------------------------------------------------------------------
   Jannah Button house style as the baseline, so it looks right even before
   any control has written a value. The hover animation moves the icon alone. */
.jhr-hh__el--button {
	line-height: 1;
}

.jhr-hh .jhr-hh__btn {
	--jhr-hh-btn-gap: 10px;
	--jhr-hh-btn-icon-size: 14px;
	--jhr-hh-btn-icon-distance: 5px;
	--jhr-hh-btn-icon-duration: 300ms;
	--jhr-hh-btn-icon-easing: ease;

	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--jhr-hh-btn-gap);
	box-sizing: border-box;
	padding: 15px 30px;
	color: #caa938;
	background-color: #fff;
	border: 1px solid #caa938;
	border-radius: 4px;
	font-size: 15px;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	pointer-events: auto;
	transition: color .3s ease, background-color .3s ease, border-color .3s ease, box-shadow .3s ease;
}

.jhr-hh .jhr-hh__btn:hover,
.jhr-hh .jhr-hh__btn:focus-visible {
	color: #fff;
	background-color: #caa938;
	text-decoration: none;
}

.jhr-hh__btn:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
}

.jhr-hh__btn--icon-right {
	flex-direction: row-reverse;
}

.jhr-hh__btn-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	font-size: var(--jhr-hh-btn-icon-size);
	line-height: 0;
	color: var(--jhr-hh-btn-icon, currentColor);
	transition:
		transform var(--jhr-hh-btn-icon-duration) var(--jhr-hh-btn-icon-easing),
		color .3s ease;
}

.jhr-hh__btn-icon svg {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

.jhr-hh__btn-icon i {
	font-size: 1em;
	line-height: 1;
}

.jhr-hh__btn:hover .jhr-hh__btn-icon,
.jhr-hh__btn:focus-visible .jhr-hh__btn-icon {
	color: var(--jhr-hh-btn-icon-hover, currentColor);
}

.jhr-hh__btn--anim-slide-right:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-slide-right:focus-visible .jhr-hh__btn-icon { transform: translateX(var(--jhr-hh-btn-icon-distance)); }
.jhr-hh__btn--anim-slide-left:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-slide-left:focus-visible .jhr-hh__btn-icon  { transform: translateX(calc(var(--jhr-hh-btn-icon-distance) * -1)); }
.jhr-hh__btn--anim-slide-up:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-slide-up:focus-visible .jhr-hh__btn-icon    { transform: translateY(calc(var(--jhr-hh-btn-icon-distance) * -1)); }
.jhr-hh__btn--anim-slide-down:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-slide-down:focus-visible .jhr-hh__btn-icon  { transform: translateY(var(--jhr-hh-btn-icon-distance)); }
.jhr-hh__btn--anim-grow:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-grow:focus-visible .jhr-hh__btn-icon        { transform: scale(var(--jhr-hh-btn-icon-grow, 1.25)); }
.jhr-hh__btn--anim-shrink:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-shrink:focus-visible .jhr-hh__btn-icon      { transform: scale(var(--jhr-hh-btn-icon-shrink, .75)); }
.jhr-hh__btn--anim-rotate:hover .jhr-hh__btn-icon,
.jhr-hh__btn--anim-rotate:focus-visible .jhr-hh__btn-icon      { transform: rotate(var(--jhr-hh-btn-icon-rotate, 45deg)); }

/* --------------------------------------------------------------------------
   Content container
   --------------------------------------------------------------------------
   A centred column of a fixed maximum width, the way a theme container
   behaves. It is a SIBLING of the artwork frame, never a child: the frame is
   cover-cropped and carries the parallax transform, so a column parented to it
   would neither hold its width nor sit still.

   Inside it, nine positions — top / middle / bottom by left / center / right.
   Each is an absolutely placed column that shrinks to its content, so any mix
   of them can be used at once without one pushing another about. The runtime
   moves items between them as the breakpoint changes, which is why placement
   cannot be a media query.
   -------------------------------------------------------------------------- */
.jhr-hh__container {
	position: absolute;
	inset: 0;
	z-index: 7; /* over the scrim and atmosphere, under the dots */
	display: flex;
	justify-content: center;
	pointer-events: none;
}

.jhr-hh__box {
	--jhr-hh-box-cap: 45%;
	--jhr-hh-zone-max: 60%;
	--jhr-hh-text-gap: 14px;
	--jhr-hh-btn-offset: 28px;
	--jhr-hh-logo-gap: 24px;
	--jhr-hh-caption-gap: 24px;

	position: relative;
	display: flex;
	width: 100%;
	height: 100%;
	max-width: 1140px;
	box-sizing: border-box;
	padding: 120px 24px 72px;
}

/* The padded content area. A size container, so items can take a share of
   its width in cqw whichever position they sit in. */
.jhr-hh__zones {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
	container-type: inline-size;
}

.jhr-hh__zone {
	position: absolute;
	display: flex;
	flex-direction: column;
	width: fit-content;
	height: fit-content;
	max-width: var(--jhr-hh-zone-max);
	max-height: 100%;
}

.jhr-hh__zone:empty {
	display: none;
}

/* Columns: an edge inset, or centred between both edges with auto margins. */
.jhr-hh__zone[data-zone$="-left"]   { left: 0;  align-items: flex-start; text-align: left; }
.jhr-hh__zone[data-zone$="-right"]  { right: 0; align-items: flex-end;   text-align: right; }
.jhr-hh__zone[data-zone$="-center"] { left: 0; right: 0; margin-left: auto; margin-right: auto; align-items: center; text-align: center; max-width: 100%; }

/* Rows, the same way. */
.jhr-hh__zone[data-zone^="top-"]    { top: 0; }
.jhr-hh__zone[data-zone^="bottom-"] { bottom: 0; }
.jhr-hh__zone[data-zone^="middle-"] { top: 0; bottom: 0; margin-top: auto; margin-bottom: auto; }

/* In a position, items are laid out by the column, not by artwork
   coordinates. The runtime clears the inline left/top/transform, and these
   rules make sure a stale value cannot leave an item stranded. */
.jhr-hh__zone > .jhr-hh__text-item {
	position: relative;
	left: auto;
	top: auto;
	transform: none;
	max-width: 100%;
}

.jhr-hh__zone > .is-hidden {
	display: none !important;
}

/* Gaps between stacked items. Sibling combinators over :not(.is-hidden), so a
   hidden item never leaves a gap behind and the first visible item never gets
   one. The more specific rules after the generic one tune particular pairs. */
.jhr-hh__zone > :not(.is-hidden) ~ :not(.is-hidden) {
	margin-top: var(--jhr-hh-text-gap);
}

.jhr-hh__zone > :not(.is-hidden) ~ .jhr-hh__el--button:not(.is-hidden) {
	margin-top: var(--jhr-hh-btn-offset);
}

.jhr-hh__zone > :not(.is-hidden) ~ .jhr-hh__caption:not(.is-hidden) {
	margin-top: var(--jhr-hh-caption-gap);
}

.jhr-hh__zone > .jhr-hh__el--logo:not(.is-hidden) + :not(.is-hidden) {
	margin-top: var(--jhr-hh-logo-gap);
}

/* Per-device show/hide. Set on the root so it holds whichever container the
   element currently lives in. */
.jhr-hh--no-text .jhr-hh__text-item:not(.jhr-hh__el),
.jhr-hh--no-caption .jhr-hh__caption {
	display: none !important;
}

.jhr-hh__anchor-caption {
	position: absolute;
	font-size: 19px;
	line-height: 1.2;
	opacity: 0;
	transition: opacity var(--jhr-hh-reveal-duration) var(--jhr-hh-reveal-easing);
	white-space: nowrap;
	pointer-events: none;
}

.jhr-hh__anchor-caption.is-active {
	opacity: 1;
}

/* Scrim, atmosphere -------------------------------------------------------- */
.jhr-hh__shade {
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background:
		linear-gradient(90deg, rgba(2, 10, 18, .48), rgba(2, 10, 18, .04) 52%, rgba(2, 10, 18, .34)),
		linear-gradient(0deg, rgba(2, 8, 14, .62), transparent 48%, rgba(2, 8, 14, .06));
}

/* Edge scrims — a band fading inwards from the top and from the bottom, each
   independent of the other and of the full-bleed shade above.

   These belong to the widget rather than to the parent Container because a
   Container's background overlay paints BEHIND its children, so the hero
   artwork would cover it. Same z-index as the shade; DOM order puts them on
   top of it, and both stay under the frame mirror (6), the boxed container (7)
   and the UI (8), so overlay text and dots stay readable rather than being
   dimmed by their own scrim. */
.jhr-hh__scrim {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 3;
	pointer-events: none;
}

.jhr-hh__scrim--top {
	top: 0;
	height: 32%;
	background: linear-gradient(
		to bottom,
		var(--jhr-hh-scrim-top-color, rgba(2, 8, 14, .65)) 0%,
		var(--jhr-hh-scrim-top-color, rgba(2, 8, 14, .65)) var(--jhr-hh-scrim-top-hold, 0%),
		transparent 100%
	);
}

.jhr-hh__scrim--bottom {
	bottom: 0;
	height: 45%;
	background: linear-gradient(
		to top,
		var(--jhr-hh-scrim-bottom-color, rgba(2, 8, 14, .7)) 0%,
		var(--jhr-hh-scrim-bottom-color, rgba(2, 8, 14, .7)) var(--jhr-hh-scrim-bottom-hold, 0%),
		transparent 100%
	);
}

.jhr-hh__fx {
	position: absolute;
	inset: 0;
	pointer-events: none;
	overflow: hidden;
}

.jhr-hh__fx--under { z-index: 2; }
.jhr-hh__fx--over  { z-index: 4; }

.jhr-hh__canvas {
	position: absolute;
	inset: 0;
	z-index: 4;
	pointer-events: none;
	mix-blend-mode: screen;
}

.jhr-hh__fx-layer {
	position: absolute;
	border-radius: 50%;
	will-change: transform;
}

.jhr-hh__fx-layer--clouds {
	border-radius: 46% 54% 52% 48% / 58% 44% 56% 42%;
}

@keyframes jhr-hh-drift {
	0%   { transform: translate3d(-6%, 3%, 0) scale(.94); }
	100% { transform: translate3d(9%, -5%, 0) scale(1.12); }
}

@keyframes jhr-hh-float {
	0%, 100% { transform: translate3d(0, 0, 0) scale(.9); opacity: .4; }
	50%      { transform: translate3d(-5%, 4%, 0) scale(1.18); opacity: .85; }
}

/* UI layer ----------------------------------------------------------------- */
.jhr-hh__ui {
	position: absolute;
	inset: 0;
	z-index: 8;
	pointer-events: none;
}

.jhr-hh__dots {
	position: absolute;
	display: flex;
	gap: 10px;
	pointer-events: auto;
}

.jhr-hh--dots-right  .jhr-hh__dots { right: var(--jhr-hh-dots-offset); top: 50%; transform: translateY(-50%); flex-direction: column; }
.jhr-hh--dots-left   .jhr-hh__dots { left: var(--jhr-hh-dots-offset);  top: 50%; transform: translateY(-50%); flex-direction: column; }
.jhr-hh--dots-bottom .jhr-hh__dots { bottom: var(--jhr-hh-dots-offset); left: 50%; transform: translateX(-50%); flex-direction: row; }
.jhr-hh--dots-top    .jhr-hh__dots { top: var(--jhr-hh-dots-offset);    left: 50%; transform: translateX(-50%); flex-direction: row; }

.jhr-hh__dot {
	position: relative;
	width: var(--jhr-hh-dot-size);
	height: var(--jhr-hh-dot-size);
	padding: 0;
	border: 1px solid var(--jhr-hh-dot-border);
	background: var(--jhr-hh-dot-bg);
	border-radius: 50%;
	cursor: pointer;
	transition: all .35s ease;
	appearance: none;
}

.jhr-hh__dot::before {
	content: "";
	position: absolute;
	inset: -8px;
	border-radius: 50%;
}

.jhr-hh__dot.is-hidden { display: none; }

.jhr-hh__dot.is-active,
.jhr-hh__dot:hover {
	background: var(--jhr-hh-dot-active);
	border-color: var(--jhr-hh-dot-active);
	box-shadow: 0 0 12px var(--jhr-hh-dot-glow);
	transform: scale(var(--jhr-hh-dot-scale));
}

.jhr-hh__dot:focus-visible {
	outline: 2px solid var(--jhr-hh-dot-active);
	outline-offset: 4px;
}

/* Caption block -----------------------------------------------------------
   No fixed width: the block shrink-wraps its text so its edge sits flush on
   the offset. Setting a width here and a max-width on the child is what makes
   the two lines fall out of alignment.
   ------------------------------------------------------------------------- */
.jhr-hh__caption {
	pointer-events: none;
	width: auto;
}

/* Corner mode. Every corner rule is scoped to the UI layer, so when the
   caption is moved into the boxed container none of them apply and the
   container's own alignment is free to win. */
.jhr-hh__ui .jhr-hh__caption {
	position: absolute;
}

.jhr-hh--caption-bottom-right .jhr-hh__ui .jhr-hh__caption { right: var(--jhr-hh-caption-x); bottom: var(--jhr-hh-caption-y); text-align: right; }
.jhr-hh--caption-bottom-left  .jhr-hh__ui .jhr-hh__caption { left: var(--jhr-hh-caption-x);  bottom: var(--jhr-hh-caption-y); text-align: left; }
.jhr-hh--caption-top-right    .jhr-hh__ui .jhr-hh__caption { right: var(--jhr-hh-caption-x); top: var(--jhr-hh-caption-y);    text-align: right; }
.jhr-hh--caption-top-left     .jhr-hh__ui .jhr-hh__caption { left: var(--jhr-hh-caption-x);  top: var(--jhr-hh-caption-y);    text-align: left; }

/* Boxed mode: the grid cell places it, so it is in normal flow. */
.jhr-hh__zone > .jhr-hh__caption {
	position: relative;
	max-width: 100%;
}

.jhr-hh__caption.is-hidden {
	display: none;
}

.jhr-hh__eyebrow {
	font-size: 9px;
	letter-spacing: 2.4px;
	text-transform: uppercase;
	line-height: 1;
	white-space: nowrap;
}

.jhr-hh__current {
	font-size: 19px;
	line-height: 1.2;
	margin-top: 7px;
	white-space: nowrap;
	transition: opacity .25s ease;
}

.jhr-hh--autofit .jhr-hh__current {
	white-space: nowrap;
}

/* Paused scenes must not swallow the pointer ---------------------------------
   `pointer-events` is inherited, but a descendant that names its own value
   overrides an ancestor's `none`. .jhr-hh__hit sets `fill`, .jhr-hh__dots and
   overlay links set `auto`, so `pointer-events: none` on the slide wrapper does
   NOT switch them off. A hidden slide therefore went on hit-testing, and its
   hotspots swallowed hovers meant for the slide underneath — anywhere the two
   shapes overlapped, neither responded.

   The rules below name each of those elements again, at a specificity that
   beats them, so the cut is explicit instead of relying on inheritance. Note
   that the hit area is a GROUP and the element carrying `pointer-events: fill`
   is the path inside it, so the path has to be named too — naming only the
   group loses to the same override this whole block exists to defeat.

   They are keyed on the class the runtime sets when a scene is paused, which
   only ever happens to a slide that is not the visible one — never in the
   editor, where every slide has to stay live for drawing. */
.jhr-hh.is-paused .jhr-hh__hero,
.jhr-hh.is-paused .jhr-hh__hit,
.jhr-hh.is-paused .jhr-hh__hit path,
.jhr-hh.is-paused .jhr-hh__dots,
.jhr-hh.is-paused .jhr-hh__dot,
.jhr-hh.is-paused .jhr-hh__text-item a,
.jhr-hh.is-paused .jhr-hh__btn {
	pointer-events: none;
}

/* No-JS / crawler fallback -------------------------------------------------- */
.jhr-hh__fallback {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Reduced motion ------------------------------------------------------------ */
.jhr-hh.is-reduced .jhr-hh__frame { transition: none; transform: none !important; }
.jhr-hh.is-reduced .jhr-hh__reveal { transition-duration: 120ms; transform: none !important; }
.jhr-hh.is-reduced .jhr-hh__fx-layer,
.jhr-hh.is-reduced .jhr-hh__pulse { animation: none; }
.jhr-hh.is-reduced .jhr-hh__canvas { display: none; }

@media (prefers-reduced-motion: reduce) {
	.jhr-hh__base { transition-duration: 1ms; }
	.jhr-hh__spinner { animation-duration: 2.4s; }
}

/* ==========================================================================
   Scene groups — several widgets in one container acting as one slideshow
   ========================================================================== */

/* The stack. Every slide occupies the same single cell, so the container is as
   tall as the tallest scene and nothing reflows during a transition.

   The track is pinned to the container's full width, and the container's own
   justify / align settings are overridden. Those settings used to reach the
   grid: any justify-content other than the default sized the column to its
   content instead — and a slide's content is all absolutely positioned, so
   the column, and every slide in it, came out zero pixels wide and the whole
   slideshow vanished. Doubled class for specificity over Elementor's
   per-element container rules. */
.jhr-hh-scenes.jhr-hh-scenes {
	position: relative;
	display: grid !important;
	grid-template-columns: minmax(0, 1fr) !important;
	grid-template-rows: auto !important;
	grid-auto-flow: row !important;
	justify-content: stretch !important;
	align-content: start !important;
	justify-items: stretch !important;
	align-items: stretch !important;
	--jhr-hh-scene-duration: 700ms;
}

.jhr-hh-scenes > .jhr-hh-scene {
	grid-column: 1 !important; /* the row is set inline: one shared row for every slide */
	min-width: 0;
	width: auto !important;
	max-width: none !important;
	margin: 0 !important;
	align-self: stretch !important;
	justify-self: stretch !important;
}

.jhr-hh-scene {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition:
		opacity var(--jhr-hh-scene-duration) cubic-bezier(.22, .61, .36, 1),
		transform var(--jhr-hh-scene-duration) cubic-bezier(.22, .61, .36, 1),
		visibility 0s linear var(--jhr-hh-scene-duration);
}

.jhr-hh-scene.is-active {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition-delay: 0s;
}

/* The frame the stack is built in. The wrappers were opaque until this very
   moment, so without this every inactive slide would fade OUT on load —
   the whole slideshow flashing up before settling on slide 1. */
.jhr-hh-scenes--init > .jhr-hh-scene {
	transition: none !important;
}

.jhr-hh-scenes--slide .jhr-hh-scene { transform: translateX(6%); }
.jhr-hh-scenes--slide .jhr-hh-scene.is-active { transform: none; }

/* Editor: nothing is stacked and the container keeps its own layout, so each
   slide can be selected and edited. Each hero carries a badge saying where it
   sits in the group — a real element, never a ::before on the slide, which
   for a container slide is Elementor's own background overlay. */
.jhr-hh__scene-badge {
	position: absolute;
	right: 0;
	top: 0;
	z-index: 40;
	max-width: 70%;
	padding: 3px 9px;
	background: rgba(10, 18, 26, .9);
	color: #9fb4c4;
	font: 10px/1.6 -apple-system, "Segoe UI", Roboto, sans-serif;
	letter-spacing: .6px;
	text-transform: uppercase;
	border-bottom-left-radius: 6px;
	pointer-events: none;
}

/* The owning slide, when a later slide is carrying settings that will be
   ignored. Worth shouting about: the symptom is a control that appears to do
   nothing at all. */
.jhr-hh__scene-badge.is-clash {
	background: rgba(120, 60, 10, .95);
	color: #ffd9a3;
}

/* Arrows and dots ---------------------------------------------------------- */
.jhr-hh-scenes {
	--jhr-hh-sdot-size: 9px;
	--jhr-hh-sdot-hit: 10px;
	--jhr-hh-sdot-gap: 10px;
	--jhr-hh-sdot-offset: 24px;
	--jhr-hh-sdot-border: rgba(255, 255, 255, .55);
	--jhr-hh-sdot-bg: transparent;
	--jhr-hh-sdot-active: #e5cb68;
	--jhr-hh-sdot-glow: rgba(225, 198, 90, .7);
	--jhr-hh-sdot-scale: 1.5;
	--jhr-hh-sarrow-size: 42px;
	--jhr-hh-sarrow-color: #fff;
	--jhr-hh-sarrow-bg: rgba(6, 14, 22, .35);
	--jhr-hh-sarrow-border: rgba(255, 255, 255, .35);
}

.jhr-hh-scenes__arrow {
	position: absolute;
	top: 50%;
	z-index: 12;
	width: var(--jhr-hh-sarrow-size);
	height: var(--jhr-hh-sarrow-size);
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 1px solid var(--jhr-hh-sarrow-border);
	border-radius: 50%;
	background: var(--jhr-hh-sarrow-bg);
	color: var(--jhr-hh-sarrow-color);
	font-size: calc(var(--jhr-hh-sarrow-size) * .52);
	line-height: 1;
	cursor: pointer;
	pointer-events: auto;
	backdrop-filter: blur(4px);
	transition: background .25s ease, border-color .25s ease;
}

.jhr-hh-scenes__arrow:hover {
	border-color: var(--jhr-hh-sdot-active);
	color: var(--jhr-hh-sdot-active);
}

.jhr-hh-scenes__arrow:focus-visible {
	outline: 2px solid var(--jhr-hh-sdot-active);
	outline-offset: 3px;
}

.jhr-hh-scenes__arrow--prev { left: clamp(10px, 2vw, 26px); }
.jhr-hh-scenes__arrow--next { right: clamp(10px, 2vw, 26px); }

.jhr-hh-scenes__nav {
	position: absolute;
	z-index: 12;
	display: flex;
	gap: var(--jhr-hh-sdot-gap);
	pointer-events: auto;
}

.jhr-hh-scenes--dots-bottom .jhr-hh-scenes__nav {
	left: 50%;
	bottom: var(--jhr-hh-sdot-offset);
	transform: translateX(-50%);
	flex-direction: row;
}

.jhr-hh-scenes--dots-top .jhr-hh-scenes__nav {
	left: 50%;
	top: var(--jhr-hh-sdot-offset);
	transform: translateX(-50%);
	flex-direction: row;
}

.jhr-hh-scenes--dots-left .jhr-hh-scenes__nav {
	left: var(--jhr-hh-sdot-offset);
	top: 50%;
	transform: translateY(-50%);
	flex-direction: column;
}

.jhr-hh-scenes--dots-right .jhr-hh-scenes__nav {
	right: var(--jhr-hh-sdot-offset);
	top: 50%;
	transform: translateY(-50%);
	flex-direction: column;
}

.jhr-hh-scenes__dot {
	position: relative;
	width: var(--jhr-hh-sdot-size);
	height: var(--jhr-hh-sdot-size);
	padding: 0;
	border: 1px solid var(--jhr-hh-sdot-border);
	background: var(--jhr-hh-sdot-bg);
	border-radius: 50%;
	cursor: pointer;
	appearance: none;
	pointer-events: auto;
	transition: all .35s ease;
}

/* A 9px circle is a poor target, especially on touch. This extends the
   clickable area well past the visible dot without moving anything. */
.jhr-hh-scenes__dot::before {
	content: "";
	position: absolute;
	inset: calc(var(--jhr-hh-sdot-hit) * -1);
	border-radius: 50%;
}

.jhr-hh-scenes__dot.is-active,
.jhr-hh-scenes__dot:hover {
	background: var(--jhr-hh-sdot-active);
	border-color: var(--jhr-hh-sdot-active);
	box-shadow: 0 0 12px var(--jhr-hh-sdot-glow);
	transform: scale(var(--jhr-hh-sdot-scale));
}

.jhr-hh-scenes__dot:focus-visible {
	outline: 2px solid var(--jhr-hh-sdot-active);
	outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
	.jhr-hh-scene { transition-duration: 1ms; }
	.jhr-hh-scenes--slide .jhr-hh-scene { transform: none; }
}
