/* ==========================================================================
   Aidem Project Case Study Widget
   assets/css/project-case-study-widget.css
   2026-10-16

   Two display modes share this one file:
     .apcs-full   - single-project case study page (hero + ACF body tiles)
     .apcs-teaser - portfolio grid card (background image + glass info strip)

   Teaser card build notes (read before editing):
   - Chamfered corner via clip-path, NOT border-radius, so the card reads
     as an angular "tech panel" rather than a rounded card. The clip-path
     keeps the card's bounding box rectangular so CSS Grid packing is
     completely unaffected - only the visual silhouette is cut.
   - The accessible link is `.apcs-teaser__cta` (the "View" button),
     stretched via `::after` to cover the whole card. Do NOT wrap the whole
     `.apcs-teaser` in a second <a> - a link cannot correctly contain
     another link for keyboard/screen-reader users. Hover/focus states are
     written against `.apcs-teaser:hover` / `.apcs-teaser:focus-within` -
     this needs no JS or :has(), since hovering the stretched link (a
     descendant) already triggers :hover on its ancestors via normal CSS
     bubbling.
   - Logo sits as an overlay chip in the top-right corner of the image
     (not inside the glass panel) so it reads against the photo itself.
     It carries a slow, continuous left-to-right light sweep (not a
     glitch) via the logo-wrap's ::after, staggered per-card by
     nth-child so a grid of cards doesn't sweep in lockstep.
   - Entrance ("materialize") uses animation-timeline: view() inside an
     @supports block - a browser without support just shows the card
     normally, never broken, just plainer.
   - Grid size/shape variety (.apcs-size-*, nth-child chamfer variants)
     assumes each Loop Grid item's template contains ONLY this widget, so
     .apcs-teaser sits directly as the grid cell. If the Loop Item
     template wraps this widget in its own container, move the nth-child
     rules to target that wrapper instead.
   - Size variety (.apcs-size-wide/tall/large) needs the Loop Grid's own
     container to define a consistent grid-auto-rows so the spans have
     something to multiply - add that in Elementor on the Loop Grid
     widget's own CSS, not here.
   ========================================================================== */

.apcs-wrap {
	--apcs-accent: #8c5ff5;
	--apcs-type-color: #abd555;
	--apcs-radius: 16px;
	--apcs-hero-height: 70vh;
	--apcs-chamfer: 32px;
	box-sizing: border-box;
}

.apcs-wrap *,
.apcs-wrap *::before,
.apcs-wrap *::after {
	box-sizing: inherit;
}

/* ──────────────────────────────────────────────────────────────────────
   TEASER CARD
   ────────────────────────────────────────────────────────────────────── */

.apcs-teaser {
	position: relative;
	display: flex;
	flex-direction: column;
	align-self: start;
	height: auto;
	width: 100%;
	overflow: hidden;
	border-radius: var(--apcs-radius);
	clip-path: polygon(
		0 0,
		calc(100% - var(--apcs-chamfer)) 0,
		100% var(--apcs-chamfer),
		100% 100%,
		0 100%
	);
	background: #0a0a12;
	isolation: isolate;
	transition: transform 0.35s ease;
}

.apcs-teaser:hover,
.apcs-teaser:focus-within {
	transform: translateY(-4px);
}

.apcs-teaser:nth-child(3n+2) {
	clip-path: polygon(
		var(--apcs-chamfer) 0,
		100% 0,
		100% 100%,
		0 100%,
		0 var(--apcs-chamfer)
	);
}

.apcs-teaser:nth-child(3n+3) {
	--apcs-chamfer: 22px;
	clip-path: polygon(
		0 0,
		100% 0,
		100% 100%,
		var(--apcs-chamfer) 100%,
		0 calc(100% - var(--apcs-chamfer))
	);
}

.apcs-teaser.apcs-size-wide {
	grid-column: span 2;
}

.apcs-teaser.apcs-size-tall {
	grid-row: span 2;
}

.apcs-teaser.apcs-size-large {
	grid-column: span 2;
	grid-row: span 2;
}

.apcs-teaser__media {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	z-index: 0;
}

.apcs-teaser__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
	transition: transform 0.6s ease, filter 0.6s ease;
}

.apcs-teaser:hover .apcs-teaser__bg,
.apcs-teaser:focus-within .apcs-teaser__bg {
	transform: scale(1.06);
}

.apcs-teaser__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.9) 0%,
		rgba(0, 0, 0, 0.55) 22%,
		rgba(0, 0, 0, 0.05) 45%,
		rgba(0, 0, 0, 0) 70%
	);
	transition: background 0.4s ease;
}

.apcs-teaser:hover .apcs-teaser__scrim,
.apcs-teaser:focus-within .apcs-teaser__scrim {
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.94) 0%,
		rgba(0, 0, 0, 0.6) 22%,
		rgba(0, 0, 0, 0.08) 45%,
		rgba(0, 0, 0, 0) 70%
	);
}

.apcs-teaser__panel {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 20px 20px 22px;
	background: rgba(255, 255, 255, 0.1);
	backdrop-filter: blur(18px) saturate(160%);
	-webkit-backdrop-filter: blur(18px) saturate(160%);
	border-top: 1px solid rgba(255, 255, 255, 0.22);
	box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.25);
}

.apcs-teaser__logo-wrap {
	position: absolute;
	top: 14px;
	right: 14px;
	z-index: 2;
	width: 68px;
	height: 68px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	pointer-events: none;
}

.apcs-teaser__logo {
	position: relative;
	z-index: 1;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55));
}

.apcs-teaser__text {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.apcs-teaser__type {
	margin: 0;
	font-size: var(--xxs-size-text-9-11px, 11px);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--apcs-type-color) !important;
}

.apcs-teaser__title {
	margin: 0;
	font-size: var(--xs-size-heading-12-30px, 19px);
	line-height: 1.25;
	font-weight: 700;
	color: #ffffff !important;
}

.apcs-teaser__client {
	margin: 0;
	font-size: var(--n-size-text-16-18px, 16px);
	color: #ffffff !important;
}

/* Visual styling (background, border, padding, radius, colour, font) is
   intentionally NOT set here - .apcs-teaser__cta also carries the site-wide
   .elementor-button class (core.css Section 6 + 8), so it automatically
   matches every other button on the site and stays in sync with it. Only
   the structural rules this card layout actually needs live here. */
.apcs-teaser__cta {
	position: relative;
	z-index: 3;
	align-self: center;
	margin-top: 6px;
	width: fit-content;
	transition: transform 0.25s ease;
}

.apcs-teaser:hover .apcs-teaser__cta {
	transform: translateX(2px);
}

.apcs-teaser__cta::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* ──────────────────────────────────────────────────────────────────────
   LOGO SHEEN - slow left-to-right light sweep, continuous, staggered
   per-card so a grid of cards doesn't sweep in lockstep. Lives on the
   logo-wrap's ::after (not the <img> itself) so it sits as a highlight
   layer above the logo without altering the logo image's own pixels.
   ────────────────────────────────────────────────────────────────────── */

.apcs-teaser__logo-wrap::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	background: linear-gradient(
		100deg,
		transparent 40%,
		rgba(255, 255, 255, 0.4) 50%,
		transparent 60%
	);
	background-size: 400% 100%;
	background-position: -160% 0;
	mix-blend-mode: screen;
	pointer-events: none;
	animation: apcs-logo-sheen 11s ease-in-out infinite;
}

@keyframes apcs-logo-sheen {
	0%, 60% {
		background-position: -160% 0;
	}
	85%, 100% {
		background-position: 160% 0;
	}
}

.apcs-teaser:nth-child(2) .apcs-teaser__logo-wrap::after { animation-delay: 0.8s; }
.apcs-teaser:nth-child(3) .apcs-teaser__logo-wrap::after { animation-delay: 1.6s; }
.apcs-teaser:nth-child(4) .apcs-teaser__logo-wrap::after { animation-delay: 2.4s; }
.apcs-teaser:nth-child(5) .apcs-teaser__logo-wrap::after { animation-delay: 1.1s; }
.apcs-teaser:nth-child(6) .apcs-teaser__logo-wrap::after { animation-delay: 1.9s; }
.apcs-teaser:nth-child(7) .apcs-teaser__logo-wrap::after { animation-delay: 0.4s; }
.apcs-teaser:nth-child(8) .apcs-teaser__logo-wrap::after { animation-delay: 2.7s; }
.apcs-teaser:nth-child(9) .apcs-teaser__logo-wrap::after { animation-delay: 1.3s; }

@media (prefers-reduced-motion: reduce) {
	.apcs-teaser__logo-wrap::after {
		animation: none;
	}
}

/* ──────────────────────────────────────────────────────────────────────
   MATERIALIZE ENTRANCE - scroll-driven, CSS-only, safe fallback
   ────────────────────────────────────────────────────────────────────── */

@supports (animation-timeline: view()) {
	.apcs-teaser {
		animation: apcs-materialize-wipe linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 55%;
	}

	.apcs-teaser__media::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: 1;
		background: repeating-linear-gradient(
			to bottom,
			rgba(140, 95, 245, 0.9) 0px,
			rgba(140, 95, 245, 0.9) 2px,
			transparent 2px,
			transparent 5px
		);
		mix-blend-mode: screen;
		opacity: 0;
		animation: apcs-materialize-scanline linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 55%;
	}

	@keyframes apcs-materialize-wipe {
		0% {
			clip-path: inset(100% 0 0 0);
			filter: brightness(2.4) blur(6px);
		}
		70% {
			filter: brightness(1.6) blur(1px);
		}
		100% {
			clip-path: inset(0 0 0 0);
			filter: brightness(1) blur(0);
		}
	}

	@keyframes apcs-materialize-scanline {
		0% {
			opacity: 0;
			transform: translateY(-100%);
		}
		15% {
			opacity: 1;
		}
		85% {
			opacity: 1;
		}
		100% {
			opacity: 0;
			transform: translateY(100%);
		}
	}
}

/* ──────────────────────────────────────────────────────────────────────
   FULL CASE STUDY PAGE  -  horizontal strip (2026-10-18)

   Markup:  .apcs-h                (wrap; JS adds .apcs-h-on when horizontal)
              .apcs-h-viewport     (pinned on desktop, sticky on touch)
                .apcs-h-track      (the strip that slides sideways)
                  .apcs-panel--media / --title / --text / --end

   Without JS (or in the Elementor editor, or with reduced motion) the
   panels simply stack vertically - nothing depends on the script to be
   readable. .apcs-h-on is added by apcs-horizontal.js only when it has
   actually built the horizontal scroll.
   ────────────────────────────────────────────────────────────────────── */

.apcs-full {
	display: block;
	width: 100%;
	--apcs-header-h: var(--aidem-header-h, 0px);
}

.apcs-h {
	position: relative;
}

.apcs-h-track {
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding: 24px 0;
}

.apcs-panel {
	position: relative;
	box-sizing: border-box;
	min-width: 0;
}

/* Media panel: featured image + client logo */
.apcs-panel--media {
	min-height: 60vh;
	border-radius: var(--apcs-radius);
	overflow: hidden;
	background: #0a0a12;
}

.apcs-media {
	position: absolute;
	inset: 0;
	view-transition-name: apcs-hero;
}

.apcs-panel--media .apcs-media .apcs-media__image {
	position: absolute;
	inset: 0;
	/* Elementor / theme rules set img { height: auto; max-width: 100% },
	   which left the image at its natural wide shape with dead space under
	   it. Force it to fill the whole panel. */
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	object-fit: cover;
	object-position: center top;
	display: block;
}

.apcs-media__logo-wrap {
	position: absolute;
	top: 24px;
	left: 24px;
	z-index: 2;
	width: 96px;
	height: 96px;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
}

.apcs-media__logo {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.55));
}

/* Title panel */
.apcs-panel--title {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 14px;
	padding: 24px 0;
}

.apcs-hero__type {
	margin: 0;
	font-size: var(--s-size-text-12-14px, 13px);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--apcs-type-color) !important;
}

.apcs-hero__client {
	margin: 0;
	font-size: var(--nl-size-text-18-22px, 18px);
	color: #ffffff !important;
}

.apcs-hero__title {
	margin: 0;
	font-size: var(--xl-size-heading-30-75px, clamp(30px, 5vw, 75px));
	font-weight: 800;
	line-height: 1.05;
	color: #ffffff !important;
	overflow-wrap: anywhere;
}

/* Text panels (Requirement, Outcomes, Challenges / Results, Social Value) */
.apcs-panel--text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 16px;
	padding: 32px;
	background: rgba(255, 255, 255, 0.05);
	border: 1px solid rgba(255, 255, 255, 0.12);
	border-radius: var(--apcs-radius);
}

.apcs-panel--text h2 {
	margin: 0;
	font-size: var(--s-size-heading-16-38px, 24px);
	font-weight: 700;
	line-height: 1.15;
	color: var(--apcs-accent);
}

.apcs-answer {
	font-size: var(--n-size-text-16-18px, 16px);
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.88);
}

.apcs-split {
	display: grid;
	grid-template-columns: 1fr;
	gap: 20px;
}

.apcs-split__col strong {
	display: block;
	margin-bottom: 8px;
	color: #ffffff;
	font-size: var(--m-size-text-14-16px, 15px);
}

.apcs-split__col ul {
	margin: 0;
	padding-left: 18px;
	font-size: var(--m-size-text-14-16px, 15px);
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.85);
}

/* End panel */
.apcs-panel--end {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 18px;
	padding: 32px;
	text-align: center;
}

.apcs-end__label {
	margin: 0;
	line-height: 1.3 !important;
	text-wrap: balance;
	font-size: var(--m-size-heading-20-48px, 28px);
	font-weight: 700;
	color: #ffffff !important;
}

/* Close button in the end panel, pushed lower than the heading */
.apcs-end__link {
	margin-top: clamp(40px, 9vh, 110px);
}

.apcs-end__link.elementor-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	padding: 0 !important;
	border-radius: 50% !important;
}

.apcs-end__link .elementor-button-content-wrapper {
	display: flex;
	align-items: center;
	justify-content: center;
}

.apcs-end__x {
	display: block;
}

.apcs-end__link:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 3px;
}

/* ── Horizontal mode (class added by apcs-horizontal.js) ───────────── */

.apcs-h.apcs-h-on {
	padding-top: var(--apcs-header-h);
}

.apcs-h-on .apcs-h-viewport {
	height: calc(100svh - var(--apcs-header-h));
	overflow: hidden;
}

.apcs-h-on .apcs-h-track {
	flex-direction: row;
	align-items: stretch;
	width: max-content;
	height: 100%;
	gap: clamp(24px, 4vw, 64px);
	padding: 0 clamp(24px, 6vw, 96px);
	will-change: transform;
}

.apcs-h-on .apcs-panel {
	flex: 0 0 auto;
	height: 100%;
	min-height: 0;
}

.apcs-h-on .apcs-panel--media {
	width: clamp(300px, 62vw, 1000px);
}

.apcs-h-on .apcs-panel--title {
	width: clamp(300px, 50vw, 760px);
}

.apcs-h-on .apcs-panel--text {
	opacity: 0; /* faded in by apcs-horizontal.js as each card scrolls into view */
	width: clamp(300px, 36vw, 520px);
	height: auto;
	align-self: center;
}

.apcs-h-on .apcs-panel--end {
	width: clamp(260px, 36vw, 480px);
}

/* Desktop: the hero image sits 20px below the menu and is 20px smaller on
   every side (so 40px top = 20px menu gap + 20px inset). */
@media (min-width: 1025px) {
	.apcs-h-on .apcs-panel--media {
		height: calc(100% - 60px);
		align-self: flex-start;
		margin: 40px 20px 20px;
	}
}

/* Touch devices (tablet / phone) */
@media (max-width: 1024px) {
	.apcs-h-on .apcs-panel--media {
		width: 82vw;
	}

	.apcs-h-on .apcs-panel--title {
		width: 78vw;
	}

	.apcs-h-on .apcs-panel--text {
		width: 78vw;
	}

	.apcs-h-on .apcs-panel--end {
		width: 70vw;
	}

	.apcs-h-sticky .apcs-h-viewport {
		position: sticky;
		z-index: 1;
	}

	/* html and body are scroll containers on this site, which silently
	   disables position: sticky. overflow-x: clip blocks sideways scroll
	   without creating a scroll container - same fix as the Cards
	   Stacking / Horizontal widget (handover doc 09). */
	html.aidem-loader-ready:has(.apcs-h),
	html.aidem-loader-ready:has(.apcs-h) body {
		overflow-x: clip !important;
		overflow-y: visible !important;
	}
}

@media (hover: none), (pointer: coarse) {
	html,
	body,
	body.native-scroll {
		scroll-behavior: auto !important;
	}
}

@media (max-width: 767px) {
	.apcs-panel--text {
		padding: 22px;
	}

	.apcs-media__logo-wrap {
		width: 68px;
		height: 68px;
		top: 16px;
		left: 16px;
	}
}

/* ── Card -> project page morph (cross-document View Transitions) ─────
   The clicked card's image gets view-transition-name: apcs-hero (set by
   apcs-horizontal.js on click); the project page's .apcs-media always has
   it, so the browser grows the card image into the first panel. Browsers
   without support just load the page normally. */
@view-transition {
	navigation: auto;
}

::view-transition-group(apcs-hero) {
	animation-duration: 0.7s;
	animation-timing-function: cubic-bezier(0.65, 0, 0.2, 1);
	overflow: clip;
	border-radius: var(--apcs-radius, 16px);
}

::view-transition-old(apcs-hero),
::view-transition-new(apcs-hero) {
	height: 100%;
	object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
	@view-transition {
		navigation: none;
	}
}
