/* =====================================================================
   Child theme — child.css
   Loaded after the parent's framework.css (see inc/enqueue.php), so
   anything here safely wins the cascade without !important.
   ===================================================================== */

/* Subtle noise-free vignette across the whole page for a premium feel. */
body {
	background-image: radial-gradient(ellipse at top, rgba(255,77,28,.05), transparent 55%);
	background-attachment: fixed;
}

/* ---------------------------------------------------------------------
   Hero: boxed / contained banner style (matches reference site) instead
   of the framework's default full-bleed, edge-to-edge hero.
   - Sits inside the page with side margins + rounded corners, like a
     card/banner rather than stretching full width.
   - Clear gap from the header above it.
   - Shorter overall height.
   --------------------------------------------------------------------- */
.gzf-hero {
	margin: 28px auto 0;
	width: calc(100% - 220px);
	max-width: 1100px;
	min-height: 260px;
	border-radius: 18px;
	overflow: hidden;
	background-position: var(--gzfc-hero-image-position, center center);
	background-size: var(--gzfc-hero-image-fit, cover);
}
.gzf-hero-content { padding: 22px 40px; }

@media (max-width: 1024px) {
	.gzf-hero { width: calc(100% - 80px); min-height: 220px; }
}
@media (max-width: 782px) {
	.gzf-hero { margin-top: 18px; width: calc(100% - 24px); min-height: 190px; border-radius: 12px; }
	.gzf-hero-content { padding: 16px 20px; }
}

/* ---------------------------------------------------------------------
   Hero Section — Text Position fix. The "Hero Text Position" setting
   (gzf_hero_align, Theme Settings > Hero > Hero Section) already existed
   and is already printed as data-align="left|center|right" on .gzf-hero —
   see template-parts/hero.php. The framework's own styling for it only
   nudges text-align, while .gzf-hero-content stays a flex column with its
   default align-items (stretch/center), so the badge/title/subtitle/
   buttons keep hugging the middle of the box no matter which option is
   picked — the bug being fixed here.

   These rules make .gzf-hero-content and its children genuinely align as
   a whole block to the left/center/right of the Hero card:
     - align-items on the column controls the true block position
       (this is what was missing — text-align alone only affects how text
       wraps inside an already-centered block).
     - width: auto on the badge/title/subtitle/buttons lets them shrink to
       their own content width instead of stretching edge-to-edge, so
       "flex-start"/"flex-end" actually reach the left/right edge instead
       of a full-width block that has nowhere to move.
     - .gzf-hero-buttons (its own row) gets a matching justify-content.

   Edge gap: .gzf-hero-content already carries 40px side padding (20px on
   mobile, set above) — comfortably inside the 20–40px asked for — so Left
   and Right never sit flush against the Hero's border; no extra spacing
   rule is needed. Nothing about the Hero's background, image, animation,
   fonts, colors, or sizing is touched — only horizontal alignment, and it
   applies identically at every breakpoint since flexbox alignment isn't
   viewport-dependent.
   --------------------------------------------------------------------- */
.gzf-hero-content {
	display: flex;
	flex-direction: column;
	width: 100%;
	box-sizing: border-box;
}
.gzf-hero-badge,
.gzf-hero-title,
.gzf-hero-subtitle {
	width: auto;
	max-width: 100%;
}
.gzf-hero-buttons {
	display: flex;
	flex-wrap: wrap;
	width: auto;
	max-width: 100%;
}

.gzf-hero[data-align="left"] .gzf-hero-content {
	align-items: flex-start;
	text-align: left;
}
.gzf-hero[data-align="left"] .gzf-hero-buttons { justify-content: flex-start; }

.gzf-hero[data-align="right"] .gzf-hero-content {
	align-items: flex-end;
	text-align: right;
}
.gzf-hero[data-align="right"] .gzf-hero-buttons { justify-content: flex-end; }

/* Center is also the safe fallback for an empty/unrecognised data-align,
   matching the appearance sites already have today. */
.gzf-hero:not([data-align="left"]):not([data-align="right"]) .gzf-hero-content {
	align-items: center;
	text-align: center;
}
.gzf-hero:not([data-align="left"]):not([data-align="right"]) .gzf-hero-buttons {
	justify-content: center;
}

/* ---------------------------------------------------------------------
   Feature Slider — OUTER FRAME (width / gutters / corners), kept fully
   independent of the static Hero Section above.

   Selector note: the slider's <section> carries BOTH .gzf-hero (for the
   shared boxed look) AND .gzfc-feature-slider. Using the two-class
   selector ".gzfc-hero.gzfc-feature-slider" here (instead of the single
   class ".gzfc-feature-slider") gives these rules higher CSS specificity
   than every ".gzf-hero" rule above — including the ones inside the
   1024px/782px media queries — so the slider's own width / max-width /
   min-height / corner-radius always win outright, at every breakpoint,
   regardless of the order rules happen to appear in this file. Nothing
   here is ever read by, or overrides, the plain ".gzf-hero" selector, so
   the static Hero Section's own size and corners (above) are completely
   untouched — including its 1100px max-width, its 260/220/190px
   min-heights and its 18px/12px corners.

   Width is driven by --gzfc-fs-max-w, which the Size presets further
   down set per Small / Medium / Large / Custom. That is why picking a
   bigger size now makes the slider genuinely WIDER as well as taller,
   the way modern gaming-site feature sliders look.

   overflow is deliberately VISIBLE on this outer frame (the stage and
   the small cards each clip their own content instead). Without this,
   the small cards' hover lift and glow were being sliced off at the
   frame edge. Nothing bleeds out, because every child is either inside
   the stage or inside a rounded card of its own.
   --------------------------------------------------------------------- */
.gzfc-hero.gzfc-feature-slider {
	width: calc(100% - (var(--gzfc-fs-side-gutter, 32px) * 2));
	max-width: var(--gzfc-fs-max-w, 1560px);
	min-height: 0;
	height: auto;
	max-height: none;
	border-radius: var(--gzfc-fs-radius, 16px);
	overflow: visible;
}
@media (max-width: 1024px) {
	.gzfc-hero.gzfc-feature-slider {
		--gzfc-fs-side-gutter: 20px;
		width: calc(100% - 40px);
		max-width: 100%;
	}
}
@media (max-width: 782px) {
	.gzfc-hero.gzfc-feature-slider {
		--gzfc-fs-side-gutter: 12px;
		width: calc(100% - 24px);
		max-width: 100%;
		margin-top: 18px;
	}
}


/* Hero decorative accents (used by template-parts/hero.php override). */
.gzfc-hero { overflow: hidden; }
.gzfc-hero-corner {
	position: absolute; width: 120px; height: 120px; pointer-events: none; opacity: .5;
}
.gzfc-hero-corner--tl { top: 24px; left: 24px; border-top: 2px solid var(--gzf-color-primary); border-left: 2px solid var(--gzf-color-primary); }
.gzfc-hero-corner--br { bottom: 24px; right: 24px; border-bottom: 2px solid var(--gzf-color-primary); border-right: 2px solid var(--gzf-color-primary); }
.gzfc-hero-scanline {
	position: absolute; inset: 0; pointer-events: none;
	background: repeating-linear-gradient(180deg, rgba(255,255,255,.015) 0px, rgba(255,255,255,.015) 1px, transparent 1px, transparent 3px);
	mix-blend-mode: overlay;
}

/* Trending strip (inc/hooks.php Example 1). Only the always-on padding
   lives here; the .gzf-post-grid--compact rules (Static Grid mode) are
   defined once, in assets/css/latest-releases-carousel.css, which is the
   stylesheet already conditionally loaded only when this strip actually
   renders — this file (child.css) loads on every page of the site, so a
   duplicate copy here would ship unused CSS to every visitor who never
   sees the strip at all (removed as part of the 1.26.6 performance pass;
   no visual change, no setting removed). */
.gzfc-trending-strip { padding: 40px 0 8px; }

/* Editor's Pick badge (inc/hooks.php Example 3) gets its own accent color
   distinct from the framework's built-in NEW/FREE/DEMO badges. */
.gzf-badge--custom { background: linear-gradient(135deg, var(--gzf-color-primary), var(--gzf-color-accent)); color: #1a0f04; }

/* Slightly stronger card hover glow to match the reference screenshots. */
.gzf-card { position: relative; }
.gzf-card::after {
	content: "";
	position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
	background: linear-gradient(180deg, transparent 60%, rgba(255,77,28,.08));
	opacity: 0; transition: opacity var(--gzf-transition);
}
.gzf-card:hover::after { opacity: 1; }

/* Category bottom bar gets a slightly warmer background than the header. */
.gzf-header-bottom { background: rgba(255,77,28,.04); }

/* Admin: highlight the Editor's Pick metabox slightly. */
#gzfc_editors_pick .gzfc-editors-pick-row { margin: 0; }

/* =====================================================================
   Feature Slider (template-parts/hero.php + featured-grid.php) — a large
   auto-rotating featured card plus 4 smaller cards, built from whichever
   posts gzfc_get_featured_query() (inc/featured.php) returns.

   SIZING MODEL (this is the part that was previously broken)
   ---------------------------------------------------------
   The old version sized the large stage with THREE competing properties
   at once — aspect-ratio + min-height + max-height. On a wide desktop
   the aspect-ratio nearly always produced a height that landed outside
   the min/max window, so whichever of min-height / max-height clamped it
   became the real height and the preset's other numbers were silently
   thrown away. That is exactly why moving the "Feature Slider
   Height/Size" setting between Small / Medium / Large / Custom appeared
   to do nothing (or almost nothing) on the frontend.

   It now uses ONE height source and nothing else:

       height: min( var(--gzfc-fs-h), 82vh )

   --gzfc-fs-h is a single plain pixel value set by the size preset (and,
   for "Custom", by the exact px from the Customizer range control). The
   82vh cap is only a safety rail so a very large custom height can never
   push the whole page off-screen on a short laptop display. aspect-ratio
   is explicitly set back to `auto` and min/max-height to neutral values,
   so there is no second opinion about how tall the stage is — the
   setting is the height, full stop.

   Every other part of the slider scales off that same one variable:
   small-card image height, title sizes, inner padding and gaps are all
   calc()/clamp() expressions built on --gzfc-fs-h. So one setting really
   does resize the whole component together — big card, small cards,
   images and titles — instead of only stretching the big card and
   leaving everything else looking undersized next to it.

   RESPONSIVE INDEPENDENCE
   -----------------------
   Desktop, tablet and mobile each read a SEPARATE variable
   (--gzfc-fs-h, --gzfc-fs-h-tablet, --gzfc-fs-h-mobile). The desktop
   value is never used below 900px, so making the desktop slider large
   cannot leak into the mobile layout. For "Custom", the tablet/mobile
   values are min()-capped versions of the chosen height, so a 900px
   desktop custom height still renders as a sane ~360px block on a
   phone instead of a full-screen wall of image.

   HERO SECTION INDEPENDENCE
   -------------------------
   Nothing in this whole section reads --gzf-hero-height or any other
   Hero Section variable, and nothing here is scoped to a bare .gzf-hero
   selector. The two components share no sizing input whatsoever: the
   Hero Section keeps its own "Hero Height — Desktop/Mobile" controls,
   the slider keeps gzfc_slider_size / gzfc_slider_custom_height. The
   same applies to corner radius (--gzfc-fs-radius, its own setting,
   never --gzf-card-radius) and to the sitewide post cards.
   ===================================================================== */

/* Shared with the badge markup used inside slider cards. */
.gzfc-slide-badge { text-decoration: none; }

.gzfc-hero.gzfc-feature-slider { padding: 0; align-items: stretch; }
/* The slider provides its own outer gutters (see the frame block above),
   so the framework container inside it must not add a second, narrower
   max-width on top — that was capping the slider well below the width
   the size preset asks for. */
.gzfc-feature-slider .gzf-container {
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
}

.gzfc-fs-body { display: flex; flex-direction: column; gap: var(--gzfc-fs-gap, 22px); }

/* ---------------------------------------------------------------------
   Feature Slider — Size presets (Theme Settings > Hero > Feature Slider
   > "Feature Slider Height/Size"). This block is the ONLY place that
   reads gzfc_slider_size, via the data-size attribute that
   template-parts/featured-grid.php writes onto the <section>.

   Base values below act as the fallback for any slider that somehow
   renders without a data-size attribute; they match "medium" exactly,
   so there is never an unstyled or half-sized state.
   --------------------------------------------------------------------- */
.gzfc-feature-slider {
	/* Animation — overridden per instance by the inline style
	   template-parts/featured-grid.php prints from the Transition Speed
	   and Auto-Rotate Speed settings. These are only the fallbacks. */
	--gzfc-fs-anim-duration: 800ms;
	--gzfc-fs-anim-ease: cubic-bezier(.4, 0, .2, 1);
	--gzfc-fs-kb-duration: 9000ms;

	/* Outer frame */
	--gzfc-fs-max-w: 1560px;
	--gzfc-fs-side-gutter: 32px;

	/* The one and only height source (see the note above) */
	--gzfc-fs-h: 560px;
	--gzfc-fs-h-tablet: 400px;
	--gzfc-fs-h-mobile: 265px;

	/* Everything else scales off --gzfc-fs-h so the whole component
	   grows and shrinks together. */
	--gzfc-fs-gap: clamp(14px, calc(var(--gzfc-fs-h) * .035), 26px);
	--gzfc-fs-thumb-h: clamp(120px, calc(var(--gzfc-fs-h) * .26), 240px);
	--gzfc-fs-pad: clamp(22px, calc(var(--gzfc-fs-h) * .07), 52px);
	/* Font sizes are set per preset (just below) rather than calculated
	   from --gzfc-fs-h: CSS calc() cannot legally convert a px length
	   into rem, so a "clever" expression here would be an invalid value
	   and the whole declaration would be dropped. These are the medium
	   defaults. */
	--gzfc-fs-title: clamp(1.7rem, 2.1vw + .7rem, 2.6rem);
	--gzfc-fs-excerpt: clamp(.98rem, .35vw + .85rem, 1.12rem);
	--gzfc-fs-thumb-title: clamp(.98rem, .3vw + .86rem, 1.12rem);
}

.gzfc-feature-slider[data-size="small"] {
	--gzfc-fs-max-w: 1280px;
	--gzfc-fs-h: 400px;
	--gzfc-fs-h-tablet: 320px;
	--gzfc-fs-h-mobile: 230px;
	--gzfc-fs-title: clamp(1.4rem, 1.6vw + .6rem, 2rem);
	--gzfc-fs-excerpt: clamp(.92rem, .25vw + .82rem, 1rem);
	--gzfc-fs-thumb-title: clamp(.92rem, .22vw + .84rem, 1rem);
}
.gzfc-feature-slider[data-size="medium"] {
	--gzfc-fs-max-w: 1560px;
	--gzfc-fs-h: 560px;
	--gzfc-fs-h-tablet: 400px;
	--gzfc-fs-h-mobile: 265px;
}
.gzfc-feature-slider[data-size="large"] {
	--gzfc-fs-max-w: 1780px;
	--gzfc-fs-h: 720px;
	--gzfc-fs-h-tablet: 470px;
	--gzfc-fs-h-mobile: 300px;
	--gzfc-fs-title: clamp(2rem, 2.6vw + .8rem, 3.1rem);
	--gzfc-fs-excerpt: clamp(1.05rem, .4vw + .9rem, 1.28rem);
	--gzfc-fs-thumb-title: clamp(1.04rem, .35vw + .9rem, 1.24rem);
}
/* Custom — the exact px height from the "Custom Height — Desktop (px)"
   range control. --gzfc-fs-stage-custom-height is printed inline, scoped
   to .gzfc-feature-slider, by gzfc_slider_inline_css() in
   inc/slider-size.php, so this works whether or not the parent framework
   auto-outputs css_var values. Tablet/mobile deliberately cap the value
   rather than ignoring it, so a huge desktop custom height degrades
   gracefully on small screens instead of breaking them. */
.gzfc-feature-slider[data-size="custom"] {
	--gzfc-fs-max-w: 1780px;
	--gzfc-fs-h: var(--gzfc-fs-stage-custom-height, 560px);
	--gzfc-fs-h-tablet: min(var(--gzfc-fs-stage-custom-height, 560px), 520px);
	--gzfc-fs-h-mobile: min(var(--gzfc-fs-stage-custom-height, 560px), 360px);
}

/* --- Large stage (shared by all layouts) ----------------------------
   No permanent dark overlay sits on top of the photo — the image itself
   stays fully visible. Title/excerpt/badge read fine on top of it via a
   bottom-only gradient scrim plus text-shadow, and the only motion on
   the image is a light hover zoom plus the existing slow crossfade.
   --------------------------------------------------------------------- */
.gzfc-fs-stage {
	position: relative;
	display: block;
	width: 100%;
	/* Single height source — see the sizing note at the top of this
	   section. aspect-ratio/min/max are neutralised on purpose. */
	aspect-ratio: auto;
	height: min(var(--gzfc-fs-h), 82vh);
	min-height: 200px;
	max-height: none;
	border-radius: var(--gzfc-fs-radius, 16px);
	overflow: hidden;
	border: 1px solid var(--gzf-color-border);
	background: var(--gzf-color-card-bg, var(--gzf-color-surface));
}
/* Slide base. Every slide sits in one of exactly three states, and the
   Transition Effect block further down redefines what those three states
   LOOK like — the states themselves never change, which is why one small
   JS class-toggle drives all eight effects:

     (no class)   idle     — waiting off-stage / invisible
     .is-active   on-stage — the post currently being shown
     .is-leaving  exiting  — the post that was just replaced, still
                             animating out. assets/js/feature-slider.js
                             removes this once the transition finishes.

   Only opacity and transform are animated (never width/height/top/left),
   so every effect stays on the GPU compositor and costs no layout work —
   that is what keeps this lightweight enough for mobile.

   .is-instant is applied by the JS for a single frame while it resets a
   finished slide back to idle, so the reset itself is never animated
   (without it, a slide that exited to the left would visibly fly back
   across the stage to its off-screen starting position on the right). */
.gzfc-fs-slide {
	position: absolute; inset: 0;
	display: block;
	color: inherit;
	text-decoration: none;
	background-position: center center;
	background-size: cover;
	background-repeat: no-repeat;
	background-color: var(--gzf-color-surface);
	opacity: 0;
	transform: none;
	z-index: 1;
	pointer-events: none;
	transition:
		opacity var(--gzfc-fs-anim-duration, 800ms) var(--gzfc-fs-anim-ease, cubic-bezier(.4, 0, .2, 1)),
		transform var(--gzfc-fs-anim-duration, 800ms) var(--gzfc-fs-anim-ease, cubic-bezier(.4, 0, .2, 1)),
		filter var(--gzfc-fs-anim-duration, 800ms) var(--gzfc-fs-anim-ease, cubic-bezier(.4, 0, .2, 1)),
		clip-path var(--gzfc-fs-anim-duration, 800ms) var(--gzfc-fs-anim-ease, cubic-bezier(.4, 0, .2, 1));
	backface-visibility: hidden;
}
.gzfc-fs-slide.is-active {
	opacity: 1;
	transform: none;
	pointer-events: auto;
	z-index: 3;
}
.gzfc-fs-slide.is-leaving { z-index: 2; }
.gzfc-fs-slide.is-instant { transition: none !important; animation: none !important; }
.gzfc-fs-slide-content {
	position: absolute; left: 0; right: 0; bottom: 0; top: 30%; z-index: 2;
	display: flex; flex-direction: column; justify-content: flex-end; gap: 10px;
	padding: var(--gzfc-fs-pad);
	/* Gradient scrim (image stays fully visible in the top ~30%) so the
	   title/excerpt stay readable over busy or bright artwork. */
	background: linear-gradient(180deg, rgba(6,6,8,0) 0%, rgba(6,6,8,.5) 40%, rgba(6,6,8,.88) 100%);
	text-shadow: 0 2px 10px rgba(0,0,0,.85), 0 1px 3px rgba(0,0,0,.9);
	overflow: hidden;
}
.gzfc-fs-slide-title {
	font-family: var(--gzf-font-heading);
	color: #fff;
	font-size: var(--gzfc-fs-title, 2.4rem);
	line-height: 1.15;
	font-weight: var(--gzf-heading-weight, 700);
	/* Clamped so an unusually long post title can never push the excerpt
	   out of the stage or overflow the scrim. */
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.gzfc-fs-slide .gzfc-slide-excerpt {
	max-width: min(760px, 62%);
	margin-bottom: 0;
	font-size: var(--gzfc-fs-excerpt, 1rem);
	text-shadow: inherit;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Progress dots under the stage. */
.gzfc-fs-dots { display: flex; justify-content: center; gap: 8px; margin-top: 14px; }
.gzfc-fs-dot {
	width: 8px; height: 8px; padding: 0; border: none; border-radius: 50%;
	background: var(--gzf-color-border); cursor: pointer;
	transition: background-color .3s ease, transform .3s ease;
}
.gzfc-fs-dot.is-active { background: var(--gzf-color-primary); transform: scale(1.3); }

/* --- Small/thumb cards (shared markup, container differs by layout) -
   The image area uses background-size: cover so every thumbnail fills
   its box edge-to-edge. The previous `background-size: 100%` sized the
   image by WIDTH only and let the height fall where it may, which left
   visible empty bands above and below wide (16:9) artwork inside a
   taller card — that is the "images look cropped / cards look broken"
   symptom. The slow pan/zoom is now done with transform instead of
   animating background-size, so the image always stays fully covering.
   --------------------------------------------------------------------- */
.gzfc-fs-thumb {
	position: relative;
	display: flex; flex-direction: column;
	width: 100%; min-width: 0; padding: 0; margin: 0;
	border: 1px solid var(--gzf-color-border);
	border-radius: var(--gzfc-fs-radius, 12px);
	overflow: hidden;
	background: var(--gzf-color-card-bg, var(--gzf-color-surface));
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
	transition: transform .35s ease, border-color .35s ease, box-shadow .35s ease;
}
/* The accent border on hover/focus is part of the card's base identity
   (and doubles as the keyboard focus indicator), so it applies at every
   Card Hover Effect setting — including "None". The motion on top of it
   is what the setting controls; see the "Card Hover Effects" block near
   the end of this file. */
.gzfc-fs-thumb:hover,
.gzfc-fs-thumb:focus-visible {
	border-color: var(--gzf-color-primary);
	outline: none;
}
.gzfc-fs-thumb-media {
	position: relative;
	flex: none;
	aspect-ratio: auto;
	height: var(--gzfc-fs-thumb-h, 150px);
	overflow: hidden;
	background-position: 50% 50%;
	background-size: cover;
	background-repeat: no-repeat;
	background-color: var(--gzf-color-surface);
	transform: scale(1);
	transition: transform .45s ease;
}
/* The image zoom itself is opt-in per Card Hover Effect (Lift, Zoom and
   Tilt use it; None and Glow don't) — see the "Card Hover Effects" block. */
.gzfc-fs-thumb-content {
	display: flex; flex-direction: column; gap: 6px;
	padding: clamp(12px, calc(var(--gzfc-fs-h) * .022), 20px) clamp(14px, calc(var(--gzfc-fs-h) * .026), 22px);
	min-width: 0;
}
.gzfc-fs-thumb-cat {
	font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
	color: var(--gzf-color-primary);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gzfc-fs-thumb-title {
	font-family: var(--gzf-font-heading);
	font-size: var(--gzfc-fs-thumb-title, 1.05rem); line-height: 1.3;
	color: var(--gzf-color-heading, #fff);
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
	overflow-wrap: anywhere;
}

/* --- Layout: single — one large auto-rotating slider only, no small
   cards at all. Gets slightly more room since it's the only element,
   scaled by the exact same size preset as everything else. ----------- */
.gzfc-fs-body[data-layout="single"] .gzfc-fs-stage {
	height: min(calc(var(--gzfc-fs-h) * 1.08), 86vh);
}

/* --- Layout: center — stage in the middle, 2 small cards each side --
   The side columns stretch to exactly the stage's height, so the three
   columns always line up top and bottom at any size preset. ---------- */
.gzfc-fs-body[data-layout="center"] {
	display: grid;
	grid-template-columns: minmax(180px, 1fr) minmax(0, 2.4fr) minmax(180px, 1fr);
	gap: var(--gzfc-fs-gap, 20px);
	align-items: stretch;
}
.gzfc-fs-body[data-layout="center"] .gzfc-fs-stage { grid-column: 2; }
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--left,
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--right {
	display: flex; flex-direction: column; gap: var(--gzfc-fs-gap, 20px);
	height: min(var(--gzfc-fs-h), 82vh);
}
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--left { grid-column: 1; }
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--right { grid-column: 3; }
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumb { flex: 1 1 0; min-height: 0; }
.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumb-media { height: auto; flex: 1 1 0; min-height: 0; }

/* =====================================================================
   Feature Slider — TABLET (<= 900px).
   Reads --gzfc-fs-h-tablet only. The desktop --gzfc-fs-h value is not
   used anywhere below this point, which is what guarantees that making
   the desktop slider large cannot distort the tablet or mobile layout.
   ===================================================================== */
@media (max-width: 900px) {
	.gzfc-feature-slider {
		--gzfc-fs-gap: 16px;
		--gzfc-fs-thumb-h: clamp(110px, calc(var(--gzfc-fs-h-tablet) * .38), 200px);
		--gzfc-fs-pad: clamp(20px, calc(var(--gzfc-fs-h-tablet) * .075), 34px);
		--gzfc-fs-title: clamp(1.4rem, 3.4vw, 1.9rem);
		--gzfc-fs-excerpt: .98rem;
		--gzfc-fs-thumb-title: .98rem;
	}
	.gzfc-fs-stage { height: min(var(--gzfc-fs-h-tablet), 72vh); }
	.gzfc-fs-body[data-layout="single"] .gzfc-fs-stage { height: min(calc(var(--gzfc-fs-h-tablet) * 1.06), 76vh); }
	.gzfc-fs-slide .gzfc-slide-excerpt { max-width: 100%; }

	.gzfc-fs-body[data-layout="center"] { display: flex; flex-direction: column; }
	.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--left,
	.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--right {
		display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
		height: auto;
	}
	.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumb-media { height: var(--gzfc-fs-thumb-h); flex: none; }

}

/* =====================================================================
   Feature Slider — MOBILE (<= 640px).
   Reads --gzfc-fs-h-mobile only, so the phone layout is completely
   insulated from both the desktop and the tablet height settings.
   ===================================================================== */
@media (max-width: 640px) {
	.gzfc-feature-slider {
		--gzfc-fs-gap: 12px;
		--gzfc-fs-thumb-h: clamp(90px, 28vw, 150px);
		--gzfc-fs-pad: 18px;
		--gzfc-fs-title: clamp(1.15rem, 5vw, 1.5rem);
		--gzfc-fs-thumb-title: .9rem;
	}
	.gzfc-fs-stage { height: min(var(--gzfc-fs-h-mobile), 62vh); }
	.gzfc-fs-body[data-layout="single"] .gzfc-fs-stage { height: min(calc(var(--gzfc-fs-h-mobile) * 1.08), 66vh); }
	.gzfc-fs-slide-content { top: 22%; }
	.gzfc-fs-slide .gzfc-slide-excerpt { display: none; }
	.gzfc-fs-body { gap: var(--gzfc-fs-gap, 12px); }
	.gzfc-fs-thumb-cat { font-size: .66rem; }
}

/* Very narrow phones only (older/compact handsets). Mainstream phones —
   390px/393px/412px — deliberately stay on the 2-column grid above: one
   card per row there would make the slider scroll for over a full extra
   screen for no readability gain. */
@media (max-width: 359px) {
	.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--left,
	.gzfc-fs-body[data-layout="center"] .gzfc-fs-thumbs--right { grid-template-columns: minmax(0, 1fr); }
	.gzfc-feature-slider { --gzfc-fs-thumb-h: clamp(120px, 42vw, 190px); }
}

/* =====================================================================
   Feature Slider — TRANSITION EFFECTS (Theme Settings > Hero > Feature
   Slider Animation & Transition Effects > "Slide Transition Effect").

   Everything below is keyed off the data-effect attribute that
   template-parts/featured-grid.php writes onto the slider's <section>,
   so ALL FOUR layouts (center, single, stream, cinematic)
   get the same eighteen effects for free — the effect and the layout are
   two independent axes and neither knows about the other. No layout rule
   above is touched.

   Each effect only has to answer three questions: where does a slide
   wait BEFORE it is shown (idle), what does it look like while it IS
   shown (.is-active), and where does it go on its way OUT (.is-leaving).
   Because only opacity and transform are involved, the browser can run
   every one of these entirely on the compositor — no reflow, no repaint
   of the layout, which is what keeps them smooth on mid-range phones.

   Specificity note: the base states (.gzfc-fs-slide.is-active etc.) are
   0,2,0. Every rule here is written as
   [data-effect="..."] .gzfc-fs-slide.is-active — 0,3,0 — so the effect
   always wins on specificity rather than on source order. That's why
   each effect block spells out all three states explicitly instead of
   relying on inheriting one of them from the base.

   Speed comes from --gzfc-fs-anim-duration, printed as an inline style
   on the section by featured-grid.php from the "Transition Speed"
   control, so each slider instance carries its own value.
   ===================================================================== */

/* --- None / Static: no motion at all, the image simply swaps. -------- */
.gzfc-feature-slider[data-effect="none"] .gzfc-fs-slide { transition: none; opacity: 0; transform: none; }
.gzfc-feature-slider[data-effect="none"] .gzfc-fs-slide.is-active { opacity: 1; transform: none; }
.gzfc-feature-slider[data-effect="none"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: none; }

/* --- Fade: one image fades out while the next fades in. ------------- */
.gzfc-feature-slider[data-effect="fade"] .gzfc-fs-slide { opacity: 0; transform: none; }
.gzfc-feature-slider[data-effect="fade"] .gzfc-fs-slide.is-active { opacity: 1; transform: none; }
.gzfc-feature-slider[data-effect="fade"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: none; }

/* --- Zoom & Fade: crossfade with a gentle scale settle. Reproduces the
   slider's previous built-in look exactly, which is why it's the
   default — existing sites see no change until they pick another. --- */
.gzfc-feature-slider[data-effect="zoom-fade"] .gzfc-fs-slide { opacity: 0; transform: scale(1.08); }
.gzfc-feature-slider[data-effect="zoom-fade"] .gzfc-fs-slide.is-active { opacity: 1; transform: scale(1); }
.gzfc-feature-slider[data-effect="zoom-fade"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: scale(1.08); }

/* --- Zoom In: the next image grows in from slightly smaller while the
   outgoing one pushes past the viewer. ------------------------------ */
.gzfc-feature-slider[data-effect="zoom-in"] .gzfc-fs-slide { opacity: 0; transform: scale(.88); }
.gzfc-feature-slider[data-effect="zoom-in"] .gzfc-fs-slide.is-active { opacity: 1; transform: scale(1); }
.gzfc-feature-slider[data-effect="zoom-in"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: scale(1.15); }

/* --- Zoom Out: the current image slowly pulls back and shrinks away as
   the next one arrives from slightly oversized. --------------------- */
.gzfc-feature-slider[data-effect="zoom-out"] .gzfc-fs-slide { opacity: 0; transform: scale(1.18); }
.gzfc-feature-slider[data-effect="zoom-out"] .gzfc-fs-slide.is-active { opacity: 1; transform: scale(1); }
.gzfc-feature-slider[data-effect="zoom-out"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: scale(.9); }

/* --- Simple Slide: a true horizontal slide — one image travels out to
   the left while the next travels in from the right. Opacity stays at 1
   throughout (it's a slide, not a fade); the slides are hidden purely by
   the stage's own overflow, which is why they must never be given a
   transform larger than 100%. ---------------------------------------- */
.gzfc-feature-slider[data-effect="slide"] .gzfc-fs-slide { opacity: 1; transform: translate3d(100%, 0, 0); }
.gzfc-feature-slider[data-effect="slide"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="slide"] .gzfc-fs-slide.is-leaving { opacity: 1; transform: translate3d(-100%, 0, 0); }

/* --- Slide Up: the next post rises in from below, the current one
   continues up and out. ---------------------------------------------- */
.gzfc-feature-slider[data-effect="slide-up"] .gzfc-fs-slide { opacity: 1; transform: translate3d(0, 100%, 0); }
.gzfc-feature-slider[data-effect="slide-up"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="slide-up"] .gzfc-fs-slide.is-leaving { opacity: 1; transform: translate3d(0, -100%, 0); }

/* --- Ken Burns: a crossfade, plus the visible image keeps slowly
   drifting and zooming for as long as it is on screen. The animation's
   duration is --gzfc-fs-kb-duration, which featured-grid.php sets from
   the Auto-Rotate Speed, so the drift finishes just as the slider moves
   on instead of stopping dead halfway or looping visibly. ------------ */
.gzfc-feature-slider[data-effect="ken-burns"] .gzfc-fs-slide { opacity: 0; transform: none; }
.gzfc-feature-slider[data-effect="ken-burns"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: none; }
.gzfc-feature-slider[data-effect="ken-burns"] .gzfc-fs-slide.is-active {
	opacity: 1;
	animation: gzfc-fs-kenburns var(--gzfc-fs-kb-duration, 9000ms) ease-out forwards;
}
@keyframes gzfc-fs-kenburns {
	from { transform: scale(1.02) translate3d(0, 0, 0); }
	to   { transform: scale(1.16) translate3d(-2%, -2%, 0); }
}

/* ---------------------------------------------------------------------
   CARD-MOTION EFFECTS
   -------------------
   Everything above animates the IMAGE — it scales, fades or slides while
   the card frame itself stays put. The group below does the opposite:
   the whole Feature Post moves as one physical object (it lifts, presses,
   flips, falls back), and the image just travels with it. That is the
   difference between "the photo zoomed" and "the card moved", and it is
   why these read as much more tactile even though they use exactly the
   same three-state mechanism as the simpler effects.

   Note on scale: a card that lifts or presses must never scale ABOVE 1
   while it is still partly visible, or its edges would be cropped by the
   stage's overflow. Idle/leaving states here scale down (or translate by
   a percentage that keeps them inside), never up.
   --------------------------------------------------------------------- */

/* --- Lift Up: the post rises off the stage and floats out of the top,
   while the next one rises into place from below. The scale-down on the
   way in and out is what sells it as the card receding away from the
   viewer rather than simply sliding. ---------------------------------- */
.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide { opacity: 0; transform: translate3d(0, 14%, 0) scale(.94); }
.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(0, -14%, 0) scale(.94); }

/* --- Button Press: the outgoing post is pushed down and in, like a key
   being pressed, and the next one springs back out. The springy easing
   (a "back out" curve that slightly overshoots before settling) is what
   makes it feel like a physical button rather than a fade — so this
   effect overrides --gzfc-fs-anim-ease for itself only. ---------------- */
.gzfc-feature-slider[data-effect="press"] { --gzfc-fs-anim-ease: cubic-bezier(.34, 1.4, .64, 1); }
.gzfc-feature-slider[data-effect="press"] .gzfc-fs-slide { opacity: 0; transform: translate3d(0, 5%, 0) scale(.9); }
.gzfc-feature-slider[data-effect="press"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
.gzfc-feature-slider[data-effect="press"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(0, 3%, 0) scale(.93); }

/* --- Smooth Lift + Fade: the gentlest of the card-motion set. A short,
   fixed 26px travel instead of a percentage, so the movement feels
   identical whether the slider is set to Small or Large. -------------- */
.gzfc-feature-slider[data-effect="lift-fade"] .gzfc-fs-slide { opacity: 0; transform: translate3d(0, 26px, 0); }
.gzfc-feature-slider[data-effect="lift-fade"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="lift-fade"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(0, -26px, 0); }

/* --- Card Stack: the current post drops back into the stack (shrinking
   and fading) while the next one slides up over the top of it, like
   dealing a card off a deck. Relies on .is-leaving sitting at z-index 2
   and .is-active at 3, so the incoming card genuinely passes in FRONT
   of the outgoing one. ------------------------------------------------ */
.gzfc-feature-slider[data-effect="stack"] .gzfc-fs-slide { opacity: 1; transform: translate3d(0, 100%, 0); }
.gzfc-feature-slider[data-effect="stack"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="stack"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(0, -4%, 0) scale(.88); }

/* =====================================================================
   3D EFFECTS
   The stage gets a perspective ONLY for these two — adding it globally
   would give every other effect a subtle, unwanted depth distortion.
   transform-style is deliberately left flat: the slides are single
   planes, so preserve-3d would buy nothing and costs extra compositing
   on mobile GPUs.
   ===================================================================== */
.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-stage,
.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-stage { perspective: 1400px; }

/* --- 3D Flip: the post swings away on its vertical axis as the next
   one swings in, like turning a card over in your hand. The rotation is
   paired with a translate so the two cards pass each other instead of
   rotating through the same space. --------------------------------- */
.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-slide { opacity: 0; transform: translate3d(22%, 0, 0) rotateY(32deg) scale(.92); }
.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0) rotateY(0deg) scale(1); }
.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(-22%, 0, 0) rotateY(-32deg) scale(.92); }

/* --- 3D Tilt: the card tips backwards away from the viewer and the next
   one tips up into place, as if hinged along its top and bottom edge.
   Subtler than the flip and reads well on wide, short stages. --------- */
.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-slide { opacity: 0; transform: translate3d(0, 8%, 0) rotateX(-14deg) scale(.94); }
.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0) rotateX(0deg) scale(1); }
.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: translate3d(0, -8%, 0) rotateX(14deg) scale(.94); }

/* =====================================================================
   SLIDE DIRECTIONS
   "Simple Slide" (above) and "Slide Up" (above) cover left and up; these
   two complete the set so the slider can travel in any of the four
   directions. Same rule as the originals: opacity stays 1 and the slides
   are hidden purely by the stage's overflow, so their transforms must
   never exceed 100%.
   ===================================================================== */
.gzfc-feature-slider[data-effect="slide-right"] .gzfc-fs-slide { opacity: 1; transform: translate3d(-100%, 0, 0); }
.gzfc-feature-slider[data-effect="slide-right"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="slide-right"] .gzfc-fs-slide.is-leaving { opacity: 1; transform: translate3d(100%, 0, 0); }

.gzfc-feature-slider[data-effect="slide-down"] .gzfc-fs-slide { opacity: 1; transform: translate3d(0, -100%, 0); }
.gzfc-feature-slider[data-effect="slide-down"] .gzfc-fs-slide.is-active { opacity: 1; transform: translate3d(0, 0, 0); }
.gzfc-feature-slider[data-effect="slide-down"] .gzfc-fs-slide.is-leaving { opacity: 1; transform: translate3d(0, 100%, 0); }

/* =====================================================================
   GAMING-SITE STAPLES
   Two patterns that show up constantly on game stores and esports sites.
   ===================================================================== */

/* --- Focus Pull: the outgoing post goes soft and out of focus while the
   next one sharpens into it, like a camera racking focus. The blur is
   kept to 12px (8px on phones) because a large blur radius over a
   full-bleed image is one of the few genuinely expensive things a
   browser can be asked to animate. ----------------------------------- */
.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide { opacity: 0; transform: scale(1.04); filter: blur(12px); }
.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide.is-active { opacity: 1; transform: scale(1); filter: blur(0); }
.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide.is-leaving { opacity: 0; transform: scale(1.04); filter: blur(12px); }

/* --- Reveal Wipe: the next post is uncovered left-to-right by a moving
   edge, the storefront "new release" reveal. Uses clip-path rather than
   a moving overlay element, so there is no extra DOM and nothing to keep
   in sync — and unlike a transform, it doesn't move the card's text,
   which stays perfectly still as the artwork is revealed around it. --- */
.gzfc-feature-slider[data-effect="wipe"] .gzfc-fs-slide { opacity: 1; clip-path: inset(0 0 0 100%); }
.gzfc-feature-slider[data-effect="wipe"] .gzfc-fs-slide.is-active { opacity: 1; clip-path: inset(0 0 0 0); }
.gzfc-feature-slider[data-effect="wipe"] .gzfc-fs-slide.is-leaving { opacity: 1; clip-path: inset(0 100% 0 0); }

/* --- Responsive trims for the heavier effects. Percentage-based travel
   is already resolution-independent, but a 22% horizontal swing and a
   12px blur both read as far more aggressive inside a 265px-tall phone
   stage than they do on a 560px desktop one, so they're dialled back.
   The perspective is shortened to match the smaller box, otherwise the
   same rotation angle looks almost flat. ----------------------------- */
@media (max-width: 640px) {
	.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-stage,
	.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-stage { perspective: 800px; }

	.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-slide { transform: translate3d(16%, 0, 0) rotateY(22deg) scale(.94); }
	.gzfc-feature-slider[data-effect="flip-3d"] .gzfc-fs-slide.is-leaving { transform: translate3d(-16%, 0, 0) rotateY(-22deg) scale(.94); }
	.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-slide { transform: translate3d(0, 6%, 0) rotateX(-10deg) scale(.95); }
	.gzfc-feature-slider[data-effect="tilt-3d"] .gzfc-fs-slide.is-leaving { transform: translate3d(0, -6%, 0) rotateX(10deg) scale(.95); }

	.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide { filter: blur(8px); }
	.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide.is-leaving { filter: blur(8px); }

	.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide { transform: translate3d(0, 10%, 0) scale(.96); }
	.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide.is-leaving { transform: translate3d(0, -10%, 0) scale(.96); }
}

/* --- Large-card hover zoom -----------------------------------------
   Kept only for the effects whose resting transform is a plain scale.
   For Simple Slide, Slide Up and Ken Burns the active slide's transform
   is already carrying the effect (a translate, or a running animation),
   so a hover transform would fight it and make the image jump — those
   three deliberately have no hover zoom on the large card. Wrapped in
   (hover: hover) so touch devices never get stuck in a hover state. */
@media (hover: hover) {
	.gzfc-feature-slider[data-effect="none"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="fade"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="zoom-fade"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="zoom-in"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="zoom-out"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="blur-fade"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="wipe"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="lift-up"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="lift-fade"] .gzfc-fs-slide.is-active:hover,
	.gzfc-feature-slider[data-effect="press"] .gzfc-fs-slide.is-active:hover {
		transform: scale(1.035);
		transition: transform .6s ease;
	}
}

/* =====================================================================
   Feature Slider — CARD HOVER EFFECTS (Theme Settings > Hero > Feature
   Slider Animation & Transition Effects > "Card Hover Effect").

   Keyed off data-hover on the same <section>, and applies to the small
   cards in every layout that has them. Independent from the transition
   effect above: any hover style can be combined with any transition.

   "Lift" is the default and reproduces the previous built-in hover
   exactly, so nothing changes for an existing site until the setting is
   moved. "None" still keeps the accent border and the keyboard focus
   ring — that's an accessibility affordance, not decoration.
   ===================================================================== */

/* Hover Lift — the card rises slightly with a soft shadow, image zooms. */
.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:hover,
.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:focus-visible {
	transform: translateY(-6px);
	box-shadow: 0 14px 30px rgba(0, 0, 0, .38);
}
.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:hover .gzfc-fs-thumb-media,
.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:focus-visible .gzfc-fs-thumb-media { transform: scale(1.07); }

/* Zoom — the card stays put, only its image scales up inside it. */
.gzfc-feature-slider[data-hover="zoom"] .gzfc-fs-thumb:hover .gzfc-fs-thumb-media,
.gzfc-feature-slider[data-hover="zoom"] .gzfc-fs-thumb:focus-visible .gzfc-fs-thumb-media { transform: scale(1.12); }

/* Glow — no movement at all, just an accent ring and coloured halo.
   The best choice when the slider sits close to other page sections and
   you don't want anything shifting around. */
.gzfc-feature-slider[data-hover="glow"] .gzfc-fs-thumb:hover,
.gzfc-feature-slider[data-hover="glow"] .gzfc-fs-thumb:focus-visible {
	box-shadow: 0 0 0 1px var(--gzf-color-primary), 0 0 22px rgba(255, 77, 28, .35);
}

/* Tilt — a small lift with a slight rotation, like a card being picked
   up. Deliberately subtle: large rotations blur text on low-DPI screens. */
.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:hover,
.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:focus-visible {
	transform: translateY(-5px) rotate(-1.1deg) scale(1.02);
	box-shadow: 0 14px 30px rgba(0, 0, 0, .38);
}
.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:hover .gzfc-fs-thumb-media,
.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:focus-visible .gzfc-fs-thumb-media { transform: scale(1.06); }

/* Touch devices: hover states can latch after a tap and stay stuck until
   the next tap elsewhere. Transform-based hover styles are neutralised
   there; the border/glow ones are harmless and stay. */
@media (hover: none) {
	.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:hover,
	.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:hover { transform: none; box-shadow: none; }
	.gzfc-feature-slider .gzfc-fs-thumb:hover .gzfc-fs-thumb-media { transform: scale(1); }
}

/* Mobile: trim the lift/tilt distance so cards in a 2-column grid never
   visually collide with their neighbour's shadow. */
@media (max-width: 640px) {
	.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:hover,
	.gzfc-feature-slider[data-hover="lift"] .gzfc-fs-thumb:focus-visible { transform: translateY(-3px); }
	.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:hover,
	.gzfc-feature-slider[data-hover="tilt"] .gzfc-fs-thumb:focus-visible { transform: translateY(-3px) rotate(-.7deg) scale(1.01); }
}

/* =====================================================================
   Feature Slider — Animated Multi-Color Border (Theme Settings > Hero >
   Feature Slider > "Animated Border"). Off by default; only applied when
   template-parts/featured-grid.php adds the .gzfc-fs-anim-border class
   (i.e. "Animated Border" is ON). Scoped strictly to
   ".gzfc-feature-slider.gzfc-fs-anim-border" — this never touches the
   Hero Section, post cards, or any other element on the site.

   How it works: a real, solid "Border Thickness"-wide border is added to
   the slider's own outer frame, then painted with two background layers
   via background-clip — a plain fill in the padding-box (invisible,
   fully covered by the slider's own content) and a rotating conic-
   gradient of the 4 customizable colors in the border-box. Because this
   uses the element's OWN real border/background-clip (not a separate
   masked layer), the ring is drawn natively by the browser on all four
   sides and every corner — continuous and identical thickness everywhere,
   with no fading, gaps, or weak edges on wide/short boxes. It also always
   follows the slider's own rounded corners (--gzfc-fs-radius) automatically,
   whatever layout or size preset is chosen above.

   @property lets the gradient's angle itself animate smoothly (a plain
   transform: rotate() would visibly warp the ring on a wide, non-square
   slider); browsers without @property support simply show the gradient
   static instead of spinning — never broken, never affecting layout.
   ===================================================================== */
@property --gzfc-fs-border-angle {
	syntax: '<angle>';
	inherits: false;
	initial-value: 0deg;
}

.gzfc-feature-slider.gzfc-fs-anim-border {
	--gzfc-fs-border-speed: 6s;
	--gzfc-fs-border-thickness: 3px;
	--gzfc-fs-border-c1: #22c55e;
	--gzfc-fs-border-c2: #eab308;
	--gzfc-fs-border-c3: #3b82f6;
	--gzfc-fs-border-c4: #ef4444;
	border: var(--gzfc-fs-border-thickness) solid transparent;
	background-image:
		linear-gradient(var(--gzf-color-background, #0a0a0c), var(--gzf-color-background, #0a0a0c)),
		conic-gradient(
			from var(--gzfc-fs-border-angle),
			var(--gzfc-fs-border-c1) 0%,
			var(--gzfc-fs-border-c2) 25%,
			var(--gzfc-fs-border-c3) 50%,
			var(--gzfc-fs-border-c4) 75%,
			var(--gzfc-fs-border-c1) 100%
		);
	background-origin: border-box;
	background-clip: padding-box, border-box;
	/* .gzf-hero sets background-size/position from the Hero Section's own
	   image-fit variables. Those are meaningless for these two gradient
	   layers, so they're reset here rather than left to be inherited — it
	   keeps the ring an even thickness on every side. */
	background-size: auto, auto;
	background-position: 0 0, 0 0;
	background-repeat: no-repeat, no-repeat;
	animation: gzfc-fs-border-spin var(--gzfc-fs-border-speed, 6s) linear infinite;
}
@keyframes gzfc-fs-border-spin {
	to { --gzfc-fs-border-angle: 360deg; }
}

/* =====================================================================
   Hero Section — Animated Multi-Color Border (Theme Settings > Hero >
   Hero Section — Animated Border). Off by default; only applied when
   template-parts/hero.php adds the .gzfc-hero-anim-border class (i.e.
   "Animated Border" is ON). Scoped strictly to
   ".gzfc-hero.gzfc-hero-anim-border" — this never touches the Feature
   Slider, post cards, or any other element on the site. The Hero Section
   and the Feature Slider are mutually exclusive (see template-parts/
   hero.php), so this and .gzfc-fs-anim-border above never apply at once.

   How it works: UNLIKE the Feature Slider's border above, this can't use
   the element's own background/background-clip, because the Hero Section
   already paints its own optional background image there (set inline by
   template-parts/hero.php from the "Hero Background Image" setting) —
   reusing that trick here would silently replace the site owner's hero
   image with a plain fill. Instead this draws the ring on a real
   <span class="gzfc-hero-border-ring"> (printed by template-parts/hero.php
   only while the switch is on) that sits on top of the section, sized to
   the full box and then masked so only a "--gzfc-hero-border-thickness"-wide band
   around the edge is visible (the middle is punched out with
   mask-composite, so it never covers the badge/title/buttons or blocks
   clicks on them: pointer-events is off and the cut-out is fully
   transparent). A real element is used instead of ::before/::after
   on purpose: the parent framework's own .gzf-hero rules may already use
   those pseudo-elements, and any leftover property from them (height,
   z-index, blend mode...) would silently distort or hide the ring. It
   automatically follows the Hero Section's own rounded
   corners via border-radius: inherit, so it matches at every breakpoint
   without any extra sizing logic.

   @property lets the gradient's angle itself animate smoothly (a plain
   transform: rotate() would visibly warp the ring on a wide, non-square
   hero); browsers without @property support simply show the gradient
   static instead of spinning — never broken, never affecting layout.
   ===================================================================== */
@property --gzfc-hero-border-angle {
	syntax: '<angle>';
	inherits: false;
	initial-value: 0deg;
}

.gzfc-hero.gzfc-hero-anim-border {
	--gzfc-hero-border-speed: 6s;
	--gzfc-hero-border-thickness: 3px;
	--gzfc-hero-border-c1: #22c55e;
	--gzfc-hero-border-c2: #eab308;
	--gzfc-hero-border-c3: #3b82f6;
	--gzfc-hero-border-c4: #ef4444;
	position: relative; /* the ring below is positioned against this box */
}
.gzfc-hero.gzfc-hero-anim-border > .gzfc-hero-border-ring {
	display: block;
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	width: auto;
	height: auto;
	margin: 0;
	z-index: 5;
	box-sizing: border-box;
	border-radius: inherit;
	padding: var(--gzfc-hero-border-thickness, 3px);
	background: conic-gradient(
		from var(--gzfc-hero-border-angle),
		var(--gzfc-hero-border-c1) 0%,
		var(--gzfc-hero-border-c2) 25%,
		var(--gzfc-hero-border-c3) 50%,
		var(--gzfc-hero-border-c4) 75%,
		var(--gzfc-hero-border-c1) 100%
	);
	-webkit-mask:
		linear-gradient(#fff 0 0) content-box,
		linear-gradient(#fff 0 0);
	-webkit-mask-composite: xor;
	mask:
		linear-gradient(#fff 0 0) content-box,
		linear-gradient(#fff 0 0);
	mask-composite: exclude;
	pointer-events: none;
	opacity: 1;
	animation: gzfc-hero-border-spin var(--gzfc-hero-border-speed, 6s) linear infinite;
}
@keyframes gzfc-hero-border-spin {
	from { --gzfc-hero-border-angle: 0deg; }
	to   { --gzfc-hero-border-angle: 360deg; }
}

/* =====================================================================
   Reduced motion. A visitor who has asked their OS for less animation
   gets the "None / Static" behaviour no matter which Transition Effect
   or Card Hover Effect the site owner picked — the slides still change
   (they'd otherwise lose the content), they just change instantly.

   The transform resets here are deliberately broad: every effect above
   parks its idle and leaving slides on a transform, and with animation
   switched off those slides would simply sit frozen off-screen or at the
   wrong scale rather than animating into place. Forcing transform back
   to none means an inactive slide is hidden by opacity alone, which is
   the one mechanism that needs no motion to work.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
	.gzfc-fs-slide,
	.gzfc-fs-slide.is-active,
	.gzfc-fs-slide.is-leaving,
	.gzfc-fs-slide.is-active:hover,
	.gzfc-fs-thumb,
	.gzfc-fs-thumb:hover,
	.gzfc-fs-thumb:focus-visible,
	.gzfc-fs-thumb-media,
	.gzfc-fs-dot { transition: none !important; animation: none !important; }

	.gzfc-feature-slider .gzfc-fs-slide,
	.gzfc-feature-slider .gzfc-fs-slide.is-active,
	.gzfc-feature-slider .gzfc-fs-slide.is-leaving,
	.gzfc-feature-slider .gzfc-fs-slide.is-active:hover {
		transform: none !important;
		/* The newer effects hide their idle slides with a blur or a
		   clip-path rather than a transform. Those have to be cleared
		   here too, or a slide would sit permanently blurred or clipped
		   once its animation is switched off. */
		filter: none !important;
		clip-path: none !important;
	}
	/* !important, like the transform resets above: the per-effect rules
	   are written as .gzfc-feature-slider[data-effect="..."] .gzfc-fs-slide,
	   which outranks this selector on specificity. Simple Slide and Slide
	   Up in particular keep their idle slides at full opacity (they're
	   hidden by being parked off-stage, not by fading), so without this
	   they would all stack up visible on top of each other the moment
	   their transforms are neutralised. */
	.gzfc-feature-slider .gzfc-fs-slide { opacity: 0 !important; }
	.gzfc-feature-slider .gzfc-fs-slide.is-active { opacity: 1 !important; }
	.gzfc-feature-slider .gzfc-fs-slide.is-leaving { opacity: 0 !important; }

	.gzfc-feature-slider .gzfc-fs-thumb:hover,
	.gzfc-feature-slider .gzfc-fs-thumb:focus-visible { transform: none !important; }
	.gzfc-feature-slider .gzfc-fs-thumb:hover .gzfc-fs-thumb-media,
	.gzfc-feature-slider .gzfc-fs-thumb:focus-visible .gzfc-fs-thumb-media { transform: none !important; }

	.gzfc-feature-slider.gzfc-fs-anim-border { animation: none !important; }
	.gzfc-hero.gzfc-hero-anim-border > .gzfc-hero-border-ring { animation: none !important; }
}

/* =========================================================================
   Header Bar — background & padding (Categories > Header Bar).
   Site-wide on purpose: this targets the shared .gzf-header-bottom wrapper
   printed by BOTH the Classic bar (template-parts/header-bottom.php) and
   the Main/Sub-Category dropdown menu (inc/header-category-menu.php), so
   it works no matter which Category Display Style is active — including
   "Classic", whose own stylesheet (header-cat-bar.css) is intentionally
   not loaded. Defaults are transparent/0px, so nothing visually changes
   until a site owner sets a value in Categories > Header Bar.
   ========================================================================= */
.gzf-header-bottom {
	background: var(--gzfc-header-bar-bg, transparent);
	padding-top: var(--gzfc-header-bar-padding, 0px);
	padding-bottom: var(--gzfc-header-bar-padding, 0px);
}
.gzfc-header-cat-page-item > a {
	display: inline-flex;
	align-items: center;
	gap: 4px;
}

/* =====================================================================
   Feature Slider — Layout: library (additive only).

   Built to match a reference screenshot: a large stage on the left with a
   category badge, title, short excerpt, a small date line and a red
   "Read More" button, plus a tight 2x2 grid of exactly 4 small cards on
   the right — each with its own badge overlaid on the image and a title
   + date sitting on a bottom gradient directly over the picture.

   Scoped strictly to [data-layout="library"], so 'center', 'single',
   'stream' and 'cinematic' above are completely untouched. Transition
   effects, hover effects, size presets, the animated border and Pin/Lock
   all keep working here exactly as they do everywhere else.
   ===================================================================== */

.gzfc-fs-body[data-layout="library"] {
	display: grid;
	grid-template-columns: minmax(0, 1.6fr) minmax(260px, 1.15fr);
	gap: var(--gzfc-fs-gap, 20px);
	align-items: stretch;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-stage {
	grid-column: 1;
	height: min(var(--gzfc-fs-h), 82vh);
}

/* --- Stage extras: date line + Read More button ---------------------- */
.gzfc-fs-body[data-layout="library"] .gzfc-fs-slide-date {
	display: inline-flex; align-items: center; gap: 6px;
	font-size: .78rem; letter-spacing: .03em;
	color: rgba(255,255,255,.75);
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-slide-date::before {
	content: "";
	width: 12px; height: 12px;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
	-webkit-mask-position: center; mask-position: center;
	-webkit-mask-size: contain; mask-size: contain;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M7 2.5v3M17 2.5v3M3.5 9.5h17'/%3E%3Crect x='3.5' y='4.5' width='17' height='16' rx='2'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M7 2.5v3M17 2.5v3M3.5 9.5h17'/%3E%3Crect x='3.5' y='4.5' width='17' height='16' rx='2'/%3E%3C/svg%3E");
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-slide-cta {
	display: inline-flex; align-items: center; gap: 8px;
	align-self: flex-start;
	margin-top: 6px;
	padding: 10px 20px;
	background: var(--gzf-color-primary);
	color: #fff;
	border-radius: 6px;
	font-size: .85rem; font-weight: 700;
	letter-spacing: .01em;
	text-shadow: none;
	transition: filter .25s ease, transform .25s ease;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-slide-cta::before {
	content: "";
	width: 13px; height: 13px;
	background-color: #fff;
	-webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
	-webkit-mask-position: center; mask-position: center;
	-webkit-mask-size: contain; mask-size: contain;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpolygon points='6,3 20,12 6,21'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpolygon points='6,3 20,12 6,21'/%3E%3C/svg%3E");
}
.gzfc-fs-slide:hover .gzfc-fs-body[data-layout="library"] .gzfc-fs-slide-cta,
.gzfc-fs-body[data-layout="library"] .gzfc-fs-slide:hover .gzfc-fs-slide-cta {
	filter: brightness(1.12);
}

/* --- 2x2 grid of 4 small cards ---------------------------------------- */
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid {
	grid-column: 2;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-template-rows: repeat(2, minmax(0, 1fr));
	gap: var(--gzfc-fs-gap, 20px);
	height: min(var(--gzfc-fs-h), 82vh);
}

/* Full-bleed card skin: image fills the card, badge sits on top of it,
   title + date sit on a bottom gradient directly over the picture —
   unlike the other layouts, where the title sits below the image on the
   card's own background. */
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb {
	position: relative;
	min-height: 0;
	justify-content: flex-end;
	border-radius: min(var(--gzfc-fs-radius, 16px), 8px);
	overflow: hidden;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-media {
	position: absolute; inset: 0;
	width: 100%; height: 100%;
	flex: none;
	z-index: 0;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-media::after {
	content: "";
	position: absolute; inset: 0;
	background: linear-gradient(180deg, rgba(6,6,8,0) 30%, rgba(6,6,8,.55) 65%, rgba(6,6,8,.92) 100%);
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-content {
	position: relative;
	z-index: 2;
	margin-top: auto;
	gap: 4px;
	padding: clamp(10px, calc(var(--gzfc-fs-h) * .02), 16px);
	text-shadow: 0 2px 8px rgba(0,0,0,.85);
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-cat {
	position: absolute;
	top: 10px; left: 10px;
	z-index: 2;
	display: inline-block;
	background: var(--gzf-color-primary);
	color: #fff;
	padding: 3px 8px;
	border-radius: 3px;
	font-size: .6rem; font-weight: 800;
	letter-spacing: .07em;
	text-shadow: none;
	max-width: calc(100% - 20px);
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-title {
	color: #fff;
	font-size: calc(var(--gzfc-fs-thumb-title, 1.05rem) * .92);
	-webkit-line-clamp: 1;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-date {
	display: inline-flex; align-items: center; gap: 5px;
	font-size: .68rem;
	color: rgba(255,255,255,.75);
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-date::before {
	content: "";
	width: 10px; height: 10px;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
	-webkit-mask-position: center; mask-position: center;
	-webkit-mask-size: contain; mask-size: contain;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M7 2.5v3M17 2.5v3M3.5 9.5h17'/%3E%3Crect x='3.5' y='4.5' width='17' height='16' rx='2'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M7 2.5v3M17 2.5v3M3.5 9.5h17'/%3E%3Crect x='3.5' y='4.5' width='17' height='16' rx='2'/%3E%3C/svg%3E");
}

/* --- library: badge position fix (all screen sizes) ------------------
   .gzfc-fs-thumb-content is position: relative (so it can sit above the
   image), and the category badge inside it is position: absolute with
   top/left: 10px. An absolute box measures from its NEAREST positioned
   ancestor — which was that text block, not the card — so the badge landed
   on top of the first letters of the title instead of the card's corner.
   Making the text block static hands the badge's containing block back to
   the card (.gzfc-fs-thumb is already position: relative); the image then
   goes one layer down inside an isolated stacking context so the static
   text still paints above it. Same look as the reference design, just
   with the badge where it was always meant to be. ------------------- */
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb {
	isolation: isolate;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-media {
	z-index: -1;
}
.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb-content {
	position: static;
}

/* --- library: TABLET (<= 900px) — stage on top, 2x2 grid stays 2x2 --- */
@media (max-width: 900px) {
	.gzfc-fs-body[data-layout="library"] {
		display: flex; flex-direction: column;
	}
	.gzfc-fs-body[data-layout="library"] .gzfc-fs-stage {
		height: min(var(--gzfc-fs-h-tablet), 72vh);
	}
	.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid {
		height: auto;
	}
	.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid .gzfc-fs-thumb {
		height: var(--gzfc-fs-thumb-h);
	}
}

/* --- library: MOBILE (<= 640px) — 2x2 collapses to a single column --- */
@media (max-width: 640px) {
	.gzfc-fs-body[data-layout="library"] .gzfc-fs-stage {
		height: min(var(--gzfc-fs-h-mobile), 66vh);
	}
	.gzfc-fs-body[data-layout="library"] .gzfc-fs-thumbs--grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ---------------------------------------------------------------------
   Pagination — long page lists (1.21.0)
   With no page limit, a site can have 100-200+ pages. The page list is
   already collapsed with "…", but let it wrap instead of overflowing on
   narrow screens, and keep wrapped rows aligned like the list itself.
   --------------------------------------------------------------------- */
.gzf-pagination ul { flex-wrap: wrap; }
.gzf-pagination[data-align="left"] ul   { justify-content: flex-start; }
.gzf-pagination[data-align="center"] ul { justify-content: center; }
.gzf-pagination[data-align="right"] ul  { justify-content: flex-end; }
@media (max-width: 768px) {
	.gzf-pagination[data-align-mobile="left"] ul   { justify-content: flex-start; }
	.gzf-pagination[data-align-mobile="center"] ul { justify-content: center; }
	.gzf-pagination[data-align-mobile="right"] ul  { justify-content: flex-end; }
}

/* ---------------------------------------------------------------------
   Post / Page content lists — bullets and numbers (1.21.3)
   The parent framework resets ul / ol to list-style: none (and on this
   site that reset wins over normal rules), so lists typed into a Post lost
   their bullets / numbers on the front end while the editor looked fine.
   The declarations below therefore use !important, but ONLY inside the
   narrow scope described here, so nothing else on the site is affected.

   Which lists this touches:
   1. any Gutenberg List block (ul / ol with .wp-block-list) — that class
      is only ever produced by post content, so it works whatever the
      single-post template wraps the content in (Posts, Pages, game posts);
   2. plain <ul> / <ol> with no class (Classic editor content) inside the
      main content column (.gzf-content-area) of single Posts / Pages.
   Never touched: a list that carries its own class (menus, widgets,
   category lists, related posts, comments, contents / download boxes ...)
   and anything inside header, footer, <nav>, <aside>, a widget or the
   pagination — their list-style: none stays exactly as it was.
   padding-inline-start is the logical form of padding-left, so RTL pages
   indent from the correct side automatically.
   --------------------------------------------------------------------- */

/* Indent + vertical spacing */
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) {
	margin: 0 0 1.25em !important;
	padding: 0 !important;
	padding-inline: 1.6em 0 !important;
	list-style-position: outside !important;
}

/* Marker types */
:is(ul.wp-block-list, body.singular:not(.home) .gzf-content-area ul:not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) {
	list-style-type: disc !important;
}
:is(ol.wp-block-list, body.singular:not(.home) .gzf-content-area ol:not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) {
	list-style-type: decimal !important;
}

/* List items. display: list-item is what actually draws the marker, and
   list-style: inherit stops any li-level reset from cancelling it. */
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li {
	display: list-item !important;
	list-style: inherit !important;
	margin: 0 0 .4em !important;
}
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li:last-child {
	margin-bottom: 0 !important;
}

/* Nested lists: ul in ul, ol in ol, ul in ol, ol in ul.
   2nd level ul = circle, 3rd level and deeper ul = square; ol stays decimal. */
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li > :is(ul, ol) {
	margin: .4em 0 0 !important;
	padding-inline: 1.4em 0 !important;
}
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li > ul {
	list-style-type: circle !important;
}
:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li > :is(ul, ol) > li > ul {
	list-style-type: square !important;
}

/* Mobile: slightly tighter indent so long lines keep their width. */
@media (max-width: 600px) {
	:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) {
		padding-inline: 1.4em 0 !important;
	}
	:is(:is(ul, ol).wp-block-list, body.singular:not(.home) .gzf-content-area :is(ul, ol):not([class])):not(header *, footer *, nav *, aside *, .widget *, .gzf-pagination *) > li > :is(ul, ol) {
		padding-inline: 1.2em 0 !important;
	}
}

/* =====================================================================
   Featured Image + Game Information table — side-by-side hero (1.26.3)
   -----------------------------------------------------------------
   gzfc_pair_thumbnail_with_game_info() (inc/game-details-hook.php) wraps
   the single post's Featured Image and SPX Core's Game Information table
   (Publisher, Developer, Release date, Genre, Platform, Version, File
   size) together via WordPress' own `post_thumbnail_html` filter, so this
   works wherever the parent theme prints the_post_thumbnail() without
   needing to touch that parent template. System Requirements is NOT part
   of this — it stays in its own separate section further down the page
   (see inc/game-details-hook.php / spx-core's frontend.php).
   ===================================================================== */
.gzfc-hero-info-wrap {
	display: flex;
	align-items: flex-start;
	gap: 24px;
	margin: 0 0 24px;
}
.gzfc-hero-image {
	flex: 0 0 44%;
	max-width: 44%;
}
.gzfc-hero-image img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 10px;
}
.gzfc-hero-info {
	flex: 1 1 0;
	min-width: 0;
	background: var( --gzf-color-card-bg, var( --gzf-color-surface ) );
	border: 1px solid var( --gzf-color-border );
	border-radius: 10px;
	padding: 4px 18px;
}
.gzfc-hero-info .spx-section { margin: 0; }
.gzfc-hero-info .spx-section-title { margin: 14px 0 4px; padding-bottom: 8px; }
.gzfc-hero-info .spx-meta-table th[scope="row"] { width: 42%; }

/* =====================================================================
   System Requirements / Key Features — heading + bullet styling (1.26.7)
   -----------------------------------------------------------------
   SPX Core (the game-details plugin — see inc/game-details-hook.php)
   wraps every block it renders — Game Information, System Requirements,
   Key Features, Screenshots, Trailer, Stores — in the same reusable
   ".spx-section" / ".spx-section-title" markup. These two rules apply
   everywhere that markup is used, so "System Requirements" and "Key
   Features" both pick it up automatically with no plugin file touched
   and no separate color setting: both simply reuse the theme's existing
   --gzf-color-primary variable — the SAME variable that already colors
   links, category badges and every other accent element on the site. If
   that color is ever changed (Customizer > Colors), this heading line
   and these bullets update automatically along with everything else.

   The border-color is marked !important only so this always wins
   regardless of whether the plugin's own stylesheet happens to load
   before or after this file — nothing else about the heading (its tag,
   font-size elsewhere, spacing) is forced this way. */
.spx-section-title {
	font-weight: 700;
	color: var(--gzf-color-heading, var(--gzf-color-text));
	padding-bottom: 8px;
	border-bottom: 2px solid var(--gzf-color-border);
	border-bottom-color: var(--gzf-color-primary) !important;
}

/* Key Features (and any other plain bulleted list SPX Core renders inside
   a ".spx-section") — colors the bullet marker itself via ::marker, the
   standard CSS way to style a list marker without extra markup or JS.
   This only ever changes marker COLOR: if a particular list already sets
   list-style: none (e.g. an icon/button row for Store links), it stays
   exactly as it was — no marker is added where none existed before. */
.spx-section ul li::marker,
.spx-section ol li::marker {
	color: var(--gzf-color-primary);
	font-weight: 700;
}
.spx-section ul,
.spx-section ol {
	padding-left: 20px;
}
.spx-section ul li,
.spx-section ol li {
	margin: 4px 0;
	line-height: 1.6;
}

/* Tablet: keep side-by-side but let the table take a little more room. */
@media (max-width: 900px) {
	.gzfc-hero-image { flex: 0 0 40%; max-width: 40%; }
}

/* Mobile: stack — image on top, table underneath, both full width. */
@media (max-width: 640px) {
	.gzfc-hero-info-wrap { flex-direction: column; gap: 14px; }
	.gzfc-hero-image, .gzfc-hero-image { flex: 0 0 auto; max-width: 100%; }
}

/* =====================================================================
   Single Post — hide author name from the top meta/byline row.
   gzf_post_meta_row() (parent theme, inc/template-functions.php) is only
   ever called with $show_author = true from single.php's header (the row
   sitting right under the category badge), so this selector only ever
   matches that one element site-wide — never post cards, archives, or
   the comment list, which all use their own separate markup/classes.
   The Author Box itself is turned off via the "Show Author Box"
   Customizer default in inc/customizer-defaults.php; this rule covers
   the one remaining place (the byline) that setting doesn't reach.
   ===================================================================== */
.gzf-single-header .gzf-meta-author {
	display: none !important;
}
