/* -----------------------------------------------------------------------------
   One project — /projects/{slug}/.

   Reading column with a sticky meta rail, a highlight grid, and the typeface
   specimen / download block. --gb-accent comes off the shell from the project's
   own entry, so nothing here is per-project.
----------------------------------------------------------------------------- */

.gb-pjs {
	padding-bottom: 140px;
}

/* --------------------------------------------------------------- reveal --- */

.gb-reveal-ready [data-gb-reveal] {
	opacity: 0;
	transform: translateY(22px);
	transition: opacity 0.45s ease-out, transform 0.45s ease-out;
}

/* Only the blocks on screen at load hold back for the title band. Scrolled-to
   blocks fire immediately — reveal.js decides which is which. */
.gb-reveal-ready [data-gb-reveal].is-above-fold {
	transition-delay: var(--gb-intro-total, 0s);
}

.gb-reveal-ready [data-gb-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.gb-reveal-ready [data-gb-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* ----------------------------------------------------------------- hero --- */

/* The hero bleeds the full width, so it sits outside .gb-shell and cancels the
   gap the title band leaves behind it. */
.gb-pjs-hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 46vh;
	/* The title band carries no bottom margin of its own, so the gap under it
	   is this padding. */
	padding: 40px 0 90px;
	overflow: hidden;
	border-bottom: 1px solid var(--gb-line);
}

/* Holds the oversized mark. Inset at the top so the mark never climbs into
   the title band, and clipped by the hero above. */
.gb-pjs-hero__ground {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/* Accent wash behind the mark, anchored to the same corner it bleeds from. */
.gb-pjs-hero__ground::before {
	content: '';
	position: absolute;
	inset: 0;
	background: radial-gradient(
		ellipse 70% 90% at 78% 55%,
		color-mix(in srgb, var(--gb-accent) 15%, transparent) 0%,
		transparent 70%
	);
}

/* Both grounds are pushed past the right edge and scaled off the viewport, so
   the shape is always cut by the page rather than sitting inside it. The mask
   dissolves them before they reach the copy. */
.gb-pjs-hero__mark,
.gb-pjs-hero__word {
	position: absolute;
	top: 50%;
	right: -8vw;
	transform: translateY(-50%);
	opacity: 0.16;
	-webkit-mask-image: linear-gradient(to left, #000 30%, transparent 92%);
	mask-image: linear-gradient(to left, #000 30%, transparent 92%);
	animation: gb-hero-ground var(--gb-hero-in, 1.6s) cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: var(--gb-intro-total, 0s);
}

.gb-pjs-hero__mark {
	width: clamp(520px, 62vw, 1020px);
	max-width: none;
	height: auto;
}

/* SnapCut's wordmark is thin line work, so it needs more presence than a solid logo. */
.gb-pjs-hero--snapcut .gb-pjs-hero__mark {
	width: clamp(640px, 78vw, 1300px);
	opacity: 0.4;
	animation-name: gb-hero-ground-strong;
}

@keyframes gb-hero-ground-strong {
	from {
		opacity: 0;
		transform: translateY(-50%) scale(1.12);
	}

	to {
		opacity: 0.4;
		transform: translateY(-50%) scale(1);
	}
}

.gb-pjs-hero__word {
	font-family: 'VilnaPlate', serif;
	font-size: clamp(260px, 38vw, 620px);
	line-height: 0.8;
	color: var(--gb-ink);
	white-space: nowrap;
	text-transform: none;
	letter-spacing: normal;
}

@keyframes gb-hero-ground {
	from {
		opacity: 0;
		transform: translateY(-50%) scale(1.12);
	}

	to {
		opacity: 0.16;
		transform: translateY(-50%) scale(1);
	}
}

/* --------------------------------------------------------- hero copy --- */

.gb-pjs-hero__inner {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 1400px;
	margin: 0 auto;
	padding: 0 var(--gb-edge);
}

.gb-pjs-hero__inner > * {
	animation: gb-hero-copy 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Each line follows the one above it, starting after the title band lands. */
.gb-pjs-hero__inner .gb-eyebrow {
	animation-delay: calc(var(--gb-intro-total, 0s) + 0.05s);
}

.gb-pjs-hero__tagline {
	/* Two or three lines at most: the title band above is already carrying
	   the name, so this is a subtitle, not the headline. */
	max-width: 19ch;
	margin: 16px 0 0;
	color: var(--gb-ink);
	font-family: var(--gb-font-head);
	font-weight: 700;
	font-size: clamp(28px, 3.2vw, 46px);
	line-height: 1.15;
	letter-spacing: -0.01em;
	animation-delay: calc(var(--gb-intro-total, 0s) + 0.15s);
}

.gb-pjs-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	margin-top: 44px;
	animation-delay: calc(var(--gb-intro-total, 0s) + 0.25s);
}

.gb-pjs-hero__actions .gb-btn {
	margin-top: 0;
}

/* The first link is the one to take; the rest are secondary. */
.gb-btn--primary {
	border-color: color-mix(in srgb, var(--gb-accent) 60%, transparent);
	background: color-mix(in srgb, var(--gb-accent) 12%, transparent);
}

.gb-btn--primary:hover {
	border-color: var(--gb-accent);
	background: color-mix(in srgb, var(--gb-accent) 22%, transparent);
}

@keyframes gb-hero-copy {
	from {
		opacity: 0;
		transform: translateY(22px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.gb-pjs-hero__mark,
	.gb-pjs-hero__word,
	.gb-pjs-hero__inner > * {
		animation: none;
	}
}

/* The shell no longer opens the page, so it does not need the title band's
   clearance on top. */
body.gb-project-single .gb-shell {
	padding-top: 90px;
}

/* ----------------------------------------------------------------- main --- */

.gb-pjs-main {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 260px;
	gap: 80px;
	align-items: start;
}

.gb-pjs-body {
	max-width: 760px;
	font-size: 16px;
	line-height: 30px;
	/* Fades in on load right after the hero copy, wherever it sits on screen. */
	animation: gb-hero-copy 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
	animation-delay: calc(var(--gb-intro-total, 0s) + 0.4s);
}

@media (prefers-reduced-motion: reduce) {
	.gb-pjs-body {
		animation: none;
	}
}

.gb-pjs-body code {
	font-family: 'Roboto Condensed', monospace;
	font-size: 15px;
	color: var(--gb-ink);
	background: rgba(255, 255, 255, 0.06);
	padding: 2px 6px;
}

.gb-pjs-body em {
	color: var(--gb-ink);
	font-style: italic;
}

/* Rides down the reading column rather than sitting in a block of its own. */
.gb-pjs-meta {
	position: sticky;
	top: calc(var(--gb-header-h) + 20px);
}

.gb-pjs-meta ul {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--gb-line);
}

.gb-pjs-meta li {
	padding: 18px 0;
	border-bottom: 1px solid var(--gb-line);
}

.gb-pjs-meta__value {
	display: block;
	color: var(--gb-ink);
	font-size: 14px;
	line-height: 22px;
}

/* ----------------------------------------------------- section headings --- */

.gb-pjs-h {
	margin: 0 0 40px;
	font-size: 28px;
	line-height: 34px;
	letter-spacing: 0.02em;
}

.gb-pjs-h::after {
	content: '';
	display: block;
	width: 48px;
	height: 2px;
	margin-top: 18px;
	background: var(--gb-accent);
}

/* ---------------------------------------------------------------- video --- */

.gb-pjs-video {
	margin-top: 110px;
}

.gb-pjs-video__frame {
	border: 1px solid var(--gb-line);
	background: #000;
}

/* Video.js 10 player, in its default skin. */
.gb-pjs-video__skin {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
}

/* ----------------------------------------------------------- highlights --- */

.gb-pjs-highlights {
	margin-top: 110px;
}

.gb-pjs-highlights__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	margin: 0;
	padding: 0;
	list-style: none;
	/* Ruled like a table rather than gapped like tiles: the container draws
	   the top and left, each cell draws its own right and bottom. An item
	   count that doesn't fill the last row then just ends, instead of leaving
	   empty bordered cells behind — which a 1px gap over a background would. */
	border-top: 1px solid var(--gb-line);
	border-left: 1px solid var(--gb-line);
}

.gb-pjs-highlights__list li {
	padding: 34px 36px 38px;
	border-right: 1px solid var(--gb-line);
	border-bottom: 1px solid var(--gb-line);
	transition: background 0.4s ease;
}

.gb-pjs-highlights__list li:hover {
	background: rgba(40, 40, 46, 0.7);
}

.gb-pjs-highlights__list h4 {
	margin: 0 0 12px;
	font-size: 17px;
	line-height: 24px;
	letter-spacing: 0.04em;
}

.gb-pjs-highlights__list p {
	margin: 0;
	font-size: 14px;
	line-height: 26px;
	color: var(--gb-muted);
}

.gb-pjs-highlights__list code {
	font-family: 'Roboto Condensed', monospace;
	color: var(--gb-ink);
}

/* Extra sections: a project's own grids after the highlights (e.g. plugins). */
.gb-pjs-extra__lead {
	max-width: 760px;
	margin: -8px 0 40px;
	font-size: 16px;
	line-height: 30px;
}

.gb-pjs-extra__tag {
	display: inline-block;
	margin-bottom: 10px;
	color: var(--gb-muted);
}

.gb-pjs-extra__tag.is-live {
	color: var(--gb-accent);
}

/* -------------------------------------------------------- typeface block --- */

.gb-pjs-face {
	margin-top: 110px;
}

.gb-specimen {
	padding: 70px 50px;
	border: 1px solid var(--gb-line);
	background:
		radial-gradient(
			ellipse at 50% 0%,
			color-mix(in srgb, var(--gb-accent) 12%, transparent) 0%,
			transparent 70%
		),
		var(--gb-black);
	text-align: center;
	color: var(--gb-ink);
	font-family: 'VilnaPlate', serif;
	/* The face is unicased and Hebrew; none of the site's uppercase or
	   letter-spacing rules should reach it. */
	text-transform: none;
	letter-spacing: normal;
}

.gb-specimen p {
	margin: 0;
}

.gb-specimen__alphabet {
	font-size: 64px;
	line-height: 1.5;
	word-spacing: 0.12em;
}

.gb-specimen__line {
	margin-top: 40px !important;
	font-size: 34px;
	line-height: 1.7;
}

.gb-specimen__small {
	margin-top: 22px !important;
	font-size: 20px;
	line-height: 1.9;
	color: var(--gb-muted);
}

/* ------------------------------------------------------------- download --- */

.gb-face-dl {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 50px;
	margin-top: 1px;
	padding: 40px 50px;
	border: 1px solid var(--gb-line);
	border-top: 0;
	background: rgba(40, 40, 46, 0.35);
}

.gb-face-dl__copy {
	max-width: 620px;
}

.gb-face-dl__copy p {
	margin: 10px 0 0;
	font-size: 15px;
	line-height: 28px;
}

.gb-face-dl__formats {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 18px 0 0;
	padding: 0;
	list-style: none;
}

.gb-face-dl__formats li {
	padding: 5px 12px;
	border: 1px solid var(--gb-line);
	color: var(--gb-label);
	font-family: var(--gb-font-label);
	font-weight: 700;
	font-size: 11px;
	letter-spacing: 0.1em;
}

.gb-face-dl__licence {
	margin: 18px 0 0;
	font-size: 13px;
	line-height: 24px;
	color: var(--gb-label);
}

.gb-face-dl__licence a {
	color: var(--gb-ink);
	border-bottom: 1px solid var(--gb-line);
}

.gb-face-dl__licence a:hover {
	border-bottom-color: var(--gb-accent);
}

/* The terms sit under the licence name rather than beside it — a sentence on
   the same line reads as part of the link. */
.gb-face-dl__licence span {
	display: block;
	margin-top: 4px;
}

.gb-btn--dl {
	flex: 0 0 auto;
	margin-top: 0;
	border-color: color-mix(in srgb, var(--gb-accent) 50%, transparent);
	text-align: center;
}

.gb-btn--dl:hover {
	border-color: var(--gb-accent);
	background: color-mix(in srgb, var(--gb-accent) 14%, transparent);
}

.gb-btn__meta {
	display: block;
	margin-top: 6px;
	color: var(--gb-label);
	font-size: 10px;
	letter-spacing: 0.12em;
}

.gb-face-dl__missing {
	flex: 0 0 auto;
	margin: 0;
	color: var(--gb-label);
	font-size: 13px;
}

/* ------------------------------------------------------------------ nav --- */

.gb-pjs-nav {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 40px;
	margin-top: 120px;
	padding-top: 50px;
	border-top: 1px solid var(--gb-line);
}

.gb-pjs-nav__link .gb-headline {
	display: block;
	font-size: 34px;
	line-height: 42px;
	transition: color 0.3s ease;
}

.gb-pjs-nav__link:hover .gb-headline {
	color: var(--gb-accent);
}

.gb-pjs-nav__all {
	flex: 0 0 auto;
	color: var(--gb-label);
	font-family: var(--gb-font-label);
	font-weight: 700;
	font-size: 12px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.gb-pjs-nav__all:hover {
	color: var(--gb-ink);
}

/* ----------------------------------------------------------- responsive --- */

@media (max-width: 1100px) {
	.gb-pjs-main {
		grid-template-columns: 1fr;
		gap: 50px;
	}

	.gb-pjs-meta {
		position: static;
	}

	.gb-pjs-meta ul {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
		gap: 0 40px;
	}
}

@media (max-width: 900px) {
	.gb-pjs-hero {
		min-height: 0;
		padding: 60px 0 70px;
	}

	/* Narrower column, so the tagline is not fighting the mark for the same
	   space the way it can on a wide screen. */
	.gb-pjs-hero__tagline {
		max-width: 100%;
	}

	.gb-pjs-hero__actions {
		margin-top: 32px;
	}

	/* The mark drops behind the copy on a phone, so it has to sit back far
	   enough to read as texture. */
	.gb-pjs-hero__mark,
	.gb-pjs-hero__word {
		right: -22vw;
		opacity: 0.09;
		-webkit-mask-image: none;
		mask-image: none;
	}

	@keyframes gb-hero-ground {
		from {
			opacity: 0;
			transform: translateY(-50%) scale(1.12);
		}

		to {
			opacity: 0.09;
			transform: translateY(-50%) scale(1);
		}
	}

	body.gb-project-single .gb-shell {
		padding-top: 60px;
	}

	.gb-face-dl {
		flex-direction: column;
		align-items: flex-start;
		gap: 28px;
		padding: 32px;
	}

	.gb-pjs-nav {
		flex-direction: column;
		align-items: flex-start;
		gap: 24px;
	}
}

@media (max-width: 600px) {
	.gb-pjs-highlights,
	.gb-pjs-face {
		margin-top: 70px;
	}

	.gb-specimen {
		padding: 44px 24px;
	}

	.gb-specimen__alphabet {
		font-size: 40px;
	}

	.gb-specimen__line {
		font-size: 24px;
	}

	.gb-specimen__small {
		font-size: 16px;
	}

	.gb-pjs-highlights__list li {
		padding: 26px 24px 30px;
	}

	.gb-pjs-nav__link .gb-headline {
		font-size: 26px;
		line-height: 32px;
	}
}
