/**
 * fly.css
 *
 * Szenen-System fuer den Platoon-Prototyp auf Ollie.
 *
 * Alle Bewegung kommt aus vier CSS-Variablen, die fly-scroll.js schreibt:
 *   --scroll / --sn      Scrollposition, als Laenge und als Zahl
 *   --vh    / --vhn      Viewporthoehe, als Laenge und als Zahl
 *   --p                  pro Szene: Fortschritt 0..1
 *   --pin                pro Szene: geklemmter Versatz fuer gepinnte Elemente
 *
 * Es gibt keine Keyframes und keine JS-Animation. Nur diese Variablen.
 */

/* --- Tokens ------------------------------------------------------------- */

:root {
	--fly-cream: #fff8ed;
	--fly-bordeaux: #a82326;
	--fly-ink: #280a0b;
	--fly-sand: #e0d4c2;

	/* Original-Label-Farbe. 2,0:1 auf Creme, praktisch unlesbar. */
	--fly-label-original: #bbb0a1;
	/* Korrigiert. Gemessen 4,7:1 auf Creme. */
	--fly-label-fixed: #7d6d5d;
	--fly-label: var(--fly-label-original);

	--fly-font-display: "Italiana", "Times New Roman", serif;
	--fly-font-body: "Jost", system-ui, sans-serif;
	--fly-font-mono: "IBM Plex Mono", ui-monospace, monospace;

	--vh: 100vh;
	--vhn: 800;
	--scroll: 0px;
	--sn: 0;
}

/* Umschalter fuer die Lesbarkeits-Demo */
body.fly-optimiert {
	--fly-label: var(--fly-label-fixed);
}

/* --- Scroll-Grundgeruest ------------------------------------------------ */

html.fly-smooth,
html.fly-smooth body {
	height: 100vh;
	overflow: hidden;
	width: 100%;
	overscroll-behavior-y: none;
}

html.fly-native {
	overflow-x: hidden;
	overflow-y: auto;
}

/*
 * Die Transform ist nicht Deko. Sie macht #fly-scrollable zum Containing Block
 * fuer position:fixed-Kinder. Ohne sie waeren gepinnte Elemente am Viewport
 * verankert und wuerden sich doppelt so schnell bewegen wie gewollt.
 * Deshalb steht sie auch im nativen Modus, wo JS die Transform nie anfasst.
 */
#fly-scrollable {
	width: 100%;
	transform: translateZ(0);
	will-change: transform;

	/* position:relative + z-index ist Pflicht, nicht Geschmack. Ohne das ist
	   der Container nicht positioniert und wird unter der fixen Buehne
	   gezeichnet, die dann alle Sektionen verdeckt. Die erste Szene ist
	   transparent, dort scheint die Buehne durch. */
	position: relative;
	z-index: 2;
}

/* --- Buehne (fixer Hintergrund hinter allem) ---------------------------- */

.fly-stage {
	position: fixed;
	inset: 0;
	height: var(--vh);
	background: #000;
	z-index: 1;
	overflow: hidden;
}

.fly-stage__media,
.fly-stage__media img,
.fly-stage__media video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.fly-stage__title {
	/* Hero-Fortschritt: 0 am Seitenanfang, 1 nach einer Viewporthoehe. */
	--hp: clamp(0, calc(var(--sn) / var(--vhn)), 1);

	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	margin: 0;
	padding: 32px;
	box-sizing: border-box;
	z-index: 3;

	font-family: var(--fly-font-display);
	font-weight: 400;
	font-size: clamp(48px, 10vw, 132px);
	line-height: 1;
	color: var(--fly-cream);

	/* Original: Deckkraft auf 0 nach einer halben Viewporthoehe,
	   gleichzeitig eine volle Viewporthoehe nach oben. */
	opacity: calc(1 - var(--hp) * 2);
	transform: translate3d(0, calc(var(--hp) * -1 * var(--vh)), 0);
	will-change: opacity, transform;
}

/*
 * Der Lesbarkeits-Fix. Im Original liegt die Headline ohne Absicherung ueber
 * dem Rendering, ueber der hellen Bodenspiegelung verschwindet sie fast.
 * Ein Verlauf von unten kostet nichts und rettet den Kontrast.
 */
/* Als Pseudo-Element, nicht als eigenes div. So kann es in Gutenberg
   niemand versehentlich loeschen und das Pattern bleibt aus reinen
   Core-Bloecken aufgebaut. */
.fly-stage::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 62%;
	z-index: 2;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.35s ease;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.82) 0%,
		rgba(0, 0, 0, 0.55) 38%,
		rgba(0, 0, 0, 0) 100%
	);
}

body.fly-optimiert .fly-stage::after {
	opacity: 1;
}

/* --- Szenen ------------------------------------------------------------- */

.fly-scene {
	position: relative;
	z-index: 2;
}

/* Erste Szene: durchsichtig, laesst die Buehne sehen und liefert Scrollweg. */
.fly-scene--hero {
	height: 200vh;
	height: calc(var(--vh) * 2);
	pointer-events: none;
}

/*
 * Gepinnt. position:fixed + Gegenverschiebung um Szenenanfang plus geklemmten
 * Versatz. Ergibt exakt ein Sticky, funktioniert aber auch im Smooth-Modus,
 * in dem echtes position:sticky nichts tut (der Scrollport bewegt sich nie).
 */
.fly-pin {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: var(--vh);
	transform: translate3d(0, calc(var(--scene-top, 0px) + var(--pin, 0px)), 0);
	will-change: transform;
}

/* --- Mission ------------------------------------------------------------ */

.fly-mission {
	background: var(--fly-cream);
	min-height: 200vh;
	min-height: calc(var(--vh) * 2);
}

.fly-mission__inner {
	/* Eintauchen und wieder ausblenden, Spitze in der Mitte.
	   Bewusst ohne CSS abs(), das ist noch nicht ueberall verlaesslich da. */
	--fade-in: clamp(0, calc((var(--pv, 0) - 0.15) * 5), 1);
	--fade-out: clamp(0, calc((0.85 - var(--pv, 0)) * 5), 1);
	--fade: calc(var(--fade-in) * var(--fade-out));

	/* Bewusst kein position:sticky. Im Smooth-Modus scrollt der Scrollport
	   nie, sticky wuerde dort wirkungslos bleiben und sich anders verhalten
	   als im nativen Modus. Wer pinnen will, nimmt .fly-pin. */
	height: var(--vh);
	display: flex;
	flex-direction: column;
	justify-content: center;
	box-sizing: border-box;
	padding: 0 32px;
	opacity: var(--fade);
	transform: translate3d(0, calc((0.5 - var(--pv, 0)) * 60px), 0);
	will-change: opacity, transform;
}

.fly-mission__copy {
	font-family: var(--fly-font-display);
	color: var(--fly-bordeaux);
	font-size: clamp(28px, 3.4vw, 46px);
	line-height: 1.18;
	max-width: 22em;
	margin: 0 0 0.6em;
	font-weight: 400;
}

.fly-mission__kicker {
	font-family: var(--fly-font-display);
	color: var(--fly-bordeaux);
	font-size: clamp(22px, 2.4vw, 34px);
	margin: 0;
	font-weight: 400;
}

/* --- Label im Split-Flap-Stil ------------------------------------------- */

.fly-label {
	font-family: var(--fly-font-mono);
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--fly-label);
	margin: 0 0 1.6em;
	display: block;
	transition: color 0.35s ease;
}

.fly-label__char {
	display: inline-flex;
	justify-content: center;
	width: 0.8em;
}

.fly-label__char.is-space {
	width: 0.4em;
}

/* --- Text-Bild mit gepinntem Panel -------------------------------------- */

.fly-textimage {
	background: var(--fly-cream);
	min-height: 250vh;
	min-height: calc(var(--vh) * 2.5);
}

/*
 * Text und Bildpanel liegen gemeinsam auf einer gepinnten Buehne. Wuerde nur
 * das Panel pinnen, liefe der Text darunter weg, waehrend das Bild steht.
 */
.fly-textimage__stage {
	display: flex;
	align-items: stretch;
	background: var(--fly-cream);
	overflow: hidden;
}

.fly-textimage__asset {
	/* Von rechts aufziehen. clip-path statt width: kein Layout pro Frame,
	   und das Bild wird nicht gestaucht. */
	--reveal: clamp(0, calc(var(--p, 0) * 2.2), 1);

	position: absolute;
	top: 0;
	right: 0;
	width: 60%;
	height: 100%;
	clip-path: inset(0 0 0 calc((1 - var(--reveal)) * 100%));
	will-change: clip-path;
	z-index: 2;
}

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

.fly-textimage__text {
	position: relative;
	z-index: 3;
	width: 40%;
	box-sizing: border-box;
	padding: 40px 32px;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 32px;

	/* Text kommt kurz nach dem Panel, sonst wirkt es gleichzeitig und flach. */
	--enter: clamp(0, calc((var(--p, 0) - 0.06) * 6), 1);
	opacity: var(--enter);
	transform: translate3d(0, calc((1 - var(--enter)) * 40px), 0);
	will-change: opacity, transform;
}

.fly-textimage__head {
	font-family: var(--fly-font-display);
	font-weight: 400;
	font-size: clamp(34px, 4.4vw, 62px);
	line-height: 1.05;
	color: var(--fly-ink);
	margin: 0;
}

.fly-textimage__body {
	font-family: var(--fly-font-body);
	font-weight: 300;
	font-size: clamp(15px, 1.25vw, 19px);
	line-height: 1.6;
	color: var(--fly-ink);
	max-width: 34ch;
	margin: 0 0 1.6em;
}

.fly-button {
	display: inline-block;
	background: var(--fly-ink);
	color: var(--fly-cream);
	font-family: var(--fly-font-body);
	font-size: 15px;
	text-decoration: none;
	padding: 14px 30px;
	border-radius: 999px;
	transition: background 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
	align-self: flex-start;
}

.fly-button:hover {
	background: var(--fly-bordeaux);
}

/* --- Zitat mit gegenlaeufigem Parallax ---------------------------------- */

.fly-quote {
	background: var(--fly-cream);
	min-height: 250vh;
	min-height: calc(var(--vh) * 2.5);
}

.fly-quote__stage {
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

.fly-quote__text {
	font-family: var(--fly-font-display);
	font-weight: 400;
	color: var(--fly-bordeaux);
	font-size: clamp(26px, 3.2vw, 46px);
	line-height: 1.2;
	text-align: center;
	max-width: 18em;
	margin: 0 auto;
	padding: 0 32px;
	position: relative;
	z-index: 2;
}

.fly-quote__cite {
	display: block;
	font-family: var(--fly-font-body);
	font-size: 15px;
	font-style: normal;
	color: var(--fly-label);
	margin-top: 1.4em;
	transition: color 0.35s ease;
}

.fly-quote__img {
	position: absolute;
	width: 25%;
	max-width: 320px;
	will-change: transform;
}

.fly-quote__img img {
	width: 100%;
	height: auto;
	display: block;
}

/* Links laeuft von unten nach oben, rechts umgekehrt. */
.fly-quote__img--a {
	left: 0;
	bottom: 0;
	transform: translate3d(0, calc((1 - var(--p, 0)) * 55vh), 0);
}

.fly-quote__img--b {
	right: 0;
	top: 0;
	transform: translate3d(0, calc((1 - var(--p, 0)) * -55vh), 0);
}

/* --- WordPress-Eigenheiten abfangen ------------------------------------- */

/*
 * Gutenberg verpackt jedes Bild in eine <figure> mit eigenem Abstand, und
 * .wp-block-group setzt zwischen Kindern einen Block-Gap. In einer
 * vollflaechigen Szene ergibt das Raender, wo keine sein duerfen.
 */
.fly-stage .wp-block-image,
.fly-pin .wp-block-image,
.fly-stage figure,
.fly-pin figure {
	margin: 0;
	height: 100%;
	width: 100%;
}

.fly-textimage__asset,
.fly-quote__img {
	/* Block-Gap innerhalb der gepinnten Bausteine ausschalten. */
	--wp--style--block-gap: 0px;
}

.fly-textimage__asset > *,
.fly-quote__img > * {
	margin-block-start: 0;
	margin-block-end: 0;
	height: 100%;
}

.fly-quote__img,
.fly-quote__img figure {
	height: auto;
}

/* Core-Zitat bringt einen Balken links mit, der hier nicht ins Bild passt. */
.fly-quote__text.wp-block-quote {
	border: 0;
	padding: 0;
}

/* Ollie zentriert Inhalte ueber das constrained-Layout. In den Szenen
   soll linksbuendig bleiben, was linksbuendig gesetzt ist. */
.fly-textimage__text > *,
.fly-mission__inner > * {
	margin-left: 0;
	margin-right: 0;
	max-width: none;
}

/* --- Umschalter fuer die Demo ------------------------------------------- */

.fly-toggle {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 999;
	display: flex;
	gap: 0;
	font-family: var(--fly-font-body);
	font-size: 13px;
	background: rgba(255, 248, 237, 0.92);
	border: 1px solid var(--fly-sand);
	border-radius: 999px;
	padding: 4px;
	backdrop-filter: blur(6px);
}

.fly-toggle button {
	border: 0;
	background: transparent;
	color: var(--fly-ink);
	padding: 7px 16px;
	border-radius: 999px;
	cursor: pointer;
	font: inherit;
}

.fly-toggle button[aria-pressed="true"] {
	background: var(--fly-ink);
	color: var(--fly-cream);
}

/* --- Mobil -------------------------------------------------------------- */

@media (max-width: 860px) {
	/* Mobil: Text oben, Bild unten. Beide bleiben in der gepinnten Buehne,
	   das Panel wird jetzt von unten aufgezogen statt von rechts. */
	.fly-textimage__stage {
		flex-direction: column;
	}

	.fly-textimage__text {
		width: 100%;
		padding-bottom: 0;
		flex: 1 1 auto;
	}

	.fly-textimage__asset {
		position: relative;
		width: 100%;
		height: 48%;
		flex: 0 0 48%;
		clip-path: inset(calc((1 - var(--reveal)) * 100%) 0 0 0);
	}

	.fly-quote__img {
		width: 38%;
	}
}

/* --- Reduzierte Bewegung ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	.fly-stage__title,
	.fly-mission__inner,
	.fly-textimage__text,
	.fly-textimage__asset,
	.fly-quote__img {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
	}
}
