/**
 * vs-home-banner.css — [vs_home_banner] Home hero banner (child-theme component, round 1, 2026-09-26).
 * Built 1:1 from Debussy's BANNER-SPEC.md §3/§4 + proof/vs-home-banner.css rev 2 (vibeslash-audit/banner-spec/):
 * full-bleed art filling the right side to the viewport edge (Ludwig), CTA deepened to AA contrast (Ludwig).
 * Ludwig rule: only vs- classes or direct-child (>) chains; no broad descendants; no !important;
 * every rule commented. All sizes / stops are custom properties so a resize is a one-line change.
 * Font: UnifrakturCook is enqueued by inc/vs-home-banner.php (same Google Fonts URL as patch 08).
 * Rev 3 (2026-09-28, Debussy; Leo un-parked banner SIZE): compact banner sized 1:1 to Leo's loved mockup
 * (homepage-mockup-loved.png, 1536 px wide; every desktop number below = mockup px x viewport/1536), headline
 * "Cut through / the noise" in title case on two lines (Ludwig/Wagner). Header and seam rules untouched.
 * Rev 3 FINAL (Ludwig 2026-09-28): phones paint phone-v2 (800x600 nave crop); button = mockup (title case
 * "Shop Vibes", 208x46 @1440); headline / subhead / button inks SAMPLED from the mockup (ΔE2000 vs bone > 2).
 */

/* Round 1004-night: headline face = Old London (Dieter Steffmann / Typographer Mediengestaltung), self-hosted as an
   UNMODIFIED full-glyph WOFF2 conversion of OldLondon.ttf (1001Fonts FFC license: §4 allows WOFF conversion, §6 web
   embedding; §3 forbids modification, so no subset). Regular weight only: the h1 asks for 400, no faux bold.
   font-display: swap + the metric-matched fallbacks below keep the 2-line break and height during the swap. */
@font-face {
	font-family: "Old London";
	src: url("../fonts/old-london.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

/* Rev 3 font-swap guard: metric-matched fallbacks for UnifrakturCook (Google Fonts, display=swap). Before the
   web font arrives the h1 renders in a local serif scaled to UnifrakturCook's widths, so the fallback also wraps
   "Cut through / the noise" on 2 lines and the banner height (and the menus row under it) does not jump.
   size-adjust = UnifrakturCook width / fallback width of "Cut through the" (measured in Chrome). Line height is
   unitless (0.9), so vertical size never depends on the face. A face whose local() font is absent is skipped. */
@font-face {
	font-family: "VS Blackletter Fallback TNR";   /* Windows / macOS / iOS Times New Roman; Linux+ChromeOS Tinos / Liberation Serif */
	src: local("Times New Roman Bold"), local("TimesNewRomanPS-BoldMT"), local("Tinos Bold"), local("Tinos-Bold"), local("Liberation Serif Bold"), local("LiberationSerif-Bold");
	font-weight: 700;
	size-adjust: 80.9%; /* 1004-night: Old London / Tinos Bold width of "Cut through the" = 5.577 / 6.890 em (fontTools hmtx) */
}

@font-face {
	font-family: "VS Blackletter Fallback Noto";  /* Android default serif */
	src: local("Noto Serif Bold"), local("NotoSerif-Bold");
	font-weight: 700;
	size-adjust: 69.4%; /* 1004-night: 72.5% x 80.9/84.5 (inferred, Noto not installed on the box) */
}

/* Banner root: variables + layout. Flex column, text vertically centred; own dark plate (#050505 = page
   field) so nothing behind it shows; isolation keeps the art/fade layers (z -2/-1) inside the banner.
   Full-bleed: negative inline margins = --vs-bleed pull the box out of the page gutters to the viewport
   edges; the same amount is added back as padding so the text column stays on the content grid. */
.vs-banner {
	/* ---- palette (existing brand hexes) ---- */
	--vs-field: #050505;               /* page field the menus sit on (body.home, P0) — banner bottom row lands on it */
	--vs-field-rgb: 5, 5, 5;
	--vs-bone: #F2E8D5;
	/* Rev 3 final inks, sampled from homepage-mockup-loved.png (median of solid glyph pixels; ΔE2000 vs bone in brackets) */
	--vs-title-ink: #F3F3F3;           /* "Cut through the" (ΔE 8.7); 18.37:1 on #050505 */
	--vs-tag-ink: #C3C3C4;             /* subhead, mockup's light grey (ΔE 12.6); 11.57:1 on #050505 */
	--vs-purple: #9B5CFF;              /* "noise" */
	--vs-purple-hover: #B47CFF;        /* brand light purple (menus hover) */
	--vs-type-shadow: #120d19;         /* live 08 hero text-shadow */
	/* CTA (Ludwig: deeper purple so the bone label passes AA). #9B5CFF shaded to 62%, hue 263° kept
	   (~ mockup button #622BA2). Bone on #9B5CFF was 3.22:1, live white on #9B5CFF 3.91:1. */
	--vs-cta-bg: #60399E;              /* label #F3F3F3 7.35:1 (bone was 6.71:1) */
	--vs-cta-bg-hover: #7344BD;        /* #9B5CFF x 0.74; label #F3F3F3 5.75:1 (bone was 5.25:1) */
	--vs-cta-ink: #F3F3F3;             /* rev 3 final: mockup label is white (sampled #F7F4FA stems); 7.35:1 on #60399E, 5.75:1 on hover */
	--vs-focus: 2px solid #B47CFF;     /* keyboard ring, 7.05:1 on #050505 */

	/* ---- size (rev 3): mockup box = 317/1536 of the width (297px @1440). Height is padding + content; this is
	   only the floor, so text never crops. Resize later = edit this ONE line (was min(72vh, 760px), 648px @1440x900) ---- */
	--vs-banner-h: clamp(15rem, 20.6vw, 28rem);
	/* full-bleed: distance from the host content box to the viewport edge; set 0px to stay inside the host */
	--vs-bleed: calc(50vw - 50%);
	--vs-banner-pad-inline: clamp(1.25rem, 4vw, 5rem);   /* text inset inside the content box */
	/* top = header border -> headline ink 30/1536 (ink sits .065em below the line box); bottom = button -> menus row 28/1536 */
	--vs-banner-pad-block: clamp(1rem, 1.63vw, 2.5rem) clamp(1.25rem, 1.82vw, 2.75rem);
	--vs-title-tag-gap: clamp(0.625rem, 1.07vw, 1.25rem);  /* headline baseline -> tagline cap top 27/1536 */
	--vs-tag-cta-gap: clamp(0.75rem, 1vw, 1.5rem);         /* tagline last line -> button top 16/1536 */
	--vs-banner-col: min(46%, 40rem);                    /* text column; mockup headline = 512/1280 = 40% */

	/* ---- art layer: right-anchored at the viewport edge, focal point = rose window (51.7% / 35.6% of the file) ---- */
	--vs-art-w: 70%;                   /* art layer width from the right (viewport) edge -> rose window at 66% (30% + .517 x 70%) */
	--vs-art-max: 1700px;              /* ultrawide cap: 1.33x upscale of the 1280 file at 2560 (= 66.4% of 2560) */
	--vs-art-focal: 51.7% 30%;         /* x = rose window (51.7% of the file); y 30% (rev 3) keeps rose window + arch crown in the short box */
	--vs-art-img: url("../img/hero-cathedral-night.png");  /* fallback; the shortcode sets the versioned URL inline */
	--vs-art-img-phone: url("../img/hero-cathedral-night-phone-v2.jpg"); /* rev 3 final: 800x600 nave crop (v1 = 800x1200); fallback, the shortcode sets it inline */
	--vs-scrim: linear-gradient(transparent, transparent); /* extra darkening over the art (phone only) */

	/* ---- gradients ---- */
	/* L->R over the art layer: art visible from ~40% of the banner, its left edge melts into the field under
	   the text; only a thin right vignette (no fade to black, no empty band at the right). */
	--vs-grad-x: linear-gradient(90deg,
		rgba(var(--vs-field-rgb), 1) 0%,
		rgba(var(--vs-field-rgb), .88) 8%,
		rgba(var(--vs-field-rgb), .55) 18%,
		rgba(var(--vs-field-rgb), .2) 30%,
		rgba(var(--vs-field-rgb), 0) 42%,
		rgba(var(--vs-field-rgb), 0) 96%,
		rgba(var(--vs-field-rgb), .3) 100%);
	/* top->bottom over the whole banner: soft top, bottom rows = EXACT field colour.
	   Bach QA: the extra opaque stop 4px above the bottom makes the last rows exactly #050505 (Δ 0, was ≤1/255).
	   Rev 3: stops tightened for the ~300px box (art reaches closer to the header and the menus row, as in the mockup). */
	--vs-grad-y: linear-gradient(180deg,
		rgba(var(--vs-field-rgb), 1) 0%,
		rgba(var(--vs-field-rgb), 0) 7%,
		rgba(var(--vs-field-rgb), 0) 74%,
		rgba(var(--vs-field-rgb), .6) 90%,
		rgba(var(--vs-field-rgb), 1) calc(100% - 4px),
		rgba(var(--vs-field-rgb), 1) 100%);

	/* ---- type: same live 08 face (UnifrakturCook 700); rev 3 = one size for both headline lines ---- */
	--vs-font-display: "Old London", "VS Blackletter Fallback TNR", "VS Blackletter Fallback Noto", "Times New Roman", serif;
	--vs-font-ui: var(--jivatma--font-buttons, Inter), system-ui, sans-serif;
	--vs-title-size: clamp(3rem, 5.25vw, 6.5rem);        /* mockup 80px @1536 -> 75.6px @1440 ("Cut through" ink 334px) */
	--vs-title-lh: 0.9;                                  /* mockup baseline pitch 72/80 */
	--vs-title-measure: 5.2em;                           /* forces "Cut through / the noise": > "Cut through" 4.46em, < "Cut through the" 5.81em */
	--vs-tag-size: clamp(1rem, 1.17vw, 1.25rem);         /* mockup 18px @1536 -> 16.9px @1440 */
	--vs-cta-size: clamp(1rem, 1.28vw, 1.25rem);         /* rev 3 final: mockup label cap 14.5/1536 -> 18.4px @1440 (Inter cap .74); 16px phones */
	--vs-cta-h: clamp(2.75rem, 3.2vw, 3.25rem);          /* mockup plate 49/1536 -> 46.1px @1440; 44px touch floor */

	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	justify-content: center;
	box-sizing: border-box;
	width: calc(100% + 2 * var(--vs-bleed));
	max-width: none;
	min-height: var(--vs-banner-h);
	margin-block: 0;
	margin-inline: calc(-1 * var(--vs-bleed));
	padding-block: var(--vs-banner-pad-block);
	padding-inline: calc(var(--vs-bleed) + var(--vs-banner-pad-inline));
	overflow: hidden;
	background-color: var(--vs-field);
	color: var(--vs-title-ink);        /* rev 3 final: mockup white (was bone) */
}

/* Art layer: the cathedral as a CSS background (never an <img>, no alt), right-anchored, focal point pinned;
   grad-x and the (phone) scrim sit on top of the image inside the same layer. */
.vs-banner > .vs-banner__art {
	position: absolute;
	z-index: -2;
	top: 0;
	right: 0;
	bottom: 0;
	width: min(var(--vs-art-w), var(--vs-art-max));
	background-image: var(--vs-grad-x), var(--vs-scrim), var(--vs-art-img);
	background-repeat: no-repeat;
	background-size: 100% 100%, 100% 100%, cover;
	background-position: 0 0, 0 0, var(--vs-art-focal);
	pointer-events: none;
}

/* Vertical fade over art + field: the banner's bottom pixel row is exactly var(--vs-field) (seam-free join
   with the menus' page field); the top fade softens the edge against the parked header gap. */
.vs-banner::after {
	content: "";
	position: absolute;
	z-index: -1;
	inset: 0;
	background-image: var(--vs-grad-y);
	pointer-events: none;
}

/* Text column: left-aligned stack, width capped so the type stays on the darkened left side. */
.vs-banner > .vs-banner__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	max-width: var(--vs-banner-col);
	width: 100%;
	text-align: left;
}

/* The page's ONLY <h1> (Wagner SEO call): live 08 blackletter face + shadow; explicit family/weight/margins
   beat the theme h1 variables (--jivatma--heading-1-*) without !important.
   Rev 3: one size on the h1; max-width in em wraps the text as "Cut through / the noise" (CSS only, no <br>,
   no markup change; same break with the Times fallback during font swap). */
.vs-banner__inner > .vs-banner__title {
	max-width: var(--vs-title-measure);
	margin: 0;
	padding: 0;
	font-family: var(--vs-font-display);
	font-size: var(--vs-title-size);
	font-weight: 400; /* 1004-night: Old London ships one Regular face; 400 avoids synthetic bold */
	font-style: normal;
	line-height: var(--vs-title-lh);
	letter-spacing: 0;
	text-transform: none;
	text-shadow: 2px 2px 0 var(--vs-type-shadow);
}

/* "Cut through the" — mockup white, title case as typed in the markup (rev 3: inline, no uppercase, headline size). */
.vs-banner__title > .vs-banner__kicker {
	display: inline;
	color: var(--vs-title-ink);
	font-size: inherit;
	line-height: inherit;
	letter-spacing: 0;
	text-transform: none;
}

/* "noise" — purple, lowercase, same size as the rest of the headline (rev 3: inline). */
.vs-banner__title > .vs-banner__noise {
	display: inline;
	margin-top: 0;
	color: var(--vs-purple);
	font-size: inherit;
	line-height: inherit;
	letter-spacing: 0;
	text-transform: none;
}

/* Subline (plain <p>): Inter, 2 lines @1024-2560 like the mockup (locked Wagner copy; rev 3 spacing = mockup's). */
.vs-banner__inner > .vs-banner__tagline {
	max-width: 24em;
	margin: var(--vs-title-tag-gap) 0 0;
	color: var(--vs-tag-ink);
	font-family: var(--vs-font-ui);
	font-size: var(--vs-tag-size);
	font-weight: 400;
	line-height: 1.25;
	text-wrap: balance;                /* rev 3: even lines, no one-word last line ("real.") on phones; wraps only, never words */
	text-shadow: 0 1px 2px rgba(var(--vs-field-rgb), .8);
}

/* "Shop Vibes" button (rev 3 final = mockup): title case as typed in the PHP, deeper purple plate (AA), 208x46 @1440
   (label 100 + gap 27.6 + arrow 19.3 + 2 x 30.4 pad), 180x44 on phones/tablets, 2px radius (live B1);
   scoped class beats theme a / a:hover colours without !important. */
.vs-banner__inner > .vs-banner__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 1.5em;                        /* mockup label -> arrow 29/1536 */
	min-height: var(--vs-cta-h);
	margin: var(--vs-tag-cta-gap) 0 0;
	padding: 0.5em 1.65em;             /* mockup plate 222/1536 wide -> 208px @1440 */
	box-sizing: border-box;
	border: 0;
	border-radius: 2px;
	background: var(--vs-cta-bg);
	color: var(--vs-cta-ink);
	font-family: var(--vs-font-ui);
	font-size: var(--vs-cta-size);
	font-weight: 500;                  /* mockup label is a regular-weight face */
	line-height: 1;
	letter-spacing: 0;                 /* mockup: normal tracking (was 0.12em for the uppercase label) */
	text-transform: none;              /* PHP prints "Shop Vibes"; the uppercase was CSS only */
	text-decoration: none;
	transition: background-color .15s ease, color .15s ease;
}

/* Arrow: 1.05em square (mockup arrow 20/1536 wide = 19.3px @1440), inherits the label colour. */
.vs-banner__cta > .vs-banner__cta-arrow {
	flex: 0 0 auto;
	width: 1.05em;
	height: 1.05em;
	transition: transform .15s ease;
}

/* Hover: slightly lighter purple plate, label stays (#F3F3F3 5.75:1). */
.vs-banner__inner > .vs-banner__cta:hover {
	background: var(--vs-cta-bg-hover);
	color: var(--vs-cta-ink);
}

/* Hover: no underline. The WPKoi parent's ".wpkoi-cld-onhover #content a:hover {text-decoration:underline}"
   carries an ID (1,2,1); :not(#vs-no-id) adds ID weight without needing any ID in the markup -> (1,3,0) wins,
   still no !important and no descendant selector. */
.vs-banner__inner > .vs-banner__cta:hover:not(#vs-no-id) {
	text-decoration: none;
}

/* Hover: arrow nudges right. */
.vs-banner__cta:hover > .vs-banner__cta-arrow {
	transform: translateX(3px);
}

/* Keyboard focus only (never on click): 2px light-purple ring. */
.vs-banner__inner > .vs-banner__cta:focus-visible {
	outline: var(--vs-focus);
	outline-offset: 3px;
}

/* Reduced motion: no colour/arrow transitions. */
@media (prefers-reduced-motion: reduce) {
	/* No transitions on the button or its arrow. */
	.vs-banner__inner > .vs-banner__cta,
	.vs-banner__cta > .vs-banner__cta-arrow {
		transition: none;
	}

	/* No arrow nudge. */
	.vs-banner__cta:hover > .vs-banner__cta-arrow {
		transform: none;
	}
}

/* Tablet 768–1024: wider art layer and text column (spec §3, rev 2). */
@media (min-width: 768px) and (max-width: 1024px) {
	/* Tablet tunables. */
	.vs-banner {
		--vs-art-w: 72%;      /* rose window at ~65% */
		--vs-banner-col: 60%;
	}
}

/* Phone <=767: text stacks CENTERED over the cathedral (phone mockup). Rev 3: compact like the desktop mockup
   (small top/bottom padding, no bottom-pinned block); full-width art with side fades and a scrim for legibility. */
@media (max-width: 767px) {
	/* Phone tunables + centred column layout. */
	.vs-banner {
		--vs-banner-h: 0px;                              /* rev 3: no floor on phones, height = padding + content */
		--vs-title-size: clamp(2.5rem, 15vw, 3.75rem);   /* 58.5px @390, 54px @360 ("Cut through" 67% of the width) */
		--vs-title-tag-gap: 0.75rem;
		--vs-tag-cta-gap: 1rem;
		--vs-banner-pad-inline: 1.25rem;
		--vs-art-w: 100%;
		--vs-art-focal: 50% 30%;
		--vs-grad-x: linear-gradient(90deg,
			rgba(var(--vs-field-rgb), 1) 0%,
			rgba(var(--vs-field-rgb), 0) 8%,
			rgba(var(--vs-field-rgb), 0) 92%,
			rgba(var(--vs-field-rgb), 1) 100%);
		/* rev 3: the headline now sits in the top half (compact box), so the scrim is even top to bottom;
		   worst-case "noise" contrast on the art stays >= 3:1 (large text) */
		--vs-scrim: linear-gradient(180deg,
			rgba(var(--vs-field-rgb), .45) 0%,
			rgba(var(--vs-field-rgb), .5) 50%,
			rgba(var(--vs-field-rgb), .6) 100%);
		--vs-grad-y: linear-gradient(180deg,
			rgba(var(--vs-field-rgb), 1) 0%,
			rgba(var(--vs-field-rgb), 0) 8%,
			rgba(var(--vs-field-rgb), 0) 70%,
			rgba(var(--vs-field-rgb), .8) 88%,
			rgba(var(--vs-field-rgb), 1) calc(100% - 4px),
			rgba(var(--vs-field-rgb), 1) 100%);
		--vs-banner-pad-block: 1.5rem 1.5rem;
		align-items: center;
		justify-content: center;
	}

	/* Centred text column, full width. */
	.vs-banner > .vs-banner__inner {
		align-items: center;
		max-width: 100%;
		text-align: center;
	}

	/* Subline: 3 lines @390. */
	.vs-banner__inner > .vs-banner__tagline {
		max-width: 22em;
	}
}

/* Subline font-swap guard, phones under 400px (Bach pre-upload QA, 2026-09-28). Inter loads with
   font-display: fallback, so a first visit can paint the system face first. Under 400px Inter wraps the locked
   copy to 3 lines, but Roboto / Segoe UI / Arial fit it on 2 at some widths (e.g. 342-345 and 372-399), so the
   banner grew by one line (20px @390) when Inter arrived. Reserving the 3-line box keeps the height the same
   either way; the Inter layout itself is unchanged because Inter is 3 lines at every width in this range. */
@media (max-width: 399px) {
	/* Hold 3 subline lines (line-height 1.25). */
	.vs-banner__inner > .vs-banner__tagline {
		min-height: 3.75em;
	}
}

/* ---- 3c seam (2026-09-27): banner directly under the header's 1px purple border, Home only, all widths ----
   This file loads on the front page only. Both rules are full `>` chains from body.home (no !important). */

/* Home: drop the theme's content-top padding (jivatma `#page #content{padding-top:var(--jivatma--content-top)}`,
   specificity 2,0,0; 57.6px @1440, 15.6px @390). This chain is 2,2,1 and wins at every breakpoint. */
body.home > .jivatma-body-padding-content > #page > #content.site-content {
	padding-top: 0;
}

/* Home: drop the 2em (38px) block gap left above entry-content by the hidden "Home" post-title h1
   (theme `.entry-content{margin:2em 0 0}`, 0,1,0; core `:where(.is-layout-constrained) > *` 24px loses too). */
body.home > .jivatma-body-padding-content > #page > #content > #primary > #main > .wp-block-group > .entry-content.wp-block-post-content {
	margin-top: 0;
}

/* ---- 3c phone crop (2026-09-27, Debussy art, Ludwig approved) ----
   Portrait phones paint the dedicated 800x1200 crop (--vs-art-img-phone) instead of the 16:9 file, which Hostinger's
   800px mobile image cap shrinks to 800x450. Same selector as the base art rule, later in the file, so it wins
   without !important; framing matches today's phone view (focal point unchanged). The media query matches the
   phone <head> preload exactly, so phones download only this image. */
@media (max-width: 767px) and (orientation: portrait) {
	.vs-banner > .vs-banner__art {
		background-image: var(--vs-grad-x), var(--vs-scrim), var(--vs-art-img-phone);
	}
}
