/* Performance page, tz-ua.md §4.4(9)–(15) — «Творча команда», «За лаштунками»,
   «Факти про виставу», «Сцени з вистави», «Перед виставою варто знати»,
   «Що кажуть ті, хто вже побачив виставу», «Ще цікаве» (task 15).

   Figma: «Creative Team» 3159:2289 / 4255:15901 · «Behind The Scenes»
   3399:9561 / 4267:15954 · «Show Facts» 3299:11237 / 4267:16004 · «Scene
   Gallery» 3327:12945 / «Event Gallery Container» 4273:16073 · «Venue
   Info» 3190:3083 / 4273:16074 · «Audience Reviews» 3199:3503 /
   4274:16161 · «More Shows» 3206:3739 / «Afisha Section» 4369:22567.

   Breakpoints: as in performance-hero.css and performance-about.css, only
   390 and 1440 frames exist for the performance page, so the 390 layout
   stays fluid up to 1440 — no invented tablet — and the 1440 layout then
   holds through 1920 (content capped at the frame's own 1328 and
   centred). Type still steps at 768 and 1920: those are the .fig's own
   variable modes, carried by tokens.css.

   Colour substitutions, all of the kind designer-questions.md already
   records for this palette:

   - «#12AD99 on white» as TEXT (the card labels of Venue Info, the
     «Рекомендує виставу» badge) is 2.8:1, under WCAG AA 4.5:1 →
     --color-primary-700 (5.6:1). The same substitution the header,
     footer, event card and show table already make.
   - the big numbers of Show Facts are #12AD99 at 60–96px, i.e. large
     text, where AA asks 3:1 → --color-primary-600 (3.7:1), which is the
     .fig's own neighbouring token and keeps the numbers the accent they
     are drawn as.
   - #2A2A2A (the credit names 3159:2300 and the footnote text 3159:2352)
     and #ECEAE7 (the review card's footer rule 3199:3510) are unbound
     literals in the design — every other colour in these nodes resolves
     to a Colors variable — so they render as their nearest tokens,
     --color-neutral-800 (#272B30) and --color-neutral-200 (#E1E5EA).
     Both logged.

   Hand-placed geometry reproduced rather than averaged away (the decision
   repertoire.css records for its own staggered grid, and each one is a
   line in designer-questions.md): the two hairlines and the six stat
   offsets of Show Facts, the per-slot label widths in the same section,
   and the 3px overhang of the Venue card's lower scrim. */

/* ---------------------------------------------------------- section rhythm */

/* The step itself is declared once, on the page's own `main`
   (`--podil-section-gap`, performance-hero.css): 120 at 390, 180 at 1440. */
.performance-team,
.performance-backstage,
.performance-facts,
.performance-gallery,
.performance-visit-info,
.performance-reviews,
.performance-more {
	margin-top: var(--podil-section-gap);
}

/* «H2/H2 S» 38/40 at 390, 56/56 at 1440, leadingTrim CAP_HEIGHT on every
   one of these title nodes. Kilok is not licensed yet, so the site runs
   Exo 2 under its name (fonts.css): Figma trims to Kilok's 0.70 em cap,
   the substitute's is 0.659 em, and the 0.041 em is added back as bottom
   padding — the remedy visit.css and performance-about.css already use. */
.performance-team__title,
.performance-facts__title,
.performance-gallery__title,
.performance-backstage__title,
.performance-visit-info__title,
.performance-reviews__title {
	margin: 0;
	padding-bottom: 0.041em;
	color: var(--color-neutral-800);
	font-family: var(--font-title);
	font-size: var(--fs-h2-s);
	font-weight: 400;
	line-height: var(--lh-h2-s);
	letter-spacing: var(--ls-h2-s);
	text-box: trim-both cap alphabetic;
	text-transform: uppercase;

	/* At 320 px with the widget's 150 % step (and again with the dyslexia
	   face, which is wider still) a single Ukrainian word of this heading is
	   longer than the column, and an unbreakable word is clipped by its own
	   box — `element-overflow.js` on the three real performances reported it
	   at 320/360/390. The theme's established remedy, used by the repertoire
	   and afisha titles for exactly this case: let the word break rather than
	   cut it or widen the page. Nothing changes at the design's own sizes,
	   where no word reaches the edge. */
	overflow-wrap: anywhere;
}

/* --------------------------------------------------------- творча команда */

.performance-team {
	padding: 0 16px; /* 4255:15901 pad 0/16. */
}

.performance-team__inner {
	display: flex;
	flex-direction: column;
	gap: 40px; /* 4255:15901 itemSpacing: title → credits. */
	margin-inline: auto;
	max-width: 1328px;
}

.performance-team__credits {
	display: flex;
	flex-direction: column;
	gap: 24px; /* 4255:15903: grid → footnote. */
}

.performance-team__grid {
	display: flex;
	flex-direction: column;

	/* One column below 1440 (4255:15904 draws all seven credits in one), so
	   the two DOM columns run on without a gap between them; at 1440 the
	   .fig's own 60 separates them side by side. */
	gap: 0;
}

.performance-team__column {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	min-width: 0;
	margin: 0;
}

/* «Director» 4255:15906 etc.: stacked at 390 (gap 8, padding 20 top and
   bottom, 1px rule under each), a space-between row at 1440. The rule is
   an inside stroke, so `box-shadow: inset` — a border would change the
   row's own box (global-constraints.md). */
.performance-team__row {
	display: flex;
	box-sizing: border-box;
	flex-direction: column;
	align-items: flex-start; /* the two texts hug, as the .fig's nodes do. */
	gap: 8px;
	padding: 20px 0;

	/* A real border: «Credit Row / Director» 4255:15906 is a hug frame 67
	   tall over 66 of content, i.e. the .fig counts this 1px stroke in the
	   row's own height. At 1440 the rows are a fixed 97 and `border-box`
	   keeps them there. */
	border-bottom: 1px solid var(--color-neutral-300);
}

/* Only the very first credit of the section loses its top padding
   (4255:15906 pad 0/0/20/0); below 1440 that is the first row of the first
   DOM column, because the two columns read as one. */
.performance-team__grid > :first-child > .performance-team__row:first-child {
	padding-top: 0;
}

.performance-team__position {
	margin: 0;
	color: var(--color-neutral-600);
	font-family: var(--font-body);
	font-size: var(--fs-s-text);
	font-weight: 400;
	line-height: var(--lh-s-text);
	letter-spacing: var(--ls-s-text);
}

.performance-team__names {
	display: flex;
	flex-direction: column;
	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;
}

/* One line per name: the field stores them one per line, and the design
   draws them that way — «Name / Polianskyi & Kudlinskyi» 3159:2214 is a
   single text node whose two lines are separated by a U+2028. */
.performance-team__name {
	display: block;
}

/* «Footnote» 4255:15946 / 3159:2351 — a note card: italic body text on
   neutral-100 with a 2px teal bar down its left edge. A REAL border, not
   the `box-shadow: inset` these sections use elsewhere: the .fig's own
   auto-layout puts its 20/34 padding INSIDE the stroke (the text starts
   at 36 of a 34-padded card), which is exactly what a border-box border
   does, and the card's outer box is unchanged either way. */
.performance-team__note {
	box-sizing: border-box;
	padding: 20px;
	border-left: 2px solid var(--color-primary-500);
	background: var(--color-neutral-100);
}

.performance-team__note-text {
	margin: 0;
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: var(--fs-s-text);
	font-style: italic;
	font-weight: 400;
	line-height: var(--lh-s-text);
	letter-spacing: var(--ls-s-text);
}

/* ------------------------------------------------------------------- факти */

.performance-facts {
	position: relative;
	padding: 80px 0 76px; /* 4267:16004: title top 80, last stat bottom 777 of 853. */
	overflow: hidden;
	background: var(--color-base-white);
}

/* The .fig's own paper texture over white, at 40 % (3299:11237 /
   4267:16004: `scaleMode: STRETCH, opacity: 0.4`) — the same asset and the
   same treatment performance-about.css uses. */
.performance-facts::before {
	content: "";
	position: absolute;
	z-index: 0;
	inset: 0;
	background-image: url(../../img/paper-texture__3110-3516.jpg);
	background-position: center;
	background-size: cover;
	opacity: 0.4;
	pointer-events: none;
}

.performance-facts__inner {
	position: static; /* the rules and the badge are placed against the section. */
	z-index: 1;
}

.performance-facts__heading {
	position: relative;
	z-index: 1;
	padding: 0 16px;
}

/* The frame hand-places two 150-wide columns 35 apart (4267:16004: column A
   at 25, column B at 210) — which is exactly what this is at the text scale
   the frame was drawn at. It is a WRAPPING flex row, not a fixed grid,
   because the accessibility widget scales the text up to 150 % and the
   dyslexia face is wider again: at that size a «Big number» is ~219 wide and
   a column can no longer be 150. `flex: 0 1 150px` keeps the frame's width
   while the text fits and lets the column grow to its own content when it
   does not — and when two grown columns no longer fit the width, the second
   one wraps under the first instead of being cut off by the section's
   `overflow: hidden` (fix round 1 C1 of plan 06 task 4: at 150 % on 320–390
   the numbers used to sit on top of the next column's labels and half the
   block was clipped, which no page-level `scrollWidth` check could see —
   tests/e2e/helpers/element-overflow.js now measures it per element). */
.performance-facts__stats {
	position: relative;
	z-index: 1;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	column-gap: 35px;
	margin: 0;
	padding: 40px 0 0 25px; /* title bottom 147 → first stat 187. */
	list-style: none;
}

.performance-facts__column {
	flex: 0 1 150px; /* every «Stat - …» frame is a fixed 150 at 390. */
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Column B starts lower than column A, and the gaps between the six stats
   are all slightly different: hand-placed in the frame. 390 (4267:16004):
   column A at y 187 / 377 / 567, column B at 281 / 471 / 681. */
.performance-facts__column--b {
	padding-top: 94px;
}

.performance-facts__stat {
	display: flex;
	flex-direction: column;
	width: auto; /* the column carries the frame's 150 and may grow with the text. */
	gap: 12px; /* 4267:16009 itemSpacing. */
}

.performance-facts__column--b .performance-facts__stat {
	gap: 14px; /* 4267:16031 itemSpacing. */
}

.performance-facts__column--a .performance-facts__stat + .performance-facts__stat {
	margin-top: 96px;
}

.performance-facts__column--b .performance-facts__stat:nth-child(2) {
	margin-top: 94px;
}

.performance-facts__column--b .performance-facts__stat:nth-child(3) {
	margin-top: 114px;
}

.performance-facts__number {
	display: block;
	width: fit-content;
	max-width: 100%;
	color: var(--color-primary-600);
	font-family: var(--font-title);
	font-size: var(--fs-big-number);
	font-weight: 400;
	line-height: var(--lh-big-number);
	letter-spacing: var(--ls-big-number);

	/* leadingTrim CAP_HEIGHT on every «Big number» node (4267:16010 …). */
	padding-bottom: 0.041em;
	text-box: trim-both cap alphabetic;
	text-transform: uppercase;
}

/* A block, so the per-slot widths below apply: `max-width` does nothing to
   an inline box. */
.performance-facts__label {
	display: block;

	/* A single Ukrainian word at 150 % («ГОЛОСНЯКОМ», «РЕПЕТИЦІЙ») is wider
	   than the slot the frame gives its label, and would be cut by the
	   section's own clip; breaking it is the project's established remedy for
	   1.4.4/1.4.10 (task-1-report.md item 8). */
	overflow-wrap: anywhere;
	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;
}

/* Each of the six labels has its own width in the frame, with no rule
   between them (134 / 135 / 150 and 148 / 145 / 152 at 390; 134 / 207 /
   312 and 148 / 145 / 152 at 1440) — the widths are what decides where
   each label wraps, so they are reproduced per slot. Logged in
   designer-questions.md. */
.performance-facts__column--a .performance-facts__stat:nth-child(1) .performance-facts__label {
	max-width: 134px;
}

.performance-facts__column--a .performance-facts__stat:nth-child(2) .performance-facts__label {
	max-width: 135px;
}

.performance-facts__column--a .performance-facts__stat:nth-child(3) .performance-facts__label {
	max-width: 150px;
}

.performance-facts__column--b .performance-facts__stat:nth-child(1) .performance-facts__label {
	max-width: 148px;
}

.performance-facts__column--b .performance-facts__stat:nth-child(2) .performance-facts__label {
	max-width: 145px;
}

.performance-facts__column--b .performance-facts__stat:nth-child(3) .performance-facts__label {
	max-width: 152px;
}

/* «Vertical Divider Left/Right» 4267:16043 / 4267:16044 — 1×590 at x 16
   and 1×586 at x 201. Both start at the top of column A although column B
   starts 94 lower, and they end 4px apart. */
.performance-facts__rule {
	position: absolute;
	z-index: 1;
	top: 187px;
	width: 1px;
	background: var(--color-neutral-400);
}

.performance-facts__rule--left {
	left: 16px;
	height: 590px;
}

.performance-facts__rule--right {
	left: 201px;
	height: 586px;
}

/* «Fun Facts Badge» 4267:16005 — the sticker, rotated −30° in the .fig.
   The span is the node's own (already rotated) bounding box, so it
   measures against the node; the image inside is the render bounds, which
   the noise texture makes larger, and it overflows the span. */
.performance-facts__badge {
	position: absolute;
	z-index: 1;
	top: 76px;
	left: 309px;
	width: 80.72px;
	height: 77.81px;
	pointer-events: none;
}

.performance-facts__badge-img {
	display: block;
	width: 93.72px;
	height: 94.87px;
	margin: -8.28px 0 0 -6.5px;
}

/* --------------------------------------------------------- перед виставою */

.performance-visit-info {
	padding: 80px 16px; /* 4273:16074 pad 80/16. */
	background: var(--color-neutral-100);

	/* `clip`, not `hidden`: `overflow: hidden` makes a box a scroll container,
	   and a scroll container ANYWHERE above a parallax layer's box becomes the
	   scroller of its `view-timeline` — the section never scrolls, so the
	   progress sat still and the layer did not move at all (fix round 1, C2).
	   `clip` clips and is not scrollable, which is the same idiom people.css
	   already uses deliberately for the portrait strip. */
	overflow: clip;
}

.performance-visit-info__inner {
	display: flex;
	flex-direction: column;
	gap: 40px; /* 4273:16074 itemSpacing. */
	margin-inline: auto;
	max-width: 1328px;
}

.performance-visit-info__cards {
	display: flex;
	flex-direction: column;
	gap: 16px; /* «Venue Info Content» 4273:16080 itemSpacing. */
}

/* «Venue Overview Card» 4273:16075 — the hall photo with two scrims, the
   format label and the hall's name at the top, «схема залу» at the
   bottom.

   The card carries its own contrast floor, which accessibility-ua.md §10
   puts on our side and not the theatre's («де не проходить — затемнення
   під текстом»):

   - the dark ground is on the CARD, not only on the no-photo variant, so
     the text is readable while a lazy photo is still loading and wherever
     a photo is transparent;
   - both scrims reach 60 % black instead of the frame's 50 / 40. Over the
     worst plausible photograph — a white one — 60 % composites to #666666
     (relative luminance 0.133), which puts white text at 5.7:1 (AA needs
     4.5) and the 36/28px hall name at 5.7:1 (large text needs 3). At 50 %
     the same photo gives 4.0:1, and the frame's own dark stage photo
     already measured 3.0–4.1:1 in review.
   - `#12AD99` cannot clear 4.5:1 over any scrim that still shows a
     photograph (it needs a ground no lighter than #363636, i.e. ~79 %
     black), so over a photo the accent moves one step up the same ramp to
     `--color-primary-200` (4.5:1 on that #666666 floor) and keeps the
     .fig's own `--color-primary-500` on the solid dark card. Logged in
     designer-questions.md. */
.performance-visit-info__hall {
	--podil-hall-accent: var(--color-primary-200);

	position: relative;
	display: flex;
	box-sizing: border-box;
	flex-direction: column;
	align-items: flex-start;
	justify-content: space-between;
	height: 424px;
	padding: 16px;
	overflow: hidden;
	background: var(--color-neutral-800);
}

/* No hall photo in the content yet (every `hall` post's `photos` field is
   empty — see task-15-report.md). On that solid ground the .fig's own
   accent passes (6.45:1), so it is what shows. */
.performance-visit-info__hall--no-photo {
	--podil-hall-accent: var(--color-primary-500);
}

.performance-visit-info__hall-photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.performance-visit-info__scrim {
	position: absolute;
	left: 0;
	width: 100%;
	pointer-events: none;
}

/* «Image Overlay» 4273:16077 / 3312:11328 — 149 tall at 390, 127 at 1440,
   dark at the card's top edge and fading down (the node's own handles run
   (0.60,1.0) → (0.60,0.315), and a render of the frame reads the same way).
   The .fig ramps from 50 % at 31.5 % of the band to nothing at its foot,
   which leaves the hall's name — the lower half of the band — over bare
   photograph. The floor holds across the whole text band instead and fades
   only below it: over the worst plausible upload (a flat #F2F2F2 foyer) that
   is 6.2:1 for the white name against 1.4:1 for the .fig's own ramp. */
.performance-visit-info__scrim--top {
	top: 0;
	height: 149px;
	background: linear-gradient(rgb(0 0 0 / 60%), rgb(0 0 0 / 60%) 88%, rgb(0 0 0 / 0%));
}

/* «Background Image» 4273:16076 — 127 tall, dark at the card's foot, and it
   hangs 3px below the card in the frame (clipped there as it is here). Same
   reasoning as the top band: full strength from 60 % of the band down, which
   is above «схема залу» at either width. */
.performance-visit-info__scrim--bottom {
	bottom: -3px;
	height: 127px;
	background: linear-gradient(rgb(0 0 0 / 0%), rgb(0 0 0 / 60%) 60%, rgb(0 0 0 / 60%));
}

.performance-visit-info__hall-header {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 12px; /* «Header Text» 4273:16078 itemSpacing. */

	/* The node's own fixed width, but never wider than the card it sits in:
	   at 320 the card is narrower than 275, and a `max-width` above the
	   available space leaves the hall's name to be clipped by its own box
	   instead of wrapped (element-overflow.js at 320/360/390 × 150 %). */
	max-width: min(275px, 100%);
}

.performance-visit-info__hall-name {
	margin: 0;
	padding-bottom: 0.041em;
	color: var(--color-base-white);
	font-family: var(--font-title);
	font-size: var(--fs-h3);
	font-weight: 400;
	line-height: var(--lh-h3);
	letter-spacing: var(--ls-h3);
	text-box: trim-both cap alphabetic;
	text-transform: uppercase;

	/* «Зала Ігоря Славинського» is the longest real hall name, and at 320 px
	   with the widget's 150 % step it is wider than the card — clipped by its
	   own box (element-overflow.js on the three real performances). The
	   theme's established remedy for the 150 % case: break the word rather
	   than cut it. */
	overflow-wrap: anywhere;
}

/* «Section Title» / «Section Label» — «S/S text (semi bold) caps». */
.performance-visit-info__label {
	margin: 0;
	color: var(--color-primary-700);
	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-transform: uppercase;
}

.performance-visit-info__label--on-photo {
	position: relative; /* over the photo layer, like the header and the link. */
	color: var(--podil-hall-accent);
}

.performance-visit-info__details {
	display: flex;
	flex-direction: column;
	gap: 16px; /* «Show Details Card» 4273:16082 itemSpacing at 390. */
}

.performance-visit-info__card {
	position: relative;
	display: flex;
	box-sizing: border-box;
	flex-direction: column;
	align-items: flex-start; /* the Details Link hugs its own text. */
	gap: 32px; /* 4273:16083 / 4273:16101 itemSpacing. */
	padding: 16px;
	overflow: hidden;
	background: var(--color-base-white);
}

.performance-visit-info__card-body {
	display: flex;
	flex-direction: column;
	align-self: stretch; /* «Production Notes Content» 4273:16085 is w:fill. */
	gap: 12px; /* itemSpacing of 4273:16085. */
	justify-content: center;
}

/* «Notes List» / «Features List»: the «/» in front of each line is the
   list's marker in the design, not part of the sentence, so it is a
   `::marker` — assistive tech reads the lines, not a slash per line. */
.performance-visit-info__list {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style-position: inside;
}

/* Each note and each accessibility line is a hug node in both frames
   (4273:16110 is 142 wide of a 326 list), so the box hugs its own text. */
.performance-visit-info__item {
	width: fit-content;
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: var(--fs-m-text);
	font-weight: 400;
	line-height: var(--lh-m-text);
	letter-spacing: var(--ls-m-text);

	/* leadingTrim CAP_HEIGHT on every «M/M text» note node (4273:16088 …),
	   which is what makes a 16/20 line 11px tall in the frame. */
	text-box: trim-both cap alphabetic;
}

.performance-visit-info__item::marker {
	content: "/ ";
}

/* «Stage Lights Illustration» 4273:16091 and «icon/availability»
   4273:16120 — 28×28, absolute in the card's top-right corner. */
.performance-visit-info__icon {
	position: absolute;
	top: 16px;
	right: 16px;
	width: 28px;
	height: 28px;
	color: var(--color-primary-500);
}

.performance-visit-info__icon svg {
	display: block;
	width: 28px;
	height: 28px;
}

/* «Accessibility Section» 4273:16100 is `align=end`: its content column is
   the card's own width, and the card aligns it to the right edge — which
   only shows when the content is narrower than the card, as the
   `<ul>` never is. Kept as the .fig has it. */
.performance-visit-info__card--access {
	align-items: flex-end;
}

/* «Accessibility Content» 4273:16106 is a fixed 168 in both frames, with the
   list and the link pushed apart inside it. */
.performance-visit-info__card--access .performance-visit-info__card-body {
	align-items: flex-start;
	justify-content: space-between;
	gap: 0;
	height: 168px;
}

/* «Accessibility Info» 4273:16107 — the label and the list, together. */
.performance-visit-info__info {
	display: flex;
	flex-direction: column;
	align-self: stretch;
	gap: 12px;
}

/* The three Details Links of this section. `.c-details-link` (the shared
   component, repertoire.css) has no standalone hover — there it is driven
   by the card around it — so these carry their own, with the numbers of
   animations.md's «Детальніше» row: gap 8 → 12 and the text to #0C9586,
   600ms cubic-bezier(0,0,0.58,1). On white that colour is 3.7:1 and fails
   AA for text, hence --color-primary-700; on the photo the .fig's own
   --color-primary-500 is what passes, as in the footer's white→teal row. */
.performance-visit-info__link:hover,
.performance-visit-info__link:focus-visible {
	gap: 12px;
	color: var(--color-primary-700);
}

/* The photo is an absolutely-placed layer inside the card, so the two things
   drawn over it («Header Text» and this link) need their own stacking
   position — without it the photo covers them once it loads. */
.performance-visit-info__link--on-photo {
	position: relative;
	color: var(--color-base-white);
}

.performance-visit-info__link--on-photo:hover,
.performance-visit-info__link--on-photo:focus-visible {
	color: var(--podil-hall-accent);
}

/* base.css's ring is --color-primary-700, 2.6:1 on this card's dark ground —
   under WCAG 1.4.11's 3:1. The same substitution slider.css makes for its own
   dark variant. */
.performance-visit-info__hall :focus-visible {
	outline-color: rgb(255 255 255);
}

/* Windows High Contrast drops the scrims' `background-image` and the card's
   own colour, but the photo keeps painting — black text on a photograph. The
   photo goes, the solid ground carries the text, as actor-card.css does for
   its own caption band. */
@media (forced-colors: active) {

	.performance-visit-info__hall {
		background: Canvas;
		forced-color-adjust: none;
		color: CanvasText;
	}

	.performance-visit-info__hall-photo,
	.performance-visit-info__scrim {
		display: none;
	}

	.performance-visit-info__hall-name,
	.performance-visit-info__label--on-photo,
	.performance-visit-info__link--on-photo {
		color: CanvasText;
	}
}

/* ---------------------------------------------------------------- ще цікаве */

.performance-more__label {
	text-align: center; /* 4369:22568: the words are centred at 390. */

	/* The shared sticky mode (section-title.css) only has somewhere to hold
	   from 1440 up, where this name becomes a full-height column beside the
	   cards; at 390/768 it is a line above them. */
	position: static;
}

.performance-more__title {
	margin: 0;
	padding-bottom: 0.041em;
	color: var(--color-neutral-800);
	font-family: var(--font-title);
	font-size: var(--fs-h2-m);
	font-weight: 400;
	line-height: var(--lh-h2-m);
	letter-spacing: var(--ls-h2-m);
	text-box: trim-both cap alphabetic;
	text-transform: uppercase;
}

/* «Section Label» 4369:22568 is a hug node centred in the 390 frame. */
.performance-more__title {
	width: fit-content;
	margin-inline: auto;
}

/* «Frame 1437255307» 4369:22569 — the cards and «Переглянути всю афішу»,
   48 apart, inside the page margin. */
.performance-more__content {
	display: flex;
	flex-direction: column;
	gap: 48px;
	margin: 40px 16px 0; /* label bottom 31 → cards 71. */
}

.performance-more .repertoire-grid {
	margin-inline: 0;
}

/* ------------------------------------------------------------ за лаштунками */

.performance-backstage {
	position: relative;
	padding: 0 16px;
	overflow: hidden;
	background: var(--color-base-white); /* 4267:15954 fill. */
}

.performance-backstage__body-wrap {
	margin-top: 40px; /* 4267:15954: title bottom 27 → track 67. */
}

/* `peek: true`: «Performance Overview» 4267:15955 starts at x=16 and the frame
   clips at 390, so the window is 374 over a 280 item — 40 of gap and 54 of the
   next block. The window bleeds to the frame's edge to get there. */
.performance-backstage .c-slider {
	--c-slider-track-gap: 40px;
	--c-slider-peek: 94px;
}

.performance-backstage .c-slider__viewport {
	margin-right: -16px;
}

/* `nav: 'heading'`: the arrow pair is this file's, not the slider's. At 390 the
   frame puts it at the right of the bottom row, beside the «1/3» counter
   (4267:15994), which is also where the slider's own counter row lands — so the
   pair is placed into that row from here. From 1440 up it is static again and
   sits beside the heading. */
.performance-backstage__nav {
	position: absolute;
	right: 16px;
	bottom: 0;
}

.performance-backstage .c-slider__nav {
	min-height: 40px; /* the row is the arrows' own height (4267:15994). */
}

.performance-backstage__item {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	width: fit-content; /* «Hero Section» 4267:15956 hugs its photo and its words. */
	gap: 20px; /* itemSpacing of 4267:15956. */
}

.performance-backstage__photo {
	flex: 0 0 auto;
	width: 280px;
	height: 209px;
}

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

.performance-backstage__text {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	gap: 20px;
	width: 280px;
}

/* 4267:15956 draws the photo above the words at 390, and the DOM has the words
   first (they are the item's own lead, and the 1440 frame reads words → photo).
   Nothing in either block is focusable, so visual order and reading order may
   differ here. */
.performance-backstage__photo {
	order: -1;
}

/* «Synopsis Text» 4267:15958 — «Menu,button» 600, upper. */
.performance-backstage__lead {
	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;
}

/* «Description Text» 4267:15965 — «S/S text (regular)»; a `<blockquote>` in the
   same field is «Quote Text» 4267:15966, the italic of the same size. */
.performance-backstage__body {
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: var(--fs-s-text);
	font-weight: 400;
	line-height: var(--lh-s-text);
	letter-spacing: var(--ls-s-text);
}

.performance-backstage__body > * {
	margin: 0;
}

.performance-backstage__body > * + * {
	margin-top: 20px;
}

.performance-backstage__body blockquote {
	font-style: italic;
}

/* ------------------------------------------------------------------ галерея */

.performance-gallery {
	display: flex;
	flex-direction: column;
	gap: 40px; /* 4273:16073 itemSpacing. */
	overflow: hidden; /* the two peeking photos hang off both edges at 390. */
}

/* «Section Title» 4273:16071 fills the 390 frame and centres its words. */
.performance-gallery__title {
	text-align: center;
}

.performance-gallery__frame {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 230px; /* «Event Gallery Carousel» 4273:16078. */
}

.performance-gallery__main {
	position: relative;
	z-index: 1;
	display: block;
	width: 308px;
	height: 230px; /* «Main Photo» 4273:16079. */
}

.performance-gallery__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* «Left Photo» / «Right Photo» 4273:16077 / 4273:16076 — 198×148 and 197×148 at
   80 % opacity, hanging 41px off each edge of the 390 frame. */
.performance-gallery__peek {
	position: absolute;
	top: 41px;
	height: 148px;
	opacity: 0.8;
}

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

.performance-gallery__peek--prev {
	left: -41px;
	width: 198px;
}

.performance-gallery__peek--next {
	right: -41px;
	width: 197px;
}

/* At 390 the frame puts the arrows and the dots on ONE row under the photo
   («Navigation Container» 4273:16080: prev, dots, next, space-between), where
   the component draws them as two stacked rows. One grid row holds both. */
@media (max-width: 1439px) {

	.performance-gallery .c-slider {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto;
	}

	.performance-gallery .c-slider > * {
		grid-column: 1; /* without it the dots claim an implicit second column. */
	}

	.performance-gallery .c-slider__viewport {
		grid-row: 1;
	}

	.performance-gallery .c-slider__nav {
		position: static;
		grid-row: 2;
		margin: 0 16px; /* «Navigation Container» 4273:16048 is 358 at x=16. */
		transform: none;
	}

	.performance-gallery .c-slider__dots {
		grid-row: 2;
		align-self: center;
		justify-self: center;
	}
}

/* ----------------------------------------------------------------- відгуки */

.performance-reviews {
	padding: 0 16px;
	background: var(--color-base-white); /* 4274:16161 fill. */
}

.performance-reviews__inner {
	margin-inline: auto;
	max-width: 1328px;
}

/* «Visit Title» 4274:16162 / 3199:3504 is a fixed-width text node (358 at
   390, 828 at 1440), which is what decides where the sentence breaks. */
.performance-reviews__title {
	max-width: 828px;
}

.performance-reviews .c-slider {
	--c-slider-track-gap: 16px; /* «Media Container» 4274:16163 itemSpacing. */

	/* `peek: true`, so the window hands the next card its gap and whatever is
	   left over. At 390 «Media Container» 4274:16163 starts at x=16 and the
	   frame clips at 390 — a 374px window over one 358 card, i.e. the gap
	   alone and nothing of the next card. */
	--c-slider-peek: 16px;

	margin-top: 40px; /* 4274:16161: title bottom 107 → cards 147. */
}

/* The card is the shared «Quote» component (components/quote.css,
   `4274:16135`), so nothing of its box, type or mark is repeated here. */

/* The track clips its own window and the mark hangs above the card, so the
   clip box is raised by the same amount. (`overflow-x: hidden;
   overflow-y: visible` cannot do it — it computes to `auto`.) */
.performance-reviews .c-slider__viewport {
	margin-top: -18px;
	margin-right: -16px;
	padding-top: 18px;
}

@media (max-width: 1439px) {

	/* The 390 frame's counter is the plain «S/S text» «1/3» of 4274:16176, not
	   the muted «Menu,button» one the 1440 row uses (3206:3682). */
	.performance-reviews .c-slider__counter {
		color: var(--color-neutral-800);
		font-size: var(--fs-s-text);
		font-weight: 400;
		line-height: var(--lh-s-text);
		letter-spacing: var(--ls-s-text);
	}
}

/* ================================================================== 768+ */

@media (min-width: 768px) {

	/* No 768 frame for any of these sections (inventory.md: the
	   performance page is drawn at 390 and 1440 only), so the 390 layout
	   stays fluid here and only the type steps, through tokens.css. The
	   one exception is «Ще цікаве», whose cards are the repertoire card:
	   that grid has its own derived 768 layout in repertoire.css, and the
	   section follows it. */
	.performance-more .performance-more__grid {
		width: 100%;
	}
}

/* ================================================================= 1440+ */

@media (min-width: 1440px) {

	/* ------------------------------------------------- творча команда */

	.performance-team {
		padding: 0 56px; /* 3159:2289 sits at x=56 in the 1440 frame. */
	}

	.performance-team__inner {
		gap: 54px; /* 3159:2289 itemSpacing. */
	}

	.performance-team__credits {
		gap: 40px; /* «Credits Section» 3159:2291 itemSpacing. */
	}

	.performance-team__grid {
		flex-direction: row;

		gap: 60px; /* «Credits Grid» 3159:2287 itemSpacing; two 634 columns. */

		/* `flex-start`: the columns hold a different number of rows
		   («Credits Column Right» 3159:2232 is 291 to the left one's 388)
		   and each hugs its own. */
		align-items: flex-start;
	}

	/* Each column's own first row keeps its padding at 1440 — only the one at
	   the very top of the section drops it. */
	.performance-team__grid > :nth-child(2) > .performance-team__row:first-child {
		padding-top: 24px;
	}

	/* «Director» 3159:2295 etc.: a space-between row, 97 tall, padding 24
	   top and bottom. 97 is the frame's own height and holds two name
	   lines (48) inside that padding; `min-height` so a third line grows
	   the row instead of overflowing it. */
	.performance-team__row,
	.performance-team__grid > :first-child > .performance-team__row:first-child {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		min-height: 97px;
		padding: 24px 0;
	}

	/* Every name node ends at the column's right edge (3159:2285 at x=1118
	   of a column ending at 1328), so the lines hug their own text and the
	   column aligns them to its end. */
	.performance-team__names {
		align-items: flex-end;
		text-align: right;
	}

	.performance-team__note {
		padding: 34px; /* 3159:2351; the 2px stroke is the border, outside it. */
	}

	.performance-team__note-text {
		max-width: 1000px; /* 3159:2352 is a fixed-width text node. */
	}

	/* -------------------------------------------------------- факти */

	.performance-facts {
		padding: 0 0 100px; /* 3299:11237: the title frame starts at y=0. */
	}

	.performance-facts__inner {
		display: grid;

		/* 3299:11237, hand-placed: title 46→416, rule 619, column A
		   644→957, rule 957, column B 982→. */
		grid-template-columns: 370px 228px 313px 25px auto;
		padding-left: 46px;
	}

	.performance-facts__heading {
		display: flex;
		align-items: flex-end;
		grid-column: 1;

		/* «Exhibition Facts Section Title» 3299:11242 is 205 tall with the
		   title bottom-aligned inside it. */
		height: 205px;
		padding: 0;
	}

	.performance-facts__stats {
		display: contents;
	}

	.performance-facts__column--a {
		grid-column: 3;
		padding-top: 100px;
	}

	.performance-facts__column--b {
		grid-column: 5;
		padding-top: 216px;
	}

	.performance-facts__column--a .performance-facts__stat + .performance-facts__stat {
		margin-top: 0;
	}

	.performance-facts__column--a .performance-facts__stat:nth-child(2) {
		margin-top: 113px;
	}

	.performance-facts__column--a .performance-facts__stat:nth-child(3) {
		margin-top: 118px;
	}

	.performance-facts__column--b .performance-facts__stat:nth-child(2) {
		margin-top: 111px;
	}

	.performance-facts__column--b .performance-facts__stat:nth-child(3) {
		margin-top: 116px;
	}

	/* At 1440 five of the six «Stat - …» frames hug their widest part; the
	   last one is a fixed 207 in the frame (3299:11259). */
	.performance-facts__stat {
		width: fit-content;
	}

	.performance-facts__column--b .performance-facts__stat:nth-child(3) {
		width: 207px;
	}

	.performance-facts__column--a .performance-facts__stat:nth-child(2) .performance-facts__label {
		max-width: 207px;
	}

	.performance-facts__column--a .performance-facts__stat:nth-child(3) .performance-facts__label {
		max-width: 312px;
	}

	.performance-facts__rule {
		top: 100px;
	}

	.performance-facts__rule--left {
		left: 619px;
		height: 697px;
	}

	.performance-facts__rule--right {
		left: 957px;
		height: 692px;
	}

	.performance-facts__badge {
		top: 465px;
		left: 0;
		width: 162.52px;
		height: 158.49px;
	}

	.performance-facts__badge-img {
		width: 188.85px;
		height: 192.94px;
		margin: -16.72px 0 0 -13.16px;
	}

	/* ------------------------------------------------ перед виставою */

	.performance-visit-info {
		padding: 100px 56px; /* 3190:3083: title 100, content bottom 617 of 717. */
	}

	.performance-visit-info__inner {
		gap: 54px; /* title bottom 139 → cards 193. */
	}

	.performance-visit-info__cards {
		flex-direction: row;
		gap: 24px; /* hall card ends at 708, «Show Details Card» 3190:3095 starts at 732. */
	}

	.performance-visit-info__hall,
	.performance-visit-info__details {
		flex: 0 0 652px;
		max-width: 652px;
	}

	.performance-visit-info__details {
		gap: 24px; /* «Show Details Card» 3190:3095 itemSpacing. */
	}

	.performance-visit-info__card {
		gap: 16px;
		height: 200px;
	}

	.performance-visit-info__scrim--top {
		width: 648px; /* «Image Overlay» 3190:3086 is 4px narrower than the card. */
		height: 127px;
	}

	.performance-visit-info__card-body {
		gap: 12px;
	}

	.performance-visit-info__card--notes {
		justify-content: space-between;
	}

	/* ----------------------------------------------------- ще цікаве */

	.performance-more {
		position: relative;
		padding: 0 56px; /* 3206:3739 sits at x=56. */
	}

	.performance-more__inner {
		position: relative;
		margin-inline: auto;
		max-width: 1328px;

		/* The name and the content column share ONE cell, which is what the
		   absolute label did visually — and what lets the name be sticky: a
		   `position: absolute` box is not in flow, so `sticky` has no cell to
		   travel in. The cell is this block's own full height, so the travel
		   ends where «Ще цікаве» ends. `4343:19691`/`4348:19863`/`4497:25442`
		   say that sentence over the three other instances of this one
		   composition (a vertical name beside a staggered grid) and no note
		   stands over this one; the «Безбар'єрність» ruling for `4550:25445`
		   already generalised a note across identical compositions, and the
		   client asked for every section with a name beside its content
		   (ПР-12), so this fourth instance behaves like the other three
		   instead of being the one that scrolls away. */
		display: grid;
		grid-template-columns: minmax(0, 1fr);
	}

	.performance-more__label,
	.performance-more__content {
		grid-area: 1 / 1;
	}

	/* «Carousel Label» 3206:3740 / «Section Label» 3206:3741: the words run
	   UP the left edge — the node's `rotation` is −1.5708 rad and the frame
	   render reads bottom-to-top. `translateX(-100%)` before the −90°
	   rotation puts the rotated box back at x=0, y=0 whatever the text's own
	   width turns out to be in the substitute face. */
	.performance-more__label {
		position: sticky;
		justify-self: start;
		width: 84px;
		height: 1073px;
		text-align: left;
	}

	.performance-more__title {
		width: auto;
		margin-inline: 0;
	}

	.performance-more__title {
		position: absolute;
		top: 120px;
		left: 0;
		transform: rotate(-90deg) translateX(-100%);
		transform-origin: 0 0;
		white-space: nowrap;
	}

	/* «Afisha Content» 3206:3742 — 1177 wide at x=151 of the 1328 section,
	   its two children 56 apart. */
	.performance-more__content {
		gap: 56px;
		margin: 0 0 0 151px;
		max-width: 1177px;
	}

	/* The grid is the repertoire's own staggered grid, and «More Shows»
	   places it 1px in from «Afisha Content» (x=152 of 1440). Pitch,
	   columns and per-column offsets are identical and come from
	   repertoire.css unchanged. */
	.performance-more .repertoire-grid {
		align-self: flex-end;
		margin-inline: 1px 0;
	}

	/* ------------------------------------------------ за лаштунками */

	.performance-backstage {
		padding: 0 0 0 56px; /* 3399:9561: the track starts at x=56 and runs off the right edge. */
	}

	/* «Visit Title» 3399:9562 at (56,25) and «Navigation Container» 3399:9584 at
	   (1257,0), 64 tall — one row, the title sitting on its bottom edge. */
	.performance-backstage__head {
		display: flex;
		align-items: flex-end;
		justify-content: space-between;
		min-height: 64px;
		padding-right: 55px;
	}

	.performance-backstage__nav {
		position: static;
	}

	.performance-backstage__body-wrap {
		margin-top: 54px; /* head bottom 64 → «Performance Overview» 118. */
	}

	/* The 1440 frame has no counter — only the 390 one does (4267:15995). */
	.performance-backstage .c-slider__nav {
		display: none;
	}

	/* 3399:9563 is a 3989px track inside a 1440 frame: after «Hero Section»
	   (868 wide at x=56) the next block starts 60 later and runs past the
	   frame's right edge — 60 + 456 of the window. The section has no right
	   padding, so the window already reaches 1440. */
	.performance-backstage .c-slider {
		--c-slider-track-gap: 60px; /* «Performance Overview» 3399:9563 itemSpacing. */
		--c-slider-peek: 516px;
	}

	.performance-backstage .c-slider__viewport {
		margin-right: 0;
	}

	.performance-backstage__item {
		flex-direction: row;
		gap: 20px; /* «Hero Section» 3419:10897 itemSpacing. */
	}

	.performance-backstage__photo {
		order: 0;
		width: 539px;
		height: 403px; /* «Stage Photo Left» 3399:9565. */
	}

	.performance-backstage__text {
		width: 309px; /* «Synopsis Card» 3399:9566. */
	}

	/* ------------------------------------------------------- галерея */

	.performance-gallery {
		--c-slider-nav-inset: -32px; /* arrows at x 24 and 1352 of the 1440 frame, i.e. 32 outside the 1328 content box. */

		padding: 0 56px;
		overflow: visible;
	}

	.performance-gallery {
		gap: 54px; /* title bottom 39 → photos 93. */
	}

	/* 3327:12949 is a hug node centred in the section, unlike the 390 one
	   that fills its frame. */
	.performance-gallery__title {
		width: fit-content;
		margin-inline: auto;
	}

	/* `nav: 'edges'` centres the pair on the whole slider, dots included; the
	   frame centres it on the PHOTO (3327:12951 at y=390 of a 658-tall
	   photo starting at 93). */
	.performance-gallery .c-slider__nav {
		top: 297px; /* 658/2 − 64/2. */
		transform: none;
	}

	.performance-gallery__frame {
		height: 658px; /* «Group 1261151691» 3327:12949. */
	}

	.performance-gallery__main {
		width: 880px;
		height: 658px; /* «Main Photo» 3327:12948. */
	}

	.performance-gallery__peek {
		top: 121px; /* photos 214 of a group starting at 93. */
		height: 416px;
	}

	.performance-gallery__peek--prev {
		left: 0;
		width: 555px;
	}

	.performance-gallery__peek--next {
		right: 0;
		width: 555px;
	}

	/* ------------------------------------------------------- відгуки */

	.performance-reviews {
		padding: 0 56px;
	}

	.performance-reviews .c-slider {
		--c-slider-track-gap: 24px; /* «Frame 1437254990» 3199:3505 itemSpacing. */

		/* 3199:3505 puts its cards at −620 / 56 / 732 / 1408 in a 1440 frame:
		   two whole cards and a 32px sliver of the next. 24 + 32 = 56 is what
		   the window hands that next card, and the window is the column plus
		   the 56px page margin it bleeds into. */
		--c-slider-peek: 56px;

		gap: 54px; /* cards bottom 444 → nav row 498. */
		margin-top: 54px; /* title bottom 95 → cards 149. */
	}

	.performance-reviews .c-slider__viewport {
		margin-top: -20px;
		margin-right: -56px;
		padding-top: 20px;
	}

}

/* ================================================================= 1920+ */

@media (min-width: 1920px) {

	/* No 1920 frame either: the 1440 layout holds, with the content block
	   centred (the same rule performance-about.css states). */
	.performance-facts__inner,
	.performance-more__inner,
	.performance-visit-info__inner,
	.performance-team__inner {
		margin-inline: auto;
	}
}
