/*
Theme Name: Federico Bresciani
Description: Black-and-white minimal child theme of Twenty Twenty-Five for federicobresciani.com.
Template: twentytwentyfive
Author: Federico Bresciani
Version: 1.0.42
Text Domain: federico-bresciani
*/

/*
 * Fixed site header: removed from document flow and pinned to the
 * viewport, so page content scrolls up and disappears behind it. Because
 * it's out of flow, every page needs compensating top padding on its main
 * content area (below) so nothing loads hidden underneath it.
 */
.site-header-fixed {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 200;
	background-color: #ffffff;
	/*
	 * Hide-on-scroll-down / show-on-scroll-up, on every viewport. The
	 * .header-hidden class is toggled by a small scroll listener
	 * (federico_bresciani_mobile_header_scroll_script() in functions.php,
	 * despite the mobile-specific name it now runs site-wide) that adds it
	 * once the user scrolls down past the header's own height, and removes
	 * it the moment they scroll back up.
	 */
	transition: transform 0.3s ease;
}

.site-header-fixed.header-hidden {
	transform: translateY(-100%);
}

/*
 * Compensates for the fixed header's height on every template's <main>,
 * so content doesn't render underneath it on load. --site-header-height
 * is set by federico_bresciani_header_height_var_script() in
 * functions.php from the header's own real, current rendered height
 * (it's no longer a fixed value now that the site title is a fluid
 * clamp()) — 84px remains only as the fallback for the brief moment
 * before that script runs, or if JS is disabled.
 */
main {
	padding-top: var(--site-header-height, 84px);
	/*
	 * WordPress's own default spacing between top-level blocks
	 * (`main` isn't <body>'s first child — the header comes before it —
	 * so it isn't exempt from the generic sibling-spacing margin) adds an
	 * extra ~1.2rem on top of the padding above, which already fully
	 * handles clearing the fixed header on its own. That stray margin is
	 * incidental, not a deliberate part of this layout, and specifically
	 * broke the homepage hero's "fit exactly within one screen" sizing by
	 * pushing everything ~19px further down than accounted for.
	 */
	margin-top: 0 !important;
}

/*
 * Biography (EN 6, DE 15, PL 16, IT 17) and Media (EN 182, DE 183, PL 184,
 * IT 185) pages: warm grey background matching the homepage, centered
 * title matching the federicobresciani.com reference layout. Scoped to
 * these specific page IDs rather than site-wide so Concerts/Contact are
 * unaffected.
 */
.page-id-6,
.page-id-15,
.page-id-16,
.page-id-17,
.page-id-182,
.page-id-183,
.page-id-184,
.page-id-185 {
	background-color: #f5f5f3;
}

.page-id-6 .wp-block-post-title,
.page-id-15 .wp-block-post-title,
.page-id-16 .wp-block-post-title,
.page-id-17 .wp-block-post-title,
.page-id-182 .wp-block-post-title,
.page-id-183 .wp-block-post-title,
.page-id-184 .wp-block-post-title,
.page-id-185 .wp-block-post-title {
	text-align: center;
	/* Pure black, distinct from the #111111 body text. */
	color: #000000;
	margin-bottom: 4rem !important;
}

/*
 * Noticeably tighter gap under the header than the original centered
 * design (which balanced margin-top against the 4rem margin-bottom above
 * — main's margin-top (1rem) + the alignfull wrapper's padding-top
 * (0.5rem) + this 2.5rem used to sum to 4rem, matching the space below).
 * Reduced on request for both Media and Biography; no longer meant to
 * preserve that top/bottom symmetry.
 */
.page-id-6 .wp-block-post-title,
.page-id-15 .wp-block-post-title,
.page-id-16 .wp-block-post-title,
.page-id-17 .wp-block-post-title,
.page-id-182 .wp-block-post-title,
.page-id-183 .wp-block-post-title,
.page-id-184 .wp-block-post-title,
.page-id-185 .wp-block-post-title {
	margin-top: 0.5rem !important;
}

/* Biography: page-title heading removed entirely on request (the page
   opens directly into the bio text/photo instead). display:none takes it
   fully out of layout, so its margin-top/bottom above don't add any space
   either — nothing else needed to close the gap they'd otherwise leave. */
.page-id-6 .wp-block-post-title,
.page-id-15 .wp-block-post-title,
.page-id-16 .wp-block-post-title,
.page-id-17 .wp-block-post-title {
	display: none;
}

/*
 * "Concert Host & Moderator" subheading, matched exactly to the
 * "Biography" title above it: same color, and (since by default an <h2>
 * renders smaller than an <h1> per the theme's own h1/h2 font-size rules)
 * the same font-size explicitly. font-weight is left alone here — both
 * headings already share the same default weight (400) from the theme's
 * global h1–h6 rule, so no override is needed to match it.
 */
.page-id-6 .bio-subheading-wrap .wp-block-heading,
.page-id-15 .bio-subheading-wrap .wp-block-heading,
.page-id-16 .bio-subheading-wrap .wp-block-heading,
.page-id-17 .bio-subheading-wrap .wp-block-heading {
	color: #000000 !important;
	font-size: var(--wp--preset--font-size--xx-large);
	font-weight: 400;
}

/*
 * Pulls the "Biography" heading closer to the header: the shared
 * page.html template stacks <main>'s own margin-top with its inner
 * full-width group's padding-top above the title (used as-is by
 * Concerts/Contact), so both are reduced here, scoped to Biography only.
 */
.page-id-6 main,
.page-id-15 main,
.page-id-16 main,
.page-id-17 main,
.page-id-182 main,
.page-id-183 main,
.page-id-184 main,
.page-id-185 main {
	margin-top: 1rem !important;
}

.page-id-6 main > .wp-block-group.alignfull,
.page-id-15 main > .wp-block-group.alignfull,
.page-id-16 main > .wp-block-group.alignfull,
.page-id-17 main > .wp-block-group.alignfull,
.page-id-182 main > .wp-block-group.alignfull,
.page-id-183 main > .wp-block-group.alignfull,
.page-id-184 main > .wp-block-group.alignfull,
.page-id-185 main > .wp-block-group.alignfull {
	padding-top: 0.5rem !important;
}

/*
 * Biography two-column sections: raw HTML (Custom HTML blocks), no
 * WordPress block classes involved at all — core/columns' own static CSS
 * (`.wp-block-columns.are-vertically-aligned-center`,
 * `.wp-block-column.is-vertically-aligned-center`, setting
 * align-items/align-self:center) kept fighting every sticky override
 * regardless of !important, so this removes that fight entirely.
 *
 * No overflow is set anywhere in this chain or on any ancestor.
 * align-items:flex-start (not stretch/center) is the standard sticky-
 * sidebar recipe: a flex item's sticky range is bounded by its
 * *container's* height, not its own box, so the container's natural
 * height (set by the taller text column) already gives .bio-photo-col
 * room to stick regardless of the photo column's own (shorter,
 * shrink-wrapped) height — flex-start just keeps it flush at the top,
 * matching "sticks right below the header" exactly, with no need to
 * artificially stretch the photo column's own box.
 */
.bio-section,
.bio-subheading-wrap {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	padding-left: 8%;
	padding-right: 8%;
	box-sizing: border-box;
	background-color: #f5f5f3;
}

.bio-section {
	display: flex;
	flex-direction: row;
	align-items: flex-start;
}

.bio-photo-col {
	width: 40%;
	position: sticky;
	/* A sticky element engages once scrolling brings it up to this offset
	   from the viewport top — raising it from 0px makes it lock into place
	   after less scrolling (sooner), at the cost of resting slightly lower
	   than flush against the top edge instead of exactly at it. */
	top: 32px;
	align-self: flex-start;
}

.bio-text-col {
	width: 60%;
	padding-left: 6%;
	box-sizing: border-box;
}

/*
 * Without this, the browser's default <p> top margin pushes the text down
 * relative to the image (which has no such default margin and sits flush
 * at the top of the row), making the photo look like it starts higher up
 * / a different size than it actually is. Aligns both to the same
 * starting line.
 */
.bio-text-col p:first-child {
	margin-top: 0;
}

/*
 * Section 2: photo on the right, text on the left. The row stays
 * flex-direction:row (not reversed) — the mirrored layout comes from
 * DOM order (text markup first, photo markup second); this just swaps
 * the text's padding to its right edge, away from the photo beside it.
 */
.bio-section--s2 .bio-text-col {
	padding-left: 0;
	padding-right: 6%;
}

.bio-photo {
	width: 100%;
	height: auto;
	border-radius: 12px !important;
	filter: grayscale(100%);
	display: block;
}

/*
 * Softer filter for the Section 2 photo only (Tczew_fot.-Marta-Papis-30):
 * still grayscale, but reduced contrast and slightly lifted brightness.
 * Compound selector (both classes) so it beats the base .bio-photo rule
 * on specificity regardless of source order. Section 1's photo is
 * untouched.
 */
.bio-photo.bio-photo--soft {
	filter: grayscale(100%) contrast(0.75) brightness(1.1);
}

@media (max-width: 781px) {
	.bio-section {
		flex-direction: column;
		padding-left: 6%;
		padding-right: 6%;
	}

	/*
	 * Two real causes, neither of which the previous attempt actually
	 * reached:
	 * 1. The wrapper carries an INLINE style baked into the page content
	 *    itself (style="padding-top:1rem;padding-bottom:1rem") — an
	 *    inline style always wins over any external rule that lacks
	 *    !important, on every viewport, so the earlier non-!important
	 *    1.5rem override here never had any effect at all.
	 * 2. .bio-subheading-wrap is a direct child of .entry-content (which
	 *    carries is-layout-constrained), so WordPress's own global flow
	 *    rule (`:where(.is-layout-constrained) > *`) also adds its own
	 *    margin-block-start:1.2rem on top of the wrapper's padding — a
	 *    second, separate source of space above it that was never
	 *    targeted before.
	 * The heading's own default browser margin (scaling with its
	 * xx-large font-size) was already correctly zeroed by the rule below
	 * and did not need to change.
	 */
	.bio-subheading-wrap {
		margin-top: 0 !important;
		padding-top: 1.5rem !important;
		padding-bottom: 1.5rem !important;
	}

	.bio-subheading-wrap .wp-block-heading {
		margin: 0;
	}

	.bio-photo-col,
	.bio-text-col {
		width: 100%;
		position: static;
		padding-left: 0;
		padding-right: 0;
	}

	/*
	 * Section 1 stacks photo-then-text on mobile (DOM order), so its photo
	 * needs its own bottom spacing before the first paragraph below it.
	 * Section 2's DOM order is text-then-photo, so its photo already ends
	 * the section with nothing stacking directly beneath it — no gap
	 * needed there.
	 */
	.bio-section:not(.bio-section--s2) .bio-photo-col {
		margin-bottom: 2.5rem;
	}
}

/*
 * Media page (EN 182, DE 183, PL 184, IT 185): curated 3-column grid of
 * video/photo thumbnails, full-bleed with the same 8% inset used by the
 * homepage hero and Biography sections.
 */
.media-page-wrap {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	padding-left: 8%;
	padding-right: 8%;
	padding-bottom: 4rem;
	box-sizing: border-box;
	background-color: #f5f5f3;
}

.media-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 2rem;
}

/*
 * .media-card is the actual grid cell (thumbnail/banner button + title
 * below it, for the photo item); .media-item is just the clickable button
 * itself, so a title paragraph can sit outside it as a plain sibling (a
 * <button> can only contain phrasing content, not a block-level title).
 */
.media-item {
	position: relative;
	display: block;
	cursor: pointer;
	width: 100%;
	aspect-ratio: 4 / 3;
	border-radius: 12px !important;
	overflow: hidden;
	background-color: #e5e5e3;
	border: none;
	padding: 0;
}

.media-title {
	margin: 0.75rem 0 0;
	font-size: var(--wp--preset--font-size--medium);
	color: #111111;
	line-height: 1.35;
}

.media-thumb {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: opacity 0.25s ease, transform 0.35s ease;
}

/* Subtle dim + slight zoom on hover — the photo item's own hover effect. */
.media-item:hover .media-thumb {
	opacity: 0.85;
	transform: scale(1.03);
}

/*
 * Video banners: no YouTube (or any external) image at all — a plain
 * text/icon card in the site's own background, overriding .media-item's
 * image-thumbnail box (aspect-ratio, overflow, fill color) entirely.
 * .media-item.media-banner beats a plain .media-item on specificity, so
 * this cleanly replaces rather than fights the base rule above.
 */
.media-item.media-banner {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
	aspect-ratio: auto;
	min-height: 220px;
	overflow: visible;
	background-color: #f5f5f3;
	border: 2px solid #111111;
	padding: 2rem 1.5rem;
	transition: background-color 0.25s ease;
}

.media-item.media-banner:hover {
	background-color: #ececea;
}

.media-banner__title {
	font-family: var(--wp--preset--font-family--playfair-display);
	font-style: italic;
	font-weight: 400;
	font-size: var(--wp--preset--font-size--large);
	color: #111111;
	text-align: center;
	line-height: 1.35;
	max-width: 90%;
}

/*
 * Minimal play icon: thin black circle outline + black triangle, no fill
 * behind it (distinct from the old dark-circle-over-image treatment,
 * which no longer applies now that banners carry no image to sit over).
 * Grows slightly on hover via the banner's own :hover state.
 */
.media-play {
	width: 52px;
	height: 52px;
	transition: transform 0.25s ease;
	pointer-events: none;
}

.media-item.media-banner:hover .media-play {
	transform: scale(1.12);
}

.media-play svg {
	width: 100%;
	height: 100%;
	display: block;
}

@media (max-width: 768px) {
	.media-page-wrap {
		padding-left: 6%;
		padding-right: 6%;
	}

	.media-grid {
		grid-template-columns: 1fr;
		gap: 1.5rem;
	}
}

/*
 * The video/photo lightbox is no longer CSS-driven: it's built entirely
 * with inline styles on elements JS creates and appends straight to
 * document.body (see federico_bresciani_media_lightbox_script() in
 * functions.php), specifically to sidestep any stacking-context/z-index
 * interference from the page's own template markup. No .media-lightbox*
 * classes exist to style here any more.
 */

/*
 * Shared "animated underline" hover treatment for is-style-link buttons
 * (hero's Learn More and Contact). Static text-decoration is disabled
 * (overriding the button style's default) in favor of a ::after line that
 * fades and slides in on hover/focus.
 */
.wp-block-button.is-style-link .wp-block-button__link {
	position: relative;
	display: inline-block;
	text-decoration: none !important;
}

.wp-block-button.is-style-link .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 1px;
	background-color: currentColor;
	opacity: 0;
	transform: scaleX(0.6);
	transform-origin: left;
	transition: opacity 0.25s ease, transform 0.25s ease;
}

.wp-block-button.is-style-link .wp-block-button__link:hover,
.wp-block-button.is-style-link .wp-block-button__link:focus-visible {
	color: #888888;
}

.wp-block-button.is-style-link .wp-block-button__link:hover::after,
.wp-block-button.is-style-link .wp-block-button__link:focus-visible::after {
	opacity: 1;
	transform: scaleX(1);
}

/*
 * Biography page: CONTACT link at the bottom, after Section 2. Centered,
 * with breathing room from the text above and the footer below.
 */
.bio-contact-link-wrap {
	text-align: center;
	margin-top: 3rem;
	margin-bottom: 3rem;
}

/*
 * Same is-style-link button as Learn More/Contact on the homepage (hence
 * .wp-block-button__link, inheriting the animated-underline hover above)
 * but larger and more spaced out to feel more prominent on its own at the
 * bottom of the page. !important: theme.json's core/button variation
 * generates `.wp-block-button.is-style-link .wp-block-button__link`,
 * a 3-class compound selector that would otherwise beat this 2-class one
 * on specificity regardless of source order.
 */
.bio-contact-link.wp-block-button__link {
	font-size: 1.2rem !important;
	letter-spacing: 0.12em !important;
}

/*
 * Homepage hero: true edge-to-edge full-bleed, independent of the theme's
 * root-padding-aware alignment (which stops short of the real viewport
 * edge). The viewport-relative negative-margin trick works regardless of
 * any max-width ancestor.
 *
 * !important is required here: the theme's own global styles force-center
 * any non-alignfull child of a constrained container via
 * `.is-layout-constrained > :where(...) { margin-left/right: auto !important }`,
 * which otherwise silently overrides these margins and pushes the whole
 * row (and everything in it) to the right.
 */
/*
 * Belt-and-suspenders: the warm grey needs to show at every layer (body,
 * the hero row, and the photo column itself), not just on <main>. <main>'s
 * own background only covers where <main>'s box actually reaches, and the
 * page's global stylesheet unconditionally paints `body` white — scoped to
 * `.home` so it doesn't touch Biography/Concerts/Contact.
 */
body.home {
	background-color: #f5f5f3;
}

/*
 * Homepage only: the footer's default padding (var(--wp--preset--spacing--60)
 * top, --50 bottom — up to 70px + 50px, fluid) is generous breathing room
 * that makes sense as the very last thing on a normal, scrolling page —
 * but it's exactly the kind of extra height that defeats fitting the
 * homepage into one screen, adding well over 100px below a hero that's
 * otherwise sized to end precisely at the viewport's bottom edge. Tightened
 * here specifically; every other page keeps the shared footer spacing.
 */
body.home footer.wp-block-group.alignfull {
	padding-top: 20px !important;
	padding-bottom: 20px !important;
}

/*
 * The stray default block-spacing margin (see main's own rule above)
 * actually lands on THIS outer <footer class="wp-block-template-part">
 * wrapper, not the inner footer.wp-block-group.alignfull targeted above
 * — it's the true third sibling directly under <body> (after the fixed
 * header and main), confirmed by inspecting the rendered DOM directly.
 */
body.home footer.wp-block-template-part {
	margin-top: 0 !important;
}

/*
 * Desktop only (the mobile media query below resets this back to a
 * natural, scrolling height for the stacked layout): fits the whole
 * homepage — hero AND the footer below it — into the screen without
 * scrolling, by sizing the hero off viewport HEIGHT instead of width.
 * The old approach sized the photo purely from viewport width (44vw *
 * its aspect ratio), which ignores how tall the screen actually is — on
 * a wide monitor that made the photo (and the whole row) taller than the
 * visible area, forcing a scroll. --site-header-height is subtracted for
 * the fixed header (see main's own padding-top above for where it's
 * set), and 60px is subtracted for the homepage's own tightened footer
 * (see body.home footer.wp-block-group.alignfull below) — leaving it
 * room to sit fully in view too, rather than only the hero fitting and
 * the footer alone forcing a small scroll.
 */
.hero-fullbleed {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	/* box-sizing:border-box so this padding is carved out of the 100vw
	   width above rather than added on top of it (which would overflow
	   the viewport and cause horizontal scroll). */
	padding-left: 8%;
	padding-right: 8%;
	box-sizing: border-box;
	gap: 0 !important;
	border: none;
	background-color: #f5f5f3;
	height: calc(100vh - var(--site-header-height, 84px) - 60px);
	min-height: 500px;
}

/*
 * Footer copyright: same full-bleed technique and exact same 48px left
 * inset as .hero-quote-column, so the two line up precisely. Plain
 * `alignfull` was inconsistent here — its inset is the theme's fluid root
 * padding (varies with viewport), which doesn't match the hero's fixed
 * 48px.
 */
.footer-copyright {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	padding-left: 48px;
	box-sizing: border-box;
}

/*
 * display:flex + justify-content:center vertically centers the quote/
 * buttons within the column's full height (now fixed to fit the screen,
 * see .hero-fullbleed) instead of them sitting at the top with empty
 * space below — the column is much taller now than the content alone
 * needs, since it stretches to match the photo column's full height.
 */
/*
 * flex:1 fills whatever horizontal space the photo column doesn't use —
 * needed now that the photo's own width is derived from its
 * aspect-ratio (see .hero-photo-column) rather than a fixed percentage,
 * so this column's width isn't a fixed number either; it's simply
 * "everything else".
 */
.hero-quote-column {
	padding-left: 48px;
	padding-right: 24px;
	box-sizing: border-box;
	border: none;
	display: flex;
	flex-direction: column;
	justify-content: center;
	flex: 1 1 auto !important;
}

/* Buttons block must span the column's full (already-inset) width for its
   own centering to be centering relative to the column, not just itself. */
.hero-quote-column .wp-block-buttons {
	width: 100%;
	box-sizing: border-box;
}

/*
 * The photo column is a plain CSS background-image (no <img> element),
 * sized via background-size:contain so the full portrait is always
 * visible with no cropping, regardless of exact box proportions. It now
 * fills the row's full height (fixed to fit the screen, see
 * .hero-fullbleed) rather than sizing itself from viewport width —
 * background-size:contain then does the work of scaling the photo down
 * to whatever that height allows, still with no cropping either way; the
 * background-color fills any residual letterboxing with the page's own
 * warm grey instead of leaving white gaps.
 */
/*
 * width:auto + flex:0 0 auto here, together with aspect-ratio below, is
 * what actually fixes the rounded-corner artifact: the box's height is
 * fixed (fills the row, see .hero-fullbleed), and aspect-ratio derives
 * its width FROM that height using the photo's own exact proportions
 * (1024x1536) — so the box's shape always matches the photo's shape
 * exactly, at every window size. Previously the box's width came from a
 * fixed 44% flex-basis while its height came from the viewport — two
 * independent numbers that only matched by coincidence at one exact
 * size. Wherever they didn't match, background-size:contain (kept, per
 * the earlier "no cropping" requirement) left an empty letterboxed strip
 * on one side, filled with this box's own background-color — and since
 * that color is nearly identical to the page background around it,
 * wherever the rounded corner fell on that empty strip rather than the
 * actual photo, the rounding became invisible (no contrast to see it
 * against) — hence corners that looked rounded in one place and sharp in
 * another as the window resized and that strip moved around. With the
 * box's own shape matching the photo exactly, that empty strip can no
 * longer exist at all, so the photo now always reaches all four
 * (visibly, consistently rounded) corners.
 */
.hero-photo-column {
	padding: 0;
	margin: 0;
	border: none;
	background-image: url('https://federicobresciani.com/wp-content/uploads/2026/09/exec-b530104b-0821-4123-a1b1-10f249b6d7f4.png');
	background-size: contain;
	background-position: center top;
	background-repeat: no-repeat;
	background-color: #f5f5f3;
	height: 100%;
	flex: 0 0 auto !important;
	width: auto !important;
	/* Must match the actual uploaded photo's real pixel dimensions
	   exactly (checked directly via Image().naturalWidth/Height — this
	   file is 1024x1536, not 1024x1388 as an earlier revision assumed).
	   Any mismatch here reopens the letterboxing bug described below:
	   background-size:contain leaves an empty strip filled with this
	   box's own background-color, and since that color nearly matches
	   the page background beside it, the strip is invisible — which
	   also swallows the rounded corners wherever they land on it. */
	aspect-ratio: 1024 / 1536;
	/* No transition here on purpose. Native window resizing already
	   repaints every frame — it's inherently continuous, nothing to
	   animate. A CSS transition on width/height instead makes the box
	   LAG behind the live target as the window drags (each new frame's
	   value gets a fresh 0.3s ease-into instead of applying instantly),
	   and that lag has to "catch up" the moment dragging stops — which is
	   exactly the snap that was reported. Removing it (tried previously
	   as a fix, confirmed by testing to be the actual cause) is what
	   makes the resize read as smooth. The one genuinely discrete jump —
	   crossing the 1150px breakpoint, where flex-direction itself
	   switches from this row-based sizing to the stacked mode below — is
	   not animatable by CSS either way (flex-direction isn't a
	   transitionable property), so no transition helps there. */
	/* !important: the theme's global "no rounded corners" rule
	   (`* { border-radius: 0 !important; }`) would otherwise win, since it's
	   also !important — a class selector beats the universal selector's
	   specificity, so this rule takes priority regardless. */
	border-radius: 8% !important;
	/*
	 * border-radius alone does NOT actually round this element's visible
	 * content — confirmed directly in a live browser: background-color
	 * respects border-radius correctly, but this large background-image
	 * does not, even with background-clip:border-box (the correct
	 * default) and even with overflow:hidden added. This is a genuine
	 * browser rendering limitation with border-radius clipping large
	 * background-images, not a sizing/aspect-ratio bug. clip-path is a
	 * separate, more direct clipping mechanism that isn't subject to the
	 * same limitation — confirmed fixing it in the same test. border-radius
	 * is kept above regardless, both as the semantically correct property
	 * and as a fallback.
	 */
	-webkit-clip-path: inset(0 round 8%);
	clip-path: inset(0 round 8%);
}

/*
 * Header, site-wide. "Federico Bresciani" must never wrap onto a second
 * line — without this, shrinking the window let the flex row's squeeze
 * fall back to breaking the title between words (a flex item's default
 * min-width:auto still permits text wrapping as its shrink mechanism).
 * Applies at every width; once the hamburger takes over below, there's
 * always ample room for the title alone anyway.
 */
.site-header-fixed .wp-block-site-title {
	white-space: nowrap;
}

/*
 * Same problem, same fix, for the nav links themselves: core/navigation's
 * own flex-wrap (set via the wp:navigation block's own "flexWrap"
 * attribute, now "nowrap" in header.html) can still be reintroduced by
 * core's own responsive-nav CSS depending on state, so it's pinned here
 * too — Biography/Media/Concerts/etc. must never break onto a second
 * line either; the media query below is what keeps that from ever being
 * necessary by switching to the hamburger with room to spare first.
 */
.wp-block-navigation {
	flex-wrap: nowrap !important;
}

/*
 * "Nie | Romantyczni" is one nav item whose own label contains spaces, so
 * even with the whole row forced to nowrap above, the browser could still
 * break that single label's *own text* onto two lines at one of those
 * spaces once the row got tight. This stops that independently of the
 * row-level fix.
 */
.wp-block-navigation-item__label {
	white-space: nowrap;
}

/*
 * Mobile/tablet header (below 1150px — deliberately wider than a typical
 * "phone" breakpoint): "Federico Bresciani" plus all five nav links plus
 * the language switcher need real estate that a laptop-width window
 * doesn't reliably have, and letting core/navigation's default 600px
 * breakpoint (or the earlier 768px used here) govern it meant there was
 * a window — nav still inline, but not enough room — where flex-wrap
 * fought back and broke links onto a second line before the hamburger
 * ever kicked in. Moving the switch to 1150px removes that window
 * entirely: nav is inline only when there's comfortably enough room for
 * one unbroken line, and it's a hamburger everywhere else.
 */
@media (max-width: 1150px) {
	/*
	 * Header row: only padding-right is reduced from the shared 4%
	 * baseline here — less inset on that side alone brings the
	 * hamburger/switcher closer to the right edge. padding-left stays at
	 * the same 4% as desktop deliberately: "Federico Bresciani" should
	 * only resize on narrower windows, never shift position — reducing
	 * padding-left too would pull it closer to the true left edge as a
	 * side effect, which is exactly the movement this avoids. padding-top/
	 * bottom are likewise left alone now (no more 22px override) — that
	 * existed only to give breathing room around the old fixed 1.45rem
	 * mobile title size; now that the title is a single fluid clamp()
	 * that stays large and scales continuously instead of snapping small,
	 * inflating the bar's own vertical padding on top of that is what
	 * made the whole bar grow taller than the desktop version. Keeping
	 * padding-top/bottom at the shared 14px baseline at every width keeps
	 * the bar's height consistent, exactly like the title's own position.
	 */
	.site-header-fixed .wp-block-group.alignwide {
		padding-right: 2% !important;
	}

	/* Hamburger icon, slightly larger. */
	.wp-block-navigation__responsive-container-open svg {
		width: 30px !important;
		height: 30px !important;
	}

	/*
	 * Language switcher, to match the larger title/icon. .pll-dropdown__menu
	 * itself must get the same font-size too, not just the links inside it:
	 * its -1em left offset and the links' compensating 1em padding-left
	 * only cancel out exactly when both resolve against the same font-size
	 * (see the fuller explanation above .pll-dropdown__menu's own rule).
	 */
	.pll-dropdown__trigger,
	.pll-dropdown__menu,
	.pll-dropdown__menu a {
		font-size: 1.1rem !important;
	}

	/*
	 * .header-actions itself needs no margin-right/padding-right: the
	 * header row's own padding-right (2% on mobile) already matches
	 * padding-left exactly, so this group already lands at the same
	 * inward inset on the right as the title does on the left.
	 *
	 * The real gap was inside .pll-dropdown: its min-width:60px +
	 * justify-content:flex-start (reserved so DESKTOP nav links never
	 * shift as the language code's width changes) leaves slack space
	 * after the arrow when the box is wider than its content — on mobile
	 * the nav links are hidden behind the hamburger, so that reservation
	 * serves no purpose and only pushes the visible trigger away from the
	 * true right edge. Shrink-wrapping it here removes that invisible gap.
	 */
	.header-actions {
		margin-right: 0 !important;
		padding-right: 0 !important;
	}

	.pll-dropdown {
		min-width: 0;
	}

	/*
	 * FOUND THE ACTUAL GAP: the header row (.wp-block-group.alignwide) sits
	 * inside a *separate* wrapper — <div class="wp-block-group
	 * has-global-padding is-layout-constrained"> — that core itself
	 * generates around any "constrained" layout group. .has-global-padding
	 * carries its own padding-left/right: var(--wp--style--root--padding-*),
	 * which resolves to var(--wp--preset--spacing--50) = clamp(30px, 5vw,
	 * 50px) — effectively a flat 30px on mobile viewports. That's a
	 * second, OUTER inset stacking on top of the alignwide row's own
	 * padding — it was never touched by any .header-actions/.pll-dropdown/
	 * .alignwide edit because it lives one level further out.
	 *
	 * Only the right side is zeroed: on the right, this outer inset was
	 * genuinely just an unwanted gap pushing the hamburger/switcher away
	 * from the true edge. On the left it's the opposite — removing it
	 * would pull "Federico Bresciani" itself closer to the edge as a side
	 * effect, moving it rather than just resizing it, which is exactly
	 * what this now avoids by leaving the left side alone.
	 */
	.site-header-fixed .has-global-padding {
		padding-right: 0 !important;
	}

	/*
	 * Force hamburger-menu mode up to 1150px: core/navigation's own
	 * built-in responsive breakpoint is a fixed 600px, which is too
	 * narrow — between 600px and this new 1150px cutoff it was rendering
	 * the full inline link row (Biography, Media, Concerts, Nie |
	 * Romantyczni) squeezed in next to the language switcher. !important
	 * is required since core's own rules governing these same elements
	 * carry no !important themselves.
	 */
	.wp-block-navigation__responsive-container-open {
		display: flex !important;
		opacity: 0.6;
	}

	.wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none !important;
	}

	/* Slightly transparent overlay instead of solid white when the mobile
	   menu is open. */
	.wp-block-navigation__responsive-container.has-background {
		background: rgba(255, 255, 255, 0.85) !important;
	}

	/*
	 * The overlay auto-focuses its first link (Biography) when opened
	 * (core/navigation's own focusFirstElement behavior), which otherwise
	 * shows the browser's default focus outline as a box around it.
	 */
	.wp-block-navigation__responsive-container a:focus {
		outline: none;
	}
}

/*
 * Homepage hero stacking — below 1150px, not 768px. Widened from the
 * original 768px specifically to fix an overlap bug: the fixed-height
 * "fit one screen" row above sizes the photo's WIDTH from its own fixed
 * HEIGHT via aspect-ratio, while the quote column just gets whatever
 * width is left over. On a narrower-but-still-"desktop-row" window, the
 * height-driven photo could claim most of the row's width, squeezing the
 * quote column below what the LEARN MORE/CONTACT buttons need to fit —
 * and since flex items overflow rather than force-shrinking content,
 * those buttons spilled out and visually landed on top of the photo.
 * Switching to the stacked layout earlier (1150px, matching the header's
 * own hamburger cutoff) removes the fixed-height row — and the
 * width-squeeze it depends on — before that overlap can happen, in
 * favor of a naturally taller, scrolling page.
 */
@media (max-width: 1150px) {
	/*
	 * Homepage hero: stack photo above quote/buttons, full width each.
	 * height/min-height are reset back to auto (natural, scrolling)
	 * here — the fixed "fit the whole screen" sizing above is a
	 * desktop-only treatment; a stacked mobile layout scrolling
	 * naturally is normal, expected behavior and isn't what that was
	 * solving for.
	 */
	.hero-fullbleed {
		flex-direction: column;
		padding-left: 5%;
		padding-right: 5%;
		height: auto;
		min-height: 0;
	}

	.hero-quote-column,
	.hero-photo-column {
		flex-basis: 100% !important;
		width: 100% !important;
	}

	/*
	 * Photo first, full width. Height is no longer a separate min-height
	 * formula here — it used 100vw, but the box's real rendered width is
	 * narrower than that (this row has its own 5% padding-left/right), so
	 * min-height was forcing the box taller than its own width actually
	 * called for. Since aspect-ratio (set on the base rule) already
	 * computes height correctly from whatever the box's real width is,
	 * that mismatch was pure redundancy at best — and at worst, exactly
	 * what let a letterboxed gap reopen here, with the same
	 * rounded-corner-turns-invisible-against-it symptom as before.
	 * Letting aspect-ratio be the single source of truth in every layout
	 * mode (not just the desktop row) is what actually keeps it fixed.
	 */
	.hero-photo-column {
		order: -1;
		flex: 0 0 auto !important;
		height: auto;
	}

	.hero-quote-column {
		padding-left: 0;
		padding-right: 0;
	}

	/*
	 * Centered in this stacked layout — the quote's text-align:left is
	 * set via an inline style baked into the page content itself, which
	 * needs !important here to override. LEARN MORE/CONTACT (below) are
	 * kept centered to match, rather than independently left-aligned.
	 */
	.hero-quote-column .wp-block-pullquote {
		font-size: 1.3rem !important;
		text-align: center !important;
	}

	.hero-quote-column .wp-block-buttons {
		justify-content: center;
	}
}

/*
 * Desktop only: separates the language switcher from the nav links (it's
 * the direct sibling right after <nav> inside .header-actions, which
 * follows Nie | Romantyczni) with a visible gap, instead of sitting right
 * up against it like Biography/Concerts/Media do against each other.
 * Scoped above the header's hamburger breakpoint (1150px) since below it
 * the nav links are hidden behind the hamburger and this gap wouldn't
 * mean anything.
 *
 * !important is required: core's own global flex-layout reset —
 * `.is-layout-flex > :is(*, div){margin:0}` — targets .pll-dropdown
 * directly (it's a div, a direct child of .header-actions, which carries
 * the is-layout-flex class) at specificity (0,1,1), beating a plain
 * `.pll-dropdown{margin-left:...}` at (0,1,0) regardless of source order.
 */
@media (min-width: 1151px) {
	.pll-dropdown {
		margin-left: 2.5rem !important;
	}
}

/*
 * Language switcher dropdown. min-width reserves the same horizontal space
 * regardless of which 2-letter code is showing (EN/DE/PL/IT), so the nav
 * items to its left in the same flex row never shift as the current
 * language changes. justify-content:flex-start (not flex-end) is what
 * makes that safe: any reserved slack appears AFTER the arrow, on the
 * right, so the container's left edge still always coincides with the
 * trigger text's left edge (needed by .pll-dropdown__menu below, which
 * anchors its own left edge to that same position).
 */
.pll-dropdown {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: flex-start;
	min-width: 60px;
}

.pll-dropdown__trigger {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	background: none;
	border: none;
	margin: 0;
	padding: 0;
	color: #111111;
	font: inherit;
	font-size: var(--wp--preset--font-size--medium);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	cursor: pointer;
}

.pll-dropdown__trigger:hover,
.pll-dropdown__trigger:focus-visible {
	text-decoration: underline;
}

.pll-dropdown__arrow {
	width: 0.55em;
	height: 0.55em;
	flex-shrink: 0;
	transition: transform 0.15s ease;
}

.pll-dropdown:hover .pll-dropdown__arrow,
.pll-dropdown:focus-within .pll-dropdown__arrow {
	transform: rotate(180deg);
}

/*
 * No margin between the trigger and the menu: the "gap" lives inside the
 * menu's own padding-top instead, so the mouse never crosses a dead zone
 * that isn't part of either element while moving from one to the other.
 */
.pll-dropdown__menu {
	position: absolute;
	top: 100%;
	/* Extends 1em further left than the trigger text's left edge; the
	   matching padding-left on .pll-dropdown__menu a below keeps the
	   letters themselves anchored at their previous visual position. */
	left: -1em;
	margin: 0;
	padding: 0.15em 0 0.4em;
	list-style: none;
	/* Must match .pll-dropdown__menu a's font-size: the -1em left offset
	   here and the compensating 1em padding-left on the links only cancel
	   out exactly if both "1em"s resolve to the same pixel value. */
	font-size: var(--wp--preset--font-size--medium);
	background: rgba(255, 255, 255, 0.85);
	border: none;
	box-shadow: none;
	/* Spans the full trigger width (plus the 1em extra on the left) —
	   rather than shrink-wrapping to its own content. */
	width: calc(100% + 1em);
	opacity: 0;
	visibility: hidden;
	/* Slide-and-fade open/close. Transitioning visibility alongside opacity
	   (even though visibility itself can't be interpolated) delays the
	   hidden switch to the end of the 0.2s on close, so the fade-out plays
	   instead of being cut off instantly; on open it flips to visible
	   immediately, as desired. */
	transform: translateY(-6px);
	transition: opacity 0.2s ease-out, transform 0.2s ease-out, visibility 0.2s;
	z-index: 100;
}

.pll-dropdown__menu li {
	margin: 0;
}

.pll-dropdown__menu a {
	display: block;
	padding: 0.1em 0 0.1em 1em;
	text-align: left;
	color: #111111;
	text-decoration: none;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	font-size: var(--wp--preset--font-size--medium);
	white-space: nowrap;
}

.pll-dropdown__menu a:hover,
.pll-dropdown__menu a:focus-visible {
	text-decoration: underline;
}

.pll-dropdown:hover .pll-dropdown__menu,
.pll-dropdown:focus-within .pll-dropdown__menu {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

/*
 * Contact page (EN 49, DE 106, PL 107, IT 108): same warm-grey background
 * as Biography/Media, applied at the page level too so there's no white
 * seam above/below the two-column section itself.
 */
.page-id-49,
.page-id-106,
.page-id-107,
.page-id-108 {
	background-color: #f5f5f3;
}

/* No page title ("Contact"/"Kontakt"/"Contatto") shown above the section. */
.page-id-49 .wp-block-post-title,
.page-id-106 .wp-block-post-title,
.page-id-107 .wp-block-post-title,
.page-id-108 .wp-block-post-title {
	display: none;
}

/*
 * Pulls the section up closer to the header: the shared page.html
 * template stacks main's own margin-top with its inner full-width
 * group's padding-top above the title (both fluid clamp() values,
 * normally sized to sit below a visible title) — now that the title is
 * hidden, that space is pure unused gap, so it's cut down here, scoped
 * to Contact only.
 */
.page-id-49 main,
.page-id-106 main,
.page-id-107 main,
.page-id-108 main {
	margin-top: 1rem !important;
}

.page-id-49 main > .wp-block-group.alignfull,
.page-id-106 main > .wp-block-group.alignfull,
.page-id-107 main > .wp-block-group.alignfull,
.page-id-108 main > .wp-block-group.alignfull {
	padding-top: 0.5rem !important;
}

/*
 * Two-column layout, left 55 / right 45, same full-bleed 8% inset
 * technique as .hero-fullbleed and the Biography sections.
 */
.contact-section {
	width: 100vw !important;
	max-width: 100vw !important;
	margin-left: calc(50% - 50vw) !important;
	margin-right: calc(50% - 50vw) !important;
	padding-left: 8%;
	padding-right: 8%;
	padding-top: 0.5rem;
	padding-bottom: 4rem;
	box-sizing: border-box;
	background-color: #f5f5f3;
	display: flex;
	flex-direction: row;
	gap: 0;
}

.contact-left-col {
	width: 55%;
	padding-right: 6%;
	box-sizing: border-box;
}

.contact-right-col {
	width: 45%;
	box-sizing: border-box;
}

/* Fills the column's full (stretched, row-height) box — object-fit:cover
   avoids distorting the image regardless of the exact box proportions. */
.contact-photo {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: grayscale(100%);
	border-radius: 12px !important;
}

.contact-email-link {
	display: inline-block;
	font-family: var(--wp--preset--font-family--playfair-display);
	font-size: var(--wp--preset--font-size--large);
	color: #111111;
	text-decoration: underline;
}

.contact-agent-line {
	margin-top: 0.5rem;
	font-size: var(--wp--preset--font-size--medium);
	color: #111111;
}

.contact-mediakit-line {
	margin-top: 1.5rem;
	max-width: 32em;
	font-size: var(--wp--preset--font-size--small);
	color: #888888;
}

.contact-direct-line {
	margin-top: 1.5rem;
	font-size: var(--wp--preset--font-size--small);
	color: #111111;
}

.contact-direct-line a {
	color: inherit;
}

.contact-form {
	margin-top: 2.5rem;
	max-width: 32em;
}

.contact-form-field {
	margin-bottom: 1.5rem;
}

.contact-form-field label {
	display: block;
	margin-bottom: 0.4em;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: #111111;
}

/* Not uppercase/letter-spaced like the label itself — reads as an aside,
   not part of the field's name. */
.contact-form-required {
	text-transform: none;
	letter-spacing: normal;
	color: #888888;
	font-size: 0.9em;
}

.contact-form-field input,
.contact-form-field textarea {
	display: block;
	width: 100%;
	box-sizing: border-box;
	padding: 0.7em 0.8em;
	background-color: #f5f5f3;
	border: 1px solid #b3b3b0;
	color: #111111;
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
}

.contact-form-field input.has-error,
.contact-form-field textarea.has-error {
	border-color: #b3261e;
}

.contact-form-error {
	display: block;
	margin-top: 0.4em;
	color: #b3261e;
	font-size: var(--wp--preset--font-size--small);
}

.contact-form-field input:focus,
.contact-form-field textarea:focus {
	outline: none;
	border-color: #111111;
}

.contact-form-field textarea {
	resize: vertical;
}

/* Honeypot: present in the markup for bots to fill in, invisible and
   unreachable by keyboard for real visitors. */
.contact-form-honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.contact-form-submit.wp-element-button {
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

.contact-form-status {
	margin-bottom: 1.5rem;
	font-size: var(--wp--preset--font-size--small);
}

.contact-form-status--success {
	color: #2f7a3d;
}

.contact-form-status--error {
	color: #b3261e;
}

@media (max-width: 781px) {
	.contact-section {
		flex-direction: column;
		padding-left: 6%;
		padding-right: 6%;
	}

	.contact-left-col,
	.contact-right-col {
		width: 100%;
		padding-right: 0;
	}

	.contact-right-col {
		margin-top: 2.5rem;
	}

	.contact-photo {
		height: auto;
		aspect-ratio: 4 / 3;
	}
}
