/*
 * Home page hype-video variant
 * Loaded only on page-home-new-variant.php (see functions.php).
 *
 * Everything in this file is scoped to .wrap-effect-video so it cannot
 * leak into the original .wrap-effect-2 home slider.
 *
 * State machine (data-mode on the .wrap-effect-video element):
 *
 *   data-mode="hero"   -> initial / load state.
 *      - Video panel is the centered, expanded "open" slide.
 *      - The other 4 panels are dim and DO NOT expand on hover. Their only
 *        hover affordance is the green hype-title color sliding up from
 *        the bottom (a "this is openable" tease).
 *      - Click on any non-video panel -> JS flips us to data-mode="normal".
 *
 *   data-mode="normal" -> after the user has clicked a side panel.
 *      - Pure hover-based navigation returns: hovering any non-video panel
 *        expands it, releasing the cursor collapses it again -- exactly
 *        like the original .wrap-effect-2 slider.
 *      - The video panel collapses to a permanent SLIVER on the side.
 *      - The video panel is the ONE thing that requires a click to open
 *        (it doesn't expand on hover); clicking it returns us to hero.
 *
 * Why the previous version expanded panels on hover in hero mode:
 *   clubhaus.css line 242 has ".container-general .gallery-wrap .item:hover
 *   { flex: 7 }" applied unconditionally. That selector also matches our
 *   .wrap-effect-video .item, so we have to explicitly override it for
 *   hero mode. Done below by setting flex:1 on :hover for non-active
 *   side panels in hero mode (with higher specificity than clubhaus).
 *
 * Bug-fix references:
 *   - .hype-video-title uses top:auto + bottom:0 so the inherited
 *     .item:hover h3 rule (top: calc(45% - 85px), width: 100%) from
 *     clubhaus.css cannot stretch the green band across the bottom half.
 */


/* =====================================================================
   Layout shell
   ===================================================================== */

.container-general .gallery-wrap.wrap-effect-video {
	display: flex;
	flex-direction: row;
	width: 100%;
	height: 70vh;
	min-height: 720px;
	gap: 0;
	/* position:relative anchors the absolutely-positioned top bar that
	   the video panel becomes in normal mode. */
	position: relative;
	transition: padding-top 0.5s ease;
}

/* Normal mode reserves a band at the top of the gallery for the video
   "PLAY HYPE VIDEO" bar. The bar is absolutely positioned (see below)
   so the four side panels never push it around as they expand on
   hover -- the bar is always exactly the same on-screen rectangle, so
   it's an easy click target. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] {
	padding-top: 56px;
}

.gallery-wrap.wrap-effect-video .item {
	position: relative;
	flex: 1;
	height: 100%;
	background-position: center;
	background-size: cover;
	background-repeat: no-repeat;
	transition: flex-grow 0.8s ease, flex-basis 0.8s ease, transform 0.8s ease;
	cursor: pointer;
	overflow: hidden;
}

/* Invisible click target that fills each panel. Below .item-content so
   inner links remain clickable when the panel is expanded. */
.gallery-wrap.wrap-effect-video .item-toggle {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	background: transparent;
	border: 0;
	padding: 0;
	margin: 0;
	cursor: pointer;
	z-index: 6;
	appearance: none;
}

.gallery-wrap.wrap-effect-video .item-toggle:focus-visible {
	outline: 3px solid #f78f1e;
	outline-offset: -6px;
}

/* CRITICAL: when the video panel is the open hero panel, the toggle
   MUST get out of the way. It sits at z-index:6, directly on top of
   .video-stage (z-index:5) and the <video controls> inside it. Without
   pointer-events:none here the toggle absorbed every click on the
   native video controls (play/pause/mute/seek), so clicking the video
   appeared to do nothing. Restricting this rule to the *video* item
   keeps the side panels' toggles fully clickable -- they need to stay
   active so the user can click an open side panel to swap focus. */
.gallery-wrap.wrap-effect-video .item-video.is-active .item-toggle {
	pointer-events: none;
}

/* Same idea, different state: once we're in normal mode, side-panel
   expansion is handled either by :hover (desktop) or by the wrap
   click-handler bubbling from .item itself (touch). The .item-toggle
   button is no longer needed as a click target on these panels -- it
   only sits on top of .item-content stealing clicks meant for the
   navigation links inside. Disabling pointer events here lets clicks
   fall through to the <a> links underneath while leaving every other
   path intact:

     - Touch tap on an unexpanded panel still bubbles to .item -> wrap
       click handler -> handlePanelClick -> setActiveOnly. Panel
       expands the same as before.
     - Hover-driven expansion on desktop is unaffected (CSS :hover
       is detected on the .item parent regardless of children's
       pointer-events).
     - Keyboard activation still works -- pointer-events: none doesn't
       block focus or the wrap-level Enter/Space keydown handler.

   Scoped carefully:
     - data-mode="normal" only      (hero mode still needs the toggle
                                      so clicking a side panel switches
                                      modes and pins .is-active)
     - .item:not(.item-video) only  (the video panel's top-bar toggle
                                      stays active so the user can
                                      click it to return to hero mode) */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .item:not(.item-video) .item-toggle {
	pointer-events: none;
}

.gallery-wrap.wrap-effect-video .item h3 {
	z-index: 8;
}


/* =====================================================================
   Green slide-up overlay
   The ::before exists in BOTH modes so that, when the user clicks a
   side panel and we flip data-mode -> "normal", the green pseudo
   continues to exist and animates SMOOTHLY back down from scaleY(1)
   to scaleY(0) (instead of disappearing instantly). The :hover that
   *raises* it is scoped to hero mode only.
   ===================================================================== */

.gallery-wrap.wrap-effect-video .item:not(.item-video)::before {
	content: "";
	position: absolute;
	inset: 0;
	background: #25675b;
	transform: scaleY(0);
	transform-origin: bottom center;
	transition: transform 0.65s cubic-bezier(0.22, 0.61, 0.36, 1);
	z-index: 8;
	pointer-events: none;
	will-change: transform;
}


/* =====================================================================
   data-mode="hero"  --  initial state
   ===================================================================== */

.gallery-wrap.wrap-effect-video[data-mode="hero"] .item.is-active {
	flex: 7;
	transform: translate3d(0, 0, 100px);
}

/* Persistent dark overlay on every NON-active item.
   IMPORTANT: animation:none defeats the global clubhaus.css rule
   ".gallery-wrap .item:hover~.item:after { animation: grow-up .5s }"
   which would otherwise re-run the height: 0% -> 100% wipe every
   single time the cursor entered the gallery. In hero mode we want
   the overlay to be visually static -- the green slide-up ::before
   is the only hover affordance. The grow-up animation IS still
   active in normal mode (where my hero-mode rule no longer matches)
   so the original wrap-effect behavior continues to work there. */
.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.is-active)::after {
	content: "";
	position: absolute;
	inset: 0;
	background: #000000b0;
	z-index: 7;
	pointer-events: none;
	transition: background-color 0.3s ease;
	animation: none !important;
}

/* Active item (the video) must NOT carry the dark overlay or its odd/even
   teal/orange tint. */
.gallery-wrap.wrap-effect-video[data-mode="hero"] .item.is-active::after {
	background: transparent !important;
	animation: none !important;
}

/* CRITICAL: defeat clubhaus.css's ".container-general .gallery-wrap
   .item:hover { flex: 7 }" for hero-mode side panels. In hero mode the
   ONLY visual response to hover should be the green slide-up. */
.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.is-active),
.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.is-active):hover {
	flex: 1;
}

@media (hover: hover) {
	/* The green wipe -- raise it on hover in hero mode only. */
	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.item-video):not(.is-active):hover::before {
		transform: scaleY(1);
	}

	/* Keep the rotated h3 looking like its default rotated white label
	   while the green climbs. clubhaus.css's .item:hover h3 would
	   otherwise rip it into a horizontal green band -- we don't want
	   that mid-wipe. Higher specificity wins without !important. */
	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.item-video):not(.is-active):hover h3 {
		transform: translateY(-50%) translateX(-50%) rotate(-90deg);
		background: transparent;
		color: #fff;
		padding: 0;
		width: auto;
		top: 50%;
		left: 50%;
		text-shadow: 1px 3px 12px rgba(0, 0, 0, 0.55);
	}

	/* clubhaus.css reveals .item-content on :hover. In hero mode we don't
	   want that -- the panel hasn't actually expanded, so showing its
	   content would just produce a cramped mess. */
	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.is-active):hover .item-content,
	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.is-active):hover .item-content > * {
		opacity: 0;
	}
}


/* =====================================================================
   data-mode="normal"  --  after first click on a side panel
   - Side panels behave EXACTLY like the original wrap-effect-2: hover
	 expands, releasing collapses. clubhaus.css's own
	 ".container-general .gallery-wrap .item:hover { flex: 7 }" does
	 the work -- we just don't block it the way hero mode does.
   - The video panel is removed from the flex row and re-pinned as an
	 absolutely-positioned TOP BAR. This means:
	   (a) it doesn't move when side panels expand on hover (was hard
		   to click as a sliver),
	   (b) the four remaining side panels reflow horizontally without
		   the video squeezed between them.
   - .was-clicked is a transient "pin" added by JS to whichever panel
	 was just clicked from hero mode, so the cursor's screen position
	 lands back on that same panel after the layout reflow. The pin is
	 released as soon as the user navigates somewhere else.
   ===================================================================== */

/* Video panel becomes the absolute top bar. Removed from flex flow.
   IMPORTANT: no height transition. If we transitioned height the bar
   would sit at 100% width while slowly shrinking from full gallery
   height down to 56px, painting over the side panels for the duration
   of the animation. Snapping to 56px instantly is the only sane option
   when the position flips from relative -> absolute. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .item-video {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	width: 100%;
	height: 56px;
	flex: none;
	flex-basis: auto;
	min-width: 0;
	max-width: none;
	min-height: 0;
	cursor: pointer;
	z-index: 20;
	border-bottom: 2px solid #f78f1e;
	transition: filter 0.4s ease;
}

/* No odd/even tint on the bar. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .item-video::after {
	background: transparent !important;
	animation: none !important;
}

/* Subtle brightness lift on hover, so the bar feels interactive. */
@media (hover: hover) {
	.gallery-wrap.wrap-effect-video[data-mode="normal"] .item-video:hover {
		filter: brightness(1.15);
	}

	/* Dim the bar slightly when the user is interacting with another
	   panel below, so it visually settles into the background. Uses
	   :has() (Safari 15.4+, Chrome 105+, Firefox 121+ -- > 92% global). */
	.gallery-wrap.wrap-effect-video[data-mode="normal"]:has(.item:not(.item-video):hover) .item-video {
		filter: brightness(0.78);
	}
}

/* "PLAY HYPE VIDEO" label is always positioned (so we can cross-fade it
   via opacity rather than a display toggle, which can't transition).
   It's hidden by default and faded in when data-mode=normal, with a
   small delay so the side-panel reflow visually settles first. */
.gallery-wrap.wrap-effect-video .hype-video-sliver-label {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	position: absolute;
	inset: 0;
	transform: none;
	color: #fff;
	font-family: var(--title);
	font-weight: bold;
	letter-spacing: 4px;
	font-size: 14px;
	text-transform: uppercase;
	text-shadow: 1px 3px 12px rgba(0, 0, 0, 0.7);
	pointer-events: none;
	z-index: 12;
	opacity: 0;
	transition: opacity 0.2s ease;
}

.gallery-wrap.wrap-effect-video[data-mode="normal"] .hype-video-sliver-label {
	opacity: 1;
	transition: opacity 0.3s ease 0.15s;
}

.gallery-wrap.wrap-effect-video .hype-video-sliver-label::before {
	content: "";
	display: inline-block;
	width: 0;
	height: 0;
	border-left: 12px solid #fff;
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
}

/* Hype-title is the in-video green band -- no room for it in bar mode. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .item-video .hype-video-title {
	opacity: 0;
}

/* Snap the player content out of view in normal mode (instead of letting
   it fade slowly while distorted by the height collapse). It already
   fades smoothly back in when entering hero mode via the default
   .video-stage transition rule. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .video-stage {
	opacity: 0;
	transition: none;
	pointer-events: none;
}

/* Mute toggle is hidden in bar mode (the video isn't even playing). */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .hype-video-controls {
	display: none;
}

/* === Sticky pin for the just-clicked panel === */

/* When the user clicks a side panel from hero mode, the layout reflows
   from 5 panels (one wide video + 4 thin side panels) to 4 panels of
   equal width. The cursor's screen position would otherwise end up
   over a NEIGHBORING panel, immediately stealing :hover from it -- the
   user sees the wrong panel open up.

   .was-clicked solves this in three ways:
     1. flex: 9 (wider than the natural :hover expansion of flex: 7)
        so even cursor positions at the very edges of the original
        small panel land safely inside the new expanded panel after
        the layout reflow.
     2. transition-property: transform overrides the default flex
        transition. The expansion happens INSTANTLY in the same paint
        as the mode switch -- no "intermediate" frame where the panel
        is at flex: 1 and cursor is over a neighbor.
     3. The :has() rule below suppresses :hover-driven expansion on
        every other panel while .was-clicked is active, so a hovered
        neighbor cannot double-expand and steal width. */
.gallery-wrap.wrap-effect-video[data-mode="normal"] .item.was-clicked {
	flex: 9;
	transition-property: transform;
	transition-duration: 0.8s;
	transition-timing-function: ease;
}

.gallery-wrap.wrap-effect-video[data-mode="normal"] .item.was-clicked::after {
	background: transparent !important;
}

/* While a panel is pinned, no other side panel may :hover-expand. The
   pin owns the layout. Once JS releases .was-clicked, hover behavior
   returns to the original wrap-effect-2 model immediately. */
@media (hover: hover) {
	.gallery-wrap.wrap-effect-video[data-mode="normal"]:has(.was-clicked) .item:not(.was-clicked):not(.item-video):hover {
		flex: 1;
	}
}


/* =====================================================================
   Hype video panel (player / backdrop / controls)
   ===================================================================== */

/* Solid black so the panel reads as "video about to play" from the
   first paint, matching the <video> element's own #000 background.
   This is what removes the old "panel shows golf-course poster, then
   pops to centered video" jarring transition. */
.gallery-wrap.wrap-effect-video .item-video {
	background-color: #000;
	overflow: hidden;
}

.gallery-wrap.wrap-effect-video .video-backdrop {
	position: absolute;
	inset: 0;
	background-color: #000;
	z-index: 1;
}

.gallery-wrap.wrap-effect-video .video-stage {
	position: absolute;
	inset: 0;
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 5;
	transition: opacity 0.4s ease;
}

.gallery-wrap.wrap-effect-video .item-video:not(.is-active) .video-stage {
	opacity: 0;
	pointer-events: none;
}

/* Locked to a stable 16:9 box from the first paint -- WITHOUT this,
   the <video> element renders at the browser default 300x150 until
   metadata loads, then snaps to its real intrinsic size, which is
   exactly the jarring transition we're trying to remove. The source
   MP4 is 1920x1080 (16:9), so this aspect-ratio matches the video
   pixel-perfect with no letterboxing. width is the binding dimension;
   max-height kicks in only on unusually short containers. */
.gallery-wrap.wrap-effect-video .hype-video {
	width: 92%;
	height: auto;
	max-height: 78%;
	aspect-ratio: 16 / 9;
	object-fit: contain;
	border-radius: 6px;
	box-shadow: 0 18px 60px rgba(0, 0, 0, 0.55);
	background-color: #000;
}

/* Bug fix: top:auto + bottom:0 keeps the green band a thin strip rather
   than letting clubhaus.css's .item:hover h3 stretch it across the
   bottom half. */
.gallery-wrap.wrap-effect-video .item-video .hype-video-title {
	position: absolute;
	left: 0;
	right: 0;
	top: auto;
	bottom: 0;
	margin: 0;
	padding: 14px 10px;
	background: #25675b;
	color: #fff;
	text-align: center;
	font-family: var(--title);
	font-weight: bold;
	letter-spacing: 6px;
	font-size: 28px;
	text-shadow: 1px 3px 12px rgba(0, 0, 0, 0.6);
	z-index: 12;
	transform: none;
	white-space: nowrap;
	transition: opacity 0.4s ease;
	height: auto;
	width: auto;
}

.gallery-wrap.wrap-effect-video .item-video:not(.is-active) .hype-video-title {
	opacity: 0;
}


/* ----- Play overlay -----
   Now serves THREE roles in priority order:
     1. Loading-state placeholder while the video buffers (visible by
        default, sized + centered to sit ON TOP of the <video>'s
        stable 16:9 box, so the user sees "video coming, click to
        play if needed").
     2. Autoplay-blocked CTA (button stays visible because the
        .is-playing class JS adds on the 'playing' event never
        arrives -- exactly the right behavior, no extra logic needed).
     3. Pause-state cue (when the user clicks the video to pause,
        the 'pause' event removes .is-playing and the button fades
        back in, signalling "click to resume").
   Fade in/out is opacity-based so the box stays in flow and we don't
   get a layout reflow when it shows / hides. */
.gallery-wrap.wrap-effect-video .hype-video-play {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	padding: 22px 28px;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	border: 2px solid #fff;
	border-radius: 999px;
	cursor: pointer;
	font-family: var(--title);
	font-weight: bold;
	letter-spacing: 2px;
	font-size: 14px;
	z-index: 15;
	backdrop-filter: blur(4px);
	opacity: 1;
	pointer-events: auto;
	transition: opacity 0.4s ease, background-color 0.2s ease,
				border-color 0.2s ease;
}

/* JS adds .is-playing to .video-stage on the <video>'s 'playing'
   event and removes it on 'pause' / 'ended'. */
.gallery-wrap.wrap-effect-video .video-stage.is-playing .hype-video-play {
	opacity: 0;
	pointer-events: none;
}

/* Hide the button entirely when the video panel isn't the active
   hero (e.g. in normal mode it's the top bar) so it doesn't peek
   through the 0-opacity stage. */
.gallery-wrap.wrap-effect-video .item-video:not(.is-active) .hype-video-play {
	display: none;
}

.gallery-wrap.wrap-effect-video .hype-video-play-icon {
	width: 0;
	height: 0;
	border-left: 22px solid #fff;
	border-top: 14px solid transparent;
	border-bottom: 14px solid transparent;
	margin-left: 4px;
}

.gallery-wrap.wrap-effect-video .hype-video-play:hover {
	background: rgba(247, 143, 30, 0.85);
	border-color: #f78f1e;
}


/* ----- Mute / unmute toggle -----
   Sized + positioned to be a "primary affordance" while muted (which
   is the default state on every load). Once the user has unmuted the
   button quietly recedes via .hype-video-mute:not(.is-muted) below. */
.gallery-wrap.wrap-effect-video .hype-video-controls {
	position: absolute;
	right: 24px;
	bottom: 84px;
	z-index: 14;
	display: flex;
	gap: 8px;
}

.gallery-wrap.wrap-effect-video .hype-video-mute {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	background: rgba(0, 0, 0, 0.62);
	color: #fff;
	border: 1.5px solid rgba(255, 255, 255, 0.85);
	padding: 11px 20px;
	border-radius: 999px;
	font-size: 13px;
	letter-spacing: 1.5px;
	cursor: pointer;
	font-family: var(--title);
	font-weight: bold;
	text-transform: uppercase;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
	transition: background-color 0.2s ease, border-color 0.2s ease,
				transform 0.2s ease, box-shadow 0.2s ease;
}

.gallery-wrap.wrap-effect-video .hype-video-mute:hover {
	background: rgba(247, 143, 30, 0.92);
	border-color: #f78f1e;
	transform: scale(1.04);
}

.gallery-wrap.wrap-effect-video .hype-video-mute:focus-visible {
	outline: 3px solid #f78f1e;
	outline-offset: 3px;
}

/* CSS-drawn speaker icon (no emoji dependency, prints reliably across
   OSes). Trapezoidal "horn" via clip-path; sound waves are a thick
   right border arc when unmuted; a diagonal slash overlay marks the
   muted state. */
.gallery-wrap.wrap-effect-video .hype-video-mute-icon {
	position: relative;
	display: inline-block;
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}

.gallery-wrap.wrap-effect-video .hype-video-mute-icon::before {
	/* speaker body */
	content: "";
	position: absolute;
	left: 0;
	top: 4px;
	width: 12px;
	height: 10px;
	background: currentColor;
	clip-path: polygon(0 30%, 35% 30%, 100% 0, 100% 100%, 35% 70%, 0 70%);
}

.gallery-wrap.wrap-effect-video .hype-video-mute-icon::after {
	/* diagonal "muted" slash; hidden when un-muted via the rule below */
	content: "";
	position: absolute;
	left: -1px;
	top: 8px;
	width: 22px;
	height: 2px;
	background: currentColor;
	transform: rotate(-30deg);
	transform-origin: left center;
}

.gallery-wrap.wrap-effect-video .hype-video-mute:not(.is-muted) .hype-video-mute-icon::after {
	display: none;
}

/* Quiet pulse to draw the eye to the unmute affordance while muted.
   Stops the moment the user unmutes, and respects reduced-motion via
   the existing global @media block at the bottom of this file. */
@keyframes hype-mute-pulse {
	0%, 100% { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45),
							0 0 0 0 rgba(247, 143, 30, 0.55); }
	50%      { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45),
							0 0 0 10px rgba(247, 143, 30, 0); }
}

.gallery-wrap.wrap-effect-video .hype-video-mute.is-muted {
	animation: hype-mute-pulse 2.4s ease-out infinite;
}

.gallery-wrap.wrap-effect-video .hype-video-mute:not(.is-muted) {
	background: rgba(0, 0, 0, 0.4);
	border-color: rgba(255, 255, 255, 0.5);
}

/* Show the right label for the current state. Action wording is the
   default ("TAP FOR SOUND" while muted, "SOUND ON" once unmuted). */
.gallery-wrap.wrap-effect-video .hype-video-mute .hype-video-mute-off {
	display: none;
}

.gallery-wrap.wrap-effect-video .hype-video-mute:not(.is-muted) .hype-video-mute-on {
	display: none;
}

.gallery-wrap.wrap-effect-video .hype-video-mute:not(.is-muted) .hype-video-mute-off {
	display: inline;
}


/* =====================================================================
   Mobile (<= 799px) — vertical column. Touch has no hover, so .is-active
   is what drives expansion on mobile in normal mode (whereas on desktop
   normal mode we let pure hover do the work).
   ===================================================================== */

@media only screen and (max-width: 799px) {

	.container-general .gallery-wrap.wrap-effect-video {
		flex-direction: column;
		background: var(--green-4);
		gap: 10px;
		height: auto;
		min-height: 0;
	}

	.gallery-wrap.wrap-effect-video .item {
		flex: 0 0 auto;
		min-height: 110px;
		transition: min-height 0.5s ease, flex-basis 0.5s ease,
					max-height 0.5s ease;
	}

	/* Float the video panel to the top of the mobile stack.
	   The DOM source order (Homeowners, Contractors, Video, Golf,
	   Horticulture) puts the video in position 3 on a vertical column,
	   which on phones reads as "wedged in the middle of the category
	   list" -- the disjointed feel the client called out. Setting
	   order:-1 here moves the video above all four category panels
	   on mobile while leaving the desktop 5-column layout completely
	   untouched (desktop never enters this media query).

	   Safe in normal mode too: the video panel is position:absolute
	   in that mode (top bar), so flex `order` has no effect on it. */
	.gallery-wrap.wrap-effect-video .item-video {
		order: -1;
	}

	/* Mobile: .is-active drives expansion (no hover available). */
	.gallery-wrap.wrap-effect-video .item.is-active {
		flex: 0 0 auto;
		min-height: 70vh;
	}

	.gallery-wrap.wrap-effect-video .item.is-active .item-content,
	.gallery-wrap.wrap-effect-video .item.is-active .item-content > * {
		opacity: 1;
	}

	/* Mobile h3 band on the active side panel (mirrors clubhaus's
	   :hover h3 since we have no hover). */
	.gallery-wrap.wrap-effect-video .item.is-active:not(.item-video) h3 {
		z-index: 40;
		color: #fff;
		padding: 10px;
		width: 100%;
		text-align: center;
		background: #25675b;
		left: 0;
		transform: none;
		top: calc(45% - 85px);
	}

	/* Tap-flash green wipe replacement for the desktop hover slide-up. */
	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item:not(.item-video):active::before {
		transform: scaleY(1);
		transition: transform 0.25s ease-out;
	}

	/* Video panel mobile sizing. */
	.gallery-wrap.wrap-effect-video .item-video {
		min-height: 220px;
	}

	.gallery-wrap.wrap-effect-video[data-mode="hero"] .item-video.is-active {
		min-height: 0;
		aspect-ratio: 16 / 10;
	}

	/* Normal mode top bar on mobile -- same idea as desktop, just slightly
	   shorter to be friendly on small screens. The padding-top on the
	   wrap (set in the desktop block, applies here too) makes room
	   underneath for the four stacked side panels. */
	.gallery-wrap.wrap-effect-video[data-mode="normal"] .item-video {
		height: 48px;
		min-height: 0;
		max-height: 48px;
	}

	.gallery-wrap.wrap-effect-video[data-mode="normal"] {
		padding-top: 48px;
	}

	.gallery-wrap.wrap-effect-video[data-mode="normal"] .hype-video-sliver-label {
		font-size: 12px;
		letter-spacing: 2px;
	}

	.gallery-wrap.wrap-effect-video[data-mode="normal"] .hype-video-sliver-label::before {
		border-left-width: 10px;
		border-top-width: 6px;
		border-bottom-width: 6px;
	}

	.gallery-wrap.wrap-effect-video .hype-video {
		max-width: 100%;
		max-height: 100%;
		width: 100%;
		height: 100%;
		/* override the desktop aspect-ratio: 16/9 -- on mobile we let
		   object-fit:cover crop the video to fill the column instead. */
		aspect-ratio: auto;
		object-fit: cover;
		border-radius: 0;
		box-shadow: none;
	}

	.gallery-wrap.wrap-effect-video .item-video .hype-video-title {
		font-size: 18px;
		letter-spacing: 3px;
		padding: 10px 6px;
	}

	.gallery-wrap.wrap-effect-video .hype-video-controls {
		right: 10px;
		bottom: 50px;
	}

	.gallery-wrap.wrap-effect-video .video-backdrop {
		filter: blur(18px) brightness(0.4);
	}
}


/* =====================================================================
   Reduced motion -- respect the user's OS preference.
   ===================================================================== */

@media (prefers-reduced-motion: reduce) {
	.gallery-wrap.wrap-effect-video .item,
	.gallery-wrap.wrap-effect-video .item::before,
	.gallery-wrap.wrap-effect-video .video-backdrop,
	.gallery-wrap.wrap-effect-video .video-stage,
	.gallery-wrap.wrap-effect-video .item-video,
	.gallery-wrap.wrap-effect-video .item-video .hype-video-title {
		transition: none !important;
	}

	/* Stop the unmute-button pulse for users who've asked for less
	   motion. The button stays fully visible and clickable -- just
	   not animated. */
	.gallery-wrap.wrap-effect-video .hype-video-mute.is-muted {
		animation: none !important;
	}
}
