/* Ads Placement by HaloWeb — frontend styles. Loaded only when a slot renders. */

.hap-root {
	font-size: 0; /* prevent inline-gap shifts; children reset below */
}

/* ---- in-flow placements (above/below/inside post, manual shortcode) ----
   Live in normal document flow, so they are visible by default with no fixed
   positioning. Centered with sensible vertical rhythm; images stay fluid. */
.hap-inline {
	position: relative; /* anchors the absolutely-filled skeleton */
	display: block;
	box-sizing: border-box;
	margin: 1.5em auto;
	width: var(--hap-w, auto);
	max-width: 100%; /* never wider than the content column */
	min-height: var(--hap-h, 0);
	aspect-ratio: var(--hap-ar, auto); /* reserves height from rendered width = no CLS */
	text-align: center;
}

.hap-inline.hap-empty {
	display: none !important;
}

.hap-inline .hap-body {
	position: relative;
}

.hap-inline .hap-body img {
	display: block;
	max-width: 100%;
	height: auto;
	margin: 0 auto;
}

.hap-slot {
	position: fixed;
	z-index: var(--hap-z, 9999);
	font-size: 1rem;
	box-sizing: border-box;
	display: none; /* hidden until JS reveals — no CLS, out of flow */
}

.hap-slot.hap-visible {
	display: block;
}

.hap-slot.hap-dismissed,
.hap-slot.hap-empty,
.hap-slot[hidden] {
	display: none !important;
}

.hap-body {
	position: relative;
}

.hap-body img {
	display: block;
	max-width: 100%;
	height: auto;
}

/* ---- positions ---- */

.hap-pos-header,
.hap-pos-footer {
	left: 0;
	right: 0;
	width: 100%;
	justify-content: center;
	align-items: center;
	background: #111;
}

.hap-pos-header.hap-visible,
.hap-pos-footer.hap-visible {
	display: flex;
}

.hap-pos-header { top: var(--hap-top, 0px); }
.hap-pos-footer { bottom: 0; }

.hap-pos-left-sidebar,
.hap-pos-right-sidebar {
	top: 50%;
	transform: translateY(-50%);
	width: var(--hap-w, auto);
}
.hap-pos-left-sidebar  { left: 0; }
.hap-pos-right-sidebar { right: 0; }

.hap-pos-left-float,
.hap-pos-right-float {
	top: 50%;
	transform: translateY(-50%);
	width: var(--hap-w, auto);
}
.hap-pos-left-float  { left: 0; }
.hap-pos-right-float { right: 0; }

.hap-pos-corner-bl,
.hap-pos-corner-br {
	bottom: 16px;
	width: var(--hap-w, auto);
	max-width: calc(100vw - 24px);
}
.hap-pos-corner-bl { left: 16px; }
.hap-pos-corner-br { right: 16px; }

/* ---- layer / popup (centered modal) ---- */
.hap-pos-layer {
	inset: 0;
	width: 100%;
	height: 100%;
	/* Let clicks pass through empty areas; backdrop & box opt back in. */
	pointer-events: none;
	align-items: center;
	justify-content: center;
}
.hap-pos-layer.hap-visible {
	display: flex;
}
.hap-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, .6);
	pointer-events: auto;
}
.hap-layer-box {
	position: relative;
	pointer-events: auto;
	width: var(--hap-w, auto);
	max-width: min(95vw, 960px);
	max-height: 90svh;
	overflow: hidden;
}
.hap-layer-box .hap-body { min-height: var(--hap-h, auto); }

/* Layer images scale to fit the box on both axes */
.hap-pos-layer .hap-body img {
	max-width: 100%;
	max-height: 90svh;
	width: auto;
	height: auto;
	display: block;
}

/* explicit dimensions when provided */
.hap-slot {
	width: var(--hap-w, auto);
}
.hap-body {
	min-height: var(--hap-h, auto);
	aspect-ratio: var(--hap-ar, auto);
}

/* ---- CLS loading skeleton ----
   Fills the reserved box behind the ad (z-index 0; the ad content is later in
   the DOM and paints on top). The standalone skeleton script fades + removes it
   once the ad paints. The reserved space above is the real CLS fix — this is the
   visual placeholder that occupies it. */
.hap-skeleton {
	position: absolute;
	inset: 0;
	z-index: 0;
	border-radius: 4px;
	background: #e9eaee; /* neutral light placeholder */
	animation: hap-pulse 1.6s ease-in-out infinite;
	transition: opacity .3s ease;
	pointer-events: none;
}

.hap-skeleton.is-loaded {
	opacity: 0;
}

@media (prefers-color-scheme: dark) {
	.hap-skeleton {
		background: #2a2c31;
	}
}

@keyframes hap-pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: .55; }
}

@media (prefers-reduced-motion: reduce) {
	.hap-skeleton {
		animation: none; /* static neutral block, no pulse */
	}
}

/* ---- close button ---- */

.hap-close {
	position: absolute;
	z-index: 2;
	width: 26px;
	height: 26px;
	line-height: 24px;
	text-align: center;
	border: 0;
	border-radius: 50%;
	background: rgba(0, 0, 0, .65);
	color: #fff;
	font-size: 18px;
	cursor: pointer;
	padding: 0;
}
.hap-close:hover { background: rgba(0, 0, 0, .85); }

/* shape */
.hap-close-square { border-radius: 2px; }

/* color */
.hap-close-light { background: rgba(255, 255, 255, .85); color: #111; }
.hap-close-light:hover { background: rgba(255, 255, 255, 1); }

/* placement — outside (default: -10px protrudes) */
.hap-close-tr { top: -10px; right: -10px; }
.hap-close-tl { top: -10px; left: -10px; }
.hap-close-br { bottom: -10px; right: -10px; }
.hap-close-bl { bottom: -10px; left: -10px; }

/* placement — inside (4px inset) */
.hap-close-inside.hap-close-tr { top: 4px; right: 4px; }
.hap-close-inside.hap-close-tl { top: 4px; left: 4px; }
.hap-close-inside.hap-close-br { bottom: 4px; right: 4px; }
.hap-close-inside.hap-close-bl { bottom: 4px; left: 4px; }

/* bars keep the close button inside the bar */
.hap-pos-header .hap-close,
.hap-pos-footer .hap-close {
	top: 50%;
	transform: translateY(-50%);
	right: 10px;
	left: auto;
	bottom: auto;
}

/* rails: close button inside bounds (overflow:hidden clips anything outside),
   centered at top, small and semi-transparent so it doesn't dominate the ad */
.hap-pos-left-sidebar .hap-close,
.hap-pos-right-sidebar .hap-close,
.hap-pos-left-float .hap-close,
.hap-pos-right-float .hap-close {
	top: 6px;
	left: 50%;
	right: auto;
	bottom: auto;
	transform: translateX(-50%);
	width: 20px;
	height: 20px;
	line-height: 18px;
	font-size: 13px;
	opacity: .45;
	background: rgba(0, 0, 0, .5);
}
.hap-pos-left-sidebar .hap-close:hover,
.hap-pos-right-sidebar .hap-close:hover,
.hap-pos-left-float .hap-close:hover,
.hap-pos-right-float .hap-close:hover {
	opacity: 1;
	background: rgba(0, 0, 0, .85);
}

/* ---- animations (CSS-only) ---- */

.hap-anim-fade.hap-visible {
	animation: hap-fade .35s ease both;
}
.hap-anim-slide.hap-pos-footer.hap-visible,
.hap-anim-slide.hap-pos-corner-bl.hap-visible,
.hap-anim-slide.hap-pos-corner-br.hap-visible {
	animation: hap-slide-up .4s ease both;
}
.hap-anim-slide.hap-pos-header.hap-visible {
	animation: hap-slide-down .4s ease both;
}
.hap-anim-slide.hap-pos-left-sidebar.hap-visible,
.hap-anim-slide.hap-pos-left-float.hap-visible {
	animation: hap-slide-right .4s ease both;
}
.hap-anim-slide.hap-pos-right-sidebar.hap-visible,
.hap-anim-slide.hap-pos-right-float.hap-visible {
	animation: hap-slide-left .4s ease both;
}

/* layer "slide" = zoom-in on the box */
.hap-anim-slide.hap-pos-layer.hap-visible .hap-layer-box {
	animation: hap-zoom .35s ease both;
}

@keyframes hap-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes hap-zoom { from { opacity: 0; transform: scale(.92); } }
@keyframes hap-slide-up   { from { opacity: 0; transform: translateY(100%); } }
@keyframes hap-slide-down { from { opacity: 0; transform: translateY(-100%); } }
@keyframes hap-slide-left  { from { opacity: 0; transform: translate(100%, -50%); } }
@keyframes hap-slide-right { from { opacity: 0; transform: translate(-100%, -50%); } }

/* sidebars/floats are vertically centered — keep their transform after anim */
.hap-pos-left-sidebar.hap-visible,
.hap-pos-right-sidebar.hap-visible,
.hap-pos-left-float.hap-visible,
.hap-pos-right-float.hap-visible {
	transform: translateY(-50%);
}

@media (prefers-reduced-motion: reduce) {
	.hap-slot.hap-visible {
		animation: none !important;
	}
}

/* ---- device confirmation (CSS layer; JS also removes) ---- */
@media (min-width: 782px) {
	.hap-device-mobile { display: none !important; }
}
@media (max-width: 781px) {
	.hap-device-desktop { display: none !important; }
	/* Always hide side rails on mobile — no gutter available regardless of laptop-width setting. */
	.hap-pos-left-sidebar,
	.hap-pos-right-sidebar,
	.hap-pos-left-float,
	.hap-pos-right-float {
		display: none !important;
	}
}

/* ---- responsive side rails (sidebars + floating windows) ----
   Side rails live in the gutter beside the content column. They scale down
   to the gutter that's actually available and hide when there's no room, so
   they never overlap the article. Tune --hap-content-max to your theme's
   content width and --hap-rail-gap for breathing room. */
.hap-root {
	--hap-content-max: 1200px; /* site content column width */
	--hap-rail-gap: 16px;      /* gap between rail and content */
}

.hap-pos-left-sidebar,
.hap-pos-right-sidebar,
.hap-pos-left-float,
.hap-pos-right-float {
	/* One-side gutter = (viewport − content) / 2 − gap. Never wider than the
	   configured size, never wider than the gutter, never negative. */
	width: min(
		var(--hap-w, 160px),
		max(0px, calc((100vw - var(--hap-content-max)) / 2 - var(--hap-rail-gap)))
	);
	max-height: calc(100svh - 24px);
	overflow: hidden;
}

/* Creative scales with the rail; aspect ratio preserved. */
.hap-pos-left-sidebar img,
.hap-pos-right-sidebar img,
.hap-pos-left-float img,
.hap-pos-right-float img {
	width: 100%;
	height: auto;
}

/* Narrow viewport: hide side rails unless an explicit laptop width is configured. */
@media (max-width: 1279px) {
	.hap-pos-left-sidebar:not(.hap-has-laptop-width),
	.hap-pos-right-sidebar:not(.hap-has-laptop-width),
	.hap-pos-left-float:not(.hap-has-laptop-width),
	.hap-pos-right-float:not(.hap-has-laptop-width) {
		display: none !important;
	}
}

/* Laptop / narrow-desktop (782–1279 px): show rails with --hap-w-laptop.
   Gutter formula still applies — they shrink with the viewport and collapse
   to zero before they can overlap the content column. */
@media (min-width: 782px) and (max-width: 1279px) {
	.hap-pos-left-sidebar.hap-has-laptop-width,
	.hap-pos-right-sidebar.hap-has-laptop-width,
	.hap-pos-left-float.hap-has-laptop-width,
	.hap-pos-right-float.hap-has-laptop-width {
		width: min(
			var(--hap-w-laptop, var(--hap-w, 120px)),
			max(0px, calc((100vw - var(--hap-content-max)) / 2 - var(--hap-rail-gap)))
		);
	}
}
