/* Site header — Figma «Navigation Bar»: Gray
   4037:11110/4182:18183/3015:2462/4190:19491, transparent
   4316:24573/4316:24521/3505:12408/4316:24453, white
   4316:24593/4316:24547/4316:24415/4316:24487. Below 1440 the design shows
   no `.site-nav` row and no ticket button at 390 (design has no visible
   Buy Tickets Button in the collapsed 390 bar — tickets first appears at
   768); above 1440 there is no `.site-header__menu-toggle`. The
   accessibility label text is icon-only below 1440 (no frame for the text
   in the 390/768 nodes) — kept in the DOM as visually-hidden text, not
   removed, so the button keeps an accessible name. See REPORT.md for the
   round-by-round diff against these nodes. */

/* The bar is opaque at rest, whatever variant the page picks. It is
   `position: sticky` (see the reveal block at the foot of this file), so a
   fill of `transparent` is not «the page shows through» — it is «the menu row
   sits on whatever the reader had scrolled to» the moment the header comes
   back. No frame in the file draws that: every page's `NavigationBar`
   instance stands on #F3F4F6, on #FFFFFF, or on an override fill of its own
   (inc/navigation.php lists them). White is the default here because it is the
   root fill of every page frame; `--gray` and `--white` below are the two the
   design actually names (client fix ПР-10). */
.site-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	padding: 16px var(--page-gutter);
	background: var(--color-base-white);
}

.site-header--gray {
	background: var(--color-neutral-100);
}

.site-header--white {
	background: var(--color-base-white);
}

/* The logo mark hangs outside the column, the only thing on the page that
   does: the frames put its left edge 4 px (390 `4036:10415`), 8 px (768
   `4181:18182`), 13 px (1440 `1159:7335`) and 12 px (1920 `4190:19490`) left of
   the 16/32/56/112 every other edge of the bar, of the page and of the footer
   stands on — an optical overhang of the glyph, not a second gutter. It is a
   negative margin rather than a smaller padding-left on `.site-header` so that
   the bar's own box IS the column (client fix ПР-20; the e2e
   `container-width.spec.js` compares the two boxes at four widths). The mark
   lands on exactly the same x as before: the margin takes off what the padding
   put on, and in the 1440+ grid the `auto` track shrinks by the same 13/12, so
   the nav beside it does not move either. */
.site-header__logo {
	display: block;
	margin-left: -4px;
	line-height: 0;
}

.site-header__logo img {
	display: block;
	width: 115px;
	height: 43px;
}

.site-header__bar {
	display: flex;
	align-items: center;
	gap: 24px;
}

/* «S/S text (semi bold) caps» is 16/22 in the design at 390 through 1440,
   only stepping to 20/24 at 1920 — it does not track --fs-s-text/
   --lh-s-text (14/18 at the 390 tier; the ticket button uses that token
   correctly, but its own 390 variant manually overrides to 14, unlike
   this label). No existing token has that 16/22/… ladder, so the base
   rule spells out the same `calc(Npx * var(--font-scale))` pattern
   tokens.css uses, keeping the accessibility widget's --font-scale
   working; @media (min-width: 1920px) switches to the token, which is
   correct there. */
.site-header__a11y {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	border: 0;
	background: transparent;
	padding: 0;
	color: var(--color-neutral-800);
	font-family: var(--font-body);
	font-size: calc(16px * var(--font-scale));
	line-height: calc(22px * var(--font-scale));
	letter-spacing: var(--ls-s-text);
	font-weight: 600;
	text-transform: uppercase;
	cursor: pointer;
}

.site-header__a11y svg {
	width: 22px;
	height: 16px;
	flex: none;
}

/* Visually hidden below 1440 (icon only in the 390/768 nodes) but still
   read by assistive tech, so the toggle keeps an accessible name at
   every width. */
.site-header__a11y span {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	padding: 0;
}

/* Same 16/22 design text style as .site-header__a11y — see its comment. */
.site-header__langs {
	display: flex;
	align-items: center;
	gap: 4px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--font-body);
	font-size: calc(16px * var(--font-scale));
	line-height: calc(22px * var(--font-scale));
	letter-spacing: var(--ls-s-text);
	font-weight: 600;
	text-transform: uppercase;
}

.site-header__langs li {
	display: flex;
	align-items: center;
}

.site-header__langs li:not(:last-child)::after {
	content: "/";
	margin-left: 4px;
	color: var(--color-neutral-800);
}

.site-header__langs a,
.site-header__langs span {
	color: var(--color-neutral-800);
	text-decoration: none;
}

.site-header__langs a[aria-current="true"] {

	/* Figma's literal #99A4B2 (--color-neutral-400) is 2.3–2.5:1 against
	   every header background — fails WCAG AA (axe "color-contrast", a
	   blocking smoke-test violation on every page, since the header is
	   site-wide). --color-neutral-600 is the closest token that clears
	   4.5:1 on all three variants (gray/white/transparent-over-page);
	   flagged in designer-questions.md. */
	color: var(--color-neutral-600);
}

.site-header__bar .c-ticket {
	display: none;
}

.site-header__menu-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	box-sizing: border-box;
	box-shadow: inset 0 0 0 2px var(--color-primary-500);
	background: transparent;
	padding: 0;
	cursor: pointer;
}

.site-header__menu-icon {
	display: flex;
}

.site-header__menu-icon svg {
	width: 20px;
	height: 20px;
}

.site-header__menu-icon--close {
	display: none;
}

.site-header__menu-toggle[aria-expanded="true"] .site-header__menu-icon--open {
	display: none;
}

.site-header__menu-toggle[aria-expanded="true"] .site-header__menu-icon--close {
	display: flex;
}

.site-nav {
	display: none;
}

@media (min-width: 768px) {

	.site-header__logo {
		margin-left: -8px;
	}

	/* «Buy Tickets Button» 4182:18203 is resized to 44 in this frame, 4 taller
	   than the component's own 40 — the header's own number, not the
	   component's tablet height (plan-end batch item 11). 1440 goes back to
	   the component's 40, which ticket-button.css already declares. */
	.site-header__bar .c-ticket {
		display: inline-flex;
		min-height: 44px;
	}
}

@media (min-width: 1440px) {

	/* Row 2 is 48px = the 24px nav row itself + the 24px the root component
	   (3015:2462) keeps as its own trailing padding-bottom, kept here as
	   track height instead of `padding` so `#site-header`'s own padding
	   reads 0/56/0/43 — the same as the inner "Logo" frame (1159:7341) it
	   is compared against; `.site-nav` gets `align-self: start` so it
	   stays 24px tall (not stretched to 48) — see REPORT.md. */
	.site-header {
		display: grid;
		grid-template-columns: auto 1fr;
		grid-template-rows: 64px 48px;
		column-gap: 56px;
		row-gap: 24px;
		padding: 0 var(--page-gutter);
	}

	/* Back to the component's own 40 («Buy Tickets Button» in the 1440
	   Navigation Bar is 128×40): the 44 above belongs to the 768 frame only. */
	.site-header__bar .c-ticket {
		min-height: 40px;
	}

	/* margin-bottom = the Logo Container's own 4px pad-bottom + the 24px
	   tail now folded into row 2's track (see the .site-header comment
	   above), so the logo's own bottom edge still lands on the
	   bar+gap+nav boundary (112px), not the track's outer edge (136px). */
	.site-header__logo {
		grid-column: 1;
		grid-row: 1 / 3;
		align-self: end;
		margin-bottom: 28px;
		margin-left: -13px;
	}

	.site-header__logo img {
		width: 204px;
		height: 77px;
	}

	.site-header__bar {
		grid-column: 2;
		grid-row: 1;
		justify-content: flex-end;
		padding: 24px 0 0 56px;
		box-sizing: border-box;

		/* A grid item's implicit min-width is `auto` (its content's own natural
		   width), not 0 — without this, the `1fr` track it sits in grows past
		   the grid's own width to fit that content instead of ever letting it
		   wrap or shrink. Harmless at the default scale (there's always slack),
		   but see the dyslexia+150% fix below, where there isn't. */
		min-width: 0;
	}

	.site-header__a11y span {
		position: static;
		width: auto;
		height: auto;
		margin: 0;
		overflow: visible;
		clip-path: none;
	}

	.site-header__menu-toggle {
		display: none;
	}

	.site-nav {
		display: block;
		grid-column: 2;
		grid-row: 2;
		align-self: start;
		min-width: 0; /* see .site-header__bar's own min-width: 0 above */
	}

	.site-nav__list {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.site-nav__link,
	.site-nav__toggle {
		display: inline-flex;
		align-items: center;
		gap: 4px;
		border: 0;
		background: transparent;
		padding: 0;
		color: var(--color-neutral-800);
		font-family: var(--font-body);
		font-size: var(--fs-menu-button);
		line-height: var(--lh-menu-button);
		letter-spacing: var(--ls-menu-button);
		font-weight: 600;
		text-transform: uppercase;
		text-decoration: none;
		cursor: pointer;
	}

	/* Figma's literal #12AD99 (--color-primary-500, the "Variant2"/
	   current-page text colour) is 2.5–2.8:1 against every header
	   background — fails WCAG AA (axe "color-contrast"). Text uses
	   --color-primary-700, the closest token that clears 4.5:1 on
	   gray/white/transparent-over-page; the arrow icon (decorative, not
	   text) keeps the measured primary-500. Flagged in
	   designer-questions.md. */
	.site-nav__link[aria-current="page"],
	.site-nav__toggle.is-current {
		color: var(--color-primary-700);
	}

	.site-nav__toggle svg {
		width: 24px;
		height: 12px;
	}

	/* Hover/open state of the toggle («About Container» Variant2): see
	   mega-menu.css. */
}

/* Task 10, item 5: with the dyslexia font's own wider letter-spacing on top of
   150% text scale, `.c-ticket` and `.site-nav__list`'s natural content width
   at 1440 overflows the header by ~24px (measured) even with the min-width: 0
   fix above (that fix stops the grid track from being forced wider than the
   viewport; it doesn't give the content itself anywhere to go). Letting the
   nav row wrap and tightening the header bar's own gap gives it that room,
   scoped to [data-font="dyslexia"] so the default design (plenty of slack
   already) is untouched; not needed at 1920, which has enough room without
   it (measured). */
@media (min-width: 1440px) and (max-width: 1919px) {

	html[data-font="dyslexia"] .site-header__bar {
		gap: 12px;
	}

	html[data-font="dyslexia"] .site-nav__list {
		flex-wrap: wrap;
		row-gap: 8px;
	}
}

@media (min-width: 1920px) {

	/* Row 2 is 56px = the 28px nav row + the 28px root pad-bottom, same
	   reasoning as the 1440 rule above. */
	.site-header {
		grid-template-rows: 84px 56px;
		row-gap: 28px;
	}

	.site-header__logo {
		margin-bottom: 34px;
		margin-left: -12px;
	}

	.site-header__logo img {
		width: 267px;
		height: 100px;
	}

	.site-header__bar {
		gap: 32px;
		padding-top: 28px;
	}

	.site-header__a11y,
	.site-header__langs {
		font-size: var(--fs-s-text);
		line-height: var(--lh-s-text);
	}
}

/* ================================ Hide on the way down, back on the way up

   Design notes `4329:28175` (Головна), `4496:35839` (Афіша), `4549:26006`
   (Репертуар), all three worded «Хедер приховується при скролі вниз і
   з'являється при скролі вгору». None of them gives a duration or an easing
   and none has a prototype transition, so the 300 ms ease-out below is
   header-reveal.js's documented choice, not a measurement.

   `data-podil-reveal` is written by header-reveal.js whenever it runs, and it
   means «sticky», not «animated»: accessibility-ua.md §4 turns off transitions,
   sliders, video backgrounds and parallax, and sticky positioning is none of
   those. With motion off the header stays sticky and simply never hides — the
   script keeps `--podil-header-shift` at 0 and the global reduced-motion rules
   zero the transition below, so nothing moves (fix round 1, I6). With no
   script at all the header stays in the flow exactly as before, which is why
   the custom properties every bar reads default to 0.

   Why `transform` and not `top`: `top` on a sticky box is a layout change per
   frame, and the header's own panels (the a11y widget and the mobile menu are
   both `position: fixed` CHILDREN of the header) would be dragged along by it.
   A transform captures fixed descendants too, which is why the shown state is
   `transform: none` and not `translateY(0)`: at rest the panels are back to
   the viewport. Mid-flight the script is holding the header down anyway — a
   panel with `aria-expanded="true"` pins it open.

   z-index 30 puts the header, and with it its own panels (whose 20 / 15 become
   local once the header is a stacking context), above every page-level sticky
   surface: afisha filters 12, sticky buy bar 10. */
.site-header[data-podil-reveal] {
	position: sticky;
	z-index: 30;
	top: 0;

	/* The literal curve, not the `ease-out` keyword, so `getTiming().easing`
	   reads back the string the motion tests compare against — the convention
	   ticket-button.css and details-link.css already follow. */
	transition: transform 300ms cubic-bezier(0, 0, 0.58, 1);
}

.site-header[data-podil-reveal][data-podil-hidden] {
	transform: translateY(-100%);
}

/* Anchor jumps, `scrollIntoView` and the browser's own sequential-focus
   scrolling land the target below the header instead of under it
   (accessibility-ua.md §3.1 «Пропуск до контенту» and §3.5 «не перекриває
   фокусований елемент»). 0 while the header is not sticky, so no page gains a
   scroll offset it has not asked for. */
:root {
	scroll-padding-top: var(--podil-header-h, 0px);
}
