/**
 * Blushwood Area Map
 *
 * An interactive service-area map with a synced city list.
 *
 * Two notes on the approach:
 *
 * 1. Everything that has to line up with the artwork (region shapes, city
 *    names) lives inside the SVG, so it scales with the map instead of being
 *    positioned in pixels. There is no resize script and no aspect-ratio hack.
 *
 * 2. The list and the map are flex items that wrap on their own, so the block
 *    stacks whenever its own width runs short. This is deliberately done with
 *    plain flex wrapping rather than container queries: `container-type`
 *    applies inline-size containment, which makes the block contribute no
 *    intrinsic width, and any content-sized ancestor (an Elementor flex
 *    container, a float, an inline-block) then collapses it to zero.
 */

.bam {
	--bam-text: #000;
	--bam-accent: #c9a6a3;
	--bam-label: #111;
	--bam-label-size: 15;
	--bam-list-size: 18px;
	--bam-gap: clamp(1.5rem, 4%, 3rem);
	--bam-ease: cubic-bezier(0.4, 0, 0.2, 1);

	position: relative;
	width: 100%;
	max-width: 100%;
	box-sizing: border-box;
}

.bam *,
.bam *::before,
.bam *::after {
	box-sizing: border-box;
}

.bam__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bam-gap);
	margin: 0;
	padding: 0;
}

/* ------------------------------------------------------- the list intro */

/*
 * Optional heading block above the city list. Type inherits from the theme so
 * the section matches whatever the site already uses; only rhythm is set here.
 */
.bam__intro {
	margin-bottom: clamp(1.5rem, 4vh, 2.5rem);
}

.bam__eyebrow {
	display: flex;
	align-items: center;
	gap: 1rem;
	margin: 0 0 1.1rem;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.3em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* The hairline that trails the eyebrow, fading out to the right. */
.bam__eyebrow::after {
	content: "";
	flex: 1 1 auto;
	max-width: 190px;
	height: 1px;
	background: linear-gradient( 90deg, currentColor, transparent );
	opacity: 0.45;
}

.bam__heading {
	margin: 0;
	font-size: clamp( 1.9rem, 3.8vw, 3rem );
	font-weight: 500;
	line-height: 1.06;
	letter-spacing: -0.01em;
}

.bam__heading em {
	font-style: italic;
}

.bam__sub {
	max-width: 46ch;
	margin: 1.1rem 0 0;
	font-size: 1.03rem;
	line-height: 1.75;
}

/* -------------------------------------------------------------- the list */

.bam__list {
	flex: 1 1 clamp(240px, 38%, 420px);
	min-width: 0;
}

/*
 * Themes routinely restyle lists, so the resets below are deliberately
 * forceful. Without them a theme's bullet, indent or margin leaks in.
 */
.bam__list-ul {
	display: grid;
	grid-template-columns: repeat(var(--bam-cols, 2), minmax(0, 1fr));
	column-gap: clamp(1rem, 5%, 2.5rem);
	row-gap: 0.35rem;
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
}

.bam--cols-1 .bam__list-ul { --bam-cols: 1; }
.bam--cols-2 .bam__list-ul { --bam-cols: 2; }
.bam--cols-3 .bam__list-ul { --bam-cols: 3; }
.bam--cols-4 .bam__list-ul { --bam-cols: 4; }

.bam__list-li {
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
}

.bam__list-li::before,
.bam__list-li::marker {
	content: none !important;
}

/*
 * Themes and builders style links aggressively, often with selectors like
 * `.elementor a`, so the link rules below are deliberately specific enough to
 * win without resorting to !important on every property.
 */
.bam .bam__list-ul .bam__list-link {
	display: flex;
	align-items: center;
	padding: 0.45rem 0;
	border: 0;
	background: none;
	box-shadow: none;
	color: var(--bam-text);
	font-family: inherit;
	font-size: var(--bam-list-size);
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	text-decoration: none !important;
	transition: color 0.3s var(--bam-ease), transform 0.3s var(--bam-ease);
}

/* Arrow marker, drawn in CSS so there is no image dependency. */
.bam__list-link::before {
	content: "";
	flex: 0 0 auto;
	width: 0;
	height: 0;
	overflow: hidden;
	opacity: 0;
	border-top: 0.42em solid transparent;
	border-bottom: 0.42em solid transparent;
	border-left: 0.62em solid var(--bam-accent);
	transition: width 0.3s var(--bam-ease), opacity 0.3s var(--bam-ease), margin 0.3s var(--bam-ease);
}

.bam .bam__list-ul .bam__list-li.is-active .bam__list-link,
.bam .bam__list-ul .bam__list-link:hover,
.bam .bam__list-ul .bam__list-link:focus,
.bam .bam__list-ul .bam__list-link:focus-visible {
	color: var(--bam-accent);
}

.bam__list-li.is-active .bam__list-link::before,
.bam__list-link:hover::before,
.bam__list-link:focus-visible::before {
	width: 0.62em;
	opacity: 1;
	margin-right: 0.6em;
}

.bam .bam__list-ul .bam__list-link:focus {
	outline: none;
}

.bam .bam__list-ul .bam__list-link:focus-visible {
	outline: 2px solid var(--bam-accent);
	outline-offset: 4px;
}

/* --------------------------------------------------------------- the map */

.bam__map {
	flex: 1 1 clamp(280px, 52%, 720px);
	min-width: 0;
}

/*
 * Icon systems in themes and plugins frequently declare rules as broad as
 * `svg { width: 1em }`. These resets keep the map from being swallowed by one.
 */
.bam__svg {
	display: block;
	width: 100% !important;
	height: auto !important;
	max-width: 100% !important;
	max-height: none !important;
	/*
	 * The base artwork is larger than the cropped viewBox, so the SVG must clip
	 * to its viewport. Without this the full image bleeds out of the block and
	 * over whatever sits beside it.
	 */
	overflow: hidden;
}

.bam__base {
	pointer-events: none;
	-webkit-user-select: none;
	user-select: none;
}

/*
 * The shaded artwork carries the raised, drop-shadowed hover look, so the
 * polygons stay invisible and act purely as hit areas.
 */
.bam__hover-img {
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.35s var(--bam-ease);
}

.bam__hover-img.is-active {
	opacity: 1;
}

.bam__region {
	/* Themes sometimes set text-decoration on every anchor, SVG included. */
	text-decoration: none !important;
	outline: none;
}

.bam__region polygon {
	/*
	 * A fully transparent shape would not receive pointer events, so the fill
	 * stays present but invisible.
	 */
	fill: #fff;
	fill-opacity: 0;
	stroke: var(--bam-accent);
	stroke-width: 0;
	stroke-linejoin: round;
	pointer-events: all;
	cursor: pointer;
	transition: stroke-width 0.3s var(--bam-ease), fill-opacity 0.3s var(--bam-ease);
}

/* Keyboard users have no cursor to follow, so give them a visible ring. */
.bam__region:focus-visible polygon {
	stroke-width: 3;
	fill-opacity: 0.15;
}

/* ------------------------------------------------------------ map labels */

/*
 * Labels are SVG text, so they scale with the artwork at any container width
 * and can never drift off their region.
 */
.bam__svg-label {
	fill: var(--bam-label);
	font-family: inherit;
	font-size: calc(var(--bam-label-size) * 1px);
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	pointer-events: none;
	-webkit-user-select: none;
	user-select: none;
	transition: fill 0.3s var(--bam-ease);
}

.bam__svg-label.is-active {
	fill: var(--bam-label);
}

/* ------------------------------------------------------------ responsive */

/*
 * Stacking needs no query: once the list and the map cannot both fit on one
 * line, flex-wrap drops the map beneath the list. This tracks the width of the
 * block itself, so a narrow column behaves the same as a narrow screen.
 *
 * The rules below only nudge type size on small screens, which is safe to base
 * on the viewport.
 */
@media (max-width: 480px) {
	.bam__list-ul {
		column-gap: 1rem;
	}

	.bam .bam__list-ul .bam__list-link {
		font-size: calc(var(--bam-list-size) * 0.86);
		letter-spacing: 0.03em;
	}
}

/*
 * Touch devices have no hover, so the map would otherwise look inert. A faint
 * permanent tint reads as "tappable".
 */
@media (hover: none) {
	.bam__region polygon {
		fill-opacity: 0.1;
		stroke-width: 1;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bam__list-link,
	.bam__list-link::before,
	.bam__region polygon,
	.bam__hover-img,
	.bam__svg-label {
		transition: none !important;
	}
}

@media (forced-colors: active) {
	.bam__region polygon {
		stroke: CanvasText;
		stroke-width: 1;
	}
}

@media print {
	.bam__hover-img {
		opacity: 0;
	}

	.bam__inner {
		display: block;
	}
}
