/*
 * Weekly Event Index — layout only (Increment 3, v0.2.25 development
 * cycle). A distinct presentation component, not a variant of the Event
 * Grid card or the monthly Event Calendar (both retained unchanged) —
 * see DECISIONS.md, Decision 031. Registered with frontend-event-card.css
 * as a dependency (Frontend\EventIndexRenderer::register_assets()) so
 * this file can rely on its :root design tokens (fonts, colors, the
 * Increment 2 Appearance tokens) and reuse its .jdx-events-card-badge/
 * .jdx-events-card-cta atomic classes as-is in templates/event-index.php
 * — only this component's own layout/typography rules live here, nothing
 * shared is redefined or duplicated.
 *
 * Final Sakura Event Presentation Alignment (event-index-card.html
 * reference — supersedes the original "compact information blocks
 * sitting directly on the page background" design entirely): each
 * event is now a large bordered card with its own background (a
 * per-event Background Image or flat Background Color, general fields
 * — see .jdx-events-index__event below), not a borderless list item.
 * No brand-specific (Sakura/Treibhaus) literal colors anywhere — every
 * color routes through an existing JDX token or a per-event CSS custom
 * property with a token-based fallback.
 *
 * Fixed four-track desktop grid, matching Increment 1's approved Event
 * Grid geometry exactly (plain repeat(4,1fr), no count-aware modifier
 * class): 1 event occupies one of four tracks, 2 occupy two, and so on,
 * never stretched to fill unoccupied tracks — this component never
 * needed a Decision-023-style count modifier to begin with, since it is
 * implemented fresh under the already-approved fixed-track policy.
 *
 * Two responsive breakpoints only (999px, 649px), deliberately reusing
 * the exact pixel values already established for Event Grid's own
 * tablet/mobile collapse (frontend-event-card.css), not new arbitrary
 * values — a page combining both components collapses at the same
 * widths, no visual seam between them. No !important anywhere.
 *
 * Increment 3A (visual refinement, v0.2.25 development cycle): adds a
 * compact poster image and a 4-line-clamped Description per the
 * approved content hierarchy, and removes the now-unreachable
 * Rooms/Artists rules (the template no longer emits that markup in this
 * component — Rooms/Artists remain fully intact and styled everywhere
 * else, see Fields\EventFields/Frontend\EventCardPresenter and Event
 * Grid/Featured Event/Single Event's own unmodified room rules).
 *
 * Increment 3B (widget-level Text Appearance, v0.2.25 development
 * cycle): every event's background here is transparent (no per-event
 * opaque/colored surface, unlike Event Grid/Featured Event/Single
 * Event), so a per-event Light/Dark choice had no consistent surface to
 * contrast against and produced inconsistent readability across the
 * same Index. The per-event .jdx-events-index__event--appearance-*
 * modifier rules are removed; a single root-level
 * .jdx-events-index--appearance-light/-dark modifier (Elementor\
 * Widgets\EventIndexWidget's own Text Appearance control) replaces them,
 * reusing the exact same two global tokens unmodified. Elements that
 * already declare their own explicit color (.jdx-events-index__week-label,
 * .jdx-events-index__pricing — both accent-toned, unrelated to
 * Appearance) are unaffected either way, exactly as Event Grid's own
 * accent-colored Pricing list was never touched by Decision 030's
 * per-event rules either — a child's own explicit color always wins
 * over any ancestor's, appearance-related or not.
 *
 * Increment 4 (rolling six-month filter toolbar, v0.2.25 development
 * cycle): styles the toolbar/count/filter buttons only — all filtering
 * behavior itself is assets/js/event-index-filter.js's own
 * responsibility (root-scoped, no server round-trip, see that file);
 * this stylesheet only ever toggles one hidden-state class
 * (.jdx-events-index__event--hidden) via plain display:none, applied by
 * that script. (A separate __week--hidden class existed briefly in
 * validation.31 for a standalone week-label element; validation.32
 * removed both the element and the class — see
 * .jdx-events-index__week-label's own comment below.)
 *
 * Increment 4A (boxed filter visual system + Elementor Style controls,
 * v0.2.25 development cycle): the filter row is now one bordered
 * rectangular surface (see .jdx-events-index__filters/__filter below)
 * rather than Increment 4's plain opacity-distinguished text buttons.
 * The active-state selector remains [aria-pressed="true"] — the exact
 * same server-rendered attribute Increment 4 already used, never a
 * JS-added class — so ALL is visibly active (filled) at first paint
 * with no JavaScript required, and Elementor\Widgets\EventIndexWidget's
 * new Style → Filter section (Normal/Hover/Active Text/Background/
 * Border Color, plus a shared Border Width) targets these exact same
 * selectors via {{WRAPPER}}-scoped Elementor 'selectors', with no
 * default value set on any control — so an untouched widget instance
 * renders exactly the CSS defaults below, and Elementor only overrides
 * a given property once a site editor explicitly sets it. No new color
 * token was introduced: the active fill reuses the existing
 * --jdx-events-color-accent token, and its text reuses the existing
 * --jdx-events-cta-primary-fg token (the same "readable against an
 * accent-driven fill" pairing the CTA buttons already use).
 *
 * Increment 4B: .jdx-events-index__filter's border-radius is now
 * explicit (0), not merely absent — a <button> element can otherwise
 * pick up a browser/theme default corner radius this file never
 * intentionally set. Elementor\Widgets\EventIndexWidget gained a
 * matching Border Radius DIMENSIONS control (Style → Filter,
 * default 0px on all four sides, unlinked-capable per Elementor's own
 * standard DIMENSIONS control shape) targeting this exact selector —
 * same no-default-value/CSS-is-authoritative pattern as every other
 * Filter style control.
 *
 * Increment 5B (LIST | CALENDAR integration, v0.2.25 development cycle):
 * .jdx-events-index__view-toggle/__view-button reuse the exact same
 * boxed-control language as .jdx-events-index__filters/__filter above
 * (border-collapsed rectangular row, square corners, aria-pressed as the
 * active-state selector, no new tokens) — a second, visually consistent
 * instance of the same established pattern, not a new styling system.
 * .jdx-events-index__list-view/__calendar-view/__calendar-month carry no
 * presentation of their own beyond the [hidden] attribute (native browser
 * behavior, no CSS needed) — assets/js/event-index-filter.js toggles that
 * attribute only; a .jdx-events-index__calendar-month reuses the existing
 * .jdx-events-calendar class (assets/css/event-calendar.css, unchanged
 * by this increment) for its own font/color inheritance, exactly as the
 * standalone Event Calendar widget's own root element already does.
 *
 * Increment 5B.1 (toolbar + shared Filter styling refinement, v0.2.25
 * development cycle): the count, LIST | CALENDAR toggle, and month
 * filters now sit in one compact right-aligned cluster (see
 * .jdx-events-index__count below) instead of the count sitting alone on
 * the left; the count's own default presentation is also toned down
 * (smaller, no uppercase/letter-spacing, reduced opacity) so it reads as
 * secondary metadata rather than a fourth control. Elementor\Widgets\
 * EventIndexWidget's existing Filter Style controls were widened to a
 * compound selector covering both .jdx-events-index__filter and
 * .jdx-events-index__view-button — no new color-control section, no
 * change to either class's own default rules below (they already
 * matched, see the Increment 5B note above).
 *
 * Increment 5D reverted the Elementor selector compounding above: Style
 * → Filter and a new, independent Style → View Toggle section each
 * target only their own class again, so the two are fully independently
 * styleable in Elementor.
 *
 * Increment 5D.1 (v0.2.25 development cycle): live validation then
 * showed that once Style → View Toggle existed as its own,
 * not-yet-configured section, LIST | CALENDAR fell back to this file's
 * default appearance while month filters kept a site editor's own
 * already-configured Filter colors — an expected consequence of the two
 * controls now being genuinely independent, not a default-CSS defect
 * (the .jdx-events-index__filter/__view-button default rules were
 * already verified byte-for-byte identical). To make that default
 * parity structurally guaranteed rather than merely coincidental, the
 * base/sibling-border/active/hover/focus-visible rules previously
 * duplicated under a separate .jdx-events-index__view-button heading are
 * now grouped into the .jdx-events-index__filter rules themselves (see
 * each rule block below) — a DEFAULT-CSS-only change. Elementor's own
 * per-class generated 'selectors' from Style → Filter and Style → View
 * Toggle remain completely independent (Increment 5D is unchanged by
 * this) and continue to override this shared default the instant a site
 * editor sets either section's own controls.
 */

.jdx-events-index {
	width: 100%;
	box-sizing: border-box;
	font-family: var(--jdx-events-font-secondary);
	color: var(--jdx-events-color-text);
}

/* Widget-level Text Appearance (Increment 3B) — a single root modifier,
 * not per-event (see this file's own docblock and templates/
 * event-index.php's root wrapper). Same specificity as .jdx-events-index
 * above (one class each); wins because it is declared later in this same
 * file — deliberately a plain single-class selector, not a compound one:
 * both classes always sit on the same root element, so simple source
 * order is sufficient here (unlike Decision 030's per-event rules, which
 * had to reliably beat a base color rule regardless of which of several
 * separate stylesheet files loaded first). Reuses the exact two global
 * tokens Decision 030 already established — no new color system, no
 * duplicated token definition. */
.jdx-events-index--appearance-light {
	color: var(--jdx-events-appearance-light-text, var(--jdx-events-color-text));
}

.jdx-events-index--appearance-dark {
	color: var(--jdx-events-appearance-dark-text, var(--jdx-events-color-text));
}

/* ARCHITECTURE (v0.2.30): Weekly Subgrid layout.
 *
 * Each physical row of the grid is 3 shared parent row tracks —
 * label (auto), card (1fr), spacer (a fixed 3em gap to the next row) —
 * and EVERY article, whether or not it owns a week label, subgrids all
 * 3 via `grid-template-rows:subgrid; grid-row:span 3`. This uniform
 * item shape is what keeps CSS Grid's auto-placement flowing
 * continuously across week boundaries (a non-uniform shape, e.g. a
 * label as its own separate full-width grid item, forces a new row at
 * every occurrence and was rejected for exactly that reason during
 * development).
 *
 * Because the label/card/spacer tracks are shared across every column
 * in a physical row, not owned by any one article:
 * - row 1 (label) auto-sizes to whichever single column actually has a
 *   label that week (0 when none do) — the label never needs its own
 *   per-card space reservation.
 * - row 2 (card) is the SAME track for all 4 (or 2, or 1) columns, so
 *   every card's actual background/border/content (on .event-inner,
 *   not the article — see below) starts at the same Y position and
 *   stretches to the same height, regardless of which column has a
 *   label.
 * - row 3 (spacer) is a fixed length, so it is never inflated by any
 *   item's own content/margin, and provides the ONLY inter-row gap —
 *   .jdx-events-index__grid's own row-gap stays 0, since a non-zero
 *   row-gap would also land between a label and its own card (row 1
 *   and row 2), not just between physical rows.
 *
 * The one unavoidable side effect of giving every article a uniform
 * span (so auto-placement stays continuous) is that the very LAST
 * physical row also gets a trailing spacer track — trimmed by the
 * grid's own `margin-bottom:-3em` below, a single, fixed, deterministic
 * correction (not a per-card one, so it cannot affect track sizing).
 *
 * The article itself carries no visible surface — no background,
 * border, or padding — only `.event-inner` does (row 2 only), so an
 * unlabeled card's own row 1 truly contributes nothing visible, and a
 * week label visually floats above the card surface rather than
 * reading as part of it. */
.jdx-events-index__event .jdx-events-index__week-label {
	grid-row: 1;
	margin: 0 0 0.5rem;
	max-width: 100%;
	overflow-wrap: break-word;
	font-family: var(--jdx-events-font-primary);
	font-size: 0.7em;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--e-global-color-accent, #c9a227);
	text-align: left;
}

.jdx-events-index__grid {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
	grid-auto-rows: auto 1fr 3em;
	row-gap: 0;
	column-gap: 1.5em;
	align-items: stretch;
	/* Trims the always-present trailing spacer track after the grid's
	 * last physical row (see this rule's own docblock above) — a fixed,
	 * one-time, container-level correction; it does not affect this
	 * grid's own internal track sizing, only the space between this
	 * element and whatever follows it in normal flow. Safe in this
	 * template specifically because nothing else ever renders visibly
	 * directly below .jdx-events-index__grid: its sibling
	 * .jdx-events-index__calendar-view is always [hidden] whenever this
	 * grid itself is visible (LIST/CALENDAR are mutually exclusive). */
	margin-bottom: -3em;
}

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

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

.jdx-events-index__event {
	position: relative;
	display: grid;
	grid-template-rows: subgrid;
	grid-row: span 3;
	/* Not load-bearing for the overlay's own negative z-index (that one
	 * resolves within .event-inner's own stacking context — see
	 * .event-overlay below), but kept as a cheap defensive boundary for
	 * this card's other z-index:1/z-index:2 content (title-link overlay,
	 * CTA row) against the grid and any other card. */
	isolation: isolate;
	color: var(--jdx-events-index-extra-text, inherit);
}

.jdx-events-index__event--bg-image .jdx-events-index__event-inner {
	background-image: var(--jdx-events-index-event-bg-image, none);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* Overlay tint: a child of .event-inner (templates/event-index.php),
 * not a sibling of it — this is required, not stylistic, since the
 * background-image/color this tints now lives on .event-inner itself,
 * and stacking rules only let you order whole elements, never "between
 * a sibling's own background and that sibling's own content."
 *
 * `z-index:-1` is required, not optional: a position:absolute element
 * with z-index:auto does NOT paint in tree order alongside its
 * non-positioned siblings (a common misreading of CSS2.1 Appendix E) —
 * EVERY positioned element, even with z-index:auto, is deferred to a
 * later painting step than plain normal-flow content, so without an
 * explicit negative value this overlay painted ABOVE the card's own
 * text/badges/prices/buttons (all non-positioned), not just above its
 * background — a real, shipped regression, not a hypothetical one.
 * `.jdx-events-index__event-inner` already establishes its own
 * stacking context (position:relative + z-index:1 together, no
 * `isolation` needed there), so this negative z-index resolves WITHIN
 * that context only: painted right after .event-inner's own background
 * (always first, unconditionally) but before its normal-flow content —
 * never escaping to the article or any other card. pointer-events:none
 * keeps it non-interactive regardless of paint order. */
.jdx-events-index__event-overlay {
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background-color: var(--jdx-events-index-event-overlay-color, #0a0806);
	opacity: var(--jdx-events-index-event-overlay-opacity, 0.55);
}

/* The card's own visible surface — background, border, padding — all
 * live here, in the shared row-2 track only (see this file's own
 * architecture comment above), never on the article itself. */
.jdx-events-index__event-inner {
	grid-row: 2;
	position: relative;
	z-index: 1;
	background-color: var(--jdx-events-index-event-bg-color, transparent);
	border: 1px solid var(--jdx-events-card-border-color);
	/* Event → Single Event navigation UX (validation.40 Part 2): the
	 * stretched title link's hover response (below) changes this same
	 * border-color, so it needs to transition here too. */
	transition: border-color 175ms;
	min-height: 0;
	display: flex;
	flex-direction: column;
	padding: 1.5em 1.5em 0;
}

/* Date + Time on one compact row — same mechanism as Event Grid's own
 * .jdx-events-card-meta (frontend-event-card.css): Date immediately
 * followed by Time with a fixed gap, single child left-aligns itself,
 * flex-wrap is the narrow-width safety net. */
.jdx-events-index__meta {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0.2em 0.75em;
	margin: 0 0 0.75em;
	min-width: 0;
}

/* Typography alignment: opacity keeps Date/Time reading as quiet
 * metadata, matching Event Grid's own .jdx-events-card-date/-time
 * treatment (frontend-event-card.css). overflow-wrap/nowrap+ellipsis
 * (Final Sakura Event Presentation Alignment): single-line, matching
 * the reference's own .eic__date treatment. */
.jdx-events-index__date,
.jdx-events-index__time {
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.85em;
	opacity: 0.7;
	margin: 0;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Status badge overlay (v0.2.31, Event Index Card Robustness — REV3,
 * corrected again after live QA against the approved reference image,
 * references/event-index-redesign/final_status_banner_position.jpg):
 * absolutely positioned at the card's upper-right corner, out of normal
 * flow entirely — supersedes REV1/REV2's in-flow "own row above
 * Date/Time+Logo" approach, which (correctly, by design) reserved
 * vertical space and pushed the row below it down; live QA asked for
 * the opposite: the badge must float over the card without ever moving
 * anything else. Comparison of in-flow vs. absolute was already made
 * explicitly for Increment 1 (see DECISIONS.md) and in-flow was chosen
 * there specifically to sidestep the two-badge-wrap edge case without a
 * hardcoded offset; that edge case still exists here, now solved
 * differently — see .jdx-events-index__badges below (flex-wrap:nowrap
 * + per-badge truncation, scoped to this context only) rather than by
 * reserving space, which is no longer permitted.
 *
 * position:absolute needs no new stacking context of its own:
 * .jdx-events-index__event-inner is already position:relative (its own
 * Subgrid-architecture requirement, Decision 039) — this resolves
 * against it directly.
 *
 * top:4px (NOT 14px, the value this rule shipped with before being
 * caught by its own static testing): measured directly via
 * getBoundingClientRect(), not assumed — .jdx-events-index__head's own
 * Date/Time+Logo row starts at a measured ~20.5px from this same
 * container's top edge (the existing, unchanged 1.5em content padding,
 * confirmed empirically rather than recomputed from the em value by
 * hand). A 14px top offset, combined with the badge's own un-tuned
 * height, measurably overlapped the Logo by ~10px — caught by static
 * testing before sign-off, not assumed safe. top:4px, together with the
 * slightly reduced badge padding/font-size on
 * .jdx-events-index__badges .jdx-events-card-badge below (scoped to
 * this context only — the shared base rule other consumers use is
 * untouched), leaves a measured ~2-3px real clearance gap above the
 * Logo at every tested width and badge combination — confirmed, not
 * estimated. right:14px matches the precedent already set by Event
 * Grid's own .jdx-events-card-badges--overlay in frontend-event-card.css
 * (same 14px offset, different corner).
 *
 * z-index:2 matches .jdx-events-index__actions' own existing value
 * (below) — both exist to sit above the Title's stretched-link ::after
 * (z-index:1); reusing that exact value rather than introducing a new
 * one.
 *
 * max-width:60% (NOT calc(100% - 28px), this rule's first draft): a
 * position:absolute block with no explicit width shrink-wraps to its
 * own content, so a wide ceiling like calc(100% - 28px) is only ever
 * reached by content that's ALREADY wider than nearly the whole card —
 * confirmed by static testing that an unrealistically long simulated
 * translated status word (e.g. a German compound word) rendered in
 * full, untruncated, well under that ceiling, which is exactly the
 * "long localized badge text" case this rule exists to guard against.
 * 60% is a real, content-independent ceiling close enough to engage
 * truncation (see .jdx-events-index__badges' own child-selector rule
 * below) for genuinely long text while still comfortably fitting two
 * short realistic badges (e.g. "Cancelled" + "Sold Out") on one line,
 * confirmed by the same round of static testing. Only rendered when a
 * status actually exists (templates/event-index.php's own
 * $index_has_status gate, unchanged) — never an empty floating box. */
.jdx-events-index__status-row {
	position: absolute;
	top: 4px;
	right: 14px;
	max-width: 60%;
	z-index: 2;
}

/* Date/Time + Logo row (v0.2.31, Event Index Card Robustness —
 * corrected after live QA): Date/Time on the left, Event Logo on the
 * RIGHT OF THIS SAME ROW — the first pass stacked the Logo below the
 * Status badge instead; live QA found that reads wrong and asked for
 * Logo back on the Date/Time row specifically, with Status fully
 * separated above (see .jdx-events-index__status-row above). The Title
 * is still not a child of this row at all — see .jdx-events-index__title
 * below, a full-width sibling rendered directly after this element
 * (or directly after .status-row, when this row is absent — see its
 * own guard below), immune to anything that happens in either row
 * above it. align-items:center vertically balances the date/time text
 * against the logo image on their shared row. margin-bottom supplies
 * the gap before the Title that this row (or .status-row, now that
 * either may legitimately be the last element before it) used to get
 * "for free" when the Title was still nested inside it; .jdx-events-index__rooms/
 * __description already supply the gap AFTER the Title unchanged (see
 * their own existing margin-top), so this is the one new gap needed. */
.jdx-events-index__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75em;
	min-width: 0;
	margin-bottom: 0.6em;
}

/* .jdx-events-index__meta needs no dedicated rule of its own here —
 * flex-shrink defaults to 1 and its own <span> children (below) already
 * carry white-space:nowrap + text-overflow:ellipsis, so long localized
 * date strings degrade safely without a flex-basis/min-width override
 * on this element itself. Its only job on this row is to sit left and
 * let .jdx-events-index__logo's own max-width:50% (below) claim no more
 * than its half. */

/* font-size/font-weight (validation.30 Correction 8, live-validated:
 * "Title needs to be larger and clearly bold"): bumped from 1.15em/
 * inherited weight to 1.4em/700 — a visible increase without radically
 * enlarging the card (placement and 2-line clamp unchanged;
 * --jdx-events-font-primary can resolve to a plain system font when
 * Elementor is inactive/unconfigured, so an explicit font-weight is
 * needed to guarantee "clearly bold" regardless of which font actually
 * loads, rather than relying on Bebas Neue's own display weight
 * alone).
 *
 * Layout context (v0.2.31, Event Index Card Robustness): no longer a
 * flex child of .jdx-events-index__head — this is now a full-width
 * sibling rendered directly after that row (see templates/event-index.php),
 * so it always has the card's full content width available regardless
 * of whether a status badge or logo rendered above it.
 *
 * flex:0 1 auto (changed from flex:1 1 auto, found during code review):
 * .jdx-events-index__event-inner is itself display:flex;flex-direction:
 * column, so this element is still a flex item — now of event-inner
 * directly, not of .head. The old flex-grow:1 was correct ONLY while
 * .jdx-events-index__spacer was this element's sole grow:1 sibling;
 * carried over unchanged, it would make the Title compete with the
 * Spacer for leftover vertical space, which exists specifically to push
 * Pricing/Status/CTAs to the bottom of the card. flex-grow:0 restores
 * the Title to its pre-increment behavior (sized to its own 2-line-clamp
 * content only); min-width:0 is kept, still relevant now that this is a
 * direct event-inner flex item. */
.jdx-events-index__title {
	font-family: var(--jdx-events-font-primary);
	font-size: 1.4em;
	font-weight: 700;
	text-transform: uppercase;
	line-height: 1.15;
	margin: 0;
	min-width: 0;
	flex: 0 1 auto;
	overflow-wrap: anywhere;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.jdx-events-index__title a {
	color: inherit;
	text-decoration: none;
	transition: color 175ms;
}

/* Event → Single Event navigation UX (validation.40 Part 2): same
 * technique as Event Grid's own .jdx-events-card-title a::after
 * (frontend-event-card.css) — the title is the only real, accessible
 * permalink anchor in this component, so its hit area is stretched via
 * inset:0 rather than wrapping the whole article in a second <a>. The
 * nearest position:relative ancestor is .jdx-events-index__event-inner
 * (below), which already spans the full card content area (Description/
 * Meta/Actions are all its children) — inset:0 against it covers the
 * whole visible card. z-index:1 stays below the CTA row, which claims
 * z-index:2 (see .jdx-events-index__actions below) so Buy Tickets/Book a
 * Table remain independently clickable on top of it. */
.jdx-events-index__title a::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	cursor: pointer;
}

.jdx-events-index__title a:focus-visible {
	position: relative;
	z-index: 1;
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

/* Sakura Event Logo — an in-flow child of .jdx-events-index__head above
 * (v0.2.31, Event Index Card Robustness — corrected after live QA: now
 * directly on the Date/Time row, not stacked beneath a Status badge in
 * a shared column as this increment's first pass had it), not an
 * absolute overlay. Subtle, subordinate, never interactive — same
 * non-clickable pointer-events:none convention as every other JDX logo
 * watermark.
 *
 * flex:0 1 50% + max-width:50% (not flex:0 0 auto / max-width:40%, the
 * pre-increment values): caps the Logo at exactly 50% of the card's
 * content width, matching the approved spec — stated directly on this
 * element now that it is no longer wrapped in an intermediate 50%-capped
 * column. flex-basis:50% (not auto) is deliberate, found by static
 * testing at narrow widths before this increment's first sign-off: with
 * flex-basis:auto + flex-shrink:0, a flex item's hypothetical size is
 * derived from its CONTENT's max-content width before max-width is
 * applied — an <img> with a wide intrinsic size (e.g. a 200px-wide
 * source logo) can win that calculation outright on a narrow card,
 * making max-width:50% a no-op in exactly the "very wide logo + narrow
 * card" combination this increment is required to handle. Starting
 * from an explicit 50% basis sidesteps that circular sizing entirely;
 * max-width:50% is kept as a reinforcing ceiling, matching this
 * codebase's existing "reinforce, don't rely on one mechanism alone"
 * convention (see e.g. Elementor\Widgets\EventIndexWidget's own
 * filter_border_radius precedent). flex-shrink:1 (not 0) lets the Logo
 * shrink further still, giving room to .meta's own date/time content
 * when the two together don't fit.
 *
 * min-width:0 is the second, independently necessary part of the same
 * fix: flex items default to min-width:auto, which for a replaced
 * element resolves to its intrinsic width (200px for a wide source
 * logo) and acts on its own as a hard floor beneath which neither
 * flex-shrink nor max-width can push it, confirmed by isolated static
 * testing during the first pass — flex-shrink:1 alone was not enough
 * without this.
 *
 * object-fit:contain (new in this pass — found by static testing, not
 * assumed): this element's first pass (Increment 1) correctly claimed
 * "no object-fit needed," because it was a flex item of a COLUMN flex
 * container, where flex-basis applies to the vertical axis and
 * width:auto freely governed width with nothing competing against it.
 * In this row context, flex:0 1 50% sets a flex-basis on the HORIZONTAL
 * axis — the same axis width:auto would otherwise control — so width
 * and max-height now resolve as two independently-constrained
 * dimensions that will not generally match the source image's own
 * aspect ratio. Without object-fit, a plain <img> stretches to fill
 * whatever box those two constraints produce, which visibly distorted
 * the very-tall (1:3) test logo (confirmed by static testing: it
 * rendered as a wide, horizontally-smeared strip instead of a tall, narrow
 * one). object-fit:contain restores correct aspect-ratio preservation —
 * the image is letterboxed within the resolved box rather than
 * stretched to fill it. max-height unchanged at 46px (validation.30
 * Correction 9's existing "safe maximum height" value — no new
 * rationale to change it this increment). */
.jdx-events-index__logo {
	flex: 0 1 50%;
	min-width: 0;
	max-width: 50%;
	max-height: 46px;
	width: auto;
	height: auto;
	object-fit: contain;
	display: block;
	pointer-events: none;
	opacity: 0.95;
}

/* Rooms/Artists — same compact scannable-list treatment as before
 * (Sakura Event Presentation Refinement), unchanged except for the
 * margin-top now needed since it follows the new head row rather than
 * the title directly. */
.jdx-events-index__rooms {
	list-style: none;
	margin: 0.75em 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.3em;
	min-width: 0;
}

.jdx-events-index__room {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5em;
	min-width: 0;
}

.jdx-events-index__room-artist {
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.9em;
	min-width: 0;
	overflow-wrap: anywhere;
}

/* Adaptive reserved zone (validation.30 Correction 10 — supersedes the
 * previous FIXED-4-line rule, which itself had superseded an earlier
 * room-count-aware clamp): always rendered, never omitted for an empty
 * description, so every card still reserves a stable TOTAL footprint
 * together with .jdx-events-index__pricing below (7 lines combined) —
 * only the split between the two shifts with pricing-line count
 * (templates/event-index.php computes --desc-lines/--price-lines; this
 * rule only consumes them). height (not just line-clamp) is what makes
 * this a true reserve — see frontend-event-card.css's own equivalent
 * Description rule for the full rationale. Visual-only:
 * $description_html itself is never truncated server-side. */
.jdx-events-index__description {
	font-family: var(--jdx-events-font-secondary);
	line-height: 1.5;
	margin: 0.75em 0 0;
	min-width: 0;
	overflow-wrap: anywhere;
	height: calc( 1em * 1.5 * var( --desc-lines, 4 ) );
	display: -webkit-box;
	-webkit-line-clamp: var(--desc-lines, 4);
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.jdx-events-index__description p {
	margin: 0 0 0.5em;
}

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

/* Plain-text preview (v0.2.32, Decision 052) — the modifier is present
 * whenever templates/event-index.php renders Frontend\EventCardPresenter's
 * description_preview (always, unless a jdx_events/event_card_data filter
 * removed that key, in which case the legacy HTML rule above still applies
 * unchanged). The zone holds plain text only, so no `p` margin, theme `p`
 * rule, or Gutenberg block can change a line box; pre-line turns each
 * paragraph break into one whole empty line, so the clamp always ends on
 * a line boundary instead of cutting the last visible line. `1lh` makes
 * the reserved height follow whatever line-height is actually in effect
 * (including an Elementor Style → Description typography override); the
 * em-based declaration before it stays as the fallback for browsers
 * without `lh` support and equals the legacy height exactly. */
.jdx-events-index__description--preview {
	white-space: pre-line;
	height: calc( 1em * 1.5 * var( --desc-lines, 4 ) );
	height: calc( 1lh * var( --desc-lines, 4 ) );
}

/* Pushes the footrow (Pricing + Status) and the CTA row to the bottom
 * of the card — same flex-spacer technique as Event Calendar's own
 * Extra tile (assets/css/event-calendar.css). */
.jdx-events-index__spacer {
	flex: 1 1 auto;
	min-height: 1em;
}

/* Pricing (FIXED reserved zone, 3 lines) + Status share one row,
 * bottom-aligned (Final Sakura Event Presentation Alignment) — matches
 * the reference's own .eic__footrow exactly: Pricing left, Status
 * right, both anchored to each other's baseline area. Status keeps its
 * existing multi-badge grouping/business logic entirely unchanged
 * (.jdx-events-card-badges, reused as-is), only its position moves. */
.jdx-events-index__footrow {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1em;
	padding-bottom: 1.5em;
	min-width: 0;
}

.jdx-events-index__pricing {
	list-style: none;
	font-family: var(--jdx-events-font-secondary);
	/* Typography alignment: unchanged at 0.85em — already matches this
	 * component's own Date/Time scale, satisfying the approved "Date
	 * and Pricing are both quiet metadata at the same scale" rule. */
	font-size: 0.85em;
	letter-spacing: 0.02em;
	color: var(--jdx-events-color-accent);
	margin: 0;
	padding: 0;
	min-width: 0;
	/* Adaptive reserved zone (validation.30 Correction 10) — always
	 * rendered (0-3 populated <li> items); height now tracks
	 * --price-lines (the actual pricing-line count, capped at 3) rather
	 * than a fixed 3, so Description above can reclaim the rest of the
	 * shared 7-line budget when there are fewer prices. Matches Event
	 * Grid's own identical Pricing treatment. */
	height: calc( 1em * 1.5 * var( --price-lines, 3 ) );
	overflow: hidden;
}

.jdx-events-index__pricing li {
	margin: 0 0 0.1em;
	min-width: 0;
	overflow-wrap: anywhere;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

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

/* Status badge group (v0.2.31, Event Index Card Robustness — REV3):
 * the sole child of the now-absolutely-positioned .jdx-events-index__status-row
 * above. Still reuses the shared .jdx-events-card-badges base rule
 * (frontend-event-card.css) for its display:flex/gap/align-items —
 * unchanged — but overrides flex-wrap to nowrap here (the base rule's
 * own flex-wrap:wrap is correct for every OTHER usage of that shared
 * class — Event Grid's own overlay badges, Room badges — and is
 * deliberately left untouched there; this override is scoped to this
 * one Event-Index-specific class only, never affecting the base rule
 * itself or any other consumer of it).
 *
 * Why nowrap, not wrap, here specifically: REV1/REV2's in-flow design
 * could safely allow wrapping because a taller, wrapped badge group
 * simply made its own reserved row taller — nothing to collide with.
 * Now that the badge floats absolutely with NO reserved space (REV3's
 * own binding requirement), a wrapped second line would grow downward
 * into .jdx-events-index__head's own Date/Time/Logo content with no
 * guard against it — exactly the overlap this correction exists to
 * prevent. nowrap plus each badge's own max-width/ellipsis truncation
 * (the .jdx-events-card-badge override directly below) guarantees the
 * floating box can only ever grow to ONE line, trading graceful text
 * truncation in the realistic worst case (two badges simultaneously,
 * in a long translated language, on the narrowest supported card) for
 * an unconditional geometric guarantee against overlap — the stronger,
 * correct trade-off given REV3's "must not overlap" requirement is
 * unconditional, not best-effort. justify-content:flex-end keeps
 * multiple badges right-aligned within the (now non-wrapping) row.
 * margin-bottom:0 overrides the base rule's own in-flow spacing value,
 * meaningless for an absolutely positioned ancestor. */
.jdx-events-index__badges {
	flex-wrap: nowrap;
	justify-content: flex-end;
	margin-bottom: 0;
}

/* Scoped exclusively to badges inside the Event Index status overlay —
 * .jdx-events-card-badge's own base rule (frontend-event-card.css) is
 * never touched, so Event Grid's badges, Room badges, and every other
 * consumer of that shared class keep their exact existing, unbounded
 * text behavior. white-space:nowrap (reinforces the parent's own
 * flex-wrap:nowrap at the text level — belt and suspenders, matching
 * this codebase's existing convention) + overflow:hidden +
 * text-overflow:ellipsis means a status label too long for the
 * available width degrades to a truncated, still-colored, still-
 * positioned badge rather than ever growing the box vertically or
 * pushing it past the card edge. max-width is deliberately generous
 * (each badge gets up to the full available row width, since realistic
 * short status words essentially never need it) — this is a safety
 * ceiling for the genuinely extreme case, not a default visual
 * truncation editors should expect to see. min-width:0 is the same
 * decisive fix already documented in full on .jdx-events-index__logo
 * above: a flex item's default min-width:auto resolves to its text's
 * own min-content width, which would silently defeat this truncation
 * mechanism entirely (ellipsis never engages while min-width:auto
 * still guarantees the untruncated text its full width) without it.
 *
 * padding/font-size (reduced from the shared base rule's 0.25em 0.6em /
 * 0.75em, scoped here only — same "never touches the base rule"
 * guarantee as above): found necessary by the same static testing that
 * set .jdx-events-index__status-row's own top:4px — at the base rule's
 * original size, even a SINGLE badge was tall enough that no top offset
 * existed which both (a) kept the badge visually near the card's top
 * corner and (b) cleared the Logo below with zero pixel overlap. This
 * reduction is a geometry requirement of the absolute-overlay design,
 * not a cosmetic preference. */
.jdx-events-index__badges .jdx-events-card-badge {
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
	padding: 0.2em 0.5em;
	font-size: 0.68em;
}

/* .jdx-events-card-ctas (frontend-event-card.css) already supplies the
 * fixed 2-column grid for the buttons inside this. Sits as the last
 * child of .jdx-events-index__event-inner, directly below the footrow —
 * no separate push-to-bottom margin needed here (the footrow's own
 * padding-bottom above already closes out the inner padded area, and
 * .jdx-events-index__spacer already did the "push down" work). */
.jdx-events-index__actions {
	margin: 0 0 1.5em;
	/* Event → Single Event navigation UX (validation.40 Part 2): stacks
	 * above the stretched title link's ::after (z-index:1, see
	 * .jdx-events-index__title a::after above) so Buy Tickets/Book a
	 * Table stay independently clickable. */
	position: relative;
	z-index: 2;
}

/* Toolbar (Increment 4) — right-aligned, minimal, a single hairline
 * separator from the week groups below it; no boxes, no fill, matching
 * this component's existing "compact information block" language. */
.jdx-events-index__toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1em;
	margin-bottom: 2em;
	padding-bottom: 1em;
	border-bottom: 1px solid var(--jdx-events-card-border-color);
}

/* Increment 5B.1: count, LIST | CALENDAR, and the month filters now sit
 * in one compact right-aligned cluster (count → view-toggle → filters —
 * templates/event-index.php's own DOM order, unchanged), rather than
 * count on the left and the filter row alone pushed right. margin-left:
 * auto on the toolbar's own first child is the standard flexbox
 * "push this item and everything after it to the end" technique — it
 * consumes all leading free space, so the existing gap:1em above already
 * supplies the "small deliberate gaps" between the three controls with
 * no separate spacing value introduced. Naturally degrades to wrapped/
 * stacked rows at narrower widths via the existing flex-wrap:wrap above
 * and the existing @media(max-width:649px) column layout below — no
 * forced right alignment where it would overflow.
 *
 * Also deliberately quieter than the view/filter buttons now: no
 * uppercase/letter-spacing (which previously made this read with the
 * same visual weight as a button), a touch smaller, and a reduced
 * opacity — still fully readable, still the same font/color tokens, no
 * new token or font family introduced. */
.jdx-events-index__count {
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.75em;
	opacity: 0.7;
	margin: 0 0 0 auto;
}

/* One restrained rectangular control surface (Increment 4A), not a
 * row of separate pills/tabs: each button carries its own 1px border
 * on every side (so Elementor's per-state Border Color controls below
 * have a real, individually-targetable border on every button, matching
 * the approved control surface), and the `+` sibling rule immediately
 * below removes the *inner* doubled border between adjacent buttons —
 * the standard border-collapse technique — so the row still reads as
 * one unbroken box, not seven bordered pills. No gap between buttons
 * (deliberately 0, not the 1em row-gap this used before this increment).
 * No border-radius anywhere: buttons and the row both stay rectangular. */
.jdx-events-index__filters {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
}

/* Inactive: transparent background, inherits whichever Text Appearance
 * color is already in effect on .jdx-events-index (Increment 3B) — no
 * color of its own declared here. Border uses the same existing
 * structural token every other hairline separator in this component
 * already uses (--jdx-events-card-border-color) — not a new token.
 *
 * Increment 5D.1: this default declaration block is now grouped with
 * .jdx-events-index__view-button (the LIST | CALENDAR toggle) rather
 * than duplicated in a separate rule further down this file — both
 * classes' *default* (unconfigured) presentation must always be
 * pixel-identical, and a shared rule makes that structurally guaranteed
 * instead of merely coincidental. This is a DEFAULT-CSS-only grouping:
 * Elementor\Widgets\EventIndexWidget's own generated 'selectors' for
 * Style → Filter and Style → View Toggle remain fully independent,
 * each targeting only its own class ({{WRAPPER}} .jdx-events-index__filter
 * vs {{WRAPPER}} .jdx-events-index__view-button) — those per-instance
 * overrides still cleanly win over this shared base rule regardless of
 * which section a site editor configures, exactly as before. */
.jdx-events-index__filter,
.jdx-events-index__view-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.8em;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	background: transparent;
	color: inherit;
	border: 1px solid var(--jdx-events-card-border-color);
	/* Explicit, not merely absent (Increment 4B): a <button> element can
	 * pick up a browser/theme user-agent-stylesheet default corner
	 * radius that this file never intentionally set — this rule removes
	 * any ambiguity rather than relying on no rule being present at all.
	 * Authoritative default; Elementor's own Border Radius controls
	 * (Style → Filter / Style → View Toggle, independently) override it
	 * only once a site editor explicitly sets another value on that
	 * specific control — see Elementor\Widgets\EventIndexWidget. */
	border-radius: 0;
	padding: 0.6em 1em;
	margin: 0;
	cursor: pointer;
}

.jdx-events-index__filter + .jdx-events-index__filter,
.jdx-events-index__view-button + .jdx-events-index__view-button {
	border-left: none;
}

/* Active: filled with the existing accent token (never a new one), text
 * switches to the same "readable against an accent-driven fill" token
 * the CTA buttons already use (frontend-event-card.css's
 * --jdx-events-cta-primary-fg) — not a separate contrast calculation.
 * Selector is the server-rendered aria-pressed="true" attribute itself,
 * never a JS-added class: ALL/LIST already carry aria-pressed="true" at
 * initial render (templates/event-index.php), so this rule paints both
 * as visibly active immediately, with no JavaScript required. */
.jdx-events-index__filter[aria-pressed="true"],
.jdx-events-index__view-button[aria-pressed="true"] {
	background: var(--jdx-events-color-accent);
	color: var(--jdx-events-cta-primary-fg);
	border-color: var(--jdx-events-color-accent);
}

@media ( hover: hover ) {
	.jdx-events-index__filter:hover,
	.jdx-events-index__view-button:hover {
		background: var(--jdx-events-color-accent);
		color: var(--jdx-events-cta-primary-fg);
		border-color: var(--jdx-events-color-accent);
	}

	/* Event → Single Event navigation UX (validation.40 Part 2): hovering
	 * anywhere on the event — including the stretched title-link overlay,
	 * a descendant of .jdx-events-index__event — also matches :hover
	 * here, since :hover applies to every ancestor of the pointed-at
	 * element. Restrained response only: existing border/title tokens,
	 * no transform/scale/glow. Targets .event-inner (v0.2.30-validation.3:
	 * the border itself moved there, see that rule's own comment — this
	 * selector just follows it to where the border-color property now
	 * actually lives). */
	.jdx-events-index__event:hover .jdx-events-index__event-inner {
		border-color: var(--jdx-events-color-accent);
	}

	.jdx-events-index__event:hover .jdx-events-index__title a {
		color: var(--jdx-events-color-accent);
	}
}

.jdx-events-index__filter:focus-visible,
.jdx-events-index__view-button:focus-visible {
	position: relative;
	z-index: 1;
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

/* Applied only by assets/js/event-index-filter.js — never present at
 * initial server render (every event is visible until the script
 * decides otherwise), so the ALL state is correct with JavaScript
 * disabled or before the script has run. Hiding an event this way also
 * hides its embedded week label, if it carries one (validation.32) —
 * there is no separate week-level hidden class any more. */
.jdx-events-index__event--hidden {
	display: none;
}

/* LIST | CALENDAR view toggle (Increment 5B; default rules consolidated
 * with .jdx-events-index__filter in Increment 5D.1 — see that rule
 * block's own comment above). This container-layout rule is the only
 * .jdx-events-index__view-toggle/__view-button CSS left in this file: the
 * button's own default appearance (base/sibling-border/active/hover/
 * focus-visible) now lives entirely in the grouped rules above, shared
 * with .jdx-events-index__filter. */
.jdx-events-index__view-toggle {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
}

.jdx-events-index__calendar-month {
	margin-bottom: 1.5em;
}

.jdx-events-index__calendar-month:last-child {
	margin-bottom: 0;
}

@media ( max-width: 649px ) {
	/* Increment 5F: small horizontal breathing room at mobile widths —
	 * .jdx-events-index is width:100%/box-sizing:border-box (see this
	 * file's own root rule above), so padding-inline here is absorbed
	 * inside that existing 100% width rather than added on top of it —
	 * no overflow risk. Applied once, on the shared root every child
	 * (toolbar, LIST content, CALENDAR content) already renders inside
	 * (templates/event-index.php) — .jdx-events-calendar itself carries
	 * no horizontal padding of its own and Increment 5E's mobile agenda
	 * rows are vertical-only (padding: 0.75em 0), so this is the sole
	 * source of horizontal padding, never doubled. */
	.jdx-events-index {
		padding-inline: 20px;
	}

	.jdx-events-index__toolbar {
		flex-direction: column;
		align-items: flex-start;
	}

	/* Increment 5B.1: the right-aligning margin-left:auto now lives on
	 * .jdx-events-index__count (the cluster's first element), not
	 * .jdx-events-index__filters — same reset, same reason: in the
	 * column layout above, an auto cross-axis margin would otherwise
	 * pull that one element out of the left-aligned stack. */
	.jdx-events-index__count {
		margin-left: 0;
	}
}

/* Event Index — CALENDAR view typography and containment (v0.2.32).
 *
 * Independent of the LIST view (no .jdx-events-index__event/__description
 * rule reaches the calendar grid) and of the standalone Event Calendar
 * widget (everything below is scoped to .jdx-events-index__calendar-view,
 * which only the Index renders; event-calendar.css itself is unchanged).
 *
 * Why fixed px defaults and explicit margins: the shared tile CSS is
 * em-based with single-class selectors (0,1,0), so Elementor Kit / theme
 * rules such as `.elementor-kit-N h3 { font-size:32px }` or
 * `.elementor-kit-N p { margin-block-end:… }` (0,1,1) overrode it, and in
 * the fixed-height desktop day cell (overflow:hidden) that pushed the
 * Details button out of view. Every rule here is (0,2,0) or stronger,
 * beating such Kit/theme rules; Style → Calendar controls in the Index
 * widget ({{WRAPPER}}-scoped, (0,3,0)) still override these defaults.
 *
 * Containment: the tile is a flex column in which title, date, rooms,
 * status row and CTA row never shrink; only the spacer and then the
 * excerpt give up space, so the Details/Tickets row always stays inside
 * the tile. The desktop day height gets a px floor so the default content
 * (date, 2-line title, rooms, 2-line excerpt, status, CTA) fits even when
 * the inherited font-size is small; at normal sizes 16em is unchanged. */
@media ( min-width: 701px ) {
	.jdx-events-index__calendar-view .jdx-events-calendar__day {
		height: max( 16em, 232px );
	}
}

.jdx-events-index__calendar-view .jdx-events-calendar__event {
	min-height: 0;
	overflow: hidden;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-date {
	flex: 0 0 auto;
	margin: 0;
	padding: 0;
	font-size: 11px;
	line-height: 1.3;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-head {
	flex: 0 0 auto;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-title {
	margin: 0;
	padding: 0;
	font-size: 14px;
	line-height: 1.25;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-rooms {
	flex: 0 0 auto;
	margin-top: 0.35em;
	font-size: 11px;
	line-height: 1.3;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-tag,
.jdx-events-index__calendar-view .jdx-events-calendar__event-lineup,
.jdx-events-index__calendar-view .jdx-events-calendar__event-status,
.jdx-events-index__calendar-view .jdx-events-calendar__event-list-time {
	font-size: 11px;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-status {
	margin: 0;
	padding: 0;
}

/* Excerpt: plain-text preview (templates/event-calendar-grid.php's
 * excerpt_preview flag), max 2 lines by default — Style → Calendar →
 * Excerpt Lines can choose 1/3 or hide it. The only shrinkable content
 * element: in an extreme case (very large custom typography) it yields
 * space before the CTA row would. */
.jdx-events-index__calendar-view .jdx-events-calendar__event-description--preview {
	--jdx-events-calendar-extra-desc-lines: 2;
	flex: 0 1 auto;
	min-height: 0;
	margin: 0.4em 0 0;
	padding: 0;
	font-size: 12px;
	line-height: 1.45;
	white-space: pre-line;
	height: auto;
	max-height: calc( 12px * 1.45 * var( --jdx-events-calendar-extra-desc-lines ) );
	max-height: calc( 1lh * var( --jdx-events-calendar-extra-desc-lines ) );
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-spacer {
	min-height: 0;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-statusrow {
	flex: 0 0 auto;
	min-height: 17px;
	margin: 0 0 0.3em;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-cta {
	flex: 0 0 auto;
	margin: 0.4em 0 0;
	padding: 0;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-details,
.jdx-events-index__calendar-view .jdx-events-calendar__event-tickets {
	font-size: 11px;
	line-height: 1.2;
}

/* Multi-event day rows: same scale (title 12px, time 11px) and list
 * margins/padding reset against theme `ul`/`li` rules. */
.jdx-events-index__calendar-view .jdx-events-calendar__event-list {
	margin: 0;
	padding: 0;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-list-item {
	margin: 0;
}

.jdx-events-index__calendar-view .jdx-events-calendar__event-list-title {
	font-size: 12px;
}
