/*
 * Default Event Card styling (Increment 10, layout completed in
 * Increment 11). Deliberately unopinionated on brand visuals — see
 * CLAUDE.md §3, "Client-specific visual identity" is out of this
 * plugin's scope. Inherits typography/color from Elementor Global
 * Fonts/Colors when active, with plain fallbacks otherwise (CLAUDE.md
 * §5). Not a grid/columns layout — see the Increment 10 specification,
 * "not yet a formal Event Grid component."
 *
 * Event Description (Decision 020): rendered HTML is sanitized with
 * wp_kses_post() after block expansion, which strips any inline `style`
 * a block's color/spacing "block supports" may have emitted. This is
 * intentional, not a bug — descriptions inherit this stylesheet's
 * typography/color entirely, via .jdx-events-card-description below,
 * rather than preserving arbitrary per-block colors, backgrounds, or
 * spacing that could break card consistency, accessibility,
 * responsiveness, or Elementor integration.
 */

:root {
	--jdx-events-font-primary: var(--e-global-typography-primary-font-family, inherit);
	--jdx-events-font-secondary: var(--e-global-typography-secondary-font-family, inherit);
	--jdx-events-color-primary: var(--e-global-color-primary, currentColor);
	--jdx-events-color-secondary: var(--e-global-color-secondary, currentColor);
	--jdx-events-color-text: var(--e-global-color-text, currentColor);
	--jdx-events-color-accent: var(--e-global-color-accent, currentColor);

	/* Structural UI, not a semantic status (Increment 11) — deliberately
	 * NOT chained through an --e-global-color-* Elementor fallback like
	 * the four variables above: this always resolves to a concrete
	 * value, so it can never collapse into a colliding currentColor
	 * fallback the way the Increment 10 CTA/badge defect did. Provisional
	 * literal values — confirm with a measured WCAG contrast check
	 * during release validation, not visual inspection alone. */
	--jdx-events-room-badge-bg: #c9a227;
	--jdx-events-room-badge-text: #1a1a1a;

	/* CTA system (Increment 3A.1). Primary/secondary fill tokens chain
	 * through the same --e-global-color-* Elementor slots the badge/CTA
	 * fallback below already used, with concrete literal fallbacks —
	 * never the collision-prone --jdx-events-color-* chain (see the badge
	 * comment above for why). Hover and border values are deterministic
	 * literals by design, not derived via color-mix()/opacity/filter. */
	--jdx-events-cta-primary-bg: var(--e-global-color-accent, #1a1a1a);
	--jdx-events-cta-primary-fg: var(--e-global-color-primary, #ffffff);
	--jdx-events-cta-primary-bg-hover: #0d0d0d;

	--jdx-events-cta-secondary-bg: var(--e-global-color-primary, #ffffff);
	--jdx-events-cta-secondary-fg: var(--e-global-color-text, #1a1a1a);
	--jdx-events-cta-secondary-bg-hover: #e6e6e6;
	--jdx-events-cta-secondary-border: #1a1a1a;

	--jdx-events-cta-min-height: 44px;

	/* Two-layer focus ring: a light inner ring immediately outside the
	 * element, a dark outer ring just beyond it. One of the two always
	 * contrasts against the surrounding surface, whichever it turns out
	 * to be — neither ring depends on the focused element's own fill. */
	--jdx-events-focus-ring-outline: #1a1a1a;
	--jdx-events-focus-ring-shadow: #ffffff;

	/* Card border (Increment 3A.2). Structural UI, not a semantic status —
	 * same rationale as the room-badge tokens above: a deterministic solid
	 * literal, not chained through an --e-global-color-* Elementor slot or
	 * currentColor, so it renders identically and predictably across
	 * transparent, dark, and configured --jdx-events-card-bg surfaces. */
	--jdx-events-card-border-color: #4a4a4a;

	/* Cancelled/Postponed badge colors (Increment 3B.1, Decision 021).
	 * Deterministic literals, not chained through --e-global-color-*
	 * Elementor slots — same rationale as the room-badge tokens above,
	 * stronger here: a CANCELLED/POSTPONED notice must render reliably
	 * regardless of whatever a theme's Elementor global colors resolve
	 * to, never collapse into an invisible currentColor fallback. Sold
	 * Out deliberately has no equivalent token — it keeps inheriting
	 * .jdx-events-card-badge's existing Elementor-chained accent/primary
	 * colors, unchanged, per Decision 021's "do not redesign Sold Out". */
	--jdx-events-badge-cancelled-bg: #b30000;
	--jdx-events-badge-postponed-bg: #9a6400;
	--jdx-events-badge-status-text: #ffffff;
}

.jdx-events-card-list {
	display: flex;
	flex-direction: column;
	gap: 1.5em;
}

/* Grid arrangement (Phase 3C): an additional modifier class alongside
 * .jdx-events-card-list, not a replacement — gap:1.5em above is
 * inherited as-is (grid and flex both support the gap property), so
 * list and grid share identical spacing without repeating the value.
 * display:grid here overrides display:flex/flex-direction above at
 * equal specificity by source order; grid-template-columns is the only
 * property that actually needs to vary by breakpoint. Base/default
 * column count (4+ events, at the widest tier) per the approved
 * reference designs (Sakura/Treibhaus event grids): 4 columns
 * >=1400px, 3 columns 1000-1399px, 2 columns 650-999px, 1 column below
 * 650px — same desktop-first max-width pattern already used elsewhere
 * in this file (see .jdx-events-card-content's 480px breakpoint above).
 * 1-3 events get a narrower column count instead of leaving the extra
 * tracks empty — see the count-modifier rules and their cascade-order
 * comment below. .jdx-events-card's own max-width:640px (Increment 11)
 * is deliberately left untouched here — it was designed to go inert
 * inside a narrower grid cell rather than fight a grid-level
 * constraint; confirm via live validation, not assumed. */
.jdx-events-card-list--grid {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
}

@media ( max-width: 1399px ) {
	.jdx-events-card-list--grid {
		grid-template-columns: repeat( 3, 1fr );
	}
}

/* Count-aware column modifiers (Phase 3C correction): applied by
 * Frontend\EventCardRenderer::wrapper_class() only when the actual
 * event count is 1-2 (--grid-cols-2) or exactly 3 (--grid-cols-3), so
 * an under-full row sizes its columns to the real count instead of
 * leaving unused 4-column tracks as dead space. 4-or-more events get
 * no extra modifier — the default .jdx-events-card-list--grid rule
 * above already produces the correct "4 per row + remainder" layout
 * for a partial last row, since explicit grid tracks don't stretch to
 * absorb missing siblings.
 *
 * Deliberate position in this file, load-bearing for the cascade —
 * do not move without re-deriving the whole matrix below:
 * - Placed AFTER the >=1400px base rule and the 1399px query, so at
 *   both of those tiers a count modifier (same 0,1,0 specificity,
 *   later source order) wins over them for 1-3 events, giving 2 or 3
 *   columns instead of the tier's own 4-or-3 default.
 * - Placed BEFORE the 999px and 649px queries below, so at THOSE
 *   narrower tiers the media query (same specificity, later still)
 *   always wins over any count modifier — every count collapses to
 *   the tier's own column count (2, then 1) exactly as it would with
 *   no count modifier applied at all. This is what keeps "count
 *   modifiers must not defeat the responsive collapse" true without
 *   needing !important anywhere.
 *
 * Resulting matrix (columns shown for 1 / 2 / 3 / 4-or-more events):
 *   >=1400px    : 2 / 2 / 3 / 4
 *   1000-1399px : 2 / 2 / 3 / 3
 *   650-999px   : 2 / 2 / 2 / 2
 *   <650px      : 1 / 1 / 1 / 1
 */
.jdx-events-card-list--grid-cols-2 {
	grid-template-columns: repeat( 2, 1fr );
}

.jdx-events-card-list--grid-cols-3 {
	grid-template-columns: repeat( 3, 1fr );
}

@media ( max-width: 999px ) {
	.jdx-events-card-list--grid {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( max-width: 649px ) {
	.jdx-events-card-list--grid {
		grid-template-columns: 1fr;
	}
}

.jdx-events-card {
	position: relative;
	/* Layout fix: without a width constraint, a flex column's default
	 * align-items: stretch grows the card to the full width of whatever
	 * container the shortcode is placed in, producing an unreadably long
	 * description line length. width:100%/max-width together shrink to
	 * fit a narrow container (no horizontal overflow, no media query
	 * needed) while never exceeding a readable ~65-75 character measure
	 * on a wide one. Scoped to the card itself, not .jdx-events-card-list
	 * — a future Grid places cards in narrower cells where this simply
	 * never activates, rather than fighting a grid-level constraint. */
	width: 100%;
	max-width: 640px;
	margin-inline: auto;
	box-sizing: border-box;
	font-family: var(--jdx-events-font-secondary);
	color: var(--jdx-events-color-text);
	/* Increment 11: set only via style="--jdx-events-card-bg: …" on the
	 * article by the template, never a direct background-color inline
	 * style (Decision 020) — transparent when unset, so an event with no
	 * configured color renders identically to Increment 10. */
	background-color: var(--jdx-events-card-bg, transparent);
	border: 1px solid var(--jdx-events-card-border-color);
}

.jdx-events-card-poster {
	display: block;
	/* width:100% (not max-width) so the poster spans the same width as
	 * the card's text content, per the approved reference layout. Safe
	 * against upscaling: Frontend\EventCardPresenter::poster() requests
	 * WordPress's 'large' size (1024px core default cap), comfortably
	 * covering this card's 640px max-width. */
	width: 100%;
	height: auto;
}

.jdx-events-card-content {
	/* Single spacing source for every text element below the poster —
	 * individual headings/paragraphs/lists must not carry their own
	 * horizontal padding. Poster stays edge-to-edge (no padding applied
	 * to it); only this wrapper is inset. */
	padding: 2rem;
}

@media ( max-width: 480px ) {
	.jdx-events-card-content {
		/* 2rem (32px) on each side leaves little room on a ~320-375px
		 * phone viewport — reduced proportionally, not a different
		 * design, just keeping the desktop spec usable at small widths. */
		padding: 1.25rem;
	}
}

/* Shared badge slot (Increment 3B.1): holds 0–2 badges in the same
 * position/order Sold Out alone previously occupied — status
 * (Cancelled/Postponed) first, Sold Out second, per approved order.
 * gap/margin-bottom reproduce the spacing a single Sold Out badge
 * already had before the date line (no dedicated rule previously
 * existed; that spacing came from the badge's own inline-block line box
 * plus the date paragraph's zero top margin). */
.jdx-events-card-badges {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4em;
	margin-bottom: 0.5em;
}

.jdx-events-card-badge {
	display: inline-block;
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.75em;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	padding: 0.25em 0.6em;
	/* Concrete, distinct fallback pair — not --jdx-events-color-accent/
	 * -primary, which both collapse to the same inherited currentColor
	 * when Elementor is inactive or those two Global Color slots are
	 * unconfigured, producing invisible label text (Increment 10 bug
	 * fix). Elementor's real global colors still win whenever set. */
	background: var(--e-global-color-accent, #1a1a1a);
	color: var(--e-global-color-primary, #ffffff);
}

/* Cancelled/Postponed variants (Increment 3B.1, Decision 021): same
 * shared .jdx-events-card-badge geometry/typography, only background/
 * color differ — deterministic literals, never chained through
 * Elementor's global colors (see the :root token comment). Doubled-class
 * selector (.jdx-events-card-badge.jdx-events-card-badge--*, specificity
 * 0,2,0) rather than the modifier class alone (0,1,0): live validation
 * found the single-class form losing to an external site rule of equal
 * or higher specificity/later print order (exact source outside this
 * plugin's codebase, not identifiable from here) — this is a targeted
 * specificity increase, not a rework of the component. Sold Out
 * intentionally has no equivalent modifier rule here — it keeps using
 * the base .jdx-events-card-badge styling above, unchanged. */
.jdx-events-card-badge.jdx-events-card-badge--cancelled {
	background: var(--jdx-events-badge-cancelled-bg);
	color: var(--jdx-events-badge-status-text);
}

.jdx-events-card-badge.jdx-events-card-badge--postponed {
	background: var(--jdx-events-badge-postponed-bg);
	color: var(--jdx-events-badge-status-text);
}

.jdx-events-card-title {
	font-family: var(--jdx-events-font-primary);
	font-size: 1.5em;
	text-transform: uppercase;
	margin: 0.75em 0 0.6em;
}

.jdx-events-card-headline {
	font-family: var(--jdx-events-font-secondary);
	font-size: 1.1em;
	font-weight: 600;
	margin: 0 0 0.5em;
}

.jdx-events-card-title a {
	color: inherit;
	text-decoration: none;
}

.jdx-events-card-date {
	font-family: var(--jdx-events-font-secondary);
	margin: 0 0 0.5em;
}

.jdx-events-card-time {
	font-family: var(--jdx-events-font-secondary);
	margin: 0 0 0.5em;
}

.jdx-events-card-excerpt {
	margin: 0 0 0.75em;
}

.jdx-events-card-rooms {
	list-style: none;
	margin: 0.5em 0 1em;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.4em;
}

.jdx-events-card-room {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5em;
}

.jdx-events-card-badge--room {
	background: var(--jdx-events-room-badge-bg);
	color: var(--jdx-events-room-badge-text);
}

.jdx-events-card-room-artist {
	font-family: var(--jdx-events-font-secondary);
}

.jdx-events-card-description {
	font-family: var(--jdx-events-font-secondary);
	margin: 0 0 0.75em;
}

.jdx-events-card-description p {
	margin: 0 0 0.75em;
}

.jdx-events-card-description p:last-child {
	margin-bottom: 0;
}

/* Grid-only description clamp (Phase 3C correction): a long Event
 * Description was the dominant driver of excessive per-row card height
 * in the grid layout, since .jdx-events-card-list--grid's default
 * align-items:stretch (unmodified — see that rule's own comment) makes
 * every card in a row match the tallest sibling's box. Scoped strictly
 * under .jdx-events-card-list--grid so layout="list" is completely
 * unaffected. Visual-only: $description_html itself is never truncated
 * — this clips rendered lines in the browser, nothing server-side. */
.jdx-events-card-list--grid .jdx-events-card-description {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 4;
	overflow: hidden;
}

.jdx-events-card-pricing {
	list-style: none;
	font-family: var(--jdx-events-font-secondary);
	margin: 0 0 0.75em;
	padding: 0;
}

.jdx-events-card-pricing li {
	margin: 0 0 0.1em;
}

.jdx-events-card-pricing li:last-child {
	margin-bottom: 0;
}

.jdx-events-card-ctas {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75em;
	margin: 0;
}

.jdx-events-card-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	min-height: var(--jdx-events-cta-min-height);
	padding: 0.5em 1em;
	/* Transparent, same width as the secondary variant's visible border,
	 * so both variants share identical box dimensions — only secondary
	 * overrides border-color below, never border-width. */
	border: 2px solid transparent;
	text-decoration: none;
	transition: background-color 175ms, color 175ms, border-color 175ms;
}

.jdx-events-card-cta--tickets {
	background: var(--jdx-events-cta-primary-bg);
	color: var(--jdx-events-cta-primary-fg);
}

.jdx-events-card-cta--table {
	/* Fully filled, not ghost/transparent — the border exists because the
	 * light fallback fill alone can disappear against an equally light
	 * surrounding surface, not as a substitute for the fill itself. */
	background: var(--jdx-events-cta-secondary-bg);
	color: var(--jdx-events-cta-secondary-fg);
	border-color: var(--jdx-events-cta-secondary-border);
}

@media ( hover: hover ) {
	/* Background-only hover (never opacity, which would also dim the
	 * label) using explicit literal tokens — no color-mix()/filter, and
	 * scoped out of touch devices to avoid sticky hover. */
	.jdx-events-card-cta--tickets:hover {
		background: var(--jdx-events-cta-primary-bg-hover);
	}

	.jdx-events-card-cta--table:hover {
		background: var(--jdx-events-cta-secondary-bg-hover);
	}
}

.jdx-events-card-cta:focus-visible,
.jdx-events-card-title a:focus-visible {
	/* Two concentric layers (light then dark) replace the single dark
	 * ring this used to be — a ring colored only for a light page
	 * background was invisible against a dark one. Spread/offset are
	 * sized to sit flush against each other with no gap and no overlap. */
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

.jdx-events-empty {
	font-family: var(--jdx-events-font-secondary);
	color: var(--jdx-events-color-text);
}
