/* =====================================================================
   3D motion layer (paired with js/scene3d.js, js/motion3d.js, js/tilt3d.js)
   Everything is scoped under .motion-3d / .scene3d-host, which the scripts
   only add when the visitor hasn't asked for reduced motion.
   ===================================================================== */

/* ---- WebGL hero scene ---- */
.scene3d-host {
	position: relative;
	overflow: hidden;
}

.scene3d-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	pointer-events: none;
	z-index: 0;
	opacity: 0;
	transition: opacity 1.4s var(--ease-premium, ease);
}

.scene3d-canvas.is-ready {
	opacity: 1;
}

/* Keep hero content above the canvas (breadcrumb overlay stays beneath it). */
.scene3d-host > .container {
	position: relative;
	z-index: 2;
}

.premium-breadcrumb.scene3d-host .premium-overlay {
	z-index: 0;
}

.premium-breadcrumb.scene3d-host .scene3d-canvas {
	z-index: 1;
}

.hero-depth {
	transform-origin: 50% 0%;
	will-change: transform, opacity;
}

/* ---- 3D scroll entrances ---- */
.motion-3d .reveal-on-scroll {
	transform: perspective(1100px) translate3d(0, 40px, -80px) rotateX(16deg);
	transform-origin: 50% 100%;
	transition: opacity 0.9s var(--ease-premium), transform 0.9s var(--ease-premium);
}

.motion-3d .reveal-on-scroll.revealed {
	transform: none;
}

.motion-3d .reveal-3d {
	opacity: 0;
	transform: perspective(1100px) translate3d(0, 46px, -90px) rotateX(20deg);
	transform-origin: 50% 100%;
	transition:
		opacity 0.9s var(--ease-premium) var(--reveal-delay, 0ms),
		transform 0.9s var(--ease-premium) var(--reveal-delay, 0ms);
}

.motion-3d .reveal-3d.in-view {
	opacity: 1;
	transform: none;
}

/* Once revealed, tilt cards respond instantly to the mouse again. */
.motion-3d .reveal-3d.in-view.tilt-3d,
.motion-3d .reveal-on-scroll.revealed.tilt-3d {
	transition: transform 0.15s ease-out, box-shadow 0.35s ease;
}

/* ---- Layered depth inside tilted cards ---- */
.motion-3d .tilt-3d {
	transform-style: preserve-3d;
}

.motion-3d .tilt-3d:hover {
	box-shadow: 0 30px 60px rgba(37, 99, 235, 0.16), 0 10px 20px rgba(17, 24, 39, 0.08);
}

.motion-3d .tilt-3d > * {
	transition: transform 0.35s var(--ease-premium);
}

.motion-3d .tilt-3d:hover > :not(.tilt-edge) {
	transform: translateZ(28px);
}

.motion-3d .tilt-3d:hover [class*="icon"],
.motion-3d .tilt-3d:hover img {
	transform: translateZ(50px);
	transition: transform 0.35s var(--ease-premium);
}

/* ---- Hero imagery parallax ---- */
.motion-3d .home-hero-media,
.motion-3d .ppd-hero-visual,
.motion-3d .about-snapshot-media {
	/* Flat (no preserve-3d): the photo's own rotateY would otherwise sort
	   in front of the orbiting icons layered on top of it. */
	transition: transform 0.6s var(--ease-premium);
	will-change: transform;
}

/* ---- Magnetic 3D buttons ---- */
.motion-3d .btn-3d {
	transform-style: preserve-3d;
	transition: transform 0.25s var(--ease-premium), box-shadow 0.25s ease;
	will-change: transform;
}

.motion-3d .btn-3d:hover {
	box-shadow: 0 14px 28px rgba(37, 99, 235, 0.28);
}

.motion-3d .btn-3d:active {
	transform: perspective(500px) translateZ(-14px) !important;
	box-shadow: 0 4px 10px rgba(37, 99, 235, 0.2);
}

/* ---- Footer CTA floats in depth ---- */
.motion-3d .footer-cta .container {
	animation: cta-float-3d 7s ease-in-out infinite;
	transform-style: preserve-3d;
}

@keyframes cta-float-3d {
	0%, 100% { transform: perspective(1000px) rotateX(0deg) translateZ(0); }
	50% { transform: perspective(1000px) rotateX(4deg) translateZ(18px); }
}

@media (max-width: 767px) {
	/* Shallower angles on small screens keep text readable mid-animation. */
	.motion-3d .reveal-3d,
	.motion-3d .reveal-on-scroll {
		transform: perspective(900px) translate3d(0, 30px, -40px) rotateX(10deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.scene3d-canvas {
		display: none;
	}
}

/* =====================================================================
   Premium 3D layer (sections, panels, cards, cursor, page transitions)
   ===================================================================== */

/* ---- Depth orbs behind every content section ---- */
.depth-host {
	position: relative;
	isolation: isolate;
}

.depth-orbs {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
	z-index: -1;
}

.depth-orb {
	position: absolute;
	border-radius: 50%;
	will-change: transform;
	/* Glossy sphere: bright specular spot top-left falling off into colour. */
	opacity: 0.55;
	filter: blur(1px);
}

.depth-orb::after {
	content: "";
	position: absolute;
	inset: -30%;
	border-radius: 50%;
	background: inherit;
	filter: blur(60px);
	opacity: 0.55;
	z-index: -1;
}

.depth-orb-a {
	background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.95), rgba(96, 165, 250, 0.55) 22%, rgba(37, 99, 235, 0.18) 58%, transparent 72%);
}

.depth-orb-b {
	background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.9), rgba(192, 132, 252, 0.5) 22%, rgba(155, 81, 224, 0.16) 58%, transparent 72%);
}

.depth-orb-c {
	background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.9), rgba(34, 211, 238, 0.5) 22%, rgba(6, 182, 212, 0.16) 58%, transparent 72%);
}

/* On dark backgrounds the white highlight reads as grey, so the orbs
   become self-lit glowing spheres instead. */
html[data-theme="dark"] .depth-orb {
	opacity: 0.6;
	mix-blend-mode: screen;
}

html[data-theme="dark"] .depth-orb-a {
	background: radial-gradient(circle at 35% 30%, rgba(147, 197, 253, 0.45), rgba(37, 99, 235, 0.22) 38%, rgba(37, 99, 235, 0.06) 60%, transparent 72%);
}

html[data-theme="dark"] .depth-orb-b {
	background: radial-gradient(circle at 35% 30%, rgba(216, 180, 254, 0.42), rgba(147, 51, 234, 0.2) 38%, rgba(147, 51, 234, 0.05) 60%, transparent 72%);
}

html[data-theme="dark"] .depth-orb-c {
	background: radial-gradient(circle at 35% 30%, rgba(103, 232, 249, 0.42), rgba(6, 182, 212, 0.2) 38%, rgba(6, 182, 212, 0.05) 60%, transparent 72%);
}

/* ---- Scroll-linked 3D turn for big panels ---- */
.motion-3d .scroll-turn {
	rotate: x var(--turn-x, 0deg);
	translate: 0 0 var(--turn-z, 0px);
	transition: rotate 0.25s linear, translate 0.25s linear;
	will-change: rotate, translate;
}

/* ---- Section headings: extruded 3D lettering ---- */
.motion-3d .section-title,
.motion-3d .section-heading h2,
.motion-3d .premium-breadcrumb-content h1,
.motion-3d .home-hero-title {
	text-shadow:
		0 1px 0 rgba(37, 99, 235, 0.10),
		0 2px 0 rgba(37, 99, 235, 0.08),
		0 3px 0 rgba(37, 99, 235, 0.06),
		0 8px 18px rgba(17, 24, 39, 0.10);
}

html[data-theme="dark"].motion-3d :is(.section-title, .section-heading h2, .home-hero-title),
.motion-3d :is(.services-hero, .premium-breadcrumb) h1 {
	text-shadow:
		0 1px 0 rgba(96, 165, 250, 0.35),
		0 2px 0 rgba(96, 165, 250, 0.22),
		0 3px 0 rgba(129, 140, 248, 0.14),
		0 10px 30px rgba(37, 99, 235, 0.35);
}

/* Eyebrow pills get a glossy bevel. */
.motion-3d .section-eyebrow {
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.45),
		inset 0 -2px 0 rgba(0, 0, 0, 0.12),
		0 8px 20px rgba(37, 99, 235, 0.25);
}

/* ---- Cards: dynamic shadow + animated gradient edge on hover ---- */
@property --edge-angle {
	syntax: "<angle>";
	initial-value: 0deg;
	inherits: false;
}

.motion-3d .tilt-3d:hover {
	box-shadow:
		var(--shadow-x, 0px) var(--shadow-y, 26px) 50px rgba(37, 99, 235, 0.18),
		0 8px 18px rgba(17, 24, 39, 0.08);
}

html[data-theme="dark"].motion-3d .tilt-3d:hover {
	box-shadow:
		var(--shadow-x, 0px) var(--shadow-y, 26px) 55px rgba(0, 0, 0, 0.55),
		0 0 30px rgba(59, 130, 246, 0.18);
}

.motion-3d .tilt-edge {
	content: "";
	position: absolute;
	inset: 0;
	padding: 1.5px;
	border-radius: inherit;
	background: conic-gradient(from var(--edge-angle), #2563eb, #06b6d4, #9b51e0, #2563eb);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
	opacity: 0;
	transition: opacity 0.4s ease;
	pointer-events: none;
	z-index: 2;
}

.motion-3d .tilt-3d:hover .tilt-edge {
	opacity: 1;
	animation: edge-spin 3s linear infinite;
}

@keyframes edge-spin {
	to { --edge-angle: 360deg; }
}

/* ---- Premium cursor (desktop, motion allowed) ---- */
.cursor-dot,
.cursor-ring {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 2147483000;
	pointer-events: none;
	border-radius: 50%;
}

.cursor-dot {
	width: 6px;
	height: 6px;
	margin: -3px 0 0 -3px;
	background: #2563eb;
	box-shadow: 0 0 10px rgba(37, 99, 235, 0.8);
}

.cursor-ring {
	width: 34px;
	height: 34px;
	margin: -17px 0 0 -17px;
}

/* The visible ring is the pseudo-element so it can tilt in 3D while the
   outer box just follows the pointer. */
.cursor-ring::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	border: 1.5px solid rgba(37, 99, 235, 0.55);
	transition: transform 0.35s var(--ease-premium), background 0.35s ease, border-color 0.35s ease;
}

.cursor-ring.is-active::after {
	transform: perspective(200px) rotateX(55deg) scale(1.7);
	background: rgba(37, 99, 235, 0.08);
	border-color: rgba(6, 182, 212, 0.8);
}

.cursor-ring.is-pressed::after {
	transform: perspective(200px) rotateX(55deg) scale(1.2);
}

.cursor-dot.is-hidden,
.cursor-ring.is-hidden {
	opacity: 0;
}

html[data-theme="dark"] .cursor-dot {
	background: #67e8f9;
	box-shadow: 0 0 12px rgba(103, 232, 249, 0.9);
}

html[data-theme="dark"] .cursor-ring::after {
	border-color: rgba(103, 232, 249, 0.55);
}

/* ---- 3D page transitions (cross-document View Transitions) ----
   Browsers without support simply navigate normally. */
@view-transition {
	navigation: auto;
}

::view-transition-old(root) {
	animation: page-out-3d 0.45s cubic-bezier(0.7, 0, 0.84, 0) both;
	transform-origin: 50% 50%;
}

::view-transition-new(root) {
	animation: page-in-3d 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
	transform-origin: 50% 50%;
}

@keyframes page-out-3d {
	to {
		opacity: 0;
		transform: perspective(1400px) translateZ(-260px) rotateY(-8deg);
		filter: blur(4px);
	}
}

@keyframes page-in-3d {
	from {
		opacity: 0;
		transform: perspective(1400px) translateZ(220px) rotateY(6deg);
		filter: blur(6px);
	}
}

@media (prefers-reduced-motion: reduce) {
	::view-transition-old(root),
	::view-transition-new(root) {
		animation: none;
	}

	.depth-orbs,
	.cursor-dot,
	.cursor-ring {
		display: none;
	}
}

/* =====================================================================
   Scroll-driven 3D story (js/scroll-story3d.js) — home "Our Process"
   ===================================================================== */
.story-track {
	position: relative;
	/* Pinned distance: ~70vh of scrolling per step. */
	height: calc(var(--story-steps, 7) * 70vh + 100vh);
	margin-top: 10px;
}

.story-sticky {
	position: sticky;
	top: 68px; /* scrolled header height */
	height: calc(100vh - 68px);
	height: calc(100svh - 68px);
	display: grid;
	grid-template-columns: 1.15fr 0.85fr 64px;
	align-items: center;
	gap: 24px;
}

.story-stage {
	position: relative;
	height: min(78vh, 640px);
}

.story-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
	transition: opacity 1s ease;
}

.story-canvas.is-ready {
	opacity: 1;
}

.story-counter {
	position: absolute;
	top: 6%;
	left: 0;
	z-index: 1;
	font-family: "Exo", sans-serif;
	font-weight: 800;
	line-height: 1;
	pointer-events: none;
}

.story-counter-current {
	font-size: clamp(64px, 9vw, 120px);
	background: var(--grad-accent);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	text-shadow: none;
}

.story-counter-total {
	margin-left: 8px;
	font-size: 20px;
	color: var(--ink-500);
}

.story-stage-label {
	position: absolute;
	left: 0;
	bottom: 6%;
	z-index: 1;
	font-family: "Exo", sans-serif;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.32em;
	text-transform: uppercase;
	color: var(--ink-500);
	pointer-events: none;
}

.story-stage.is-switching .story-counter-current,
.story-stage.is-switching .story-stage-label {
	animation: story-flip-in 0.55s var(--ease-premium);
}

@keyframes story-flip-in {
	from {
		opacity: 0;
		transform: perspective(600px) rotateX(-70deg) translateY(16px);
	}
}

.story-stage .story-counter-current,
.story-stage .story-stage-label {
	display: inline-block;
	transform-origin: 50% 100%;
}

/* Card deck: every step stacked in one spot, scrubbed in 3D by scroll. */
.story-deck {
	position: relative;
	height: 320px;
	perspective: 1200px;
	counter-reset: process;
}

.story-card {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	transform-origin: 50% 50% -120px;
	will-change: transform, opacity;
	backface-visibility: hidden;
}

.story-card .process-step {
	width: 100%;
	padding: 44px 38px;
}

.story-card .process-step h4 {
	font-size: 26px;
}

.story-card .process-step p {
	font-size: 16px;
	line-height: 1.7;
}

.story-host .process-step::after {
	display: none !important;
}

/* Progress rail with step dots */
.story-rail {
	position: relative;
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 26px;
	z-index: 1;
}

.story-rail li {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 14px;
}

.story-rail li span {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: rgba(100, 116, 139, 0.35);
	transition: transform 0.35s var(--ease-premium), background 0.35s ease, box-shadow 0.35s ease;
}

.story-rail li.is-done span {
	background: #60a5fa;
}

.story-rail li.is-active span {
	transform: scale(1.7);
	background: #06b6d4;
	box-shadow: 0 0 0 4px rgba(6, 182, 212, 0.18), 0 0 16px rgba(6, 182, 212, 0.7);
}

.story-rail li em {
	position: absolute;
	right: calc(50% + 16px);
	font-style: normal;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.08em;
	white-space: nowrap;
	color: var(--ink-500);
	opacity: 0;
	transform: translateX(8px);
	transition: opacity 0.3s ease, transform 0.3s ease;
}

.story-rail li.is-active em {
	opacity: 1;
	transform: none;
}

.story-progress {
	position: absolute;
	right: 31px;
	top: 50%;
	height: calc(7 * 40px);
	width: 2px;
	transform: translateY(-50%);
	background: rgba(100, 116, 139, 0.2);
	border-radius: 2px;
	overflow: hidden;
}

.story-progress span {
	display: block;
	height: 100%;
	background: linear-gradient(180deg, #2563eb, #06b6d4, #9b51e0);
	transform-origin: top;
	transform: scaleY(0);
}

@media (max-width: 991px) {
	.story-track {
		height: calc(var(--story-steps, 7) * 60vh + 100vh);
	}

	.story-sticky {
		grid-template-columns: 1fr;
		grid-template-rows: 1fr auto;
		align-items: stretch;
		gap: 0;
		padding-bottom: 18px;
	}

	.story-stage {
		height: auto;
		min-height: 0;
	}

	.story-deck {
		height: 250px;
	}

	.story-card .process-step {
		padding: 28px 24px;
	}

	.story-card .process-step h4 {
		font-size: 21px;
	}

	.story-card .process-step p {
		font-size: 14.5px;
	}

	.story-rail,
	.story-progress {
		display: none;
	}

	.story-counter-current {
		font-size: 56px;
	}
}

/* =====================================================================
   Orbiting network (js/orbit3d.js) — any .tech-network[data-orbit]
   ===================================================================== */
.tech-network.is-orbiting .tech-node {
	top: 50% !important;
	left: 50% !important;
	width: 40px;
	height: 40px;
	border-radius: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 15px;
	color: #ffffff;
	animation: none !important;
	will-change: transform, opacity;
	box-shadow: 0 10px 22px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.tech-network.is-orbiting .tech-network-lines line {
	stroke-width: 1.2;
	stroke-dasharray: 3 3;
	animation: orbit-line-flow 1.2s linear infinite;
}

@keyframes orbit-line-flow {
	to { stroke-dashoffset: -12; }
}

/* Orbit ring behind the nodes, drawn as a tilted ellipse. */
.tech-network.is-orbiting::before {
	content: "";
	position: absolute;
	left: 14%;
	right: 14%;
	top: 20%;
	bottom: 20%;
	border-radius: 50%;
	border: 1px dashed rgba(96, 165, 250, 0.4);
	transform: translateZ(-1px);
	pointer-events: none;
}

.tech-network.is-orbiting .tech-network-core {
	box-shadow:
		0 20px 50px rgba(37, 99, 235, 0.45),
		0 0 0 8px rgba(96, 165, 250, 0.12),
		0 0 0 18px rgba(96, 165, 250, 0.06);
}

/* =====================================================================
   Word-by-word 3D headline entrance — any heading with data-3d-words
   ===================================================================== */
.motion-3d [data-3d-words] {
	perspective: 800px;
}

.word-3d {
	display: inline-block;
	transform-style: preserve-3d;
}

.word-3d > span {
	display: inline-block;
	transform-origin: 50% 100%;
	animation: word-flip-up 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes word-flip-up {
	from {
		opacity: 0;
		transform: translateY(0.6em) rotateX(-85deg);
		filter: blur(4px);
	}
}

/* Info-card icons spin like a coin when their card is hovered (all pages). */
.motion-3d .tilt-3d .info-card-icon {
	transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

.motion-3d .tilt-3d:hover .info-card-icon {
	transform: perspective(400px) translateZ(50px) rotateY(360deg);
}

/* 3D layers (orbs, glows, gallery frames flying in from the sides) may
   extend past the screen edge; never let them make the page scroll
   sideways. "clip" (unlike "hidden") keeps position: sticky working. */
html.motion-3d,
html.motion-3d body {
	overflow-x: clip;
}
