/* Actor Card — Figma component set «Actor Card» 3009:1969
   (template-parts/components/actor-card.php).

   Every number below is one of the set's four width variants, read from
   the REST dump, never interpolated:

   | | mob | tablet | 1440 | Full HD |
   |---|---|---|---|---|
   | Default | 4154:17356 | 4190:18813 | 3009:1873 | 4214:13052 |
   | Variant3 | 4316:28111 | 4316:28093 | 3286:10976 | — |
   | card, photo | 358, 358² | 334, 334² | 376, 376² | 486, 486² |
   | photo → text | 20 | 24 | 24 | 32 |
   | name → rank | 12 | 24 | 24 | 28 |
   | name | Kilok 20/20 | 32/32 | 36/36 | 44/44 |
   | rank | 14/18 | 16/22 | 16/22 | 20/24 |
   | role band | 71 | 83 | 81 | — |

   The card itself is fluid: the photo is a square of the column's width,
   and the type steps are the tokens' own breakpoint modes (tokens.css),
   which is where those variant sizes already live. Only the numbers that
   are NOT in the token file — the two gaps, the band height and the role
   line's own width — are written out here.

   The 1920 column has no Variant3, so the band keeps its 1440 height
   there; noted in designer-questions.md. */

.c-actor-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.c-actor-card__media {
	position: relative;
	aspect-ratio: 1;
	overflow: hidden;
}

.c-actor-card__photo {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;

	/* The resting portrait is BLACK AND WHITE — see the hover block below for
	   where that reading comes from. On `--empty` (no portrait at all) the
	   filter is a no-op: a neutral placeholder has no colour to remove. */
	filter: grayscale(1);

	/* The literal curve, not the `ease-out` keyword, so `getTiming().easing`
	   reads back the string tests/e2e/helpers/motion-sample.js compares
	   against. */
	transition: filter 600ms cubic-bezier(0, 0, 0.58, 1);
}

/* Same reasoning as the repertoire poster: a square 358 box keeps the travel
   under 12% instead of the shared 80px default's 22%. */
.c-actor-card__photo.c-parallax {
	--c-parallax-travel: 40px;
}

/* «Rounded Profile Picture» 3009:1874 — the variant's own placeholder
   fill, so a person with no portrait keeps the card's shape instead of
   collapsing it. */
.c-actor-card__photo--empty {
	background: var(--color-neutral-300);
}

/* Hover — animations.md, row «Картка актора», re-read for client fix ПР-17.

   The row says «Profile Picture» gains a SECOND image fill on hover
   (3009:1873 → 3009:1970, 4214:13052 → 4316:28010), 600 ms ease-out, and
   that was implemented literally: a second attachment crossfading in. What
   the row did not say is WHAT the two fills are. Pulled out of the .fig's
   own uploads by their imageRef (fig-assets.py, no API):

   | layer | imageRef | size | mean chroma (max−min per pixel) |
   |---|---|---|---|
   | rest, «Profile Picture» | 100a1405… | 360² | **0.0** |
   | hover, second fill | a0afb887… | 1024² | 19.6 |

   The two are the SAME photograph of the same actor: the resting one is its
   black-and-white version, the hover one its colour original. And the B/W
   upload is not a quirk of one variant — every one of the 175 resting Actor
   Card instances in the file uses `100a1405…`, at every width and in
   Variant3 as well; only the 5 hover instances add `a0afb887…` on top.

   So the design's hover is «the portrait comes into colour», which is what
   the client asked for in ПР-17 and what the `.fig` draws with two uploads
   because a mock has no database behind it. With one portrait per person
   there is nothing to crossfade to: the same picture is `grayscale(1)` at
   rest and `grayscale(0)` on hover, over the same 600 ms ease-out. Hence
   the rest state on `.c-actor-card__photo` above, and the reveal below on
   `.c-actor-card` — NOT on `--hoverable`, which is only ever about the
   second attachment.

   `person.photo_wide` (the second portrait) is still honoured where it
   exists: it fades in over the same 600 ms, and it arrives in colour
   because the reveal below covers both layers. No person in the database
   has one yet (theatre-questions.md), so on real pages the grayscale is the
   whole effect — and that is the state the client was looking at.

   «Люди театру» draws Variant3 (3286:10976 / 4316:28093 / 4316:28111), and
   the set gives Variant3 no hover pair at all, which is why that archive had
   no hover before ПР-17. The client asks for the reveal on actor photos
   without exempting a page, and Variant3 rests on the same B/W upload as
   every other variant — so the reveal belongs to the component, not to a
   page, and the archive gets it too. Ruling recorded in animations.md. */
.c-actor-card__photo--hover {
	opacity: 0;

	/* The shorthand replaces the base layer's own `transition`, so the
	   filter has to be named again here or the second portrait would arrive
	   in colour with no fade of its own saturation. */
	transition:
		opacity 600ms cubic-bezier(0, 0, 0.58, 1),
		filter 600ms cubic-bezier(0, 0, 0.58, 1);
}

/* ≥768 only: the set draws no hover for mob=on — `4154:17356` and
   `4316:28111` have no pair in `3009:1969` — so the phone card keeps its
   rest state, and a 390-wide desktop window does not get a state the phone
   never has. Focus-within carries the same state for the keyboard: the card
   is one link, so focusing it is the same reach as hovering it. */
@media (min-width: 768px) {

	.c-actor-card:focus-within .c-actor-card__photo {
		filter: grayscale(0);
	}

	.c-actor-card--hoverable:focus-within .c-actor-card__photo--hover {
		opacity: 1;
	}
}

/* :hover only where a pointer can hover — on touch a tap would leave the
   card stuck in colour (the same guard view-all.css uses). */
@media (min-width: 768px) and (hover: hover) {

	.c-actor-card:hover .c-actor-card__photo {
		filter: grayscale(0);
	}

	.c-actor-card--hoverable:hover .c-actor-card__photo--hover {
		opacity: 1;
	}
}

/* Variant3's caption over the photo — «Vector 4» (the band) and «Frame
   1437254983» (its 14px inset, bottom-flush with the photo) as one
   element. The band's top edge is a straight diagonal: measured off the
   frame renders it drops 36 % of the band's own height from left to
   right at BOTH widths that draw it (29.2/81 at 1440, 26/71 at 390). */
.c-actor-card__role {
	position: absolute;
	display: flex;
	right: 0;
	bottom: 0;
	left: 0;
	box-sizing: border-box;
	height: 71px;
	align-items: flex-end;
	padding: 14px;
	margin: 0;
	background: var(--color-neutral-100);
	clip-path: polygon(0 0, 100% 36%, 100% 100%, 0 100%);
	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);
}

/* «Title» 4316:28137 / 3286:10988 is a FIXED-width text inside a wider
   band (232 of 330 at 390, 231 of 348 at 1440), which is what makes the
   mock's role wrap after «домогосподарка,». The tablet variant's own 348
   is wider than its 334 box — a defect of that node, so between the two
   frames the line simply fills the band (designer-questions.md). */
.c-actor-card__role-text {
	display: block;
	width: 232px;
	max-width: 100%;
}

.c-actor-card__text {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.c-actor-card__name {
	margin: 0;
	font-family: var(--font-title);
	font-size: var(--fs-h6);
	font-weight: 400;
	line-height: var(--lh-h6);
	letter-spacing: var(--ls-h6);

	/* leadingTrim CAP_HEIGHT on «Name» (4316:28119, 3286:10984,
	   4214:13053); the padding is the substitute font's cap-height
	   shortfall, as performance-t14.css's own note explains. */
	padding-bottom: var(--podil-cap-fix, 0);
	text-box: trim-both cap alphabetic;
	color: var(--color-neutral-800);
	text-transform: uppercase;
}

.c-actor-card__name a {
	color: inherit;
	text-decoration: none;
}

/* One link for the whole card: the `.fig` draws the hover cursor over the
   PHOTO, so the photo has to be clickable, and a second link to the same
   person would only add a stop for keyboard and screen-reader users. */
.c-actor-card__name a::after {
	position: absolute;
	content: "";
	inset: 0;
}

.c-actor-card__rank {
	margin: 0;
	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);
	color: var(--color-neutral-800);
	text-transform: uppercase;
}

@media (min-width: 768px) {

	.c-actor-card {
		gap: 24px;
	}

	.c-actor-card__role {
		height: 83px;
	}

	.c-actor-card__role-text {
		width: 100%;
	}

	.c-actor-card__text {
		gap: 24px;
	}

	.c-actor-card__name {
		font-size: var(--fs-h3);
		line-height: var(--lh-h3);
		letter-spacing: var(--ls-h3);
	}
}

@media (min-width: 1440px) {

	.c-actor-card__role {
		height: 81px;
	}

	.c-actor-card__role-text {
		width: 231px;
	}
}

@media (min-width: 1920px) {

	.c-actor-card {
		gap: 32px;
	}

	.c-actor-card__text {
		gap: 28px;
	}
}

/* Windows High Contrast: the band is a background, which forced-colors
   drops, so the caption would sit straight on the photo. A solid Canvas
   fill keeps it readable; the diagonal stays, it is only a clip. */
@media (forced-colors: active) {

	.c-actor-card__role {
		background: Canvas;
		forced-color-adjust: none;
		color: CanvasText;
	}

	/* The rest state's `grayscale(1)` hides nothing — it only desaturates —
	   but forced colours are a request for the most legible rendering the
	   page can give, and a photograph is one of the few things the mode
	   leaves alone. So the portrait is shown untouched, exactly as
	   a11y-themes.css already does with `html[data-contrast="high"] img
	   { filter: none }` for the widget's own high-contrast mode (which,
	   being 0,1,1, already wins over the rest state there). The reveal
	   above still computes to `grayscale(0)`, i.e. the same picture. */
	.c-actor-card__photo {
		filter: none;
	}
}
