/*
 * Single Event — layout only (Phase 4D, Decision 027). Deliberately
 * isolated from frontend-event-card.css: functional/neutral fallback
 * styling only, not the approved final Sakura/Treibhaus design (see
 * this decision's own "not final design" note, matching Decisions
 * 025/026 for the hero and calendar). Registered with
 * frontend-event-card.css as a dependency (Frontend\
 * SingleEventRenderer::register_assets()) so this file can rely on its
 * :root design tokens (fonts, colors, badge/CTA tokens) and reuse its
 * .jdx-events-card-badge and .jdx-events-card-cta atomic classes as-is
 * in templates/single-event-content.php — only this page's own
 * layout/typography rules live here, nothing atomic is redefined.
 *
 * Single vertical column below the hero, still deliberate: the hero
 * image itself is never split side-by-side with content (unlike the
 * Featured Event hero) — a single-event page's media still reads
 * top-to-bottom like an article. Below the hero, the body content area
 * is a two-column layout (main content + a sticky Pricing/CTA sidebar,
 * Sakura Event Presentation Refinement — see .jdx-events-single__layout
 * below), matching the approved event-single.html reference. No
 * !important anywhere.
 */

.jdx-events-single {
	/* No max-width here (validation.44 live Sakura correction — removed
	 * the validation.43 1680px cap): even 1680px still read as a visibly
	 * boxed hero on large desktop monitors. .jdx-events-single__media
	 * (the hero) has no width rule of its own, so it now simply uses
	 * 100% of whatever real width its actual WordPress/theme page
	 * wrapper provides — never wider than that real parent, never a
	 * viewport unit, never able to overflow it. The information section
	 * below stays independently controlled via
	 * .jdx-events-single__content's own max-width (see below), so this
	 * change is purely about the hero. margin-inline:auto is inert with
	 * no max-width here but kept as a harmless no-op, matching the
	 * approved decision to preserve it. */
	margin-inline: auto;
	width: 100%;
	box-sizing: border-box;
	/* Reuses the exact tokens .jdx-events-card already relies on
	 * (frontend-event-card.css) — background set only via
	 * style="--jdx-events-card-bg: …" on the article by the template
	 * (templates/single-event-content.php), never a direct
	 * background-color inline style (Decision 020); transparent when
	 * unset, so an event with no configured color is unaffected.
	 * --jdx-events-card-extra-text (validation.42 Decision D.2): the same
	 * per-event Extra Text Color override Event Grid/Event Index already
	 * honor alongside Background Color — Single Event previously ignored
	 * it entirely (color was hardcoded to the global text token), so an
	 * event with both a custom background and custom text color would
	 * render correctly everywhere else but not here. Falls back to the
	 * existing global token, identical to Grid's own rule, when unset. */
	color: var(--jdx-events-card-extra-text, var(--jdx-events-color-text));
	background-color: var(--jdx-events-card-bg, transparent);
}

.jdx-events-single__media {
	position: relative;
	margin-bottom: 1.5rem;
}

/* Cinematic vignette (validation.41 — Single Event Premium Presentation):
 * a restrained bottom-fade over the hero photo, matching the approved
 * event-single.html reference's own .event-hero-img::after treatment
 * (same technique, gentler stops). Purely decorative — literal black,
 * not an Elementor/global color token, matching the same "structural
 * dark canvas" precedent Featured Event's own hero already uses.
 * pointer-events:none + no z-index (auto): .jdx-events-single__hero-overlay
 * below carries an explicit z-index (1), which always paints above a
 * z-index:auto layer regardless of DOM order, so it's never covered by
 * this gradient. */
.jdx-events-single__media::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient( to top, rgba( 0, 0, 0, 0.55 ) 0%, rgba( 0, 0, 0, 0 ) 40% );
}

/* Controlled cinematic frame, not natural-height rendering: a tall
 * source photo (common for club/event flyers) previously rendered at
 * full natural height, dominating the page. object-fit: cover crops
 * to a stable frame regardless of the source image's own aspect ratio —
 * default center crop, no crop-position control in this increment.
 * No absolute positioning/pseudo-elements/overlay needed here (unlike
 * the Featured Event hero): the image sits in normal flow above the
 * content, not behind it.
 *
 * Responsive aspect-ratio (validation.41): the approved reference
 * switches to a taller mobile crop (its own .event-hero-img uses 4/5
 * under 760px) so the image still reads at narrow widths instead of
 * being cropped down to a thin strip. Locking straight to 4/5 here was
 * evaluated and rejected — on a narrow phone viewport (~375-430px wide)
 * a 4/5 crop is ~470-540px tall, which can approach or exceed the
 * initial viewport height on shorter devices, contradicting "must not
 * dominate the entire initial viewport." 1/1 (square) is used instead at
 * the existing 480px breakpoint: still meaningfully taller than desktop's
 * wide 2/1 for image readability, but capped well short of viewport
 * domination, and square geometry is already this system's own stated
 * visual language (Featured/Grid/Calendar). 16/10 at the existing 860px
 * breakpoint gives tablet a controlled, intermediate step rather than
 * jumping straight from 2/1 to 1/1. aspect-ratio (not a fixed height)
 * means no crop ever clips content regardless of viewport size.
 *
 * max-height (validation.44 live Sakura correction): now that
 * .jdx-events-single carries no width ceiling, aspect-ratio:2/1 alone
 * would make the hero grow TALLER as it grows wider on large desktop
 * monitors — the opposite of "wider cinematic banner, not bigger."
 * 840px is exactly what 2/1 already computes at validation.43's own
 * approved 1680px width (1680/2), the height that was already
 * live-validated as correct — so this is a cap, not a new value: at any
 * width ≤1680px the aspect-ratio-derived height is already ≤840px and
 * this never engages (desktop, tablet's 16/10, and mobile's 1/1 below
 * all stay pixel-for-pixel identical to before); only once the hero
 * exceeds 1680px wide does it start cropping additional width at a
 * fixed height instead of growing taller. */
.jdx-events-single__image {
	display: block;
	width: 100%;
	aspect-ratio: 2 / 1;
	max-height: 840px;
	object-fit: cover;
}

/* Hero overlay stack (validation.44 live Sakura correction): the single
 * positioned element for both Logo and Status — see
 * templates/single-event-content.php's own comment for why a shared
 * wrapper replaced two independently-positioned siblings (Status's
 * rendered height varies with badge count/wrapping, which a calculated
 * fixed offset for Logo can't reliably anticipate). flex-direction:column
 * + align-items:flex-end stacks whichever of Logo/Status are actually
 * present — Logo (first child, when present) above Status — right-
 * aligned regardless of either one's own width, with no per-child
 * position/inset math at all. Top-left is deliberately left empty; the
 * Sakura site header already owns that corner. */
.jdx-events-single__hero-overlay {
	position: absolute;
	right: 1rem;
	bottom: 1rem;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 0.5rem;
}

/* .jdx-events-single__badges carries no rule of its own any more
 * (validation.44): .jdx-events-card-badges (frontend-event-card.css)
 * already supplies the flex row/gap for the badge row itself, and
 * positioning now lives entirely on the shared
 * .jdx-events-single__hero-overlay wrapper above. The class stays in the
 * template purely as an identifying hook. */

/* Sakura Event Logo watermark (Sakura Event Presentation Refinement) —
 * same subtle, non-interactive treatment as Event Grid's own
 * .jdx-events-card-logo (frontend-event-card.css), scaled up slightly to
 * suit this page's larger hero. Positioning now lives entirely on the
 * shared .jdx-events-single__hero-overlay wrapper above (validation.44). */
.jdx-events-single__logo {
	max-width: 130px;
	max-height: 65px;
	width: auto;
	height: auto;
	pointer-events: none;
	opacity: 0.95;
	filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55));
}

/* Single Event Hero Overlay (v0.2.28-validation.2): Date/Opening Time,
 * Title, Headline, and Rooms/Artists restated directly over the hero
 * image, bottom-left, matching the approved reference design.
 *
 * Overlap safety (structural, not assumed): .jdx-events-single__hero-overlay
 * above (the existing, untouched bottom-right logo/status block) has a
 * hard, non-responsive footprint — .jdx-events-single__logo's own
 * max-width:130px never changes at any breakpoint in this file, and its
 * wrapper sits right:1rem (16px) from the hero's edge, badge text being
 * shorter still. 130px + 16px = 146px is therefore a real, provable
 * upper bound on the right-hand block's width at every viewport size,
 * not an estimate based on "typical" content. Reserving 160px (14px of
 * margin above that hard floor) via calc() below means this block's own
 * box can never extend into that territory, regardless of how long the
 * Title/Headline/Room/Artist strings actually are — combined with
 * overflow-wrap:break-word (inherited by every child below), even a
 * single unbroken long word is forced to wrap inside that box rather
 * than overflow past it. Because both blocks are independently
 * bottom-anchored, this horizontal reservation holds for the whole box
 * regardless of how tall it grows (extra Room rows extend upward, past
 * where the right-hand block already ends, never sideways into it).
 * min(640px, …) keeps the readable-line-length cap already established
 * elsewhere in this plugin (Featured Event's own 640px text columns)
 * on very wide heroes, where 100% - 160px alone would otherwise produce
 * an uncomfortably long line length. */
.jdx-events-single__hero-info {
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 1;
	box-sizing: border-box;
	max-width: min(640px, calc(100% - 160px));
	padding: 2.5rem;
	color: #ffffff;
	overflow-wrap: break-word;
}

/* Isolated readability layer (approved decision): scoped to this new
 * element only — the existing shared .jdx-events-single__media::after
 * vignette above is completely untouched, so the already-validated
 * bottom-right overlay's own readability is unaffected. A restrained
 * bottom-left-anchored darkening, not a full-image overlay: only strong
 * enough to keep text legible, never a visible panel/card (no
 * background-color, no border, no border-radius on the info element
 * itself — text sits directly on this gradient). */
.jdx-events-single__hero-info::before {
	content: '';
	position: absolute;
	inset: -1rem;
	z-index: -1;
	pointer-events: none;
	background: radial-gradient(
		ellipse at bottom left,
		rgba(0, 0, 0, 0.65) 0%,
		rgba(0, 0, 0, 0.4) 45%,
		rgba(0, 0, 0, 0) 80%
	);
}

/* Hero Details: Date & Time (v0.2.30-validation.6, Single Event
 * Typography). Every var() fallback is this rule's own original,
 * unchanged literal — color's fallback is `inherit`, the exact
 * equivalent of this rule never having declared its own color at all
 * (it has always inherited .hero-info's #ffffff; see that rule's own
 * comment). This target is NOT merged with Headline or Rooms & Artists
 * into one "Hero Details" control, even though the spec groups all
 * three under one expandable UI section — they have different existing
 * sizes/weights today (0.9em plain vs 1.1em/600 vs 0.9em+badge), and
 * collapsing them into one shared override would destroy that existing
 * hierarchy, which the approved spec explicitly disallows. */
.jdx-events-single__hero-meta {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0.25em 0.75em;
	margin: 0 0 0.5em;
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-hero-date-time-font-size, 0.9em);
	font-weight: var(--jdx-events-single-typography-hero-date-time-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-hero-date-time-font-style, inherit);
	line-height: var(--jdx-events-single-typography-hero-date-time-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-hero-date-time-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-hero-date-time-color, inherit);
	opacity: 0.85;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

/* Hero Title (v0.2.30-validation.6, Single Event Typography) — the one
 * target with three independent font-size fields (Desktop/Tablet/
 * Mobile) rather than one; see the @media rules below for Tablet/Mobile.
 * This desktop/default declaration's own font-size fallback (2.75em) is
 * unchanged; every other property's fallback is likewise this rule's
 * own original literal. No forced desktop-to-mobile ratio is computed
 * anywhere here — each tier is a fully independent, optional value;
 * leaving all three blank reproduces today's exact two-tier behavior
 * (2.75em above 860px, 2.25em at or below it) because the Tablet/Mobile
 * rules below fall back to those same two literals, not to a formula
 * derived from this one. */
.jdx-events-single__hero-title {
	font-family: var(--jdx-events-font-primary);
	font-size: var(--jdx-events-single-typography-hero-title-font-size-desktop, 2.75em);
	font-weight: var(--jdx-events-single-typography-hero-title-font-weight, 700);
	font-style: var(--jdx-events-single-typography-hero-title-font-style, inherit);
	letter-spacing: var(--jdx-events-single-typography-hero-title-letter-spacing, -0.01em);
	text-transform: uppercase;
	line-height: var(--jdx-events-single-typography-hero-title-line-height, 1.03);
	color: var(--jdx-events-single-typography-hero-title-color, inherit);
	margin: 0 0 0.2em;
	text-shadow: 0 2px 6px rgba(0, 0, 0, 0.65);
}

/* Hero Details: Headline (v0.2.30-validation.6, Single Event
 * Typography) — see .jdx-events-single__hero-meta's own comment above
 * for why this is a separate target from Date & Time and Rooms &
 * Artists rather than one shared "Hero Details" override. */
.jdx-events-single__hero-headline {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-hero-headline-font-size, 1.1em);
	font-weight: var(--jdx-events-single-typography-hero-headline-font-weight, 600);
	font-style: var(--jdx-events-single-typography-hero-headline-font-style, inherit);
	line-height: var(--jdx-events-single-typography-hero-headline-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-hero-headline-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-hero-headline-color, inherit);
	margin: 0 0 0.6em;
	opacity: 0.95;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

.jdx-events-single__hero-rooms {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.3em;
}

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

/* Hero Details: Rooms & Artists (v0.2.30-validation.6, Single Event
 * Typography) — paired across two elements under ONE set of controls,
 * unlike Date & Time/Headline above: the artist name and its room
 * badge are one visual unit, not two differently-weighted roles, so
 * sharing font-size/weight/style/line-height/letter-spacing between
 * them is a reasonable "make this unit bigger/smaller together," not
 * the kind of hierarchy-flattening the spec warns against. Text Color
 * is the one exception — it applies ONLY to the artist name below, not
 * the badge (next rule): the badge has its own deliberate background/
 * text color PAIRING (--jdx-events-room-badge-bg/-text,
 * frontend-event-card.css) that an independent text-color override
 * could put out of contrast with its own background. */
.jdx-events-single__hero-room-artist {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-hero-rooms-artists-font-size, 0.9em);
	font-weight: var(--jdx-events-single-typography-hero-rooms-artists-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-hero-rooms-artists-font-style, inherit);
	line-height: var(--jdx-events-single-typography-hero-rooms-artists-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-hero-rooms-artists-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-hero-rooms-artists-color, inherit);
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

/* The room badge itself: .jdx-events-card-badge--room is a cross-widget
 * atomic class (frontend-event-card.css) also rendered by Event Grid,
 * Event Index, Event Calendar, and Featured Event — styling it bare
 * here would leak into all of them. Ancestor-scoped to
 * .jdx-events-single, the same technique Elementor\Widgets\
 * FeaturedEventWidget's own Room Badge Typography control already uses
 * safely in production, so this can only ever match a badge actually
 * rendered on this page. Font-size/weight/style/line-height/
 * letter-spacing only — no color override, see this rule block's own
 * comment above. */
.jdx-events-single .jdx-events-card-badge--room {
	font-size: var(--jdx-events-single-typography-hero-rooms-artists-font-size, 0.75em);
	font-weight: var(--jdx-events-single-typography-hero-rooms-artists-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-hero-rooms-artists-font-style, inherit);
	line-height: var(--jdx-events-single-typography-hero-rooms-artists-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-hero-rooms-artists-letter-spacing, 0.05em);
}

/* Previously undeclared: content had no horizontal padding of its own
 * at all, so it touched the component's edges directly. Desktop value
 * bumped in validation.42 (3rem) with proportionally more generous
 * whitespace; reduced at the existing narrow breakpoint below.
 *
 * max-width/margin-inline (validation.43, still current in validation.44
 * now that .jdx-events-single itself carries no width constraint of its
 * own): this is now the SOLE width boundary for the information section,
 * keeping it at its own controlled 1320px column independent of however
 * wide the hero above it renders. */
/* Wide content canvas (v0.2.28-validation.3): raised from 1320px to
 * 1680px so the body aligns with the hero above it — 1680px matches the
 * same wide ceiling already live-validated for the hero image itself
 * (validation.43/.44), not a new, unrelated number. margin-inline:auto +
 * padding:3rem are unchanged — a wider canvas with controlled outer
 * gutters, not edge-to-edge paragraph text. */
/* Fluid body canvas (v0.2.28-validation.3 follow-up): replaces the
 * previous fixed 1680px ceiling, which produced a visibly boxed section
 * under the full-width hero above on ultra-wide screens (the hero has
 * no max-width of its own at all). 96vw tracks the viewport directly,
 * with no additional hard pixel cap — a second arbitrary ceiling here
 * would only recreate the same mismatch at a larger screen size. The
 * readable main-column measure and the sidebar's premium width are now
 * constrained independently, below (.jdx-events-single__section,
 * .jdx-events-single__sidebar), not by this canvas-level rule. */
.jdx-events-single__content {
	box-sizing: border-box;
	max-width: 96vw;
	margin-inline: auto;
	padding: 3rem;
}

/* Two-column body (Sakura Event Presentation Refinement, Single Event
 * recreation): main content + a sticky sidebar, per the approved
 * event-single.html reference. align-items:start keeps the sidebar from
 * stretching to the (usually taller) main column's height, which is
 * what makes position:sticky below meaningful.
 *
 * Proportional 2fr/minmax(320px,1fr) columns (v0.2.28-validation.3):
 * replaces the previous fixed "1fr 380px" — a fixed sidebar width read
 * as increasingly narrow/lopsided once the canvas widened to 1680px
 * above. ~65/35 at typical desktop widths; minmax(320px, …) keeps the
 * sidebar from narrowing further than its own card content (Tickets &
 * Tables/Quick Facts) comfortably allows as the viewport shrinks toward
 * the 860px collapse below. */
.jdx-events-single__layout {
	display: grid;
	grid-template-columns: 2fr minmax(320px, 1fr);
	gap: 2.5rem;
	align-items: start;
}

.jdx-events-single__main {
	min-width: 0;
}

/* Visually-hidden semantic page title (v0.2.28-validation.3): the exact
 * same clip technique already established and live-validated by this
 * plugin's own Event Calendar (.jdx-events-calendar__sr-only,
 * event-calendar.css) — mirrored here rather than reused directly, to
 * keep each component's utility class scoped to itself, matching this
 * plugin's existing per-component naming convention. Never rely on the
 * active theme providing a frontend .screen-reader-text class — that is
 * a wp-admin guarantee only, not a frontend one. */
.jdx-events-single__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;
}

/* Back to Events Overview (v0.2.28-validation.1): a full-width block
 * sibling of .jdx-events-single__layout (the main/sidebar grid) rather
 * than a child of either column — deliberately NOT part of this
 * increment's layout refinement scope, so the existing two-column grid
 * is left completely untouched; this simply sits below it. Hidden
 * entirely when the Events Overview URL setting is unconfigured (see
 * templates/single-event-content.php), never a dead link. */
/* Full Events Calendar (v0.2.28) joins here: same restrained structural
 * navigation-link treatment, same container spacing rhythm between
 * stacked left-column blocks — not a duplicated CSS block. */
.jdx-events-single__back-link,
.jdx-events-single__more-nights-calendar-link {
	margin: 2.5rem 0 0;
}

/* Single Event Link Color system (v0.2.28 — Styling Architecture
 * Correction): .jdx-events-single__structural-link joins this shared
 * rule as the standard-link treatment for Directions & Parking/View
 * Hotel Options (templates/single-event-content.php) — both were
 * previously styled with .jdx-events-card-cta/--single-accent (a filled
 * CTA-button look) despite behaving as secondary navigation actions,
 * which is what actually caused their hover to visually resemble a
 * button rather than a link. They are now plain text links, identical
 * in treatment to Back to Events Overview/Full Events Calendar, sharing
 * this exact rule rather than a near-duplicate one.
 *
 * Color now sources from the new Link Color token (was: Accent/Button
 * Color directly) — Accent/Button Color remains the fallback, so an
 * existing site with only Heading/Accent configured (current Sakura)
 * renders unchanged without any new configuration. */
.jdx-events-single__back-link a,
.jdx-events-single__more-nights-calendar-link a,
.jdx-events-single__structural-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.85em;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
	transition: opacity 175ms;
}

/* :visited (v0.2.28 — Styling Architecture Correction): all four are
 * real <a href> elements, so a previously-clicked link (e.g. a tester
 * following Directions & Parking to a maps site and returning) can
 * otherwise pick up a theme/browser default visited-link color —
 * commonly a red/purple hue — instead of staying within the Link Color
 * system. This is the smallest rule needed: explicitly pin :visited to
 * the exact same resolved color as the base state, no separate visited
 * setting. */
.jdx-events-single__back-link a:visited,
.jdx-events-single__more-nights-calendar-link a:visited,
.jdx-events-single__structural-link:visited {
	color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
}

@media ( hover: hover ) {
	/* Host-theme isolation: `color` is explicitly redeclared alongside
	 * `opacity` here, using the new Link Hover Color token (falling back
	 * through Link Color, then Accent/Button Color, then the global
	 * chain) — so an unconfigured site keeps today's exact opacity-only
	 * hover response. */
	.jdx-events-single__back-link a:hover,
	.jdx-events-single__more-nights-calendar-link a:hover,
	.jdx-events-single__structural-link:hover {
		color: var(--jdx-events-single-link-hover-color, var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent))));
		opacity: 0.75;
	}
}

.jdx-events-single__back-link a:focus-visible,
.jdx-events-single__more-nights-calendar-link a:focus-visible,
.jdx-events-single__structural-link:focus-visible {
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

/* More Nights (v0.2.28): compact horizontal event-preview rail, placed
 * inside .jdx-events-single__main (see templates/single-event-content.php)
 * so it naturally fills whatever left-column space About This Night/Back
 * to Events don't already use, independently of the sidebar's own height
 * — no change to .jdx-events-single__layout's grid or the sidebar itself.
 * Same 2.5rem top rhythm as .jdx-events-single__back-link above. */
.jdx-events-single__more-nights {
	margin: 2.5rem 0 0;
}

/* Heading + Previous/Next on one row (v0.2.28-validation.5.1). */
.jdx-events-single__more-nights-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin: 0 0 1em;
}

/* Dedicated section heading (v0.2.28-validation.5.1) — see
 * templates/single-event-content.php's own comment for why this is
 * ".../-heading", not ".../-title" (that name is already taken by each
 * card's own title, .jdx-events-single__more-nights-title below).
 * Deliberately NOT .jdx-events-single__eyebrow: a full section-heading
 * scale/weight, not another small eyebrow label — .jdx-events-single__eyebrow
 * itself is untouched and still governs Tickets & Tables/Quick
 * Facts/Getting There/Need a Hotel exactly as before. Same Heading Color
 * token .jdx-events-single__eyebrow already reads, since this remains a
 * structural section heading, not per-event content. */
/* Main Content Headings: More Nights (v0.2.30-validation.6, Single
 * Event Typography) — deliberately its own target, separate from About
 * This Night (.jdx-events-single__eyebrow above): this is already a
 * distinct class with its own, much larger existing size (2.2em vs
 * 0.7em) and role (a full section heading, not a small uppercase
 * label) — sharing one control between the two would flatten that
 * existing difference, which the approved spec explicitly disallows.
 * Color's fallback chain is extended, not replaced, same as the
 * eyebrow rules above — a site using only the existing
 * single_event_heading_color setting renders identically to today. */
.jdx-events-single__more-nights-heading {
	font-family: var(--jdx-events-font-primary);
	font-size: var(--jdx-events-single-typography-main-heading-more-nights-font-size, 2.2em);
	font-weight: var(--jdx-events-single-typography-main-heading-more-nights-font-weight, 700);
	font-style: var(--jdx-events-single-typography-main-heading-more-nights-font-style, inherit);
	letter-spacing: var(--jdx-events-single-typography-main-heading-more-nights-letter-spacing, -0.01em);
	text-transform: uppercase;
	line-height: var(--jdx-events-single-typography-main-heading-more-nights-line-height, 1.05);
	margin: 0;
	color: var(--jdx-events-single-typography-main-heading-more-nights-color, var(--jdx-events-single-heading-color, var(--jdx-events-color-accent)));
}

/* Previous/Next controls (v0.2.28-validation.5.1): compact, square,
 * accent-colored outline buttons — no border-radius, no filled/boxed
 * background, matching this system's restrained geometry language
 * rather than a modern rounded-carousel look. Progressive enhancement
 * only: assets/js/single-event-more-nights.js attaches the click
 * behavior; the rail beneath remains natively scrollable either way. */
.jdx-events-single__more-nights-nav {
	display: flex;
	gap: 0.5rem;
	flex: 0 0 auto;
}

/* Single Event Link Color system (v0.2.28 — Styling Architecture
 * Correction): icon/border now source from Link Color (was: Accent/
 * Button Color + a dedicated Frame Color setting, both removed) —
 * falling back through Accent/Button Color to the existing global
 * chain, so an unconfigured site renders unchanged. Background stays a
 * hard-coded, non-configurable `transparent` in BOTH normal and hover
 * states (no settings drive it at all, in either state) — the arrows'
 * role is a transparent outline control and must stay that way
 * unconditionally. */
.jdx-events-single__more-nights-nav-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 2em;
	height: 2em;
	padding: 0;
	border: 1px solid var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
	background: transparent;
	color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
	font-size: 1em;
	line-height: 1;
	cursor: pointer;
	transition: opacity 175ms;
}

/* Disabled at a rail boundary (assets/js/single-event-more-nights.js) —
 * stays visible, only visually subdued, per the approved requirement
 * that boundary controls remain visible rather than disappearing. */
.jdx-events-single__more-nights-nav-btn:disabled {
	opacity: 0.35;
	cursor: default;
}

@media ( hover: hover ) {
	/* Host-theme isolation: background/border-color/color are explicitly
	 * redeclared here, using Link Hover Color (falling back through Link
	 * Color, then Accent/Button Color, then the global chain) for
	 * icon/border — background is unconditionally `transparent`, the
	 * exact same literal as the base rule, never token-driven in either
	 * state, per the explicit requirement that these controls stay
	 * transparent regardless of configuration. This selector's own
	 * specificity (0,3,0: one class + :not() + :hover) already exceeds a
	 * generic external button:hover rule (0,1,1), so no !important is
	 * needed. */
	.jdx-events-single__more-nights-nav-btn:not( :disabled ):hover {
		background: transparent;
		border-color: var(--jdx-events-single-link-hover-color, var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent))));
		color: var(--jdx-events-single-link-hover-color, var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent))));
		opacity: 0.75;
	}

	/* Disabled-hover ownership: a disabled arrow at a rail boundary can
	 * still receive a :hover match from the host theme/Elementor reset's
	 * generic `button:hover` rule (0,1,1 specificity), which the base
	 * :disabled rule above (0,2,0: one class + :disabled) does not
	 * outrank on its own for background/border-color/color. This
	 * selector's specificity (0,3,0: one class + :disabled + :hover)
	 * exceeds it, so no !important is needed. Uses the normal Link Color
	 * chain (not Link Hover Color) and the same disabled opacity/cursor
	 * as the base :disabled rule — a disabled arrow must look identical
	 * whether hovered or not. */
	.jdx-events-single__more-nights-nav-btn:disabled:hover {
		background: transparent;
		border-color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
		color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
		opacity: 0.35;
		cursor: default;
	}
}

/* Focus ownership (v0.2.28-validation.5.5): unconditional (not inside
 * @media(hover:hover) — focus is not a hover-only concern) redeclaration
 * of background/border-color/color for plain :focus, distinct from the
 * :focus-visible ring rule below. The host theme/Elementor reset's
 * generic `button:focus` rule (0,1,1 specificity) otherwise wins over
 * the unclaimed base rule (0,1,0) for background-color/color whenever a
 * button is focused without also being hovered (keyboard focus, or a
 * mouse click after which the cursor no longer rests over the ~2em
 * target). This selector's specificity (0,2,0: one class + :focus)
 * exceeds it, so no !important is needed. Uses Link Color, not Link
 * Hover Color — focus alone is not a hover state — and no opacity
 * change, matching the requirement that keyboard focus keeps the
 * existing accessibility ring look, not a hover look. A :disabled
 * button cannot receive focus at all, so no :disabled:focus case exists. */
.jdx-events-single__more-nights-nav-btn:focus {
	background: transparent;
	border-color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
	color: var(--jdx-events-single-link-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
}

.jdx-events-single__more-nights-nav-btn:focus-visible {
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

/* CSS-only horizontal rail: no JS dependency for scrolling itself, no
 * carousel library, no autoplay, no infinite loop, no smooth scrolling
 * declared here (scroll-behavior left at its default/instant value —
 * assets/js/single-event-more-nights.js opts into 'smooth' itself, only
 * when prefers-reduced-motion does not request otherwise). Scrollbar is
 * now visually hidden (v0.2.28-validation.5.1, superseding the previous
 * thin-scrollbar treatment): the Previous/Next buttons are the
 * discoverability affordance now, so a visible scrollbar is redundant.
 * overflow-x remains auto (never hidden) — native touch/trackpad
 * scrolling is fully preserved. */
.jdx-events-single__more-nights-rail {
	display: flex;
	gap: 1rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	list-style: none;
	margin: 0;
	padding: 0;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.jdx-events-single__more-nights-rail::-webkit-scrollbar {
	display: none;
	height: 0;
}

/* Card width/scroll-snap live on the actual flex item (the <li>), not the
 * <a> inside it — the standard place for both on a flex child. */
.jdx-events-single__more-nights-item {
	flex: 0 0 auto;
	width: 220px;
	scroll-snap-align: start;
}

/* Deliberately borderless/no background (unlike the sidebar's own
 * ticket-box/quick-facts/getting-there/hotel surfaces): a "dashboard
 * card" box here would read at odds with the cinematic, image-led Sakura
 * language already established by the hero — this is a plain image +
 * text teaser, matching Featured Event's own restrained aesthetic. No
 * border-radius anywhere, matching this system's existing square
 * geometry language. */
.jdx-events-single__more-nights-card {
	display: flex;
	flex-direction: column;
	gap: 0.5em;
	width: 100%;
	color: inherit;
	text-decoration: none;
}

.jdx-events-single__more-nights-media {
	position: relative;
	display: block;
	aspect-ratio: 4 / 5;
	overflow: hidden;
}

.jdx-events-single__more-nights-media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.jdx-events-single__more-nights-badges {
	position: absolute;
	top: 0.5rem;
	right: 0.5rem;
}

.jdx-events-single__more-nights-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25em 0.5em;
	font-family: var(--jdx-events-font-secondary);
	font-size: 0.75em;
	opacity: 0.7;
}

/* Main Content Body: Related Event Text (v0.2.30-validation.6, Single
 * Event Typography) — deliberately just this element, not also
 * .jdx-events-single__more-nights-meta (the quiet date/time line inside
 * the same card): that element has a markedly different existing
 * treatment (0.75em/opacity:0.7 vs this rule's 1em/weight 700/
 * uppercase) and combining the two under one "Related Event Text"
 * override would flatten that distinction, which the approved spec
 * explicitly disallows — .more-nights-meta is intentionally left
 * unstyled by this feature. Color applies to the BASE (non-hover)
 * state only; the existing @media(hover:hover) rule below, being more
 * specific, continues to override it on hover unconditionally, with or
 * without this setting configured. */
.jdx-events-single__more-nights-title {
	font-family: var(--jdx-events-font-primary);
	font-size: var(--jdx-events-single-typography-main-body-related-font-size, 1em);
	font-weight: var(--jdx-events-single-typography-main-body-related-font-weight, 700);
	font-style: var(--jdx-events-single-typography-main-body-related-font-style, inherit);
	letter-spacing: var(--jdx-events-single-typography-main-body-related-letter-spacing, -0.01em);
	text-transform: uppercase;
	line-height: var(--jdx-events-single-typography-main-body-related-line-height, 1.2);
	color: var(--jdx-events-single-typography-main-body-related-color, inherit);
	transition: color 175ms;
}

@media ( hover: hover ) {
	/* Existing Single Event Accent/Button Color token — the same one the
	 * Back to Events/Full Events Calendar links, sidebar hover borders,
	 * and Pricing already use. No cursor/transform change, matching the
	 * restrained hover language established for informational surfaces
	 * elsewhere on this page. */
	.jdx-events-single__more-nights-card:hover .jdx-events-single__more-nights-title {
		color: var(--jdx-events-single-accent-color, var(--jdx-events-color-accent));
	}
}

.jdx-events-single__more-nights-card:focus-visible {
	box-shadow: 0 0 0 3px var(--jdx-events-focus-ring-shadow);
	outline: 2px solid var(--jdx-events-focus-ring-outline);
	outline-offset: 3px;
}

/* Sticky so the sidebar stays visible while a long Description scrolls
 * past in the main column — a common affordance in the approved
 * reference. top offset leaves a small gap from the viewport edge
 * rather than sitting flush against it.
 *
 * display:flex/gap (validation.42): the sidebar now always renders (see
 * templates/single-event-content.php's own comment — Quick Facts is
 * meaningful even without a ticket box), so it can hold up to two boxes
 * stacked vertically; this replaces the old single-child assumption
 * (the previous .jdx-events-single__main:only-child fallback rule is
 * removed — .jdx-events-single__main is never this grid's only child
 * any more, so that rule was dead weight). */
/* Controlled premium sidebar width (v0.2.28-validation.3 follow-up):
 * .jdx-events-single__layout's own minmax(320px, 1fr) track can now grow
 * much wider on an ultra-wide canvas (see .jdx-events-single__content
 * above) — max-width keeps Tickets & Tables/Quick Facts at a sensible
 * card width instead of stretching with the track. Because this is a
 * CSS Grid item, applying max-width alone (without justify-self/margin)
 * would leave it snapped to the START (left) edge of its now-wider
 * track — margin-left:auto instead keeps it flush against the canvas's
 * right gutter, matching where a sidebar visually belongs. Inert at the
 * <=860px single-column collapse below, where this track is the grid's
 * only column and the sidebar already spans it normally. */
.jdx-events-single__sidebar {
	max-width: 460px;
	margin-left: auto;
	position: sticky;
	top: 2rem;
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

/* Premium surface treatment (validation.41, extended to Quick Facts in
 * validation.42 — both sidebar boxes share one definition, not two
 * near-duplicate rules): a subtle tint (not a solid fill) plus a hover
 * border-color response toward the existing accent token — same
 * restrained language Event Grid/Event Index/Calendar's own cards
 * already use for their border-hover response (validation.40), a
 * literal low-opacity white rather than a new token (decorative depth
 * only, not a themed color decision). Still square/bordered, not a
 * rounded UI card — no border-radius anywhere, matching Sakura's own
 * geometry language. Scoped to hover-capable input only, matching every
 * other hover rule in this plugin, so touch devices are unaffected. */
.jdx-events-single__ticket-box,
.jdx-events-single__quick-facts,
.jdx-events-single__getting-there,
.jdx-events-single__hotel {
	box-sizing: border-box;
	border: 1px solid var(--jdx-events-card-border-color);
	/* v0.2.28-validation.4.1: 1.75rem → 1.5rem for a more compact/elegant
	 * sidebar per live validation feedback — Getting There/Need a Hotel
	 * inherit this automatically through the existing shared selector,
	 * no separate override needed. Border width/color untouched (already
	 * a minimal 1px hairline). */
	padding: 1.5rem;
	background-color: rgba( 255, 255, 255, 0.015 );
	transition: border-color 175ms;
}

@media ( hover: hover ) {
	/* Getting There/Need a Hotel joined here (v0.2.28 — Getting There +
	 * Need a Hotel) after inspecting what this rule actually does, per
	 * explicit instruction not to extend it "merely because" Tickets &
	 * Tables/Quick Facts already share it: it changes border-color only
	 * — no cursor, no fill, no transform/elevation — and Quick Facts
	 * (a plain, non-interactive definition list with zero links) already
	 * carries this exact treatment today without suggesting the whole
	 * box is clickable. Getting There/Need a Hotel are the same kind of
	 * informational container, so the same restrained response is
	 * visual-consistency, not new interactive affordance. The CTA inside
	 * either box keeps its own separate, real interactive hover/focus
	 * behavior via .jdx-events-card-cta below, unaffected by this rule. */
	.jdx-events-single__ticket-box:hover,
	.jdx-events-single__quick-facts:hover,
	.jdx-events-single__getting-there:hover,
	.jdx-events-single__hotel:hover {
		/* v0.2.28-validation.1: checks the new global Single Event Accent/
		 * Button Color setting first, falling back to the existing
		 * Elementor-chained accent token when unconfigured — preserves
		 * current appearance with zero settings changes. */
		border-color: var(--jdx-events-single-accent-color, var(--jdx-events-color-accent));
	}
}

/* Getting There map (v0.2.28): a CSS-only responsive embed container —
 * no JS, no fixed pixel height. aspect-ratio + position:absolute/inset:0
 * on the iframe is the standard responsive-iframe technique, already
 * used elsewhere in this plugin for images (e.g. the hero); percentage
 * width means this can never cause horizontal overflow regardless of
 * viewport size. The iframe's own src is always a plain, validated URL
 * constructed by the template (Frontend\EventCardPresenter/
 * Support\CtaResolver::is_valid_url()) — never stored/arbitrary iframe
 * HTML. */
.jdx-events-single__map {
	position: relative;
	aspect-ratio: 16 / 9;
	margin: 0 0 1.25em;
}

.jdx-events-single__map iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* Need a Hotel promo image (v0.2.28): plain responsive native image
 * output — width/height attributes (already resolved by
 * Frontend\EventCardPresenter::hotel_image(), same
 * wp_get_attachment_image_src() pattern as poster()/logo()) prevent
 * layout shift while the CSS width:100%/height:auto lets it scale down
 * with the sidebar, never overflowing it. */
.jdx-events-single__hotel-image {
	display: block;
	width: 100%;
	height: auto;
	margin: 0 0 1.25em;
}

/* Hero Title — Tablet tier (v0.2.30-validation.6, Single Event
 * Typography). 999px is not a new arbitrary value — it reuses the same
 * breakpoint Elementor\Widgets\EventIndexWidget's own Event Index grid
 * already establishes elsewhere in this plugin, so there is exactly one
 * new breakpoint NUMBER introduced anywhere in this feature, not an
 * invented one. Nothing previously happened to Hero Title between this
 * width and the existing 860px step below — the fallback here is
 * therefore the SAME 2.75em the unmedia'd desktop rule above already
 * uses, so leaving this tier unset reproduces exactly what already
 * rendered in this width range before this setting existed. */
@media ( max-width: 999px ) {
	.jdx-events-single__hero-title {
		font-size: var(--jdx-events-single-typography-hero-title-font-size-tablet, 2.75em);
	}
}

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

	/* Mobile/tablet sidebar reset (v0.2.28-validation.3.2): the desktop
	 * base rule's max-width:460px/margin-left:auto (added for the
	 * ultra-wide canvas fix above) are independent properties that do
	 * not stop applying just because the grid collapses to one column
	 * here — confirmed via live Sakura testing, not assumed. Without
	 * this reset the sidebar rendered narrow and pushed to the right
	 * edge instead of spanning the single column like the main content
	 * above it. max-width:none + margin-left:0 + width:100% restore full
	 * width; position:static is unchanged from before. */
	.jdx-events-single__sidebar {
		position: static;
		max-width: none;
		margin-left: 0;
		width: 100%;
	}

	/* Tablet transition step — see .jdx-events-single__image's own
	 * comment above for the full responsive-hero rationale. */
	.jdx-events-single__image {
		aspect-ratio: 16 / 10;
	}

	/* Single Event Hero Overlay (v0.2.28-validation.2): the 160px
	 * reservation against .jdx-events-single__hero-overlay's hard 146px
	 * floor (see .jdx-events-single__hero-info's own comment) still holds
	 * unchanged at this tier — the right-hand block's footprint is not
	 * responsive, so the same reservation remains valid here. Only
	 * padding/title size step down, matching the shorter 16/10 hero
	 * above. */
	.jdx-events-single__hero-info {
		padding: 1.75rem;
	}

	/* Hero Title — Mobile tier (v0.2.30-validation.6, Single Event
	 * Typography): the existing breakpoint/fallback value (2.25em) are
	 * both unchanged — only the literal is now also configurable. */
	.jdx-events-single__hero-title {
		font-size: var(--jdx-events-single-typography-hero-title-font-size-mobile, 2.25em);
	}
}

/* Eyebrow label (validation.42): the small uppercase gold section marker
 * the approved reference repeats above every content block ("ABOUT THIS
 * NIGHT", "TICKETS & TABLES", "QUICK FACTS") — one shared rule, reused
 * verbatim by all three headings rather than three near-duplicate
 * ones. Deliberately plain static UI copy (not Event Meta), same
 * category as "Sold Out"/"Cancelled" elsewhere in this template. */
/* Main Content Headings: About This Night / Sidebar Headings (v0.2.30-
 * validation.6, Single Event Typography): .jdx-events-single__eyebrow
 * is ONE shared class rendered in FIVE places — "About This Night" in
 * the main column, and Tickets & Tables/Quick Facts/Getting There/Need
 * a Hotel in the sidebar. validation.5 targeted the bare class with one
 * control and live testing rejected it: adjusting what was labeled
 * "sidebar heading" also resized the main-column heading, and vice
 * versa. The fix needs no markup change — every "About This Night"
 * occurrence is already nested inside .jdx-events-single__main, and
 * every sidebar occurrence inside .jdx-events-single__sidebar — so an
 * ancestor-scoped selector disambiguates the two contexts in pure CSS.
 * Each rule below reads its OWN typography custom properties
 * (main_heading_about / sidebar_heading — see
 * Support\PluginSettings::typography_targets()), so configuring one can
 * never resize, reweight, or recolor the other. Every var() fallback
 * below is this rule's own original, unchanged literal value — color
 * additionally keeps its pre-existing fallback chain to the global
 * single_event_heading_color setting, now inserted as an intermediate
 * fallback rather than replaced, so a site using only that older color
 * setting (no Typography color configured) renders identically to
 * today. */
.jdx-events-single__main .jdx-events-single__eyebrow {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-main-heading-about-font-size, 0.7em);
	font-weight: var(--jdx-events-single-typography-main-heading-about-font-weight, 700);
	font-style: var(--jdx-events-single-typography-main-heading-about-font-style, inherit);
	line-height: var(--jdx-events-single-typography-main-heading-about-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-main-heading-about-letter-spacing, 0.18em);
	text-transform: uppercase;
	color: var(--jdx-events-single-typography-main-heading-about-color, var(--jdx-events-single-heading-color, var(--jdx-events-color-accent)));
	margin: 0 0 1em;
}

.jdx-events-single__sidebar .jdx-events-single__eyebrow {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-sidebar-heading-font-size, 0.7em);
	font-weight: var(--jdx-events-single-typography-sidebar-heading-font-weight, 700);
	font-style: var(--jdx-events-single-typography-sidebar-heading-font-style, inherit);
	line-height: var(--jdx-events-single-typography-sidebar-heading-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-sidebar-heading-letter-spacing, 0.18em);
	text-transform: uppercase;
	color: var(--jdx-events-single-typography-sidebar-heading-color, var(--jdx-events-single-heading-color, var(--jdx-events-color-accent)));
	margin: 0 0 1em;
}

/* Readable main-column measure (v0.2.28-validation.3 follow-up):
 * .jdx-events-single__main's own grid track can now be very wide on an
 * ultra-wide canvas (see .jdx-events-single__content above) — this caps
 * the actual "About This Night" text block at a comfortable reading
 * line length independently of that track width, leaving natural
 * whitespace within the main column at large screens rather than
 * stretching prose edge to edge. No centering: this wrapper already
 * sits at the left edge of .jdx-events-single__main, matching the
 * existing left-aligned layout. */
.jdx-events-single__section {
	max-width: 780px;
}

/* Main Content Body: Event Description (v0.2.30-validation.6, Single
 * Event Typography). font-size/color fallbacks are `inherit` — this
 * rule has never declared either of its own, so that is the exact
 * equivalent of its current, unconfigured behavior. Navigation links
 * inside the main column (Back to Events Overview, Full Events
 * Calendar) are deliberately excluded from this target — they already
 * have their own dedicated single_event_link_color/_link_hover_color
 * settings and read as UI, not body copy. */
.jdx-events-single__description {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-main-body-description-font-size, inherit);
	font-weight: var(--jdx-events-single-typography-main-body-description-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-main-body-description-font-style, inherit);
	letter-spacing: var(--jdx-events-single-typography-main-body-description-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-main-body-description-color, inherit);
	line-height: var(--jdx-events-single-typography-main-body-description-line-height, 1.6);
	margin: 0 0 1.5em;
}

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

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

/* Pricing now lives inside .jdx-events-single__ticket-box in the
 * sidebar, not as a Description sibling in the main column (Sakura
 * Event Presentation Refinement, Single Event recreation) — the
 * previous Description-adjacent divider rule no longer applies and was
 * removed; the ticket box's own border (see .jdx-events-single__ticket-box
 * above) provides the equivalent visual separation from the rest of the
 * page instead. */
/* Stronger Pricing hierarchy (validation.41): font-size bumped from
 * 0.9em and weight added so Pricing reads as a clear, confident price
 * line rather than quiet metadata — still the existing plain per-line
 * string content (Pricing is never parsed into label/amount pairs, per
 * scope), just presented with more visual weight. */
/* Sidebar Body: Pricing (v0.2.30-validation.6, Single Event
 * Typography) — its own target, separate from Quick Facts Labels/
 * Values (below): Pricing already has a markedly different existing
 * size/weight (0.9em/400 vs dt's 0.8em/opacity-0.7 vs dd's 0.85em), and
 * sharing one override across all three would flatten that existing
 * hierarchy, which the approved spec explicitly disallows. Color's
 * fallback chain is extended, not replaced — a site using only the
 * existing single_event_accent_color setting renders identically to
 * today. */
.jdx-events-single__pricing {
	list-style: none;
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-sidebar-pricing-font-size, 0.9em);
	font-weight: var(--jdx-events-single-typography-sidebar-pricing-font-weight, 400);
	font-style: var(--jdx-events-single-typography-sidebar-pricing-font-style, inherit);
	line-height: var(--jdx-events-single-typography-sidebar-pricing-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-sidebar-pricing-letter-spacing, 0.02em);
	color: var(--jdx-events-single-typography-sidebar-pricing-color, var(--jdx-events-single-accent-color, var(--jdx-events-color-accent)));
	margin: 0 0 1em;
	padding: 0;
}

.jdx-events-single__pricing li {
	margin: 0 0 0.35em;
}

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

/* .jdx-events-card-ctas (frontend-event-card.css) already supplies the
 * flex row/gap for the buttons inside this. No top margin by default
 * (unlike the previous single-column layout): this sits inside
 * .jdx-events-single__ticket-box's own padding, directly after Pricing
 * when present, and when Pricing is absent this is simply the box's own
 * first/only child.
 *
 * Section rhythm via a thin rule (validation.41, same technique as the
 * Rooms/Description divider above): when Pricing IS present, a hairline
 * top border + spacing separates it from the CTA row below, matching the
 * approved reference's own visual grouping inside its ticket box — sibling
 * combinator, so an event with no Pricing configured gets no dangling
 * border. */
.jdx-events-single__pricing ~ .jdx-events-single__actions {
	border-top: 1px solid var(--jdx-events-card-border-color);
	padding-top: 1.25em;
}

.jdx-events-single__actions {
	margin: 0;
}

/* Quick Facts (validation.42): a plain definition list — dt/label,
 * dd/value — restyled as quiet, restrained editorial rows rather than an
 * admin-style key/value table. Browser default <dl>/<dd> margins are
 * reset explicitly; nothing else in this file resets them since no
 * other element here uses a definition list. */
.jdx-events-single__quick-facts-list {
	margin: 0;
	padding: 0;
}

/* v0.2.28-validation.4.1: 0.75em → 0.6em — the main lever for a lighter
 * row rhythm per live validation feedback. */
.jdx-events-single__quick-facts-row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1em;
	padding: 0.6em 0;
	border-bottom: 1px solid var(--jdx-events-card-border-color);
}

.jdx-events-single__quick-facts-row:first-child {
	padding-top: 0;
}

.jdx-events-single__quick-facts-row:last-child {
	border-bottom: none;
	padding-bottom: 0;
}

/* Sidebar Body: Quick Facts Labels (v0.2.30-validation.6, Single Event
 * Typography) — see .jdx-events-single__pricing's own comment above
 * for why this is a separate target from Pricing and Quick Facts
 * Values rather than one shared "Sidebar Body" override. Color's
 * fallback is `inherit`: this rule has never declared its own color,
 * only the opacity:0.7 below, which is untouched by this setting and
 * continues to apply on top of whatever color renders (configured or
 * inherited). */
.jdx-events-single__quick-facts-row dt {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-sidebar-facts-label-font-size, 0.8em);
	font-weight: var(--jdx-events-single-typography-sidebar-facts-label-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-sidebar-facts-label-font-style, inherit);
	line-height: var(--jdx-events-single-typography-sidebar-facts-label-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-sidebar-facts-label-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-sidebar-facts-label-color, inherit);
	opacity: 0.7;
	margin: 0;
}

/* Sidebar Body: Quick Facts Values (v0.2.30-validation.6, Single Event
 * Typography) — same rationale as Quick Facts Labels above for why
 * this is its own target. */
.jdx-events-single__quick-facts-row dd {
	font-family: var(--jdx-events-font-secondary);
	font-size: var(--jdx-events-single-typography-sidebar-facts-value-font-size, 0.85em);
	font-weight: var(--jdx-events-single-typography-sidebar-facts-value-font-weight, inherit);
	font-style: var(--jdx-events-single-typography-sidebar-facts-value-font-style, inherit);
	line-height: var(--jdx-events-single-typography-sidebar-facts-value-line-height, inherit);
	letter-spacing: var(--jdx-events-single-typography-sidebar-facts-value-letter-spacing, inherit);
	color: var(--jdx-events-single-typography-sidebar-facts-value-color, inherit);
	margin: 0;
	text-align: right;
	/* flex/min-width (validation.42): without these, a flex item's default
	 * content-based min-width can resist wrapping — the Venue row's full
	 * address is long enough to need to wrap within the 380px sidebar
	 * column rather than overflow it. dt (always a short single word/
	 * phrase) needs neither. */
	flex: 1 1 auto;
	min-width: 0;
}

@media ( max-width: 480px ) {
	.jdx-events-single__content {
		padding: 1.25rem;
	}

	/* Mobile step — see .jdx-events-single__image's own comment above
	 * for the full responsive-hero rationale (square, not the reference's
	 * own 4/5, to stay clear of viewport-domination territory). */
	.jdx-events-single__image {
		aspect-ratio: 1 / 1;
	}

	/* Single Event Hero Overlay (v0.2.28-validation.2): the 160px
	 * reservation (see .jdx-events-single__hero-info's own comment) is
	 * kept unchanged — .jdx-events-single__hero-overlay's 146px floor
	 * does not shrink at this tier either, so reducing the reservation
	 * here would be the exact "assumption" this design was built to
	 * avoid. Only this block's own padding/typography scale down, the
	 * same way .jdx-events-single__content already does above, so more
	 * of the narrower available width goes to actual text. */
	.jdx-events-single__hero-info {
		padding: 1.25rem;
	}

	.jdx-events-single__hero-title {
		font-size: 1.5em;
	}

	.jdx-events-single__hero-headline {
		font-size: 1em;
	}

	.jdx-events-single__hero-meta {
		font-size: 0.8em;
	}

	/* Quick Facts (validation.42): the Venue value in particular is a
	 * full address, long enough that a right-aligned space-between row
	 * would squeeze it into an uncomfortably narrow column on a phone
	 * viewport. Stacking label above value (both left-aligned) at this
	 * existing breakpoint keeps every row easy to scan regardless of
	 * value length, without introducing a new breakpoint. */
	.jdx-events-single__quick-facts-row {
		flex-direction: column;
		align-items: flex-start;
		gap: 0.25em;
	}

	.jdx-events-single__quick-facts-row dd {
		text-align: left;
	}

	/* More Nights (v0.2.28): existing breakpoint reused, no new one
	 * added. ~175px lets part of the next card peek into view on a
	 * narrow phone — a recognizable "more to scroll" affordance. */
	.jdx-events-single__more-nights-item {
		width: 175px;
	}

	/* More Nights heading (v0.2.28-validation.5.1): scaled down so it
	 * doesn't overpower the narrower cards below it; the header row
	 * stays flex/one-line, letting Previous/Next keep their own fixed
	 * ~2em size alongside the smaller heading text. */
	.jdx-events-single__more-nights-heading {
		font-size: 1.6em;
	}
}
