/* Dónde Jugar Listings — Public board + single-listing detail.
 * Mobile-first, low-specificity, class-based. No IDs in selectors.
 * Self-contained: defines the tokens + button + field styles it needs
 * (scoped to .djl-board / .djl-listing-detail) so the page works without
 * dashboard.css or profile.css. */

/* --- Base (tokens live globally in tokens.css, enqueued as djl-tokens) --- */
.djl-board,
.djl-listing-detail {
	color: var(--djl-text);
	background: var(--djl-bg);
	font-family: var(--djl-font-body, inherit);
	line-height: 1.4;
	box-sizing: border-box;
}

.djl-board *,
.djl-board *::before,
.djl-board *::after,
.djl-listing-detail *,
.djl-listing-detail *::before,
.djl-listing-detail *::after {
	box-sizing: inherit;
}

.djl-board {
	display: block;
	padding: 1rem;
	max-width: 1360px;
	margin: 0 auto;
}

/* --- Filter bar ---
 * Compact default view (2026-08-19): search + sort + "Búsqueda avanzada".
 * As of 2026-08-20 that toggle opens the advanced panel below — see
 * .djl-board__advanced further down and the doc comment on
 * render_filters() in class-djl-board.php. As of 2026-08-25, Vendedor moved
 * from that panel into this same compact bar (search / sort / seller / the
 * toggle), leaving condition/min_price/max_price/city in the panel.
 * Sticky: scrolls normally with the page until it hits the top of the
 * viewport, then sticks there (native `position: sticky`, not JS). */
.djl-board__filters {
	display: flex;
	/* Wrap so the advanced panel (flex-basis: 100%, see below) can drop onto
	 * its own row below search/sort/toggle instead of squeezing into them. */
	flex-wrap: wrap;
	align-items: center;
	/* column-gap keeps the confirmed 0.75rem spacing between search/sort/
	 * toggle; row-gap (the space above the advanced panel once it wraps
	 * onto its own line) is intentionally tighter so the open panel stays
	 * within roughly double the closed bar's height (Walter's spec). */
	column-gap: 0.75rem;
	row-gap: 0.4rem;
	/* min-height instead of a fixed height: with the panel closed the bar is
	 * still exactly 60px (Walter's confirmed spec — nothing inside is taller
	 * than that), but it can grow when the advanced panel opens below. */
	min-height: 60px;
	background: var(--djl-card);
	border: 1px solid var(--djl-border);
	/* Square corners on the outer bar (Walter: "ponlo recto en las 4
	 * esquinas") — the 6px rounding on the search/sort pills inside is kept,
	 * only the outer container is squared off. */
	border-radius: 0;
	/* Explicit vertical padding (was `0 1rem`, relying on min-height +
	 * align-items:center to center the 40px row inside 60px — that trick
	 * only works for a single line. Once the advanced panel wraps a second
	 * line below, the container's height is no longer just the 60px
	 * min-height, so there's nothing left to center against and the top
	 * gap visually collapsed to 0). 10px top/bottom + the 40px field height
	 * still equals exactly 60px closed, and now stays constant however many
	 * lines wrap below. */
	padding: 10px 1rem;
	margin-bottom: 1.25rem;
	position: sticky;
	top: 0;
	z-index: 5;
}

.djl-board__search {
	position: relative;
	display: block;
	flex: 1 1 auto;
	min-width: 0;
	/* Opaque on purpose — during the sticky transition the rounded edges of
	 * the bar can show a sliver of whatever's scrolling underneath. */
	background: #fff;
	border-radius: 6px;
}

.djl-board__search-icon {
	position: absolute;
	left: 0.7rem;
	top: 50%;
	transform: translateY(-50%);
	width: 32px;
	height: 32px;
	fill: var(--djl-muted);
	pointer-events: none;
}

/* Scoped as ".djl-board__search .djl-field__input" (2 classes = specificity
 * 0,2,0), same pattern as ".djl-board__sort .djl-field__input" below. The
 * plain single-class ".djl-board__search-input" selector used before had the
 * SAME specificity (0,1,0) as the base ".djl-field__input" rule further down
 * this file — and because that base rule comes later in source order, it was
 * winning the border/background/color cascade every time (equal specificity
 * → last declared wins), which is why the appearance:none fix alone never
 * visibly changed anything: appearance was never being fought over, but
 * border/background/color were. */
.djl-board__search .djl-field__input {
	/* type="search" gets special native OS chrome in WebKit/Blink (its own
	 * background, border, and internal padding) that silently overrides
	 * plain `background`/`border` — resetting appearance strips that native
	 * styling so the rules below actually take effect. */
	-webkit-appearance: none;
	appearance: none;
	/* Explicit height (matches .djl-board__sort .djl-field__input below) —
	 * without it the search <input> and the sort <select> settle at
	 * slightly different natural heights and visibly misalign. */
	height: 40px;
	/* Explicit radius, matching the sort <select> below — type="search"
	 * renders its own smaller native corner radius in some browsers even
	 * with appearance:none, so this has to be stated instead of relying on
	 * the 6px inherited from the base .djl-field__input rule. */
	border-radius: 6px;
	/* Clears the (now 2x) icon: 0.7rem left offset + 32px icon + a bit of
	 * breathing room before the placeholder text starts. */
	padding-left: 3.25rem;
	border: none;
	background: #eef3f6;
	color: #748b9c;
}

/* Placeholder color is a lighter tint than the typed-text color (748B9C)
 * so there's visual contrast between "empty, showing hint" and "has a
 * value" — browsers don't inherit `color` into ::placeholder by default. */
.djl-board__search .djl-field__input::placeholder {
	color: #aec0cd;
	opacity: 1;
}

.djl-board__search .djl-field__input:focus {
	outline: none;
	box-shadow: none;
}

/* .djl-board__seller (Vendedor) shares every rule below with
 * .djl-board__sort — moved into this same compact bar 2026-08-25 (Walter:
 * "la busqueda simple siempre este el Search, Ordenamiento y filtro de
 * Vendedor"), right after Sort. It used to live inside .djl-board__advanced
 * as a .djl-board__field; visually it should look identical to Sort now
 * that it's a peer of it, so the two share one selector list throughout
 * instead of duplicating the block. */
.djl-board__sort,
.djl-board__seller {
	display: block;
	flex: 0 0 auto;
	background: #fff;
	border-radius: 6px;
}

.djl-board__sort .djl-field__input,
.djl-board__seller .djl-field__input {
	width: auto;
	min-width: 190px;
	/* Same explicit height as .djl-board__search .djl-field__input above —
	 * <select> and <input> render at different natural heights otherwise. */
	height: 40px;
	/* Explicit radius, matching the search input above. */
	border-radius: 6px;
	border: none;
	background: #eef3f6;
	color: #748b9c;
	/* Custom chevron (round 7, Walter: "las flechas chevron ... estan muy
	 * chicas deben estar al doble de tamaño y con un padding minimo de 8px
	 * a la derecha") — the native OS arrow can't be resized or given
	 * guaranteed spacing, so appearance:none strips it and this SVG
	 * (20x20, ~double a typical ~10px native glyph) stands in, fixed 8px
	 * from the right edge via background-position. padding-right clears
	 * the icon + a small gap so the selected text never runs under it:
	 * 8px offset + 20px icon + 8px breathing room = 36px = 2.25rem. */
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23748b9c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 8px center;
	background-size: 20px 20px;
	padding-right: 2.25rem;
}

.djl-board__sort .djl-field__input:focus,
.djl-board__seller .djl-field__input:focus {
	outline: none;
	box-shadow: none;
}

.djl-board__advanced-toggle {
	/* Now a <button> (was an inert <a href="#">) so it can carry
	 * aria-expanded correctly — reset the native button chrome so it still
	 * reads as the same plain text link visually. */
	flex: 0 0 auto;
	background: none !important;
	border: none !important;
	/* Same box (padding/height/inline-flex) in BOTH closed and open states —
	 * round 7 fix (2026-08-20), Walter: "algo esta haciendo que crezca el
	 * searchbar al abrirse". Root cause: rounds 2-6 only added padding/
	 * height/display to the [aria-expanded="true"] state, leaving the closed
	 * state's box literally narrower (plain-text, zero padding). Since
	 * .djl-board__search is the only flex-grow item in the row (flex: 1 1
	 * auto) while .djl-board__sort and this toggle are flex: 0 0 auto, any
	 * change in the toggle's own box width forces the search field to
	 * resize to compensate — that resize IS the "growing/shrinking searchbar"
	 * Walter's comparison screenshots caught (the closed-state field
	 * boundaries didn't line up with the open-state ones). Giving the toggle
	 * a constant box regardless of state removes the reflow entirely; only
	 * the background/radius now differ between closed and open (see
	 * [aria-expanded="true"] below), so visually it still reads as plain
	 * text when closed (no visible pill without the background). */
	/* Walter, 29-Ago-2026: "homologar Búsqueda avanzada y Limpiar filtros,
	 * usar el azul de Búsqueda avanzada pero el tamaño de Limpiar filtros"
	 * -- antes esta caja era fija en 40px con padding (round 7, para que
	 * cerrado/abierto no reflowara el buscador de al lado); se achica al
	 * tamaño compacto de .djl-board__advanced-clear (sin padding/altura
	 * forzada) y se mantiene igual en los dos estados, así que la razón
	 * original del round 7 sigue cumplida -- .djl-board__filters ya tiene
	 * align-items:center, así que una caja más chica se centra bien sin
	 * mover al buscador/selects de al lado. */
	gap: 0.3rem;
	display: inline-flex !important;
	align-items: center !important;
	font: inherit;
	cursor: pointer;
	color: var(--djl-link);
	font-size: 0.9rem;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	/* Plain <button> elements get a UA focus ring. Two earlier attempts
	 * (2026-08-20) tried outline:none, then outline+box-shadow:none, and the
	 * pink/red box survived both — meaning it's most likely a `border`
	 * declared by Elementor/hello-elementor's own global button CSS at
	 * matching or higher specificity, printed after ours in <head>, so a
	 * plain (non-!important) `border: none` above loses the cascade. All
	 * three properties are now `!important` here to settle it regardless of
	 * which one it actually turns out to be. */
	outline: none !important;
	box-shadow: none !important;
}

.djl-board__advanced-toggle:hover,
.djl-board__advanced-toggle:focus {
	text-decoration: underline;
	outline: none !important;
	box-shadow: none !important;
	border: none !important;
}

/* Confirmed via Walter's DevTools Computed panel (2026-08-20, round 5): the
 * `box-shadow: none` from round 3 DID win (Computed showed box-shadow:
 * none) — the surviving pink box is a literal `border` (rgb(204,51,102)
 * solid ~0.83px on all four sides), and it was STILL beating the
 * `border: none !important` above. That only happens if Elementor's own
 * rule is also `!important` — among two `!important` declarations,
 * specificity decides, not source order, and a plain one-class selector
 * (0,1,0) loses to whatever multi-class/kit selector Elementor generates.
 * Repeating the class 3x is a specificity-boosting trick (adds to the
 * class count without changing what it matches) so this wins without
 * needing to know Elementor's exact selector. Longhands declared
 * explicitly too, since a shorthand `border` and Elementor's `border-color`
 * etc. are resolved per-longhand-property by the cascade, not as a bundle. */
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle,
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle:hover,
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle:focus {
	border: none !important;
	border-color: transparent !important;
	border-style: none !important;
	border-width: 0 !important;
}

/* Walter, 29-Ago-2026 (2ª pasada): confirmado con DevTools que el color/
 * tamaño de texto de este <button> NO estaba saliendo de las reglas de
 * arriba (`color: var(--djl-link)` / `font-size: 0.9rem`) — el Computed
 * mostraba 16px y #2A91FF (un azul de OTRO token, --djl-vendor-color, o
 * del tema, no --djl-link), mismo tipo de pelea de especificidad que ya
 * resolvimos para el borde arriba. Pide explícitamente "font 14px y azul
 * 2A91FF" para AMBOS botones -- valor fijo, ya no vía var(--djl-link),
 * con el mismo remedio de clase repetida + !important. */
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle,
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle:hover,
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle:focus,
.djl-board__advanced-toggle.djl-board__advanced-toggle.djl-board__advanced-toggle span {
	color: #2A91FF !important;
	font-size: 14px !important;
}

/* Active/open state: same grey as the search/sort fields, as a pill — so
 * the toggle visibly reads as "on" instead of just a text color that's
 * already blue either way (Walter, 2026-08-20 round 2). As of round 7 the
 * box (padding/height/display) is already constant from the base rule
 * above — this only needs to flip the background + radius to turn the
 * plain text into a visible pill, so it can no longer disturb row layout
 * when it toggles. !important kept for the same reason as the block
 * above — an unrelated theme rule was already beating non-!important
 * declarations here once. */
.djl-board__advanced-toggle[aria-expanded="true"] {
	background: #eef3f6 !important;
	border-radius: 6px !important;
}

/* Full label by default (desktop); the short one is swapped in on mobile —
 * see the @media (max-width: 600px) block further down. */
.djl-board__advanced-toggle-short {
	display: none;
}

/* adv-search.svg icon next to "Avanzada" on mobile (2026-08-25 round 3,
 * Walter: "pintarlo del mismo color de la lupa en el search bar") — same
 * color token as .djl-board__search-icon above, kept as a variable
 * reference (not a repeated literal) so both stay in sync if that token
 * ever changes. Sits inline before the text; align-items:center on the
 * short span (mobile media query below) keeps icon and text on one
 * baseline instead of the icon's own SVG baseline looking off. */
.djl-board__advanced-icon {
	fill: var(--djl-muted);
	flex: none;
}

/* --- Advanced search panel ---
 * Condición / Vendedor / Ciudad — wired since the 2026-08-19 compact
 * redesign (read_filters()/build_query_args()), now exposed here behind the
 * "Búsqueda avanzada" toggle. flex-basis: 100% drops it onto its own row
 * under search/sort/toggle inside the same flex-wrap bar; `order` keeps it
 * last regardless of the mobile reordering below.
 *
 * Toggled via the `is-open` class (board.js), not the `hidden` attribute —
 * `hidden` can't be animated (it's a hard display:none), and Walter wants a
 * 300ms collapse instead of the panel snapping shut instantly. `overflow:
 * hidden` + `max-height` transition does the animation; the 240px open
 * cap is a generous ceiling (real content is far shorter, ~54px on desktop
 * where it's a single row) chosen to comfortably fit the mobile stacked
 * layout too without clipping it. */
.djl-board__advanced {
	order: 4;
	flex-basis: 100%;
	overflow: hidden;
	max-height: 0;
	opacity: 0;
	transition: max-height 300ms ease, opacity 200ms ease;
}

.djl-board__advanced.is-open {
	max-height: 240px;
	opacity: 1;
}

/* Padding/border live on the inner wrapper, not on .djl-board__advanced
 * itself — box-sizing: border-box (inherited, see the top of this file)
 * means a max-height:0 on an element with its own padding still renders at
 * least that padding's height, never truly collapsing to 0. Nesting the
 * padding one level in lets the outer element's overflow:hidden clip it
 * away completely while closed. */
.djl-board__advanced-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
	padding: 0.4rem 0;
	border-top: 1px solid var(--djl-border);
}

.djl-board__advanced .djl-field__input {
	background: #eef3f6;
	color: #748b9c;
	border: none;
	height: 40px;
}

/* Chevron only for the <select> fields in this panel (Condición del juego /
 * Ciudad) — split out from the shared rule above (2026-08-25) when Precio
 * Min/Max (plain number <input>s, no dropdown) joined this panel; applying
 * the select-only background-image/padding-right to them too would have
 * drawn a meaningless dropdown arrow on a number field. `select.djl-field__
 * input` (0,2,1) still outranks the shared `.djl-board__advanced
 * .djl-field__input` (0,2,0) above regardless of source order, so this only
 * ever adds to it for <select>, never changes anything for <input>. Same
 * custom chevron as .djl-board__sort .djl-field__input elsewhere in this
 * file — doubled size + 8px minimum right offset (round 7, Walter's spec). */
.djl-board__advanced select.djl-field__input {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23748b9c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 8px center;
	background-size: 20px 20px;
	padding-right: 2.25rem;
}

/* Precio Min/Max (type="number") — plain padding, no chevron reservation. */
.djl-board__advanced input.djl-field__input {
	padding: 0 0.75rem;
}

/* Persistent "$" prefix on Precio Min/Max (2026-08-25 round 2, Walter: "solo
 * tienen el $ en el placeholder ponerlo tambien al escribir") — a "$" can't
 * be typed into type="number" itself (rejected as a non-numeric character),
 * and a placeholder disappears the instant there's a value, so the "$" has
 * to be a separate glyph absolutely positioned over the field, same trick
 * as .djl-board__search-icon above. .djl-board__price is the positioning
 * context; the input's own left padding is widened just enough to clear it
 * (higher specificity than the shared `input.djl-field__input` padding rule
 * above via the extra .djl-board__price-input class, so this always wins
 * regardless of source order). */
.djl-board__price {
	position: relative;
	display: block;
}

.djl-board__price-prefix {
	position: absolute;
	left: 0.75rem;
	top: 50%;
	transform: translateY(-50%);
	color: #748b9c;
	font-size: 0.95rem;
	pointer-events: none;
}

.djl-board__advanced input.djl-field__input.djl-board__price-input {
	width: 100%;
	padding-left: 1.4rem;
}

.djl-board__advanced .djl-field__input:focus {
	outline: none;
	box-shadow: none;
}

/* "Limpiar filtros" — same plain-text-link language as the toggle, plus a
 * refresh icon, sitting right after the last field (Ciudad) on the same
 * row instead of on its own full-width action row. */
.djl-board__advanced-clear {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	flex: 0 0 auto;
	color: var(--djl-link);
	font-size: 0.9rem;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

/* Walter, 29-Ago-2026: "usar el azul de Búsqueda avanzada" -- ambos ya
 * apuntaban al mismo --djl-link, pero este es un <a> (el toggle de al
 * lado es un <button>, no afectado por reglas de color de enlaces del
 * tema) y este archivo ya tiene un historial confirmado de reglas del
 * tema (hello-elementor/Elementor) ganándole al azul local en elementos
 * parecidos -- mismo remedio ya usado arriba para el borde del toggle:
 * repetir la clase sube la especificidad sin cambiar a qué le pega. */
.djl-board__advanced-clear.djl-board__advanced-clear.djl-board__advanced-clear,
.djl-board__advanced-clear.djl-board__advanced-clear.djl-board__advanced-clear:hover,
.djl-board__advanced-clear.djl-board__advanced-clear.djl-board__advanced-clear:focus,
.djl-board__advanced-clear.djl-board__advanced-clear.djl-board__advanced-clear:visited {
	/* Walter, 29-Ago-2026 (2ª pasada): "font 14 px y azul 2A91FF" para
	 * ambos botones -- valor fijo en vez de var(--djl-link) (que resuelve
	 * a #3498DB, un azul distinto), para que coincida exacto con el
	 * toggle de al lado. */
	color: #2A91FF !important;
	font-size: 14px !important;
}

.djl-board__advanced-clear svg {
	fill: currentColor;
	flex: none;
}

.djl-board__advanced-clear:hover,
.djl-board__advanced-clear:focus {
	text-decoration: underline;
}

/* Mobile (2026-08-25 revision, Walter): search takes its own full-width row
 * up top; Sort + Vendedor share the row below it, split evenly (the
 * desktop 190px min-width would force them onto 2 separate lines on a
 * phone, so it's reset to 0 here and each select stretches to fill its
 * half); "Búsqueda avanzada" has no room left on that 2nd line so it wraps
 * to its own 3rd line automatically (flex-wrap, no extra rule needed for
 * that part — margin-left:auto still right-aligns it there). */
@media (max-width: 600px) {
	.djl-board__filters {
		height: auto;
		flex-wrap: wrap;
		padding: 0.6rem 1rem;
		row-gap: 0.5rem;
	}

	.djl-board__search {
		order: 1;
		flex-basis: 100%;
	}

	.djl-board__sort,
	.djl-board__seller {
		order: 2;
		flex: 1 1 0;
		min-width: 0;
	}

	.djl-board__sort .djl-field__input,
	.djl-board__seller .djl-field__input {
		width: 100%;
		min-width: 0;
	}

	.djl-board__advanced-toggle {
		order: 3;
		margin-left: auto;
	}

	/* "Avanzada" + adv-search.svg icon instead of "Búsqueda avanzada"
	 * (2026-08-25 rounds 2-3, Walter) — the toggle now shares its 3rd line
	 * with nothing else so space isn't strictly the issue, but a shorter
	 * label + icon reads faster next to the (N) count on a narrow screen.
	 * inline-flex (not plain inline, round 2's original value) so the icon
	 * and "Avanzada" sit on one row with a small gap and share a baseline
	 * instead of the SVG dropping below the text's baseline like an inline
	 * image would. */
	.djl-board__advanced-toggle-full {
		display: none;
	}

	.djl-board__advanced-toggle-short {
		display: inline-flex;
		align-items: center;
		gap: 0.3rem;
	}
}

/* Condición / Precio Min / Precio Max / Ciudad cell wrapper inside
 * .djl-board__advanced-inner — flex-basis 160px lets the four fields share
 * the row evenly on desktop (Walter: "en una sola linea deben ir" all 4 +
 * Limpiar filtros, 2026-08-25) and wrap naturally on narrow viewports since
 * the inner wrapper is flex-wrap: wrap. Vendedor used to be the 3rd field
 * here too until it moved to the compact bar the same round — the fields
 * left behind still fit one row comfortably at this same sizing. */
.djl-board__field {
	flex: 1 1 160px;
	min-width: 140px;
}

/* Visually-hidden but focusable — keeps the filter form submittable via Enter
   and without JS now that the visible "Filtrar" button is gone. */
.djl-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* --- Field (reused from profile.css conventions) --- */
.djl-field {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}

.djl-field__label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--djl-text);
}

.djl-field__input {
	padding: 0.5rem 0.7rem;
	border: 1px solid var(--djl-border);
	border-radius: 6px;
	background: #fff;
	font-size: 0.95rem;
	color: var(--djl-text);
	font-family: inherit;
	width: 100%;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.djl-field__input:focus {
	outline: none;
	border-color: var(--djl-primary);
	box-shadow: 0 0 0 3px rgba(0, 51, 98, 0.15);
}

/* --- Buttons --- */
/* Button styles (.djl-btn / --primary / --ghost / --whatsapp …) live in the
 * shared assets/css/buttons.css, loaded before this file. */

/* --- Card grid --- */
/* Column counts are admin-editable (Ajustes → Tarjetas → "Columnas de la
 * cuadrícula"); the tablet/mobile counts live in the media queries below. */
.djl-board__grid {
	display: grid;
	grid-template-columns: repeat(var(--djl-cols-desktop), minmax(0, 1fr));
	gap: 1rem;
}

.djl-board__empty {
	padding: 2rem 1rem;
	text-align: center;
	background: var(--djl-card);
	border: 1px dashed var(--djl-border);
	border-radius: 10px;
	color: var(--djl-muted);
	font-size: 0.95rem;
}

/* --- Card --- */
.djl-bcard {
	display: flex;
	flex-direction: column;
	background: var(--djl-card);
	border: 1px solid var(--djl-border);
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	/* Positioning context for the "stretched link" overlay below — makes
	 * the whole card clickable via a single link (2026-08-20, Walter). */
	position: relative;
}

.djl-bcard:hover {
	transform: translateY(-2px);
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.djl-bcard__media {
	display: block;
	position: relative; /* Checkpoint 11: ancla el tag de Condición/Lote sobre la imagen. */
	aspect-ratio: 4 / 3;
	background: #eef1f4;
	overflow: hidden;
}

.djl-bcard__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.djl-bcard__noimg {
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #8a96a3;
	font-size: 0.85rem;
	letter-spacing: 0.02em;
	background: repeating-linear-gradient(
		45deg,
		#eef1f4,
		#eef1f4 8px,
		#e6eaef 8px,
		#e6eaef 16px
	);
}

.djl-bcard__body {
	padding: 0.75rem 0.9rem 0.9rem;
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	flex: 1;
	font-family: var(--djl-font-body, 'Open Sans', system-ui, sans-serif);
}

.djl-bcard__title {
	margin: 0 0 0.25rem;
	font-family: var(--djl-font-title, inherit);
	font-size: var(--djl-card-title-size);
	font-weight: var(--djl-card-title-weight);
	color: var(--djl-text);
	line-height: 1.25;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* Reserve the full 2-line height even when the title only needs one
	 * line, so the Condición tag below lines up across every card in the
	 * row (Walter, 29-Ago-2026). */
	min-height: calc(var(--djl-card-title-size) * 1.25 * 2);
}

.djl-bcard__title a {
	color: inherit;
	text-decoration: none;
}

.djl-bcard__title a:hover,
.djl-bcard__title a:focus {
	text-decoration: none;
}

/* "Stretched link" (2026-08-20, Walter): the title's own link grows an
 * invisible overlay that fills the whole card (via .djl-bcard's
 * position:relative above), so clicking anywhere — image, blank space,
 * price — opens the listing, with only ONE real link per card for
 * accessibility. The vendor link and the "Ver detalles" icon button stay
 * on top of this overlay (see z-index:2 rules below) so they keep working
 * as their own, independent links. */
.djl-bcard__title a::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Condición/Lote como tag sólido sobre la esquina inferior derecha de la
 * imagen de la tarjeta (Checkpoint 11, 31-Ago-2026, Walter) — antes era una
 * pastilla bajo el título; ahora vive dentro de .djl-bcard__media, que ya
 * tiene position:relative. Mismos colores en tablero público e Inventario
 * (ver .djl-card__condition en dashboard.css). */
.djl-bcard__condition {
	position: absolute;
	right: 0.5rem;
	bottom: 0.5rem;
	z-index: 1;
	margin: 0;
	padding: 0.15rem 0.6rem;
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 700;
	line-height: 1.4;
	white-space: nowrap;
	color: #FFF;
	/* Fallback for an empty/unrecognized condition slug. */
	background: var(--djl-muted);
}

.djl-bcard__condition--nuevo {
	background: #25D366;
}

.djl-bcard__condition--semi_nuevo {
	background: #418AFF;
}

.djl-bcard__condition--usado {
	background: #FFAF02;
}

.djl-bcard__condition--lote {
	background: #9848FF;
}

.djl-bcard__meta {
	/* Bottom margin removed 2026-08-20 (Walter): the line-to-line spacing
	 * within the meta block now comes only from the 0.25rem gap on
	 * .djl-bcard__body, so it stays a tight, consistent 4px regardless of
	 * which meta lines are present. (Condición moved to its own
	 * .djl-bcard__condition tag above — this class is only the Vendedor
	 * line now.) */
	margin: 0.1rem 0 0;
	font-size: var(--djl-card-meta-size);
	font-weight: var(--djl-card-meta-weight);
	color: var(--djl-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.djl-bcard__meta--vendor {
	color: var(--djl-vendor-color);
	/* No top margin of its own — relies on the 4px flex gap above for a
	 * tight-but-legible 4px gap under the condition tag (Walter, 2026-08-20). */
	margin-top: 0;
}

/* Sits above the card's stretched-link overlay (z-index:1) so clicking the
 * vendor name still goes to the seller's storefront, not the listing
 * (Walter, 2026-08-20 — explicitly asked to keep this independent). */
.djl-bcard__meta--vendor a {
	position: relative;
	z-index: 2;
}

/* Seller note shown as a one-line description; truncates with an ellipsis.
 * The full text is shown on the single-listing detail (.djl-detail__notes). */
.djl-bcard__note {
	margin: 0.1rem 0;
	font-size: var(--djl-card-meta-size);
	line-height: 1.3;
	/* Reserved even when the seller left no note (render_card() now always
	 * prints this <p>, empty or not) — keeps Vendedor pinned to the same
	 * row above Precio across every card, note or no note (Walter,
	 * 29-Ago-2026: "el link del Vendedor siempre este pegado arriba del
	 * Precio"). */
	min-height: calc(var(--djl-card-meta-size) * 1.3);
	color: var(--djl-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.djl-bcard__note:empty {
	visibility: hidden;
}

/* Price + "Ver detalles" icon button share one row (2026-08-20 redesign):
 * price on the left, icon button pinned to the right edge via
 * space-between; `gap` guarantees breathing room between them even if the
 * price text is unusually long. margin-top:auto keeps this row pinned to
 * the card's bottom edge (unchanged from the old .djl-bcard__price
 * behavior) so cards in the same grid row line up evenly. */
.djl-bcard__pricerow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	margin-top: auto;
	/* Half of the previous 0.4rem (Walter, 2026-08-20). */
	padding-top: 0.2rem;
	/* Checkpoint 17 (6-Sep-2026, Walter): cierra el espacio hacia
	 * .djl-bcard__date de abajo -- probado a mano por Walter en Local,
	 * revierte un intento anterior con align-items:flex-end que encogia
	 * el cuerpo de texto de las tarjetas (causa no confirmada). */
	margin-bottom: -5px;
}

.djl-bcard__price {
	font-size: var(--djl-price-size);
	font-weight: var(--djl-price-weight);
	color: var(--djl-price-color);
}

/* Fecha de publicacion bajo el precio (Checkpoint 17, 6-Sep-2026) -- Walter
 * pidio solo la fecha, sin el prefijo "Publicado el:" que si lleva el
 * detalle (.djl-detail__meta). Tamano fijo en px (no un token --djl-*)
 * porque Walter especifico un valor exacto, no un ajuste configurable. */
.djl-bcard__date {
	/* 0.1rem top margin, misma convencion que .djl-bcard__meta -- el resto
	 * del espaciado ya lo da el gap:0.25rem de .djl-bcard__body, mas el
	 * margin-bottom:-5px de .djl-bcard__pricerow de arriba. */
	margin: 0.1rem 0 0;
	font-family: 'Open Sans', system-ui, sans-serif;
	font-size: 13px;
	color: var(--djl-muted);
}

/* The "Ver detalles" card button (.djl-bcard__btn) is styled in the shared
 * buttons.css so it matches every other outline button. */

/* --- Defeat the theme underline on the card title link --------------------
 * hello-elementor underlines all <a> at specificity 0,1,1, so these two-class
 * selectors (0,2,x) win for every state. Button underlines are handled
 * globally in buttons.css. (.djl-bcard__media stopped being a link
 * 2026-08-20 — the title link's ::after now stretches over the whole card
 * instead, see above.) */
.djl-bcard .djl-bcard__title a,
.djl-bcard .djl-bcard__title a:visited,
.djl-bcard .djl-bcard__title a:hover,
.djl-bcard .djl-bcard__title a:focus {
	text-decoration: none;
}

/* --- Pagination ---
 * Mirrors the shared .djl-btn--small .djl-btn--ghost visual language (same
 * tokens) so the pagination buttons stay in lockstep with the rest of the
 * button system. Update --djl-btn-outline-color / --djl-btn-radius /
 * --djl-btn-border in Ajustes → Dónde Jugar → Botones and the pagination
 * follows. */
.djl-board__pagination {
	margin: 0;
}

/* Bottom copy stands alone (no count next to it), so it owns its own gap
 * above the nav. The top copy's gap is instead owned by
 * .djl-board__pagination-bar--top below, since it sits inside that bar
 * next to the count. */
.djl-board__pagination--bottom {
	margin: 20px 0 0;
}

.djl-board__pagination ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	justify-content: center;
}

.djl-board__pagination li {
	display: inline-block;
}

.djl-board__pagination a,
.djl-board__pagination span {
	display: inline-block;
	padding: 0.3rem 0.6rem;
	font-size: 0.8rem;
	font-weight: 600;
	line-height: 1.2;
	border: var(--djl-btn-border) solid var(--djl-btn-outline-color);
	border-radius: var(--djl-btn-radius);
	background: transparent;
	color: var(--djl-btn-outline-color);
	text-decoration: none;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.djl-board__pagination a:hover,
.djl-board__pagination a:focus {
	background: var(--djl-btn-outline-color);
	color: #fff;
	border-color: var(--djl-btn-outline-color);
}

.djl-board__pagination .current {
	background: var(--djl-btn-outline-color);
	color: #fff;
	border-color: var(--djl-btn-outline-color);
	cursor: default;
}

/* "Ir al inicio" / "Ir al final" — icon-only edge buttons. Same border/hover
 * language as the rest of .djl-board__pagination a (inherited from the
 * shared selector above); this just centers the icon (each direction ships
 * its own SVG from pagination_edge_icon() in PHP). */
.djl-board__pagination-edge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding-left: 0.5rem;
	padding-right: 0.5rem;
}

.djl-board__pagination-edge svg {
	display: block;
	fill: currentColor;
}

/* --- Results count + top pagination bar ---
 * Three-column grid (1fr / auto / empty 1fr) instead of flex: the count
 * sits pinned to the left in column 1, and because column 3 is an empty
 * mirror of column 1's share, the nav in column 2 stays truly centered
 * across the bar — same visual centering as the bottom pagination — no
 * matter how long/short the count text is. (An earlier flex:1 attempt let
 * the nav's own centered <ul> float inside a stretched box, leaving big
 * dead gaps on both sides of the visible buttons — this avoids that.) */
.djl-board__pagination-bar {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 0.75rem;
	margin: 0 0 20px;
}

.djl-board__count {
	grid-column: 1;
	justify-self: start;
	margin: 0;
	font-size: 0.85rem;
}

.djl-board__pagination-bar .djl-board__pagination {
	grid-column: 2;
	margin: 0;
}

/* Only the total is meant to stand out — bold, green, and larger than the
 * rest of the "Mostrando A al B de: N juegos disponibles" line (which is
 * 0.85rem via .djl-board__count above). */
.djl-board__count-total {
	font-size: 1rem;
	font-weight: 700;
	color: var(--djl-price-color);
}

/* Narrow screens: stack the count above the nav instead of squeezing both
 * into a cramped grid row. */
@media (max-width: 600px) {
	.djl-board__pagination-bar {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 0.5rem;
	}
}

/* --- Storefront full-page background (Checkpoint 8, 23-Ago-2026) ---
 * The standalone storefront render (get_header()/get_footer() around
 * .djl-board.djl-storefront) has no page-level background of its own —
 * hello-elementor's <body> is plain white, so only the .djl-board column
 * (max-width 1360px, see .djl-board above) showed gray, leaving the sides on
 * wide viewports (and/or the gap below short content) white. Walter,
 * 23-Ago-2026: "la pagina despliega el fondo mitad gris y el resto en
 * blanco... hacer toda la pagina gris". Fix: DJL_Storefront::add_body_class()
 * appends this class via the body_class filter; setting body's own
 * background-color here covers the WHOLE canvas (not just body's box) per
 * the CSS background-propagation rule, since <html> itself has no background
 * set anywhere in this theme — so this one rule fixes both the side margins
 * and any vertical gap below the content. !important guards against
 * hello-elementor's own body/background rules winning the same-property
 * fight (same pattern already used elsewhere in this file for that theme). */
body.djl-storefront-page {
	background: var(--djl-bg) !important;
}

/* "INICIO" (Checkpoint 8, 23-Ago-2026; 4ª tanda same day): filled/dark like
 * the plugin's other primary actions (.djl-btn--primary — navy
 * var(--djl-primary), same "dark button style" used elsewhere in the
 * system, e.g. Agregar Juego/Guardar).
 *
 * Earlier versions this same day anchored it to the header box itself
 * (absolute, right or left edge) — both broke at intermediate window widths:
 * Walter, 23-Ago-2026: "el boton inicio se esconde a la izquierda cuando el
 * ancho de la ventana no es suficiente para el boton, y el desplegar la
 * casita dentro de la caja del vendedor sugiere que es el inicio de la
 * tienda y no del tablero principal" — plus at that same narrow width the
 * store name's 2nd line was getting covered (that dark sliver bleeding into
 * the title was this very button, no longer fitting beside the header).
 * Walter's own fix, implemented as asked: a `position: fixed` tab pinned to
 * the browser viewport's left edge — independent of the header's box
 * entirely (any width, any promo state), independent of scroll position,
 * and no longer sits inside/near the seller's own card so it can't be
 * misread as "home of THIS store" vs. the main board.
 *
 * No `top` is set on purpose (Walter, same day, DevTools screenshot: with
 * `top:50%` + the translateY(-50%) below disabled, the button already
 * landed exactly where he wants it — asked for both to be removed). Fixed
 * elements with `top:auto` fall back to their normal in-flow ("static")
 * vertical position — here, the top of `.djl-board.djl-storefront`'s own
 * content box (this element is markup's first child, right before
 * `<header>`), which happens to line up with the header's own top edge. */
a.djl-btn.djl-storefront__home-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	position: fixed;
	left: 0;
	z-index: 20;
	white-space: nowrap;
	border-top-left-radius: 0;
	border-bottom-left-radius: 0;
	box-shadow: 2px 0 8px rgba(0, 0, 0, 0.18);
}

.djl-storefront__home-btn svg {
	fill: currentColor;
	flex: 0 0 auto;
}

/* Mobile (Checkpoint 8, 23-Ago-2026): icon-only — the "INICIO" label hides,
 * only the house stays, same fixed left-edge tab as desktop (Walter's ask
 * this round applies to every width, not just the header-relative version
 * from earlier today). */
@media (max-width: 720px) {
	a.djl-btn.djl-storefront__home-btn {
		padding: 0.5rem 0.6rem;
	}

	.djl-storefront__home-btn-label {
		display: none;
	}
}

/* --- Seller storefront header (Checkpoint 5, 21-Agosto-2026) ---
 * 4 columns: avatar | info | promo | flyer. Promo (text + flyer image) is
 * optional per seller (Mi Perfil → switch "Activar promoción"); when a
 * column is absent the header doesn't just leave it blank, it STOPS at the
 * last visible column and narrows — Walter: no empty white space, the page's
 * gray background shows through instead. The three states below scale
 * column-count and width together on purpose: avatar/info always render at
 * the exact same pixel width regardless of state (100%÷4 = 75%÷3 = 50%÷2),
 * so neither ever visibly resizes when a seller turns Promo on/off.
 *
 * Checkpoint 7, 22-Agosto-2026: promo text + flyer now render together
 * inside ONE shared box (.djl-storefront__promo-box), so the promo reads
 * as visually separate from the basic store info (avatar+info), which
 * stays borderless — Walter's mockup. The dashed blue border itself is
 * opt-in per seller (.djl-storefront__promo-box--dashed, "Mostrar línea
 * punteada" in Mi Perfil, 2ª tanda). When both
 * text and flyer are on, the box spans the last 2 grid tracks (still
 * 30fr+30fr worth of width, just merged under one border) and splits them
 * 50/50 internally with flex; when only one of the two is on, the box is
 * simply the 3rd (last) track and shows just that one item. */
.djl-storefront__header {
	display: grid;
	gap: 1.25rem;
	height: 280px;
	margin: 0 0 1.25rem;
	padding: 1.25rem;
	background: var(--djl-card, #fff);
	border: 1px solid var(--djl-border, #e0e6ed);
	border-radius: 10px;
	box-sizing: border-box;
}

/* Column widths, Walter 21-Ago-2026: 11% / 29% / 30% / 30% across the 4
 * columns when all are present. Expressed as fr (not %) so the 1.25rem
 * column gap is subtracted automatically instead of overflowing the row —
 * fr splits only the space left after gaps, % would stack on top of them.
 * Column 1 keeps a 150px floor via minmax() so the avatar itself never
 * gets clipped on a narrower viewport, even though that means col 1 can
 * end up wider than a literal 11% below ~1360px container width. When a
 * column is absent (no flyer / promo off), its share folds into whichever
 * column is now the last one, keeping the same 11%-ish left column. */
.djl-storefront__header--full {
	grid-template-columns: minmax(150px, 11fr) 29fr 30fr 30fr;
	width: 100%;
}

.djl-storefront__header--promo-single {
	grid-template-columns: minmax(150px, 11fr) 29fr 60fr;
	width: 75%;
}

.djl-storefront__header--compact {
	grid-template-columns: minmax(150px, 11fr) 89fr;
	width: 50%;
}

/* Only in the --full state (both text + flyer on) does the box need to span
 * 2 grid tracks — in --promo-single it's already the lone 3rd track. */
.djl-storefront__header--full .djl-storefront__promo-box {
	grid-column: 3 / 5;
}

.djl-storefront__col {
	min-width: 0;
	height: 100%;
	overflow: hidden;
}

.djl-storefront__col--avatar {
	display: flex;
	align-items: flex-start;
	justify-content: center;
}

.djl-storefront__avatar {
	width: 150px;
	height: 150px;
	border-radius: 50%;
	object-fit: cover;
	background: #eef1f4;
	border: 1px solid var(--djl-border, #e0e6ed);
}

.djl-storefront__col--info {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}

.djl-storefront__title {
	margin: 0;
	font-size: 1.75rem;
	font-weight: 700;
	color: #2C3E50;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.djl-storefront__city {
	margin: 0;
	color: #999999;
	font-size: 1rem;
	font-weight: 600;
}

.djl-storefront__count {
	margin: 0;
	font-size: 1.3rem;
	font-weight: 600;
	color: #2C3E50;
}

.djl-storefront__count strong {
	color: #418AFF;
	font-weight: 700;
}

.djl-storefront__shipping {
	margin: 0;
	font-size: 0.82rem;
	color: var(--djl-muted, #5a6b7b);
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

.djl-storefront__whatsapp-icon {
	display: block;
	flex: 0 0 auto;
}

/* Ícono de WhatsApp en el botón "Me Interesa!" del detalle público
 * (individual/lote) — mismo patrón que .djl-storefront__whatsapp-icon de
 * arriba, 24x24 en vez de 32x32 (Walter, 29-Ago-2026). */
.djl-detail__whatsapp-icon {
	display: block;
	flex: 0 0 auto;
}

.djl-storefront__contact {
	margin-top: auto;
	padding-top: 0.5rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

/* Flex-center each button's own content (icon+label, or label alone)
 * instead of the old vertical-align hack — robust regardless of icon
 * size, and keeps "Escríbeme" and "Facebook" the same height (21-Ago-2026
 * fix: the doubled 32px WhatsApp icon broke the vertical-align offset). */
.djl-storefront__contact .djl-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	height: 36px;
	padding-top: 0;
	padding-bottom: 0;
}

/* Green WhatsApp button only (Walter, 29-Ago-2026): tighter horizontal
 * padding and icon-to-label gap so this row stays on one line next to
 * Facebook / Sitio web even when the promo box pushes it to wrap. Facebook
 * / Sitio web keep their normal padding above. */
.djl-storefront__contact .djl-btn--whatsapp {
	padding-left: 6px;
	padding-right: 6px;
	gap: 4px;
}

/* The shared promo+flyer box (Checkpoint 7, 22-Agosto-2026). Padding keeps
 * the text/flyer from touching the border area even when there's no border
 * to show, so turning the dashed line on/off (2ª tanda: "Mostrar línea
 * punteada" switch in Mi Perfil, per-seller and OFF by default) never
 * reflows the box, only reveals/hides the outline. */
.djl-storefront__promo-box {
	display: flex;
	align-items: stretch;
	gap: 1rem;
	overflow: hidden;
	padding: 0.85rem;
	border: 2px solid transparent;
	border-radius: 8px;
	box-sizing: border-box;
}

/* Blue matches .djl-storefront__count strong (the "Juegos disponibles: N"
 * number) instead of --djl-link — Walter, Checkpoint 7, 3ª tanda. */
.djl-storefront__promo-box--dashed {
	border-style: dashed;
	border-color: #418AFF;
}

/* Free text from the seller's own mini editor (assets/js/promo-editor.js) —
 * bold/italic/underline/size/color arrive inline from there, already
 * sanitized server-side (DJL_Ajax::sanitize_promo_html()). line-clamp is a
 * CSS-only safety net for a very tall font size inside the fixed 280px
 * header; the real length guard is the 250-char limit enforced in the
 * editor + on save. */
/* Plain overflow:hidden on a fixed-height box instead of -webkit-box +
 * -webkit-line-clamp (21-Ago-2026 fix): line-clamp's flex-like layout mode
 * doesn't reliably run manual <br> breaks — the seller's own line breaks
 * were rendering correctly in the Mi Perfil editor but collapsing back
 * into one run-on paragraph here on the public storefront (Walter,
 * 21-Ago-2026). Losing the "…" ellipsis-on-overflow is an acceptable
 * trade for correctly honoring the seller's actual line breaks; text that
 * doesn't fit the fixed 280px header still just gets cut off cleanly at
 * the column's own height, same as the original spec ("que se trunque"). */
.djl-storefront__promo-text {
	flex: 1 1 0;
	min-width: 0;
	height: 100%;
	font-size: 0.88rem;
	line-height: 1.4;
	color: var(--djl-text, #2c3e50);
	overflow: hidden;
}

.djl-storefront__promo-box-flyer {
	flex: 1 1 0;
	min-width: 0;
	height: 100%;
}

/* Overrides lightbox.css's `aspect-ratio: 4/3` (2 classes beats 1
 * element+class, wins regardless of stylesheet load order) — the flyer
 * fills the box's full height instead of a fixed ratio. */
.djl-storefront__promo-box-flyer .djl-gallery__main {
	height: 100%;
	aspect-ratio: auto;
}

/* Small screens: stack instead of forcing a 280px-tall grid row. */
@media (max-width: 720px) {
	/* Avatar stays beside the store name (Walter, Checkpoint 7, 4ª tanda)
	 * instead of stacking full-width above it — 2 columns (avatar | info)
	 * on row 1, promo box (if present) spans both on row 2. */
	.djl-storefront__header--full,
	.djl-storefront__header--promo-single,
	.djl-storefront__header--compact {
		grid-template-columns: auto 1fr;
		width: 100%;
		height: auto;
	}

	.djl-storefront__col--avatar {
		grid-column: 1;
		grid-row: 1;
		justify-content: flex-start;
	}

	.djl-storefront__col--info {
		grid-column: 2;
		grid-row: 1;
	}

	/* Half the desktop size (150px → 75px), Walter, Checkpoint 7, 4ª tanda. */
	.djl-storefront__avatar {
		width: 75px;
		height: 75px;
	}

	.djl-storefront__col {
		height: auto;
		overflow: visible;
	}

	/* Stack text above flyer inside the box on mobile instead of side by
	 * side, and span both mobile columns (avatar|info) instead of just
	 * the one it'd auto-place into. */
	.djl-storefront__promo-box {
		grid-column: 1 / -1;
		flex-direction: column;
	}

	/* Same specificity (2 classes) as the desktop --full rule that places
	 * the box at grid-column:3/5 across 4 desktop tracks — this rule wins
	 * the specificity tie by coming later in the file, so on the 2-track
	 * mobile grid the box doesn't try to sit in tracks that don't exist. */
	.djl-storefront__header--full .djl-storefront__promo-box {
		grid-column: 1 / -1;
	}

	/* .djl-storefront__promo-text normally uses flex:1 1 0 to split 50/50
	 * with the flyer in the desktop ROW layout — in this mobile COLUMN
	 * layout that flex-basis:0 collapsed the text to zero height (its own
	 * overflow:hidden disables flexbox's automatic min-height-from-content
	 * safety net), so the promo text disappeared entirely and only the
	 * flyer (which gets its own explicit height below) still showed
	 * (Walter, Checkpoint 7, 4ª tanda: "el texto de la promo desaparece
	 * completamente"). Let it size to its own content instead. */
	.djl-storefront__promo-text {
		flex: 0 0 auto;
		height: auto;
		overflow: visible;
	}

	.djl-storefront__promo-box-flyer,
	.djl-storefront__promo-box-flyer .djl-gallery__main {
		height: 220px;
	}

	/* El flyer usa object-fit:cover (lightbox.css) que por defecto centra
	 * el recorte vertical — en esta altura fija de 220px eso cortaba la
	 * imagen tanto arriba como abajo. Alineado al top: si algo se corta,
	 * se corta por abajo, no por arriba (pedido de Walter, 22-Agosto-2026). */
	.djl-storefront__promo-box-flyer .djl-gallery__main .djl-detail__img {
		object-position: top;
	}
}

/* --- Single-listing detail --- */
.djl-listing-detail {
	display: block;
	max-width: 980px;
	margin: 0 auto;
	padding: 1rem;
}

/* Admin-styled title (size/weight/color/align come from inline style). */
.djl-detail__title {
	margin: 0 0 0.75rem;
	font-family: var(--djl-font-title, inherit);
	line-height: 1.2;
}

.djl-detail__back {
	margin: 0 0 1rem;
	font-size: 0.9rem;
}

.djl-detail__back a {
	color: var(--djl-primary);
	text-decoration: none;
	font-weight: 600;
}

.djl-detail__back a:hover,
.djl-detail__back a:focus {
	text-decoration: underline;
}

.djl-detail__layout {
	display: grid;
	grid-template-columns: minmax(240px, 380px) minmax(0, 1fr);
	gap: 1.5rem;
	align-items: start;
	background: var(--djl-card);
	border: 1px solid var(--djl-border);
	border-radius: 10px;
	padding: 1.25rem;
}

/* Keep the info column from stretching full-width (Walter: "demasiados
   espacios vacíos") — caps line length and pulls the stats/contact in. */
.djl-detail__info {
	max-width: 560px;
}

/* The media column holds the main image AND the thumbnail strip, so it must
   grow with its content — a fixed aspect-ratio + overflow:hidden here clips the
   thumbnails when a tall image is swapped into the main slot. The uniform 4:3
   frame lives on .djl-gallery__main (see lightbox.css) instead. */
.djl-detail__media {
	background: transparent;
	border-radius: 8px;
}

.djl-detail__info {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.djl-detail__price {
	margin: 0;
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--djl-price-color);
}

.djl-detail__meta {
	margin: 0;
	font-size: 0.95rem;
	color: var(--djl-text);
}

/* Jugadores / Duración / Edad (and Complejidad) sit inline on one row; they
   wrap only when the column is too narrow to hold them. */
.djl-detail__stats {
	margin: 0.75rem 0 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
}

/* Lista de juegos incluidos en el detalle público de un Lote — Checkpoint 10. */
.djl-detail__lote-games {
	margin-top: 0.75rem;
}

.djl-lote-games-list {
	list-style: none;
	margin: 0.4rem 0 0;
	padding: 0;
	display: grid;
	gap: 0.5rem;
}

.djl-lote-games-list li {
	position: relative; /* Checkpoint 11: ancla el número de orden en la esquina. */
	padding: 0.5rem 0.65rem;
	border: 1px solid var(--djl-border);
	border-radius: 6px;
	/* Walter, 29-Ago-2026: "las cajas del listado de juegos aparecen en
	 * gris, cambiarlas a blanco con el border gris que ya tiene" -- solo
	 * esta caja cambia; el fondo general de la sección (--djl-bg) se deja
	 * como está a propósito, Walter lo confirmó bien así. */
	background: var(--djl-card);
}

/* Checkpoint 11, Walter (31-Ago-2026): número secuencial en la esquina
 * superior izquierda del recuadro; .djl-lote-games-list__info se recorre
 * 8px a la derecha (padding-left) para no encimarse con él. */
.djl-lote-games-list__num {
	position: absolute;
	top: 0.4rem;
	left: 0.5rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.1rem;
	height: 1.1rem;
	padding: 0 0.15rem;
	border-radius: 999px;
	background: var(--djl-border);
	color: var(--djl-muted);
	font-size: 0.7rem;
	font-weight: 700;
	line-height: 1;
}

.djl-lote-games-list__info {
	display: block;
	/* Walter, 31-Ago-2026: el número se seguía encimando con el título;
	 * +1rem (16px) más de padding izquierdo (8px -> 24px). */
	padding-left: 24px;
}

/* Recuadro a 2 líneas (Checkpoint 11): Línea 1 = Nombre, Línea 2 = Condición
 * (tag) | Precio (bold) | Nota, separados por "|". En móvil las notas
 * pueden saltar a su propia línea por el ancho reducido — no importa
 * (Walter, 31-Ago-2026). */
.djl-lote-games-list__name {
	display: block;
	font-weight: 600;
}

.djl-lote-games-list__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.3rem;
	margin-top: 0.15rem;
	font-size: 0.85rem;
}

.djl-lote-games-list__tag {
	display: inline-block;
	padding: 0.1rem 0.5rem;
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 700;
	line-height: 1.4;
	white-space: nowrap;
	color: #FFF;
	background: var(--djl-muted);
}

.djl-lote-games-list__tag--nuevo {
	background: #25D366;
}

.djl-lote-games-list__tag--semi_nuevo {
	background: #418AFF;
}

.djl-lote-games-list__tag--usado {
	background: #FFAF02;
}

.djl-lote-games-list__price {
	font-weight: 700;
	color: var(--djl-text);
}

.djl-lote-games-list__sep {
	color: var(--djl-muted);
}

.djl-lote-games-list__notes {
	color: var(--djl-muted);
	font-style: italic;
}

.djl-detail__stats > div {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
}

.djl-detail__stats dt {
	font-size: 0.7rem;
	font-weight: 700;
	color: var(--djl-muted);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.djl-detail__stats dd {
	margin: 0;
	font-size: 0.95rem;
	color: var(--djl-text);
}

.djl-detail__notes {
	margin: 0.75rem 0 0;
	font-size: 0.95rem;
	color: var(--djl-text);
}

.djl-detail__contact {
	margin: 1rem 0 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

/* Vertically center each button's own content (icon+label, or label alone)
 * at a shared fixed height — mirrors .djl-storefront__contact .djl-btn
 * below. Without this the WhatsApp button (its icon forces a ~24px flex
 * row) is taller than the plain-text Facebook/Sitio web buttons, and their
 * text sits near the top of the row instead of centered against it
 * (Walter, 29-Ago-2026, captura del modal de detalle). */
.djl-detail__contact .djl-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	height: 36px;
	padding-top: 0;
	padding-bottom: 0;
}

.djl-detail__unavailable {
	margin: 1rem 0 0;
	padding: 0.75rem 1rem;
	background: #fff4ec;
	border: 1px solid #f5cba7;
	border-radius: 6px;
	color: #8a4a16;
	font-size: 0.95rem;
}

/* --- Grid columns: tablet / mobile (counts are admin-editable tokens) --- */
@media (max-width: 1024px) {
	.djl-board__grid {
		grid-template-columns: repeat(var(--djl-cols-tablet), minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.djl-board__grid {
		grid-template-columns: repeat(var(--djl-cols-mobile), minmax(0, 1fr));
		gap: 0.75rem;
	}
}

/* --- Small screens --- */
@media (max-width: 720px) {
	.djl-detail__layout {
		grid-template-columns: 1fr;
		gap: 1rem;
	}

	.djl-detail__media {
		max-width: 320px;
	}
}

/* --- Listing detail modal (2026-08-20) ---
   Card click opens the same render_single_detail() markup inline instead of
   navigating to /juego/<slug>/ (see board.js). Visual language matches the
   existing image lightbox (lightbox.css) — dark overlay, rounded panel, ×
   close button — but on its own z-index band, since a listing's own image
   gallery can open its lightbox (z-index 100000) on top of this panel. */
body.djl-modal-lock {
	overflow: hidden;
}

.djl-modal {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 99000;
	background: rgba(15, 23, 31, 0.6);
	align-items: flex-start;
	justify-content: center;
	padding: 2.5rem 1rem;
	overflow-y: auto;
}

.djl-modal.is-open {
	display: flex;
}

.djl-modal__panel {
	position: relative;
	width: 100%;
	max-width: 900px;
	background: #fff;
	border-radius: 12px;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
	padding: 2rem;
	margin: auto 0;
}

/* Reverted from the tripled-size circle (Walter, 20-Agosto-2026 second
 * screenshot: "así quiero que se vea") — small square with a thin blue
 * border/icon, matching his reference. box-sizing/padding/flex-centering
 * set explicitly because .djl-modal lives outside .djl-board/.djl-listing-
 * detail (appended straight to <body> by board.js), so it never inherits
 * the box-sizing:border-box reset those scopes give everything inside them
 * — without this, the theme's own <button> padding was adding onto the
 * explicit width/height, which is what stretched the tripled version into
 * a lopsided pill instead of a circle. */
.djl-modal__close {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 40px;
	height: 40px;
	padding: 0;
	color: #748B9C;
	background: #FFFFFF;
	border: 1.5px solid #748B9C;
	/* !important: hello-elementor's own button:focus outline (the pink/red
	 * ring Walter kept seeing) otherwise wins over a plain `outline: none` —
	 * see "Reset rosa/outline de hello-elementor" in project memory. */
	outline: none !important;
	border-radius: 6px;
	cursor: pointer;
	z-index: 1;
}

.djl-modal__close svg {
	fill: currentColor;
	display: block;
}

.djl-modal__close:hover {
	background: #748B9C;
	color: #fff;
}

.djl-modal__body {
	min-height: 120px;
}

.djl-modal__loading,
.djl-modal__error {
	text-align: center;
	color: var(--djl-muted, #5a6b7b);
	padding: 2rem 0;
}

/* "Volver a la lista" only makes sense on the standalone detail page — inside
   the modal, the × close button already does that job. */
.djl-modal__body .djl-detail__back {
	display: none;
}

/* Image zoom, in place (2026-08-20, Walter: "no se ve bien" abrir un segundo
 * overlay encima del modal) — swaps into the SAME .djl-modal__panel instead
 * of a second full-screen lightbox. Visibility is toggled purely via the
 * `hidden` attribute (lightbox.js), so no .is-open class is needed here. */
.djl-modal__zoom {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 240px;
}

.djl-modal__zoom-img {
	display: block;
	max-width: 100%;
	max-height: 65vh;
	object-fit: contain;
	border-radius: 6px;
}

/* Prev/next are children of .djl-modal__panel (not .djl-modal__zoom),
 * positioned just inside its edges — same small square button styling
 * fought for on .djl-modal__close (white/748B9C/6px radius/40px), see
 * board.js. (Originally sat OUTSIDE the panel over the dark backdrop, but
 * .djl-modal's `overflow-y: auto` forces its overflow-x to the equivalent of
 * `auto` too per the CSS overflow spec, which was clipping anything
 * positioned past the panel's edge whenever the panel was close to the
 * viewport's own width — Walter, 20-Agosto-2026: "no aparecen". Kept inside
 * the panel avoids relying on that overflow behavior at all.) */
.djl-modal__zoom-nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 40px;
	height: 40px;
	padding: 0;
	color: #748B9C;
	background: #FFFFFF;
	border: 1.5px solid #748B9C;
	outline: none;
	border-radius: 6px;
	cursor: pointer;
	z-index: 2;
}

.djl-modal__zoom-nav svg {
	fill: currentColor;
	display: block;
}

.djl-modal__zoom-nav:hover {
	background: #748B9C;
	color: #fff;
}

.djl-modal__zoom-nav--prev { left: 8px; }
.djl-modal__zoom-nav--next { right: 8px; }

/* Bug (Walter, 20-Agosto-2026): "las flechas estan apareciendo en la ventana
 * de detalle, y solo se deben ver en ZOOM". Root cause: the base rule above
 * sets `display: flex` unconditionally. Author-stylesheet declarations beat
 * the browser's own UA stylesheet regardless of specificity for normal
 * (non-!important) rules, so that class rule was overriding the `hidden`
 * attribute's built-in `display: none` the whole time — the buttons were
 * only ever "hidden" in the accessibility tree, not visually. This puts
 * `display: none` back in charge whenever `hidden` is present. */
.djl-modal__zoom-nav[hidden] {
	display: none !important;
}

@media (max-width: 600px) {
	.djl-modal {
		padding: 0;
	}

	.djl-modal__panel {
		max-width: none;
		min-height: 100%;
		border-radius: 0;
		margin: 0;
	}
}
