/*
 * Elham Virtual Christmas Market — front end.
 *
 * Everything is scoped under .ecm-market so the plugin cannot affect the rest
 * of the site, and nothing in here targets a theme selector.
 *
 * Colours are taken from the printed 2025 leaflet: its cream paper, its deep
 * green ink, its Christmas red and the berries in its garland border.
 *
 * Sizes are in px, never rem, and that is deliberate. Bootstrap — which Elara
 * and a great many other themes bundle — sets `html { font-size: 10px }`, so a
 * rem here would render at 62.5% of its intended size on those sites. px is
 * immune to whatever the host page does to the root.
 */

.ecm-market.ecm-market {
	/* Palette */
	--ecm-green-deep: #0d2e23;
	--ecm-green: #143f31;
	--ecm-green-mid: #1b5241;
	--ecm-leaf: #3f7b3e;
	--ecm-leaf-light: #7fa855;
	--ecm-leaf-dark: #2b5a30;
	--ecm-cream: #f7f0da;
	--ecm-cream-bright: #fdf8e9;
	--ecm-cream-warm: #efe3c2;
	--ecm-red: #b0242b;
	--ecm-red-deep: #8d1a20;
	--ecm-berry: #c9302c;

	/* Type */
	--ecm-font-display: "Playfair Display", "Hoefler Text", Georgia, "Times New Roman", serif;
	--ecm-font-serif: "Cormorant Garamond", "Hoefler Text", Georgia, serif;
	--ecm-font-body: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	/* Rhythm */
	--ecm-pad: clamp(16px, 3.2vw, 44px);
	--ecm-radius: 3px;

	position: relative;
	margin: 0 0 32px;
	font-family: var(--ecm-font-body);
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- reset --
 * A small, deliberately narrow reset: it only neutralises the handful of
 * properties themes commonly set on these elements.
 *
 * The element part is wrapped in :where() so it contributes no specificity.
 * Without that, `.ecm-market p { margin: 0 }` would quietly beat a component
 * rule like `.ecm-card__desc { margin-top: 13px }`, because the element
 * selector makes it the more specific of the two.
 *
 * The root is written three times over, which is not a typo either. It puts
 * the reset at three classes — enough to outrank the `.page .entry-content p`
 * rules themes use, which would otherwise reach in and set margins, fonts and
 * text-transform on the market's own elements. Component rules further down
 * sit at the same weight and win on source order, which is why the reset must
 * stay at the top of this file.
 * ------------------------------------------------------------------------ */

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

.ecm-market.ecm-market.ecm-market :where(h2, h3, p, ul, li, figure) {
	margin: 0;
	padding: 0;
	border: 0;
	text-transform: none;
	letter-spacing: normal;
}

.ecm-market.ecm-market.ecm-market :where(ul) {
	list-style: none;
}

.ecm-market.ecm-market.ecm-market :where(button) {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	margin: 0;
	padding: 0;
	text-align: inherit;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

.ecm-market.ecm-market.ecm-market :where(a) {
	text-decoration: none;
	box-shadow: none;
}

.ecm-market.ecm-market.ecm-market :where(img) {
	display: block;
	max-width: 100%;
	height: auto;
}

.ecm-market.ecm-market [hidden] {
	display: none !important;
}

/* ---------------------------------------------------------------- frame -- */

.ecm-market.ecm-market .ecm-market__frame {
	position: relative;
	overflow: hidden;
	/* No bottom padding: the lower garland sits flush against the edge, the
	   same way the upper one does. */
	padding: 0 var(--ecm-pad);
	border-radius: var(--ecm-radius);
	background:
		/* Corner shadow, so the square feels lit from within. */
		radial-gradient(130% 110% at 50% 44%, rgba(5, 22, 16, 0) 52%, rgba(5, 22, 16, 0.42) 100%),
		/* A soft light over the market floor, so the tables stand in it rather
		   than floating on flat colour. */
		radial-gradient(120% 58% at 50% 62%, rgba(58, 122, 96, 0.5) 0%, rgba(58, 122, 96, 0) 70%),
		radial-gradient(115% 82% at 50% 26%, var(--ecm-green-mid) 0%, var(--ecm-green) 44%, var(--ecm-green-deep) 100%);
	box-shadow:
		inset 0 0 0 1px rgba(247, 240, 218, 0.18),
		0 18px 46px rgba(13, 46, 35, 0.28);
}

/* A faint tooth, so the green reads as cloth rather than flat pixels. */
.ecm-market.ecm-market .ecm-market__frame::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: 0.055;
	mix-blend-mode: overlay;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* -------------------------------------------------------------- garland -- */

.ecm-market.ecm-market .ecm-market__garland-band {
	position: relative;
	height: clamp(46px, 4.6vw, 58px);
	margin: 0 calc(var(--ecm-pad) * -1);
	overflow: hidden;
	pointer-events: none;
}

.ecm-market.ecm-market .ecm-market__garland-band--bottom {
	transform: scaleY(-1);
	margin-top: clamp(26px, 3.4vw, 46px);
}

.ecm-market.ecm-market .ecm-garland {
	display: block;
	width: 100%;
	/* Must not be shorter than the pattern tile, or the tile repeats
	   vertically and a seam appears across the band. */
	height: 62px;
}

/*
 * The greenery takes its colours from the custom properties above, applied as
 * inline styles on the shapes themselves. That is deliberate: the sprigs and
 * trees are drawn with <use>, and CSS rules written here cannot reach inside a
 * <use> shadow tree — but custom properties inherit into it perfectly well.
 * So to recolour the decoration, change --ecm-leaf and friends, not these
 * shapes. See includes/ecm-decorations.php.
 */

/* Sprays tucked into the upper corners of the frame, where the garland ends.
   They sit above the band but below everything the visitor interacts with. */
.ecm-market.ecm-market .ecm-market__corners {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
}

.ecm-market.ecm-market .ecm-deco--spray {
	position: absolute;
	/* Below the garland, hanging into the band of green either side of the
	   centred heading — which is otherwise the emptiest part of the market. */
	top: clamp(38px, 4.4vw, 52px);
	width: clamp(78px, 10vw, 150px);
	height: auto;
	aspect-ratio: 104 / 92;
	filter: drop-shadow(0 4px 6px rgba(9, 32, 24, 0.5));
}

.ecm-market.ecm-market .ecm-deco--spray-tl {
	left: -14px;
}

.ecm-market.ecm-market .ecm-deco--spray-tr {
	right: -14px;
	transform: scaleX(-1);
}

/* There is no room for them beside the heading once it starts wrapping. */
@media (max-width: 780px) {
	.ecm-market.ecm-market .ecm-market__corners {
		display: none;
	}
}

/* --------------------------------------------------------------- header -- */

.ecm-market.ecm-market .ecm-market__header {
	position: relative;
	z-index: 2;
	text-align: center;
	padding: clamp(18px, 3vw, 34px) 0 0;
}

.ecm-market.ecm-market .ecm-market__kicker {
	font-family: var(--ecm-font-serif);
	font-weight: 600;
	font-size: clamp(13.76px, 1.6vw, 17.6px);
	letter-spacing: 0.46em;
	text-indent: 0.46em;
	text-transform: uppercase;
	color: var(--ecm-cream-warm);
	opacity: 0.95;
}

.ecm-market.ecm-market .ecm-market__title {
	font-family: var(--ecm-font-display);
	font-weight: 700;
	font-size: clamp(31.2px, 4.9vw, 53.6px);
	line-height: 1.1;
	letter-spacing: 0.005em;
	color: var(--ecm-cream-bright);
	margin: 0.16em 0 0;
	text-shadow: 0 2px 0 rgba(13, 46, 35, 0.4);
}

.ecm-market.ecm-market .ecm-market__intro {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: clamp(10px, 1.6vw, 18px);
	margin-top: clamp(10px, 1.7vw, 17px);
	font-family: var(--ecm-font-serif);
	font-weight: 600;
	font-size: clamp(12.8px, 1.45vw, 16px);
	letter-spacing: 0.26em;
	text-indent: 0.26em;
	text-transform: uppercase;
	color: var(--ecm-cream);
	opacity: 0.82;
}

.ecm-market.ecm-market .ecm-market__rule {
	display: block;
	width: clamp(26px, 7vw, 74px);
	height: 1px;
	background: linear-gradient(90deg, transparent, var(--ecm-cream-warm));
	opacity: 0.8;
}

.ecm-market.ecm-market .ecm-market__intro .ecm-market__rule:last-child {
	background: linear-gradient(270deg, transparent, var(--ecm-cream-warm));
}

.ecm-market.ecm-market .ecm-market__hint {
	position: relative;
	z-index: 2;
	text-align: center;
	margin: clamp(26px, 3.6vw, 42px) 0 clamp(20px, 2.8vw, 32px);
	font-family: var(--ecm-font-serif);
	font-size: clamp(11.84px, 1.1vw, 13.6px);
	font-weight: 600;
	letter-spacing: 0.24em;
	text-indent: 0.24em;
	text-transform: uppercase;
	color: var(--ecm-cream);
	opacity: 0.6;
}

/* A logo heading replaces the written lockup entirely. */
.ecm-market.ecm-market .ecm-market__title--logo {
	margin: 0;
	line-height: 1;
}

.ecm-market.ecm-market .ecm-market__logo {
	display: block;
	width: auto;
	max-width: clamp(190px, 26vw, 340px);
	max-height: clamp(150px, 22vw, 290px);
	height: auto;
	margin: 0 auto;
	border-radius: 0;
	box-shadow: none;
}

/* A logo saved without transparency gets a cream panel, so it reads as a
   deliberate crest rather than a white rectangle stuck on the green. */
.ecm-market.ecm-market .ecm-market__title--logo.has-panel .ecm-market__logo {
	padding: clamp(10px, 1.4vw, 18px);
	background: var(--ecm-cream);
	border-radius: 4px;
	box-shadow:
		inset 0 0 0 1px rgba(13, 46, 35, 0.16),
		0 10px 26px rgba(9, 32, 24, 0.4);
}

/* --------------------------------------------------------------- ground -- */

.ecm-market.ecm-market .ecm-market__ground {
	position: relative;
	z-index: 1;

	/* On a very wide, full-width page the frame and its garlands still span
	   the whole width, but the market square itself stops growing — otherwise
	   the tables stretch into flat wide bands and lose their character. */
	max-width: 1280px;
	margin: 0 auto;

	/*
	 * The market has to fit the space it is given, not the size of the window.
	 * Dropped into a page with a sidebar it may have only 600px to work with
	 * on a 1400px screen, and a twelve-column square in 600px leaves tables
	 * too narrow to hold a trader's name. The viewport media queries further
	 * down remain as a fallback; the container queries at the end of the file
	 * are what actually decide, wherever the browser supports them.
	 */
	container-type: inline-size;
	container-name: ecm-ground;
}

.ecm-market.ecm-market .ecm-market__trees {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.ecm-market.ecm-market .ecm-deco--tree {
	position: absolute;
	width: clamp(62px, 8vw, 112px);
	height: auto;
	aspect-ratio: 100 / 170;
	opacity: 0.95;
}

.ecm-market.ecm-market .ecm-deco--tree-fl {
	left: -0.5%;
	bottom: -2%;
}

.ecm-market.ecm-market .ecm-deco--tree-fr {
	right: -0.5%;
	bottom: -2%;
	transform: scaleX(-1);
}

/* --------------------------------------------------------------- stalls -- */

.ecm-market.ecm-market .ecm-stalls {
	display: grid;
	grid-template-columns: repeat(var(--ecm-cols, 12), minmax(0, 1fr));
	column-gap: clamp(9px, 1.35vw, 20px);
	row-gap: clamp(17px, 2.5vw, 34px);

	/*
	 * Every table is the same size. grid-auto-rows: 1fr makes all five rows
	 * equal, and stretching the stalls into them makes every table match.
	 *
	 * The alternative — a min-height on the table — let a one-word name like
	 * "Pure Wix" sit shorter than a wrapped one, which looked untidy and moved
	 * the corner sprig with it. Sizing from content rather than a fixed height
	 * means a long trader name can never be clipped.
	 */
	grid-auto-rows: 1fr;
	align-items: stretch;
}

.ecm-market.ecm-market .ecm-stall {
	grid-column: var(--ecm-col) / span var(--ecm-span, 2);
	grid-row: var(--ecm-row);
	position: relative;

	/* Without this a grid item refuses to shrink below its content's minimum
	   width, so one long unbroken word ("Foragers/Nutters") pushed its table
	   wider than every other. */
	min-width: 0;

	/* Sizing a trader's name against the table it sits on, rather than against
	   the window, is the only way it stays right both in a narrow column and
	   on a full-width page. */
	container-type: inline-size;

	/* A single cell, so the table below fills it in both directions. */
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: 1fr;
}

/* ---------------------------------------------------------------- table -- */

.ecm-market.ecm-market .ecm-stall__table {
	--ecm-lift: 0px;
	--ecm-scale: 1;

	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	height: 100%;
	transform: translateY(var(--ecm-lift)) scale(var(--ecm-scale));
	transition: transform 220ms cubic-bezier(0.22, 0.68, 0.3, 1);
	will-change: transform;
}

.ecm-market.ecm-market .ecm-stall__top {
	position: relative;
	display: flex;
	flex: 1;
	align-items: center;
	justify-content: center;

	/*
	 * This width looks redundant — the cream box is the only child of a
	 * column flex container, so the cross-axis stretch should size it — but
	 * WebKit does not stretch a flex item when the flex container is a
	 * <button>. Without it, Safari sized each table to its own trader name:
	 * "Pure Wix" sat on a visibly narrower table than its neighbours, while
	 * empty pitches (whose container is a <span>, not a button) filled their
	 * cells correctly. Chromium stretches it either way, which is why this
	 * only ever showed up on Safari.
	 */
	width: 100%;
	min-height: 5.8em;
	padding: 1.05em 0.8em;
	text-align: center;
	background:
		linear-gradient(174deg, var(--ecm-cream-bright) 0%, var(--ecm-cream) 58%, var(--ecm-cream-warm) 100%);
	border-radius: 2px;
	box-shadow:
		inset 0 0 0 1px rgba(13, 46, 35, 0.15),
		0 10px 20px rgba(9, 32, 24, 0.4);
	transition: box-shadow 220ms ease;
}

/* A printed keyline, the same motif as the trader card. It is what turns a
   cream rectangle into something that reads as a hand-made market sign. */
.ecm-market.ecm-market .ecm-stall__top::before {
	content: "";
	position: absolute;
	inset: 5px;
	border: 1px solid rgba(20, 63, 49, 0.17);
	border-radius: 1px;
	pointer-events: none;
}

/*
 * A little depth across the square: the back wall sits lighter and the front
 * row heavier, as though nearer. Only the shadow changes — every table stays
 * exactly the same size.
 */
.ecm-market.ecm-market .ecm-stall--back .ecm-stall__top {
	box-shadow:
		inset 0 0 0 1px rgba(13, 46, 35, 0.15),
		0 7px 15px rgba(9, 32, 24, 0.34);
}

.ecm-market.ecm-market .ecm-stall--front .ecm-stall__top {
	box-shadow:
		inset 0 0 0 1px rgba(13, 46, 35, 0.15),
		0 13px 26px rgba(9, 32, 24, 0.45);
}

.ecm-market.ecm-market .ecm-stall__name {
	font-family: var(--ecm-font-display);
	font-weight: 700;
	font-size: clamp(12px, 9.5cqw, 17.9px);
	line-height: 1.32;
	color: var(--ecm-red);
	text-wrap: balance;

	/* Not `auto`: hyphenation turned "Fascinating Felt" into "Fascin-ating
	   Felt", which reads worse than simply wrapping between the words. */
	hyphens: manual;
	overflow-wrap: break-word;
}

.ecm-market.ecm-market .ecm-stall.has-long-name .ecm-stall__name {
	font-size: clamp(11px, 8.2cqw, 15.4px);
}

/* Hover, focus and the open stall all lift in the same way, so the
   interaction reads identically however it was triggered. */
.ecm-market.ecm-market .ecm-stall__table:hover,
.ecm-market.ecm-market .ecm-stall__table:focus-visible {
	--ecm-lift: -5px;
	--ecm-scale: 1.035;
	z-index: 3;
}

.ecm-market.ecm-market .ecm-stall__table:hover .ecm-stall__top,
.ecm-market.ecm-market .ecm-stall__table:focus-visible .ecm-stall__top {
	box-shadow:
		inset 0 0 0 1px rgba(176, 36, 43, 0.42),
		0 18px 32px rgba(9, 32, 24, 0.5);
}

.ecm-market.ecm-market .ecm-stall__table:focus-visible {
	outline: 3px solid var(--ecm-cream-bright);
	outline-offset: 4px;
	border-radius: 3px;
}

.ecm-market.ecm-market .ecm-stall__table:active {
	--ecm-lift: -2px;
	--ecm-scale: 1.01;
}

.ecm-market.ecm-market .ecm-stall.is-active {
	z-index: 5;
}

.ecm-market.ecm-market .ecm-stall.is-active .ecm-stall__table {
	--ecm-lift: -6px;
	--ecm-scale: 1.045;
}

.ecm-market.ecm-market .ecm-stall.is-active .ecm-stall__top {
	box-shadow:
		inset 0 0 0 2px var(--ecm-red),
		0 20px 36px rgba(9, 32, 24, 0.55);
}

/* Empty pitches: the ghost of a table, so the market square keeps its shape
   without looking like something failed to load. Never interactive. */
.ecm-market.ecm-market .ecm-stall.is-empty .ecm-stall__table {
	cursor: default;
}

.ecm-market.ecm-market .ecm-stall.is-empty .ecm-stall__top::before {
	display: none;
}

/* An unlet pitch has the same footprint as a table — it is simply quiet. */
.ecm-market.ecm-market .ecm-stall.is-empty .ecm-stall__top {
	background: rgba(247, 240, 218, 0.05);
	box-shadow: inset 0 0 0 1px rgba(247, 240, 218, 0.09);
	border-radius: 2px;
}

.ecm-market.ecm-market .ecm-stall__empty-label {
	font-family: var(--ecm-font-body);
	font-size: 10.88px;
	font-weight: 600;
	color: rgba(247, 240, 218, 0.45);
}

/* ----------------------------------------------------- table decoration -- */

.ecm-market.ecm-market .ecm-deco--corner {
	--ecm-sprig: 30px;

	position: absolute;
	width: var(--ecm-sprig);
	height: auto;
	pointer-events: none;
	filter: drop-shadow(0 2px 3px rgba(9, 32, 24, 0.4));
}

/* Each sprig keeps its own proportions. The viewBoxes are cropped tight to the
   artwork, so a shared aspect ratio would squash one of them — and a loose
   viewBox is what used to leave the holly floating off its corner. */
.ecm-market.ecm-market .ecm-deco--holly {
	aspect-ratio: 34.5 / 39.5;
}

.ecm-market.ecm-market .ecm-deco--fir {
	width: calc(var(--ecm-sprig) * 1.16);
	aspect-ratio: 40 / 33;
}

/*
 * Offsets are a fraction of the sprig rather than fixed pixels, so about a
 * third of it always overhangs the corner however large the sprig, the table
 * or the window is.
 */
.ecm-market.ecm-market .ecm-deco--tl {
	top: calc(var(--ecm-sprig) * -0.3);
	left: calc(var(--ecm-sprig) * -0.24);
	transform: rotate(-14deg);
}

.ecm-market.ecm-market .ecm-deco--tr {
	top: calc(var(--ecm-sprig) * -0.3);
	right: calc(var(--ecm-sprig) * -0.24);
	transform: scaleX(-1) rotate(-14deg);
}

.ecm-market.ecm-market .ecm-deco--bl {
	bottom: calc(var(--ecm-sprig) * -0.28);
	left: calc(var(--ecm-sprig) * -0.26);
	transform: rotate(22deg);
}

/* --------------------------------------------------------------- scrim -- */

.ecm-market.ecm-market .ecm-market__scrim {
	display: none;
}

/* ----------------------------------------------------------------- card -- */

.ecm-market.ecm-market .ecm-card {
	position: absolute;
	z-index: 40;
	width: min(340px, calc(100vw - 28px));
	opacity: 0;
	overflow: visible;
	transform: translateY(6px);
	transition: opacity 170ms ease, transform 170ms ease;
	pointer-events: none;
}

.ecm-market.ecm-market .ecm-card.is-open {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
}

.ecm-market.ecm-market .ecm-card__inner {
	position: relative;
	padding: clamp(18px, 2.2vw, 24px);
	background: linear-gradient(168deg, var(--ecm-cream-bright), var(--ecm-cream) 70%, var(--ecm-cream-warm));
	border-radius: 3px;
	box-shadow:
		inset 0 0 0 1px rgba(13, 46, 35, 0.16),
		0 20px 44px rgba(9, 32, 24, 0.48);

	/* A very tall trader card scrolls inside itself rather than growing past
	   the bottom of the screen. */
	max-height: calc(100vh - 28px);
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* The printed hairline that gives the card its market-sign character. It lives
   on the outer box so it stays put while the contents scroll. */
.ecm-market.ecm-market .ecm-card::before {
	content: "";
	position: absolute;
	z-index: 3;
	inset: 7px;
	border: 1px solid rgba(176, 36, 43, 0.28);
	border-radius: 2px;
	pointer-events: none;
}

/* The little pointer back to the stall. Only drawn once the card has actually
   landed beside it — see .has-no-arrow in market.js. */
.ecm-market.ecm-market .ecm-card::after {
	content: "";
	display: none;
	position: absolute;
	left: var(--ecm-arrow-x, 50%);
	width: 14px;
	height: 14px;
	margin-left: -7px;
	background: var(--ecm-cream-bright);
	transform: rotate(45deg);
	pointer-events: none;
}

.ecm-market.ecm-market .ecm-card.is-below::after,
.ecm-market.ecm-market .ecm-card.is-above::after {
	display: block;
}

.ecm-market.ecm-market .ecm-card.is-below::after {
	top: -7px;
	border-left: 1px solid rgba(13, 46, 35, 0.16);
	border-top: 1px solid rgba(13, 46, 35, 0.16);
}

.ecm-market.ecm-market .ecm-card.is-above::after {
	bottom: -7px;
	background: var(--ecm-cream-warm);
	border-right: 1px solid rgba(13, 46, 35, 0.16);
	border-bottom: 1px solid rgba(13, 46, 35, 0.16);
}

.ecm-market.ecm-market .ecm-card__close {
	position: absolute;
	top: 13px;
	right: 13px;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	color: var(--ecm-green);
	background: rgba(20, 63, 49, 0.07);
	transition: background 160ms ease, color 160ms ease;
}

.ecm-market.ecm-market .ecm-card__close svg {
	width: 17px;
	height: 17px;
}

.ecm-market.ecm-market .ecm-card__close:hover {
	background: var(--ecm-red);
	color: var(--ecm-cream-bright);
}

.ecm-market.ecm-market .ecm-card__close:focus-visible {
	outline: 3px solid var(--ecm-red);
	outline-offset: 2px;
}

.ecm-market.ecm-market .ecm-card__eyebrow {
	font-family: var(--ecm-font-serif);
	font-weight: 600;
	font-size: 12.16px;
	letter-spacing: 0.28em;
	text-indent: 0.28em;
	text-transform: uppercase;
	color: rgba(20, 63, 49, 0.66);
}

.ecm-market.ecm-market .ecm-card__name {
	font-family: var(--ecm-font-display);
	font-weight: 700;
	font-size: clamp(20.8px, 2.2vw, 25.28px);
	line-height: 1.2;
	color: var(--ecm-red);
	margin: 0.1em 35.2px 0 0;
	text-wrap: balance;
}

.ecm-market.ecm-market .ecm-card__images {
	display: grid;
	gap: 8px;
	margin-top: 14px;
}

.ecm-market.ecm-market .ecm-card__images--two {
	grid-template-columns: 1fr 1fr;
}

.ecm-market.ecm-market .ecm-card__figure {
	overflow: hidden;
	border-radius: 2px;
	box-shadow: inset 0 0 0 1px rgba(13, 46, 35, 0.18);
	background: var(--ecm-cream-warm);
}

.ecm-market.ecm-market .ecm-card__image {
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

.ecm-market.ecm-market .ecm-card__images--one .ecm-card__image {
	aspect-ratio: 16 / 9;
}

.ecm-market.ecm-market .ecm-card__desc {
	margin-top: 13px;
	font-size: 15.12px;
	line-height: 1.58;
	color: #21453a;
}

.ecm-market.ecm-market .ecm-card__links {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin-top: 15px;
}

.ecm-market.ecm-market .ecm-card__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 36px;
	padding: 5px 11px;
	font-size: 13.28px;
	font-weight: 700;
	color: var(--ecm-green);
	background: rgba(20, 63, 49, 0.07);
	border-radius: 2px;
	box-shadow: inset 0 0 0 1px rgba(20, 63, 49, 0.16);
	transition: background 150ms ease, color 150ms ease;
}

.ecm-market.ecm-market .ecm-card__link:hover {
	background: var(--ecm-green);
	color: var(--ecm-cream-bright);
}

.ecm-market.ecm-market .ecm-card__link:focus-visible {
	outline: 3px solid var(--ecm-red);
	outline-offset: 2px;
}

.ecm-market.ecm-market .ecm-icon {
	width: 15px;
	height: 15px;
	flex: none;
}

.ecm-market.ecm-market .ecm-card__actions {
	margin-top: 17px;
}

.ecm-market.ecm-market .ecm-card__more {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 46px;
	width: 100%;
	padding: 10px 18px;
	font-family: var(--ecm-font-body);
	font-size: 13.12px;
	font-weight: 700;
	letter-spacing: 0.15em;
	text-indent: 0.15em;
	text-transform: uppercase;
	color: var(--ecm-cream-bright);
	background: linear-gradient(180deg, var(--ecm-red), var(--ecm-red-deep));
	border-radius: 2px;
	box-shadow: 0 5px 14px rgba(141, 26, 32, 0.34);
	transition: filter 150ms ease, transform 150ms ease;
}

.ecm-market.ecm-market .ecm-card__more:hover {
	filter: brightness(1.09);
	transform: translateY(-1px);
}

.ecm-market.ecm-market .ecm-card__more:focus-visible {
	outline: 3px solid var(--ecm-green);
	outline-offset: 3px;
}

.ecm-market.ecm-market .ecm-card__admin-note,
.ecm-market.ecm-market .ecm-market__admin-warning {
	margin-top: 14px;
	padding: 9px 11px;
	font-size: 12.48px;
	line-height: 1.45;
	color: #6b4a10;
	background: #fdf3d6;
	border-left: 3px solid #c9a227;
	border-radius: 2px;
}

.ecm-market.ecm-market .ecm-market__admin-warning {
	margin: 14px 0 0;
	font-size: 13.6px;
}

/* ---------------------------------------------------------- tablet down -- */

@media (max-width: 900px) {

	/* The market composition needs room. Below this the stalls flow in stall
	   order instead, which keeps names readable and targets comfortably large. */
	.ecm-market.ecm-market .ecm-stalls {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		column-gap: 12px;
		row-gap: 16px;
	}

	.ecm-market.ecm-market .ecm-stall {
		grid-column: auto;
		grid-row: auto;
	}

	/* Free pitches are useful on the desktop plan but are only clutter here. */
	.ecm-market.ecm-market .ecm-stall.is-empty {
		display: none;
	}

	.ecm-market.ecm-market .ecm-deco--tree {
		display: none;
	}
}

@media (max-width: 620px) {
	.ecm-market.ecm-market .ecm-stalls {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 10px;
		row-gap: 14px;
	}

	.ecm-market.ecm-market .ecm-stall__name {
		font-size: 15.68px;
	}

	.ecm-market.ecm-market .ecm-stall.has-long-name .ecm-stall__name {
		font-size: 13.76px;
	}

	.ecm-market.ecm-market .ecm-stall__top {
		min-height: 5.4em;
	}

	/* The hint wraps to two lines on a phone; loose tracking makes that look
	   accidental rather than set. */
	.ecm-market.ecm-market .ecm-market__hint {
		letter-spacing: 0.15em;
		text-indent: 0.15em;
		line-height: 1.7;
	}

	.ecm-market.ecm-market .ecm-deco--corner {
		--ecm-sprig: 30px;
	}
}

/* ------------------------------------------------------- card on mobile -- */

@media (max-width: 780px) {
	.ecm-market.ecm-market .ecm-market__scrim {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 998;
		background: rgba(9, 32, 24, 0.62);
		backdrop-filter: blur(2px);
		opacity: 0;
		transition: opacity 180ms ease;
	}

	.ecm-market.ecm-market .ecm-market__scrim.is-open {
		opacity: 1;
	}

	.ecm-market.ecm-market .ecm-card {
		position: fixed;
		z-index: 999;
		top: auto;
		right: 12px;
		bottom: 12px;
		left: 12px;
		width: auto;
		transform: translateY(14px);
	}

	.ecm-market.ecm-market .ecm-card__inner {
		max-height: min(86vh, 620px);
		-webkit-overflow-scrolling: touch;
	}

	.ecm-market.ecm-market .ecm-card.is-open {
		transform: translateY(0);
	}

	/* The pointer only makes sense when the card sits beside its stall. */
	.ecm-market.ecm-market .ecm-card::after {
		display: none;
	}

	.ecm-market.ecm-market .ecm-card__inner {
		padding: 20px 18px 22px;
	}

	.ecm-market.ecm-market .ecm-card__images--two {
		gap: 7px;
	}

	.ecm-market.ecm-market .ecm-card__link {
		min-height: 42px;
		font-size: 13.76px;
		padding: 7px 13px;
	}
}

/* ---------------------------------------------------------- preferences -- */

@media (prefers-reduced-motion: reduce) {
	.ecm-market.ecm-market *,
	.ecm-market.ecm-market *::before,
	.ecm-market.ecm-market *::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
	}

	.ecm-market.ecm-market .ecm-stall__table:hover,
	.ecm-market.ecm-market .ecm-stall__table:focus-visible,
	.ecm-market.ecm-market .ecm-stall.is-active .ecm-stall__table {
		--ecm-scale: 1;
		--ecm-lift: 0px;
	}
}

@media (forced-colors: active) {
	.ecm-market.ecm-market .ecm-stall__top,
	.ecm-market.ecm-market .ecm-card__inner {
		border: 1px solid CanvasText;
	}

	.ecm-market.ecm-market .ecm-stall.is-active .ecm-stall__top {
		border-width: 3px;
	}
}

/* ------------------------------------------------------- theme defence --
 * A plugin has to survive whatever theme it lands in. Everything above is
 * written as `.ecm-market.ecm-market …` — the root class doubled — which is
 * not a typo: it lifts every rule above the two-class-plus-element selectors
 * themes routinely use for content, such as `.page .entry-content a`.
 *
 * The rules below handle the cases specificity alone cannot reach, and each
 * one exists because a real theme was doing this to the market. The only other
 * !important declarations in this file are [hidden] and the reduced-motion
 * overrides, both of which are standard practice.
 * ------------------------------------------------------------------------ */

/*
 * Drop caps. The Elara theme (and it is far from the only one) enlarges and
 * floats the first letter of the first paragraph in the content:
 *
 *   .entry-singular .entry-content p:first-child:first-letter { font-size: 64px; float: left }
 *
 * That turned "Elham" into a giant floating E, and "Stall 14" on a trader card
 * into a giant S. A pseudo-element rule at that specificity cannot be beaten
 * by ordinary means, so it is overruled outright.
 */
.ecm-market.ecm-market :where(p, h2, h3, li, span, a)::first-letter {
	float: none !important;
	font-size: inherit !important;
	font-weight: inherit !important;
	font-family: inherit !important;
	line-height: inherit !important;
	color: inherit !important;
	text-transform: inherit !important;
	letter-spacing: inherit !important;
	margin: 0 !important;
	padding: 0 !important;
	background: none !important;
}

.ecm-market.ecm-market :where(p, h2, h3, li)::first-line {
	font-size: inherit !important;
	font-weight: inherit !important;
	font-family: inherit !important;
	color: inherit !important;
	letter-spacing: inherit !important;
	text-transform: inherit !important;
}

/* Themes very commonly underline and recolour every link inside the content.
   The market's links carry their own colour, so only the decoration and the
   inherited extras need saying again here, at full component weight. */
.ecm-market.ecm-market .ecm-card__link,
.ecm-market.ecm-market .ecm-card__more {
	text-decoration: none;
	box-shadow: none;
	border: 0;
}

/* Likewise list styling, which themes set on `.entry-content ul`. */
.ecm-market.ecm-market .ecm-stalls,
.ecm-market.ecm-market .ecm-card__links {
	list-style: none;
	margin: 0;
	padding: 0;
}

.ecm-market.ecm-market .ecm-stall,
.ecm-market.ecm-market .ecm-card__link-item {
	list-style: none;
	margin: 0;
	padding: 0;
	text-indent: 0;
}

.ecm-market.ecm-market .ecm-card__links {
	margin-top: 15px;
}

/*
 * Text that relied on inheriting its font from the market root. A theme rule
 * written directly at a paragraph — `.page .entry-content p { font-family:
 * Georgia }` — beats an inherited value no matter how specific the ancestor
 * is, so anything carrying words has to name its own family.
 *
 * The same goes for alignment, which themes sometimes justify.
 */
.ecm-market.ecm-market .ecm-card__desc,
.ecm-market.ecm-market .ecm-card__link,
.ecm-market.ecm-market .ecm-card__admin-note,
.ecm-market.ecm-market .ecm-market__admin-warning {
	font-family: var(--ecm-font-body);
	text-align: left;
}

.ecm-market.ecm-market .ecm-market__kicker,
.ecm-market.ecm-market .ecm-market__title,
.ecm-market.ecm-market .ecm-market__hint {
	text-align: center;
}

.ecm-market.ecm-market .ecm-stall__name,
.ecm-market.ecm-market .ecm-stall__empty-label {
	text-align: center;
}

/* Images: themes like to round and shadow everything inside the content. */
.ecm-market.ecm-market .ecm-card__image {
	border-radius: 0;
	box-shadow: none;
}

/* ------------------------------------------------- the space it is given --
 * These restate the arrangement decisions above against the market's own
 * width rather than the window's. They come last, so where container queries
 * are supported they are what counts; the viewport media queries remain the
 * fallback. Thresholds are the media-query ones less the frame padding.
 * ------------------------------------------------------------------------ */

@container ecm-ground (max-width: 820px) {
	.ecm-market.ecm-market .ecm-stalls {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		column-gap: 12px;
		row-gap: 16px;
	}

	.ecm-market.ecm-market .ecm-stall {
		grid-column: auto;
		grid-row: auto;
	}

	.ecm-market.ecm-market .ecm-stall.is-empty {
		display: none;
	}

	.ecm-market.ecm-market .ecm-deco--tree {
		display: none;
	}
}

@container ecm-ground (max-width: 560px) {
	.ecm-market.ecm-market .ecm-stalls {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 10px;
		row-gap: 14px;
	}

	.ecm-market.ecm-market .ecm-deco--corner {
		--ecm-sprig: 30px;
	}
}

/* And the full square when there is room, so a wide market inside a narrow
   window is not left in the three-column flow by the media query above. */
@container ecm-ground (min-width: 821px) {
	.ecm-market.ecm-market .ecm-stalls {
		grid-template-columns: repeat(var(--ecm-cols, 12), minmax(0, 1fr));
		column-gap: clamp(9px, 1.35vw, 20px);
		row-gap: clamp(17px, 2.5vw, 34px);
	}

	.ecm-market.ecm-market .ecm-stall {
		grid-column: var(--ecm-col) / span var(--ecm-span, 2);
		grid-row: var(--ecm-row);
	}

	.ecm-market.ecm-market .ecm-stall.is-empty {
		display: block;
	}
}
