/* Event Card — Figma component set 3336:16765 (see
   template-parts/event-card.php's header for why this set, not the
   3274:9334/3009:47 family global-constraints.md names, is the one actually
   placed on the Афіша page). Mobile-first: base rules match `Property
   1=Variant3, mob=on` (390, `4287:29271`); the `min-width: 768px` block
   matches `Property 1=Variant2, mob=off` (1440, `3336:16766`) and is reused
   unscaled through 1920+ (no dedicated tablet/FullHD variant exists for this
   card — residual, task-5-report.md). No radius anywhere in the source node
   (checked `cornerRadius` on the mask, badge and age-rating rectangles — all
   null). */

.event-card {
	display: flex;
	flex-direction: column;

	/* 55 = (390 − 280) / 2 — the card's own artboard is edge-to-edge with the
	   page at 390, this is its sole gutter. Below 390 the gutter gives way
	   instead of pushing the poster past the viewport: at a 320px viewport
	   (1280 window at 400% zoom, accessibility-ua.md §7.2 item 8) it resolves
	   to 20px and the 280 poster still fits exactly. At 390 and above it is
	   the frame's own 55 again, so the measured geometry is unchanged
	   (final review I1). */
	padding-inline: min(55px, max(0px, (100% - 280px) / 2));
}

.event-card__poster {
	position: relative;

	/* 280 is «Poster» 4287:29272; `max-width` rather than `width` so a
	   container narrower than 280 + gutters shrinks the poster instead of
	   overflowing (I1). At 390–767 the content box is ≥ 280, so it measures
	   280 exactly as the frame draws it. */
	width: 100%;
	max-width: 280px;
	height: 376px;
	margin: 0 auto 12px;
	overflow: hidden;
	background: var(--color-neutral-200);
}

.event-card__poster-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 40px, not the shared 80: this poster is 376 tall, and the same share of the
   box the article banner's 80 is of its 600 (parallax.css). */
.event-card__poster-img.c-parallax {
	--c-parallax-travel: 40px;
}

.event-card__poster-placeholder {
	width: 100%;
	height: 100%;
	background: var(--color-neutral-300);
}

/* «Age Rating Container» — the shared slanted band (poster-band.css). Its
   top edge, measured on the 1:1 frame renders (design/figma/frames, the
   REST dump has no vector geometry): 280×58 at 390 (4287:29271) drops
   31px left → right, 207×51.6 at 1440 (3336:16766) drops 32px. */
.event-card__age-rating {
	--c-poster-band-height: 58px;
	--c-poster-band-rise: 31px;
}

.event-card__details {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
}

.event-card__info {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.event-card__title-section {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.event-card__header {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.event-card__time-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
}

/* Figma's own colour (#12AD99, --color-primary-500) is 2.7:1 on the page
   background (#FAFAFA) — fails WCAG AA outright. --color-primary-600
   (3.56:1) was the first substitute, but it only clears the large-text 3:1
   floor: at 390 --fs-h5 is 22px/font-weight 600, and axe's bold cutoff is
   700 — so this text counts as *normal* weight there, needs the full
   4.5:1, and 3.56:1 fails it (axe-core, `/components/` @ 390 — see
   designer-questions.md). --color-primary-700 (5.26–5.49:1) clears 4.5:1
   at every size this token is used at, so one colour now covers all
   breakpoints instead of relying on the large-text exemption; same token
   already used for every other primary-600-on-light substitution in this
   theme (site-header nav, footer site-map link, phone). */
.event-card__time {
	color: var(--color-primary-700);
	font-family: var(--font-body);
	font-size: var(--fs-h5);
	font-weight: 600;
	line-height: var(--lh-h5);
	letter-spacing: var(--ls-h5);
}

.event-card__tags {
	display: flex;
	align-items: center;
	gap: 20px;
}

.event-card__access {
	display: flex;
	align-items: center;
	gap: 8px;
}

.event-card__access-item svg {
	display: block;
	width: 29px;
	height: 24px;
}

.event-card__badge {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100px; /* Fixed at both breakpoints (Figma «Frame 1437254854», 3286:10928/30/32 — all three availability variants share one width so the badge doesn't resize the row when the state changes). */
	padding: 4px 8px;
	font-family: var(--font-body);
	font-size: var(--fs-xs-text);
	line-height: var(--lh-xs-text);
	letter-spacing: var(--ls-xs-text);
	white-space: nowrap;
}

.event-card__badge--available {
	background: var(--color-primary-100);
	color: var(--color-primary-800);
}

.event-card__badge--few {
	background: var(--color-attention-100);
	color: var(--color-attention-700);
}

.event-card__badge--sold_out {
	background: var(--color-neutral-100);
	color: var(--color-neutral-700);
}

/* Mobile title uses the H6 scale, not a smaller H3 (Figma text-style «H6/2»
   on `Event Title` inside `Property 1=Variant3, mob=on`, 20px/20px — the
   same numbers as the H6 token at 390, confirmed against
   tokens/figma-variables.json's `type.h6` mode). Desktop (`Property
   1=Variant2, mob=off`) uses H3 (36px at 1440) — a real style swap between
   breakpoints, not a scaled instance of one style, so it can't be a single
   `--fs-h3`/`--fs-h6` var either way. */
.event-card__title {
	margin: 0;
	color: var(--color-neutral-800);
	font-family: var(--font-title);
	font-size: var(--fs-h6);
	font-weight: 400;
	line-height: var(--lh-h6);
	letter-spacing: var(--ls-h6);
	text-transform: uppercase;
}

.event-card__title a {
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-decoration: none;
	text-transform: inherit;
}

.event-card__title a:hover,
.event-card__title a:focus-visible {
	text-decoration: underline;
}

/* The hover variants of the card family turned «Event Title» #272B30 → #0C9586
   in the 22.09 .fig (4351:24489 at Full HD=off, 4351:24389 at Full HD=on,
   action unchanged at ON_HOVER SMART_ANIMATE 600 ms ease-out). Those variants
   belong to the vertical card set 3274:9334, which is `.c-repertoire-card`
   (repertoire.css) — this horizontal list card is the other set, 3336:16765,
   and that one has no hover variant at all. Carried over anyway so the two
   visually identical cards on neighbouring pages do not behave differently
   (fix round 1, I4); if the designer rules the horizontal card is meant to
   stay inert, this block is the one to remove.

   Driven by the CARD, like the vertical one: the action in the .fig is on the
   whole variant, not on the title layer. #0C9586 is --color-primary-600 and
   3.7:1 on white, which fails AA for text, so this is the same substitution
   details-link.css and the header already make: --color-primary-700 at 5.5:1
   (designer-questions.md). The literal curve, not the `ease-out` keyword, so
   `getTiming().easing` reads back the string the motion tests compare
   against. */
.event-card__title a {
	transition: color 600ms cubic-bezier(0, 0, 0.58, 1);
}

.event-card:hover .event-card__title a,
.event-card:focus-within .event-card__title a {
	color: var(--color-primary-700);
}

/* Excerpt: visible=false on the mobile variant (`Event Description
   (hidden)`, `4287:29295`) — hidden below 768, two-line clamp above it
   (Figma shows the text cut mid-word at a fixed two-line box). */
.event-card__excerpt {
	display: none;
}

.event-card__specs {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.event-card__spec {
	display: flex;
	flex-direction: column;
	gap: 2px; /* 4px at >= 768px — see the media query below (Figma: SpecRow/* gap is 2 at 390, 4 at 1440). */
}

/* Ruling R16 (task-6-review.md, replaces fix round 1's R10 — see the
   longer comment in event-card.php): genre/stage/duration are independent
   short labels, not a WCAG 1.3.2 "meaningful sequence", so `order` is back
   for <768px only, reordering the DOM's desktop-matching Genre/Stage/
   Duration into the mobile frame's own Duration+Stage row, Genre below
   (`4287:29271`). >=768px (below) resets `order` to 0 — DOM already
   matches Figma there (`3336:16766`), nothing to reorder. */
.event-card__spec--duration {
	order: 1;
	flex: 1 1 0;
}

.event-card__spec--stage {
	order: 2;
	flex: 1 1 0;
}

.event-card__spec--genre {
	order: 3;
	flex: 1 1 100%;
}

.event-card__spec-heading {
	display: flex;
	align-items: center;
	gap: 4px;
}

.event-card__spec-heading svg {
	display: block;
	width: 16px;
	height: 16px;
	flex-shrink: 0;
}

.event-card__spec--duration .event-card__spec-heading svg {
	width: 14px;
	height: 14px;
}

.event-card__spec-label,
.event-card__spec-value,
.event-card__spec-note {
	font-family: var(--font-body);
	font-size: var(--fs-s-text);
	line-height: var(--lh-s-text);
	letter-spacing: var(--ls-s-text);
}

.event-card__spec-label {
	color: var(--color-neutral-600);
}

.event-card__spec-value {
	color: var(--color-neutral-800);
	font-weight: 600;
}

.event-card__spec-value-row {
	display: flex;
	align-items: baseline;
	gap: 2px;
	flex-wrap: wrap;
}

.event-card__spec-note {
	color: var(--color-neutral-500);
}

.event-card__divider {
	height: 1px;
	margin: 16px 0;
	background: var(--color-neutral-200);
}

.event-card__sidebar {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.event-card__price {
	align-self: flex-start; /* Figma: Price is `size=w:hug` inside a column Sidebar/Price Container — a stretched block <p> would fill the sidebar's full width instead. */
	margin: 0;
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: var(--fs-menu-button);
	font-weight: 600;
	line-height: var(--lh-menu-button);
	letter-spacing: var(--ls-menu-button);
	text-transform: uppercase;
}

.event-card__actions {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 8px 20px;
}

/* No Figma node covers the sold-out explanation
   (`podil_ticket_button()`'s `.c-ticket__note`, Task 4) inside this card's
   Action Buttons row — it simply wasn't drawn for this card. Dropped to its
   own full-width line rather than left to overflow the row
   (`overflow-sweep.js` caught the overflow before this rule existed);
   designer-questions.md has a line asking for the intended placement. */
.event-card__actions .c-ticket__note {

	/* Row (mobile) layout only — its own full-width line, instead of
	   competing with the ticket button and Details Link for horizontal
	   space. */
	flex-basis: 100%;
	min-width: 0;
}

.event-card__details-link {
	display: inline-flex;
	align-items: baseline;
	gap: 8px;
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: var(--fs-s-text);
	font-weight: 600;
	line-height: var(--lh-s-text);
	letter-spacing: var(--ls-s-text);
	text-decoration: none;
	text-transform: uppercase;

	/* animations.md row 60 «Картка події»: 600ms ease-out (the same
	   duration/easing as row 61, «Детальніше», confirmed against the
	   aggregated `fig-canvas.js interactions` output — 532× "ON_HOVER →
	   SWAP_STATE SMART_ANIMATE 600ms cubic-bezier(0,0,0.58,1)", with the
	   Details Link's own Default node (3009:38) listed as one of the
	   examples). Written as the literal curve, not the `ease-out` keyword
	   they're equal to, so `effect.getTiming().easing` reports the same
	   string the rest of the codebase's motion tests compare against
	   (tests/e2e/animations.spec.js). `prefers-reduced-motion`/
	   `html[data-motion="reduced"]` already zero every transition-duration
	   globally (base.css / a11y-themes.css) — no per-component override
	   needed here.

	   `gap` itself is NOT animated (fix round 4, `animations.spec.js:543`
	   failing on `main`): this link is the last, hug-width child of a
	   right-pinned Sidebar/Action Buttons chain (`.event-card__info` is
	   `flex: 1 1 auto` and absorbs the width change) — animating `gap`
	   8px→12px grows the link's own box from its *left* edge, so the
	   label moved left and the arrow stayed still, the mirror of what
	   `Property 1=Hover` (4312:24184) draws (label fixed, arrow +4px
	   right). Figma's own SMART_ANIMATE tweens layer *positions*, not an
	   auto-layout property, so the arrow SVG's `transform: translateX()`
	   below reproduces that directly — visual-only, doesn't touch this
	   element's box width, so nothing upstream (Sidebar, Info, the card's
	   1440 geometry — tests/design/event-card/) shifts at all. */
	transition: color 600ms cubic-bezier(0, 0, 0.58, 1);
}

.event-card__details-link svg {
	display: block;
	width: 27.1111px;
	height: 12px;
	align-self: center;
	transition: transform 600ms cubic-bezier(0, 0, 0.58, 1);
}

/* animations.md row 60 «Картка події» (not row 61 «Детальніше», which is a
   different, node-level hover on the Details Link itself — 3336:16765
   doesn't have its own card-level hover variant, but the *effect* row 60
   specifies — the Details Link inside going to its Hover state, ticket
   button keeping its own separate hover — is identical, so it's built the
   same way here): trigger is hovering the card, not just the small link
   hit-area, plus `:focus-within` for keyboard parity (tabbing to either
   link or the ticket button inside the card). Hovering the Ticket Button
   specifically still triggers this too, since it's a descendant of
   `.event-card` — that is `:hover`'s normal cascade, not a second,
   separate trigger, and the ticket button's own hover (Task 3/4) runs
   independently alongside it. `Property 1=Hover` (4312:24184): text
   darkens and the gap to the arrow grows 8px → 12px, arrow itself
   unchanged. The Figma hover colour (#0C9586, --color-primary-600) is
   3.71:1 on white — fails WCAG AA for normal text (needs 4.5:1);
   substituted with --color-primary-700 (#0F766C, 5.49:1) — see
   designer-questions.md. */
.event-card:hover .event-card__details-link,
.event-card:focus-within .event-card__details-link {
	color: var(--color-primary-700);
}

.event-card:hover .event-card__details-link svg,
.event-card:focus-within .event-card__details-link svg {
	transform: translateX(4px);
}

@media (min-width: 768px) {

	.event-card {
		flex-direction: row;
		align-items: stretch;
		gap: 20px;
		padding-inline: 0;
	}

	.event-card__poster {
		flex: 0 0 207px;
		width: 207px;
		height: 278px;
		margin: 0;
	}

	.event-card__age-rating {
		--c-poster-band-height: 52px;
		--c-poster-band-rise: 32px;
	}

	.event-card__details {
		flex: 1 1 auto;
		min-width: 0; /* Without it, a flex item's default min-width (auto) refuses to shrink below its content's min-content size — at 768–1024px that content (real title/genre/price text, all longer than Figma's placeholders) is wider than the viewport, so the row pushes past it instead of wrapping/eliding (overflow-sweep.js). */
		flex-direction: row;
		align-items: stretch;
		gap: 20px;
		padding-right: 24px;
	}

	.event-card__info {
		flex: 1 1 auto;
		min-width: 0;
		justify-content: space-between;
		gap: 40px;
		padding-block: 12px;
	}

	.event-card__title-section {
		gap: 20px;
	}

	.event-card__title {
		font-size: var(--fs-h3);
		line-height: var(--lh-h3);
		letter-spacing: var(--ls-h3);
		text-box: trim-both cap alphabetic; /* leadingTrim=CAP_HEIGHT on this text node (3336:16783) — confirmed in file.json, desktop only; not set on the mobile "H6/2" instance. */
	}

	.event-card__excerpt {
		display: -webkit-box;
		overflow: hidden;
		margin: 0;
		color: var(--color-neutral-800);
		font-family: var(--font-body);
		font-size: var(--fs-s-text);
		line-height: var(--lh-s-text);
		letter-spacing: var(--ls-s-text);
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
	}

	.event-card__specs {
		flex-wrap: nowrap;
		gap: 20px;
	}

	.event-card__spec {
		flex: 1 1 0;
		order: 0;
		gap: 4px;
	}

	.event-card__divider {
		flex: 0 0 auto;
		width: 1px;
		height: auto;
		margin: 12px 0;
	}

	.event-card__sidebar {
		flex: 0 0 auto;
		max-width: 220px; /* Figma's own value is 146 since the 22.09 .fig (was 141.111: the sidebar used to hug the Details Link because Ticket Button was `w:fill`; the re-laid-out set 3336:16765 lets the button hug its own 146 and the sidebar follows it). Widened past both, not matched exactly, because real price text ("від 300 до 500 грн") and the unscoped sold-out note (see above) both run longer than the Figma placeholders — capped so neither can push the row past the viewport (overflow-sweep.js), not to reproduce a specific measurement. The residual against 146 is the shared ticket button's hug padding (16 vs the frame's 36), already logged for `c-ticket`. */
		justify-content: space-between;
		padding-block: 12px;
		background: var(--color-base-white);
	}

	.event-card__actions {
		flex-direction: column-reverse; /* Sidebar/Action Buttons: Details Link above Ticket Button (source order is Ticket Button, Details Link — see event-card.php). */
		flex-wrap: nowrap; /* `wrap` (the mobile rule) plus `column-reverse` opens a second *column* the first is too short for — the sold-out note (below) escaped the row into it (overflow-sweep.js). Not wrapped at all here: `align-items: stretch` already gives every row's worth of a single column its full width. */
		align-items: stretch; /* Ticket Button hugs inside Action Buttons in the 22.09 set (3336:16766) and is the widest child, so stretching to the sidebar's width lands on the same box; Details Link overrides back to hug below. */
		justify-content: flex-start;
		gap: 20px;
	}

	.event-card__details-link {
		align-self: flex-start;
	}
}
