/* =============================================================================
   Portfolio Showcase — full-bleed tabbed project grid
   Markup:  template-parts/portfolio-showcase.php
   Script:  assets/js/portfolio-showcase.js
   Figma:   node 1626:2858 (card default 1428:4905, card hover 1428:4972)

   Namespaced to .ldv-pfs throughout, so the theme's existing .portfolioMain and
   .portfolioSec grids are untouched.

   This section is intentionally full-bleed — no .max-con, no gutter, no gap and
   no border-radius on the cards. The 2-up grid meets edge to edge by design.

   Contents
     1. Tokens + section shell
     2. Layout      — heading, tab bar, grid
     3. Components  — card, media, scrim, pill, body (logo, description, CTA)
     4. State       — panel visibility, hover reveal, focus
     5. Media queries  (one block per breakpoint, widest first)
   ========================================================================== */


/* -----------------------------------------------------------------------------
   1. Tokens + section shell
   -------------------------------------------------------------------------- */

.ldv-pfs {
	/* Same red the theme's existing portfolio tabs use for their active pill. */
	--ldv-pfs-accent: #d01f30;
	--ldv-pfs-muted: #666666;
	/* Heading ink + accent underline, shared with .recentWork and the other
	   slider sections so this section's title reads identically to them. */
	--ldv-pfs-ink: #333333;
	--ldv-pfs-underline: #e3725d;
	--ldv-pfs-inset: 50px;
	--ldv-pfs-pill-radius: 38px;
	--ldv-pfs-blur: 16px;
	/* Hover state: the scrim's bottom stop warms to this red, and the revealed
	   copy steps down with the rest of the type at each breakpoint. */
	--ldv-pfs-hot: rgba(204, 31, 47, 0.71);
	--ldv-pfs-desc: 24px;
	--ldv-pfs-cta: 20px;
	--ldv-pfs-reveal-gap: 24px;
	--ldv-pfs-ease: cubic-bezier(0.25, 0.8, 0.25, 1);
	--ldv-pfs-dur: 0.45s;

	position: relative;
	isolation: isolate;
}


/* -----------------------------------------------------------------------------
   2. Layout — heading, tab bar, grid
   -------------------------------------------------------------------------- */

/* The section itself is full-bleed, so the heading re-establishes the site
   gutter on its own — same 90% width .max-con uses elsewhere. Centred, matching
   the other portfolio/slider section titles. */
.ldv-pfs .main-ldv-pfs {
	width: 90%;
	margin: 0 auto;
	/* Bottom pad carries the gap down to the tab bar, which sets only its own
	   bottom spacing. */
	padding: 80px 0 50px;
	text-align: center;
}

.ldv-pfs .main-ldv-pfs h2 {
	margin-bottom: 20px;
	color: var(--ldv-pfs-ink);
	font-size: 46px;
	font-weight: 500;
	line-height: 60px;
}

.ldv-pfs .main-ldv-pfs h2 span {
	position: relative;
	z-index: 1;
	color: var(--ldv-pfs-accent);
	font-family: "Scotch Text Comp Sm It", serif;
	font-size: 58px;
}

.ldv-pfs .main-ldv-pfs h2 span::before {
	content: "";
	position: absolute;
	bottom: 10px;
	z-index: -1;
	width: 100%;
	height: 7px;
	border-bottom: 7px solid var(--ldv-pfs-underline);
}

.ldv-pfs .main-ldv-pfs p {
	width: 75%;
	margin: 0 auto;
	color: var(--ldv-pfs-ink);
	font-size: 20px;
	font-weight: 500;
	line-height: 32px;
}

.ldv-pfs__nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 15px;
	padding: 0 20px 60px;
}

.ldv-pfs__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	/* Cards butt together — the design has no gutter between them. */
	gap: 0;
}

/* `hidden` alone would be overridden by `display:grid`. */
.ldv-pfs__grid[hidden] {
	display: none;
}


/* -----------------------------------------------------------------------------
   3. Components — card, media, scrim, pill, logo
   -------------------------------------------------------------------------- */

.ldv-pfs__tab {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 10px 24px;
	border: 1px solid var(--ldv-pfs-muted);
	border-radius: var(--ldv-pfs-pill-radius);
	background: transparent;
	-webkit-backdrop-filter: blur(var(--ldv-pfs-blur));
	backdrop-filter: blur(var(--ldv-pfs-blur));
	color: var(--ldv-pfs-muted);
	font-family: "Guminert", sans-serif;
	font-size: 16px;
	font-weight: 700;
	line-height: 22px;
	white-space: nowrap;
	cursor: pointer;
	transition: color var(--ldv-pfs-dur) var(--ldv-pfs-ease),
		border-color var(--ldv-pfs-dur) var(--ldv-pfs-ease);
}

.ldv-pfs__tab.is-active {
	border-color: var(--ldv-pfs-accent);
	color: var(--ldv-pfs-accent);
}

.ldv-pfs__card {
	position: relative;
	display: block;
	/* Square cards, so the grid height follows the viewport width. */
	aspect-ratio: 4/3;
	overflow: hidden;
	background: #000;
	/* Kills the baseline gap that would otherwise show between rows. */
	line-height: 0;
	text-decoration: none;
}

.ldv-pfs__media {
	position: absolute;
	inset: 0;
	display: block;
}

.ldv-pfs__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* object-position and --ldv-pfs-zoom come from the per-card inline style; the
	   hover state multiplies the zoom rather than replacing it. */
	transform: scale(var(--ldv-pfs-zoom, 1));
	transition: transform 0.8s var(--ldv-pfs-ease);
}

/* Two stacked gradients, straight from the design: a flat 10% black wash over
   the whole card, then a directional falloff that carries the bottom-left
   corner dark enough for the logo to hold contrast. */
.ldv-pfs__scrim {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)),
		linear-gradient(201.455deg,
			rgba(0, 0, 0, 0) 34.413%,
			rgba(0, 0, 0, 0.54) 54.257%,
			rgba(0, 0, 0, 0.92) 73.951%);
}

/* Hover twin of the scrim — identical geometry, red final stop. It cross-fades on
   top of the base scrim because a background-image cannot itself transition. */
.ldv-pfs__scrim--hot {
	z-index: 1;
	opacity: 0;
	background-image:
		linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)),
		linear-gradient(201.455deg,
			rgba(0, 0, 0, 0) 34.413%,
			rgba(0, 0, 0, 0.54) 54.257%,
			var(--ldv-pfs-hot) 73.951%);
	transition: opacity var(--ldv-pfs-dur) var(--ldv-pfs-ease);
}

.ldv-pfs__pill {
	position: absolute;
	top: var(--ldv-pfs-inset);
	left: var(--ldv-pfs-inset);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 10px 24px;
	border-radius: var(--ldv-pfs-pill-radius);
	-webkit-backdrop-filter: blur(var(--ldv-pfs-blur));
	backdrop-filter: blur(var(--ldv-pfs-blur));
	color: #fff;
	font-family: "Guminert", sans-serif;
	font-size: 13px;
	font-weight: 700;
	line-height: 22px;
	white-space: nowrap;
}

.ldv-pfs__card--dark .ldv-pfs__pill {
	background: rgba(0, 0, 0, 0.1);
}

/* The Law Firm card sits on a near-black photo, so its pill lifts on a light
   tint instead — carried through from the design rather than normalised away. */
.ldv-pfs__card--light .ldv-pfs__pill {
	background: rgba(255, 255, 255, 0.1);
}

/* Logo, description and CTA share one bottom-anchored column, so the revealed copy
   grows upward and the logo keeps its baseline in both states: bottom + height =
   910 of 960 in the design, hover or not. */
.ldv-pfs__body {
	position: absolute;
	bottom: var(--ldv-pfs-inset);
	left: var(--ldv-pfs-inset);
	z-index: 2;
	display: flex;
	flex-direction: column;
	/* Stops the default `stretch` from widening the logo to the column. */
	align-items: flex-start;
	/* No gap here — it lives inside .ldv-pfs__reveal so it collapses with it. */
	width: calc(100% - (var(--ldv-pfs-inset) * 2));
	/* 738 of 960 in the design. */
	max-width: 77%;
	/* The card zeroes line-height to kill the row gap; text needs it back. */
	line-height: normal;
}

.ldv-pfs__logo {
	flex: 0 0 auto;
	width: auto;
	height: auto;
	/* Logos vary 63–140px tall; cap the height and let width follow the artwork. */
	max-height: 140px;
	/* The cap is 45% of the *card*, as it was when the logo was positioned against
	   the card itself. Percentages now resolve against .ldv-pfs__body, which is
	   capped at 77% of the card — hence 45/77. */
	max-width: 58%;
}

/* Collapsed to a zero-height row until the card opens. The 0fr → 1fr rows
   transition keeps the height animated without hard-coding one. */
.ldv-pfs__reveal {
	display: grid;
	grid-template-rows: 0fr;
	overflow: hidden;
	opacity: 0;
	transition: grid-template-rows var(--ldv-pfs-dur) var(--ldv-pfs-ease),
		opacity var(--ldv-pfs-dur) var(--ldv-pfs-ease);
}

/* Padding rather than a gap on .ldv-pfs__body, so the 24px sits inside the
   collapsing row instead of leaving a permanent hole under the logo. */
.ldv-pfs__reveal-in {
	display: flex;
	flex-direction: column;
	gap: var(--ldv-pfs-reveal-gap);
	min-height: 0;
	padding-top: var(--ldv-pfs-reveal-gap);
}

.ldv-pfs__desc {
	margin: 0;
	color: #fff;
	font-family: "Guminert", sans-serif;
	font-size: var(--ldv-pfs-desc);
	font-weight: 500;
	line-height: 40px;
}

.ldv-pfs__cta {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: #fff;
	font-family: "Guminert", sans-serif;
	font-size: var(--ldv-pfs-cta);
	font-weight: 700;
	line-height: 40px;
}

.ldv-pfs__cta-icon {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
}


/* -----------------------------------------------------------------------------
   4. State — panel visibility, hover, focus
   -------------------------------------------------------------------------- */

.ldv-pfs__tab:hover,
.ldv-pfs__tab:focus-visible {
	border-color: var(--ldv-pfs-accent);
	color: var(--ldv-pfs-accent);
}

.ldv-pfs__tab:focus-visible,
.ldv-pfs__card:focus-visible {
	outline: 2px solid var(--ldv-pfs-accent);
	outline-offset: 3px;
}

/* Hover / open state (Figma 1428:4972). `is-open` is set by the script on touch,
   where there is no hover; `:focus-within` covers keyboard users tabbing to a
   linked card. All three do exactly the same three things. */
.ldv-pfs__card:hover .ldv-pfs__scrim--hot,
.ldv-pfs__card:focus-within .ldv-pfs__scrim--hot,
.ldv-pfs__card.is-open .ldv-pfs__scrim--hot {
	opacity: 1;
}

.ldv-pfs__card:hover .ldv-pfs__reveal,
.ldv-pfs__card:focus-within .ldv-pfs__reveal,
.ldv-pfs__card.is-open .ldv-pfs__reveal {
	grid-template-rows: 1fr;
	opacity: 1;
}

/* Slow push-in, 1.15 past the card's own crop in the design. */
.ldv-pfs__card:hover .ldv-pfs__img,
.ldv-pfs__card:focus-within .ldv-pfs__img,
.ldv-pfs__card.is-open .ldv-pfs__img {
	transform: scale(calc(var(--ldv-pfs-zoom, 1) * 1.15));
}

@media (prefers-reduced-motion: reduce) {
	.ldv-pfs__img,
	.ldv-pfs__tab,
	.ldv-pfs__scrim--hot,
	.ldv-pfs__reveal {
		transition: none;
	}

	/* The copy still appears — only the movement goes. */
	.ldv-pfs__card:hover .ldv-pfs__img,
	.ldv-pfs__card:focus-within .ldv-pfs__img,
	.ldv-pfs__card.is-open .ldv-pfs__img {
		transform: scale(var(--ldv-pfs-zoom, 1));
	}
}


/* -----------------------------------------------------------------------------
   5. Media queries — widest first, matching the theme's existing breakpoints
   -------------------------------------------------------------------------- */

/* Heading steps down on the same breakpoints the theme's other section titles
   use, so it stays in step with them at every width. */
@media (max-width: 1600px) {
	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 42px;
		line-height: 55px;
	}

	.ldv-pfs .main-ldv-pfs h2 span {
		font-size: 48px;
	}

	.ldv-pfs .main-ldv-pfs p {
		font-size: 18px;
	}
}

@media (max-width: 1440px) {
	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 40px;
		line-height: 50px;
	}
}

@media (max-width: 1200px) {
	.ldv-pfs {
		--ldv-pfs-inset: 36px;
		--ldv-pfs-desc: 20px;
		--ldv-pfs-cta: 18px;
		--ldv-pfs-reveal-gap: 20px;
	}

	/* Fixed 40px leading is a design constant at desktop size only; below that it
	   opens the block up too far. */
	.ldv-pfs__desc,
	.ldv-pfs__cta {
		line-height: 1.6;
	}

	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 35px;
		line-height: 1.2;
	}

	.ldv-pfs .main-ldv-pfs h2 span {
		font-size: 40px;
	}

	.ldv-pfs .main-ldv-pfs p {
		font-size: 16px;
		line-height: 1.6;
	}

	.ldv-pfs__logo {
		max-height: 110px;
	}
}

@media (max-width: 991px) {
	.ldv-pfs {
		--ldv-pfs-inset: 28px;
		--ldv-pfs-desc: 18px;
		--ldv-pfs-cta: 16px;
		--ldv-pfs-reveal-gap: 16px;
	}

	.ldv-pfs .main-ldv-pfs {
		padding: 60px 0 40px;
	}

	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 30px;
	}

	.ldv-pfs .main-ldv-pfs h2 span {
		font-size: 35px;
	}

	/* Theme drops the underline once the heading wraps tightly. */
	.ldv-pfs .main-ldv-pfs h2 span::before {
		display: none;
	}

	.ldv-pfs .main-ldv-pfs p {
		width: 100%;
	}

	.ldv-pfs__nav {
		padding-bottom: 40px;
	}

	.ldv-pfs__logo {
		max-height: 90px;
	}
}

@media (max-width: 767px) {
	.ldv-pfs {
		--ldv-pfs-inset: 24px;
		--ldv-pfs-desc: 16px;
	}

	/* Single column, so the copy can use the full card width. */
	.ldv-pfs__body {
		max-width: 100%;
	}

	.ldv-pfs .main-ldv-pfs {
		padding: 50px 0 30px;
	}

	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 28px;
	}

	.ldv-pfs .main-ldv-pfs h2 span {
		font-size: 30px;
	}

	.ldv-pfs .main-ldv-pfs p {
		font-size: 14px;
	}

	/* Single column below the tablet break, so each card keeps its square crop
	   instead of shrinking to a strip. */
	.ldv-pfs__grid {
		grid-template-columns: 1fr;
	}

	.ldv-pfs__nav {
		gap: 10px;
		padding-bottom: 30px;
	}

	.ldv-pfs__tab {
		min-height: 42px;
		padding: 8px 20px;
		font-size: 14px;
	}

	.ldv-pfs__logo {
		max-height: 100px;
		max-width: 55%;
	}
}

@media (max-width: 480px) {
	.ldv-pfs {
		--ldv-pfs-inset: 20px;
		--ldv-pfs-desc: 15px;
		--ldv-pfs-cta: 15px;
		--ldv-pfs-reveal-gap: 14px;
	}

	.ldv-pfs__cta-icon {
		width: 18px;
		height: 18px;
	}

	.ldv-pfs .main-ldv-pfs h2 {
		font-size: 26px;
	}

	/* The forced break is fine on desktop but strands a single word on a phone. */
	.ldv-pfs .main-ldv-pfs h2 br {
		display: none;
	}

	.ldv-pfs__tab {
		padding: 8px 16px;
		font-size: 13px;
	}

	.ldv-pfs__pill {
		padding: 8px 18px;
		font-size: 12px;
	}

	.ldv-pfs__logo {
		max-height: 80px;
	}
}
