/* ==========================================================================
   Vertwo Premium — Page Hero (v0.17.0, Round 3)
   --------------------------------------------------------------------------
   Reusable hero component shared across the site:
     • .vw-hero--medium  → /about/, /services/, /works/, /news/, /jobs/,
                            /contact/. Centered text, ~50vh, eyebrow + title
                            + optional sub.
     • .vw-hero--small   → work-detail, news-detail, privacy/T&C. Left-
                            aligned text, ~28vh, breadcrumb pill below title.

   Layered z-stack (back to front):
       0  .vw-hero-bg-media   bg image OR video (full-bleed cover)
       0  .vw-hero-bg         blob layer (mix-blend:screen over the media)
       1  .vw-hero-grain      feTurbulence noise (mix-blend:overlay)
       2  .vw-hero-veil       radial vignette + bottom linear-gradient
       3  .vw-hero-inner      content (eyebrow / title / sub / breadcrumb)

   This is a verbatim aesthetic port from prototypes 04-works.html (medium)
   and 05-work-details.html (small), generalized so one CSS file covers
   both shapes via a size-modifier class on the root.
   ========================================================================== */


/* ─────────────── Root container ─────────────── */
/* Two sizes share the same skeleton; only height, padding, and content
   alignment differ. min-height clamps the floor so a hero with no sub
   copy still has presence. height:auto so a long title can grow. */

.vw-hero {
	position: relative;
	display: flex;
	overflow: hidden;
	background: #0a0a0c;          /* falls back when no bg media; matches prototype */
	isolation: isolate;            /* contains z-stack so blobs don't bleed onto siblings */
	width: 100%;
	color: #fff;
}

.vw-hero--medium {
	/* v0.32.91 — Vic's call: 50vh → 60vh for /about, /services, /works,
	   /news, /careers, /contact. Heavier presence at the top of each
	   landing page. */
	min-height: 60vh;
	height: auto;
	align-items: center;
	justify-content: center;
	padding: 120px 24px 70px;
}

.vw-hero--small {
	min-height: 28vh;
	height: auto;
	align-items: flex-end;
	justify-content: flex-start;
	padding: 110px 24px 40px;
}


/* ─────────────── Background media (image OR video) ─────────────── */
/* Lowest visual layer. Sits BEHIND the blob layer so blobs blend
   atop the photo as colored highlights — orange/gold glow over a
   dark webtoon panel reads as atmosphere, not noise. */

.vw-hero-bg-media {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	overflow: hidden;
}

.vw-hero-bg-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
	will-change: transform;        /* hinted for parallax JS */
	transition: opacity .35s ease;
}

/* v0.32.94 — when the 3D parallax canvas is ready, the underlying
   <img> hides so we don't paint the same picture twice. The CSS
   transition smooths the swap so editors don't see a hard cut. */
.vw-hero-bg-img.is-replaced-by-3d {
	opacity: 0;
}

/* v0.32.94 — 3D depth parallax canvas. Sits ON TOP of the <img>
   inside .vw-hero-bg-media so it inherits the scroll-parallax
   translate3d() the parent already gets from page-hero.js. Same
   cover-fit as the img (via the shader's coverUv()). Opacity
   transitioned in once the textures have actually uploaded so
   there's no first-frame flash. */
.vw-hero-3d-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	pointer-events: none;
	opacity: 0;
	transition: opacity .35s ease;
}
/* v0.32.108 — REMOVED CSS brightness filter. v0.32.107's brightness(1.3)
   was clamping vivid colors past 255, causing the "still dark yet
   over-saturated" symptom Vic flagged — saturated greens got pushed
   over the clamp boundary and read as neon, while the veil corners
   still ate the overall brightness. Two opposing problems. Removing
   brightness entirely fixes the clamping (canvas at source brightness,
   natural saturation) and the lighter veil below removes the corner
   tint. If the hero ends up too dim after this, we add gentle veil
   back; if too bright, slight brightness compensation can be re-added. */
.vw-hero-3d-canvas.is-ready {
	opacity: 1;
}

/* v0.32.113 — REMOVED the .has-3d-parallax veil override. (v0.32.112
   intended this but the Edit didn't persist due to a file-state
   sync issue.) Now that linearToSRGB in the shader correctly
   encodes canvas output (v0.32.110), the standard v0.32.91 vignette
   (center 0.25, corners 0.72) applies to 3D heroes too — same as
   non-3D image heroes. The vignette Vic wanted is back. */

/* ════════════════════════════════════════════════════════════════
   v0.32.96 — "click to tilt" CTA badge (touch devices only)
   ────────────────────────────────────────────────────────────────
   Design ported VERBATIM from .pd-cover-tilt-cta in work-detail.css
   (the work-detail book cover's tilt CTA, v0.26.5+). Same dark
   glassy pill with the phone-tilt icon and pulse animation. Two
   adaptations:
     • Position is FLOW (not absolute) — sits below the hero title
       inside .vw-hero-inner. Vic's spec from the v0.32.96 round.
     • Slightly larger padding because the hero canvas is much
       larger than the cover, so the badge needs more presence.
   Created by page-hero-3d.js (no PHP markup), so this CSS is the
   sole source of truth for its look.
═════════════════════════════════════════════════════════════════ */
.vw-hero-tilt-cta {
	display: none;                            /* JS reveals via :not([hidden]) on create */
	display: inline-flex;                     /* shorthand for "use inline-flex when shown" */
	margin-top: 22px;
	align-items: center;
	gap: 7px;
	padding: 8px 14px 8px 12px;
	border-radius: 980px;
	background: rgba(0, 0, 0, 0.45);
	border: 1px solid rgba(255, 255, 255, 0.22);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	color: #fff;
	font-family: var(--font-title, 'NHG', 'Helvetica Neue', sans-serif);
	font-weight: 600;
	font-size: 0.66rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
	transition: opacity .35s cubic-bezier(.16,1,.3,1),
	            transform .35s cubic-bezier(.16,1,.3,1),
	            background .25s ease;
	-webkit-tap-highlight-color: transparent;
	animation: vwHeroTiltCtaPulse 2.6s ease-in-out infinite;
}
.vw-hero-tilt-cta svg {
	width: 14px; height: 14px; display: block; flex-shrink: 0;
}
.vw-hero-tilt-cta-label { display: inline-block; }
.vw-hero-tilt-cta:active { transform: scale(0.94); }

/* Granted — fade out + scale down before JS removes the node */
.vw-hero-tilt-cta.is-granted {
	animation: none;
	opacity: 0; transform: scale(0.85);
	pointer-events: none;
}
/* Denied — red tint, then JS restores to allow retry */
.vw-hero-tilt-cta.is-denied {
	animation: none;
	background: rgba(220, 38, 38, 0.55);
	border-color: rgba(255, 255, 255, 0.30);
}

@keyframes vwHeroTiltCtaPulse {
	0%, 100% { box-shadow: 0 4px 14px rgba(0,0,0,0.25), 0 0 0 0 rgba(242,122,15,0.50); }
	50%      { box-shadow: 0 4px 14px rgba(0,0,0,0.25), 0 0 0 7px rgba(242,122,15,0.00); }
}

@media (prefers-reduced-motion: reduce) {
	.vw-hero-tilt-cta { animation: none; }
}

/* Desktop hides the badge entirely — the gyro IIFE never activates
   on hover+pointer:fine devices, so it would be a no-op cue. */
@media (hover: hover) and (pointer: fine) {
	.vw-hero-tilt-cta { display: none; }
}

/* v0.32.109 — REMOVED brightness(0.78) from the img filter (was v0.32.90).
   Vic showed source-vs-hero comparisons making it clear the hero is
   darker than the source image, and ten rounds of canvas-side tuning
   couldn't bridge a gap that was being held wide by ALSO dimming the
   img element. Now both img (loading state) AND canvas (loaded state)
   display at source brightness, so the transition Vic sees in his
   videos no longer reads as "bright → dark" — it's "source → source".
   The remaining vignette comes from .vw-hero-veil only. saturate(1.05)
   stays as a gentle vividness kicker. */
.vw-hero.is-image .vw-hero-bg-img,
.vw-hero.is-video .vw-hero-bg-img {
	filter: saturate(1.05);
}

.vw-hero-bg-media--video { /* container only — the actual swap is below */ }

.vw-hero-bg-video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
	will-change: transform;
	/* v0.32.109 — removed brightness for parity with bg-img. */
	filter: saturate(1.05);
}

/* CSS-only mobile video swap — the spec's preferred approach.
   Below 769px the <video> is hidden entirely (saves bandwidth, avoids
   autoplay issues on iOS Low Power Mode), and the <picture> poster
   takes over. Above 768px the poster is hidden so the video plays.
   Browser still resolves both up-front but only renders the one
   matching the media query — no flash, no JS dependency. */
.vw-hero-bg-poster-mobile {
	position: absolute;
	inset: 0;
	display: none;                /* shown only on small viewports */
}
@media (max-width: 768px) {
	.vw-hero-bg-video { display: none; }
	.vw-hero-bg-poster-mobile { display: block; }
}


/* ─────────────── Blob layer ─────────────── */
/* Three radial-gradient blobs, mix-blend:screen so they brighten the
   bg into colored highlights. inset:-10% -5% gives parallax some
   travel room before the blurred edge gets exposed.

   Each blob's color is set per-instance via the --blob-color custom
   property emitted inline by the renderer (style="--blob-color:#hex").
   That keeps the CSS file static (no per-archive overrides cluttering
   the cascade) while letting the editor pick any color in the admin. */

.vw-hero-bg {
	position: absolute;
	inset: -10% -5%;
	z-index: 0;
	pointer-events: none;
	filter: blur(70px) saturate(140%);
	opacity: 0.85;
	will-change: transform;       /* hinted for parallax JS */
}

.vw-hero-blob {
	position: absolute;
	border-radius: 50%;
	mix-blend-mode: screen;
}

/* Three fixed slot positions + animation timings, mirrored from the
   About-hero prototype. Different durations (22s / 28s / 34s) keep
   them perpetually out of phase so the field never repeats. */
.vw-hero-blob--1 {
	width: 55vw; height: 55vw;
	left: -10%; top: -10%;
	background: radial-gradient(circle at 30% 30%,
		var(--blob-color, #F27A0F) 0%,
		transparent 60%);
	animation: vwHeroDriftA 22s ease-in-out infinite alternate;
}
.vw-hero-blob--2 {
	width: 50vw; height: 50vw;
	right: -12%; top: 8%;
	background: radial-gradient(circle at 70% 50%,
		var(--blob-color, #EC2F7A) 0%,
		transparent 60%);
	animation: vwHeroDriftB 28s ease-in-out infinite alternate;
}
.vw-hero-blob--3 {
	width: 62vw; height: 62vw;
	left: 18%; bottom: -22%;
	background: radial-gradient(circle at 50% 50%,
		var(--blob-color, #F5A623) 0%,
		transparent 60%);
	animation: vwHeroDriftC 34s ease-in-out infinite alternate;
}

/* GPU-friendly transform-only animations — no width/height/position. */
@keyframes vwHeroDriftA {
	0%   { transform: translate3d(0, 0, 0) scale(1); }
	100% { transform: translate3d(8vw, 4vh, 0) scale(1.12); }
}
@keyframes vwHeroDriftB {
	0%   { transform: translate3d(0, 0, 0) scale(1.05); }
	100% { transform: translate3d(-6vw, 5vh, 0) scale(1); }
}
@keyframes vwHeroDriftC {
	0%   { transform: translate3d(0, 0, 0) scale(1); }
	100% { transform: translate3d(-4vw, -6vh, 0) scale(1.15); }
}


/* ─────────────── Grain layer ─────────────── */
/* Subtle film grain via inlined SVG feTurbulence — adds tactile
   texture that pure CSS gradients can't fake. mix-blend:overlay
   means it darkens where the bg is bright and brightens where it's
   dark, giving organic depth. opacity tuned slightly higher on
   blobs-only heroes since there's less natural noise from a photo. */

.vw-hero-grain {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	opacity: 0.10;
	background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' /%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	background-size: 200px 200px;
	mix-blend-mode: overlay;
}

.vw-hero.is-image .vw-hero-grain,
.vw-hero.is-video .vw-hero-grain {
	opacity: 0.08;                /* photo already adds noise */
}


/* ─────────────── Veil layer ─────────────── */
/* v0.32.90 — Reworked to a CENTERED radial vignette per Vic. Previously
   the veil was a bottom-weighted darkening (radial anchored at 50% 80%
   + linear bottom-up gradient) which evenly tinted the center of the
   hero. New treatment: clear in the center, fading to dark at the
   corners — proper vignette. Reduces overall black tint while keeping
   text contrast at the framed edges and pulling the eye inward. */

/* v0.32.91 — Vic asked for the center to be ~0.25 tinted rather than
   fully transparent. Center now starts at rgba(0,0,0,0.25), holds
   through the inner band, then ramps to the existing corner values.
   Net effect: subtle even darkening across the whole hero with the
   vignette still pulling the eye toward center. */
.vw-hero-veil {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background:
		radial-gradient(ellipse at center,
			rgba(0,0,0,0.25) 0%,
			rgba(0,0,0,0.25) 40%,
			rgba(0,0,0,0.42) 80%,
			rgba(0,0,0,0.62) 100%);
}

/* Small-hero variant: same centered vignette, slightly stronger at
   the corners since the smaller frame benefits from a tighter edge
   pull. */
.vw-hero--small .vw-hero-veil {
	background:
		radial-gradient(ellipse at center,
			rgba(0,0,0,0.25) 0%,
			rgba(0,0,0,0.25) 35%,
			rgba(0,0,0,0.45) 80%,
			rgba(0,0,0,0.66) 100%);
}

/* Bg-media heroes get a slightly deeper corner pull so text holds up
   over photos. v0.32.91 — center now at 0.25 instead of clear. */
.vw-hero.is-image .vw-hero-veil,
.vw-hero.is-video .vw-hero-veil {
	background:
		radial-gradient(ellipse at center,
			rgba(0,0,0,0.25) 0%,
			rgba(0,0,0,0.25) 35%,
			rgba(0,0,0,0.48) 78%,
			rgba(0,0,0,0.72) 100%);
}
.vw-hero--small.is-image .vw-hero-veil,
.vw-hero--small.is-video .vw-hero-veil {
	background:
		radial-gradient(ellipse at center,
			rgba(0,0,0,0.25) 0%,
			rgba(0,0,0,0.25) 30%,
			rgba(0,0,0,0.52) 78%,
			rgba(0,0,0,0.76) 100%);
}


/* ─────────────── Inner / content ─────────────── */

.vw-hero-inner {
	position: relative;
	z-index: 3;
	width: 100%;
}

.vw-hero--medium .vw-hero-inner {
	max-width: 920px;
	text-align: center;
	margin: 0 auto;
}

.vw-hero--small .vw-hero-inner {
	max-width: 1200px;
	text-align: left;
	margin: 0 auto;
}


/* ─────────────── Eyebrow ─────────────── */
/* Two looks from the same node: medium = plain inline-block with
   tracked uppercase; small = inline-flex with a leading 1px line
   prefix that anchors the text on the left rail. The prefix line
   is the small-hero signature from the prototype. */

.vw-hero-eyebrow {
	font-family: var(--font-body, system-ui, sans-serif);
	/* v0.32.111 — was var(--orange); Vic asked for all hero eyebrows
	   to be solid white. Matches the kp-slide-eyebrow change from
	   v0.32.89 (key persons section also went orange → white). */
	color: #fff;
	text-transform: uppercase;
	margin: 0 0 18px;
}

.vw-hero--medium .vw-hero-eyebrow {
	display: inline-block;
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.2em;
}

.vw-hero--small .vw-hero-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: 0.66rem;
	font-weight: 700;
	letter-spacing: 0.18em;
	margin-bottom: 14px;
}
.vw-hero--small .vw-hero-eyebrow::before {
	content: "";
	display: inline-block;
	width: 18px;
	height: 1px;
	/* v0.32.111 — was orange + opacity 0.7; now solid white to match the
	   parent eyebrow color change. */
	background: #fff;
	opacity: 1;
}


/* ─────────────── Title + accent ─────────────── */

.vw-hero-title {
	font-family: var(--font-title, 'NHG', 'Helvetica Neue', sans-serif);
	font-weight: 900;
	color: #fff;
	margin: 0 0 22px;
}

.vw-hero--medium .vw-hero-title {
	font-size: clamp(2.2rem, 5.8vw, 4.4rem);
	letter-spacing: -0.045em;
	line-height: 1.02;
}

.vw-hero--small .vw-hero-title {
	font-size: clamp(1.6rem, 3.6vw, 2.8rem);
	letter-spacing: -0.045em;
	line-height: 1.04;
	max-width: 880px;
	margin-bottom: 0;             /* breadcrumb has its own top margin */
}

.vw-hero-accent {
	font-style: normal;
	color: var(--orange, #F27A0F);
}


/* ─────────────── Sub copy (medium hero only) ─────────────── */

.vw-hero-sub {
	font-family: var(--font-body, system-ui, sans-serif);
	font-size: clamp(0.95rem, 1.25vw, 1.1rem);
	font-weight: 300;
	line-height: 1.7;
	color: rgba(255, 255, 255, 0.75);
	max-width: 580px;
	margin: 0 auto;
}


/* ─────────────── Breadcrumb pill (small hero only) ─────────────── */
/* Glass pill with backdrop-filter blur — same visual language as the
   floating nav. On hover the pill warms toward orange. The chevron
   nudges left to telegraph "go back" without feeling jumpy. */

.vw-hero-breadcrumb {
	display: inline-flex;
	align-items: center;
	gap: 0;
	max-width: 100%;
	margin-top: 18px;
	padding: 6px 6px 6px 14px;
	background: rgba(255, 255, 255, 0.08);
	border: 1px solid rgba(255, 255, 255, 0.14);
	border-radius: 980px;
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	font-family: var(--font-body, system-ui, sans-serif);
	font-size: 0.74rem;
	font-weight: 500;
	letter-spacing: -0.005em;
	color: rgba(255, 255, 255, 0.62);
	text-decoration: none;
	transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
	min-width: 0;
}
.vw-hero-breadcrumb:hover,
.vw-hero-breadcrumb:focus-visible {
	background: rgba(242, 122, 15, 0.16);
	border-color: rgba(242, 122, 15, 0.40);
	color: #fff;
}
.vw-hero-breadcrumb:focus-visible {
	outline: 2px solid var(--orange, #F27A0F);
	outline-offset: 3px;
}

.vw-hero-breadcrumb-back {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: rgba(255, 255, 255, 0.85);
	font-weight: 700;
	transition: color 0.25s ease;
	flex-shrink: 0;
}
.vw-hero-breadcrumb-back svg {
	width: 11px;
	height: 11px;
	transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
.vw-hero-breadcrumb:hover .vw-hero-breadcrumb-back svg,
.vw-hero-breadcrumb:focus-visible .vw-hero-breadcrumb-back svg {
	transform: translateX(-3px);
}

.vw-hero-breadcrumb-sep {
	display: inline-block;
	margin: 0 10px;
	width: 3px;
	height: 3px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.30);
	flex-shrink: 0;
}

.vw-hero-breadcrumb-current {
	display: inline-block;
	padding: 5px 12px;
	border-radius: 980px;
	background: rgba(255, 255, 255, 0.06);
	border: 1px solid rgba(255, 255, 255, 0.10);
	color: rgba(255, 255, 255, 0.92);
	font-weight: 600;
	margin-left: 2px;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}


/* ─────────────── Entrance animation ─────────────── */
/* Staggered fade-up on initial paint — same curve and stagger as
   the homepage hero (cubic-bezier(.16,1,.3,1) — Vic's standard).
   Animations fire on initial paint, NOT scroll-into-view, since
   the page hero is always above the fold. */

@keyframes vwHeroFadeUp {
	from { opacity: 0; transform: translate3d(0, 14px, 0); }
	to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.vw-hero-eyebrow,
.vw-hero-title,
.vw-hero-sub,
.vw-hero-breadcrumb {
	opacity: 0;
	animation: vwHeroFadeUp 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.vw-hero-eyebrow    { animation-delay: 0.30s; }
.vw-hero-title      { animation-delay: 0.45s; }
.vw-hero-sub        { animation-delay: 0.60s; }
.vw-hero-breadcrumb { animation-delay: 0.60s; }


/* ─────────────── Responsive — mobile (≤600px) ─────────────── */

@media (max-width: 600px) {
	.vw-hero--medium {
		min-height: 42vh;
		padding: 100px 20px 50px;
	}
	.vw-hero--small {
		min-height: 24vh;
		padding: 96px 20px 32px;
	}
	.vw-hero--small .vw-hero-title {
		font-size: clamp(1.4rem, 5.5vw, 2rem);
	}
}

@media (max-width: 420px) {
	.vw-hero--small {
		padding: 90px 18px 28px;
	}
	.vw-hero--small .vw-hero-eyebrow {
		font-size: 0.62rem;
	}
	.vw-hero-breadcrumb {
		font-size: 0.70rem;
		padding: 5px 5px 5px 12px;
	}
	.vw-hero-breadcrumb-sep {
		margin: 0 8px;
	}
	.vw-hero-breadcrumb-current {
		padding: 4px 10px;
	}
}


/* ─────────────── Responsive — tablet portrait + landscape ─────────────── */
/* Tightens padding without breaking the visual rhythm. */

@media (min-width: 601px) and (max-width: 1024px) {
	.vw-hero--medium {
		padding: 110px 28px 60px;
	}
	.vw-hero--small {
		padding: 104px 28px 36px;
	}
}


/* ─────────────── Reduced motion ─────────────── */
/* Per spec: prefers-reduced-motion disables BOTH parallax (handled
   in JS) and blob drift + entrance animations (handled here). The
   blobs stay visible — they just don't drift. */

@media (prefers-reduced-motion: reduce) {
	.vw-hero-blob {
		animation: none !important;
	}
	.vw-hero-eyebrow,
	.vw-hero-title,
	.vw-hero-sub,
	.vw-hero-breadcrumb {
		animation: none !important;
		opacity: 1 !important;
		transform: none !important;
	}
	.vw-hero-breadcrumb-back svg {
		transition: none !important;
	}
}


/* ─────────────── Print ─────────────── */
/* If anyone prints a Work detail page, the hero collapses to plain
   text. Saves ink and prevents the dark bg from blasting through. */

@media print {
	.vw-hero {
		min-height: 0;
		padding: 24px 0;
		background: transparent;
		color: #000;
	}
	.vw-hero-bg-media,
	.vw-hero-bg,
	.vw-hero-grain,
	.vw-hero-veil { display: none; }
	.vw-hero-title,
	.vw-hero-eyebrow { color: #000 !important; }
	.vw-hero-accent { color: #d96a05 !important; }
}
