/* Case study pages. Builds on the tokens in main.css.
   Layout: header, intro and cover on the home margins (--gutter); the
   sticky index + text column below are centered as one reading block. */

:root {
	--case-index: 260px;
	--case-gap: var(--space-3xl);
	/* Text column measured in characters, so the line length stays the
	   same whatever the text size: 52ch of Aeonik ≈ 66 characters per line
	   (60–75 is the comfortable range). Wherever it's used (column, intro
	   on tablets, index bar alignment) it resolves on the body text size */
	--case-measure: 52ch;
	--case-width: calc(var(--case-index) + var(--case-gap) + var(--case-measure));
}

/* Same page margins as the home */
.container {
	margin: 0 var(--gutter);
}

/* Breadcrumb, inside the home header bar */
.bread {
	display: flex;
	gap: var(--space-xs);
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--color-text-muted);
	/* Navigation style, same as the home menu and the index */
	font-size: var(--text-small);
	letter-spacing: var(--tracking-caps-s);
	text-transform: uppercase;
}
.bread li + li::before {
	content: "/";
	margin-right: var(--space-xs);
}
.bread a {
	/* Block box so the underline padding counts, like the home menu links:
	   keeps the header the same height on both pages */
	display: inline-block;
	color: var(--color-text);
	text-decoration: none;
}

/* Intro statement, like the home hero */
#T-flex {
	padding: var(--space-l) 0 var(--space-3xl);
}
/* Number + category above the statement, as on the home cards. Width and
   alignment are set on the wrapper, so the two always share the left edge.
   Same width as the home hero statement: left half minus its 32px padding */
.case-intro {
	max-width: calc(50% - var(--space-m));
}
/* No color square here: on this page the square marks the current section
   in the index, so it would read as a second "you are here" */
.case-intro .project__category::before {
	content: none;
}
.TitleProject {
	margin: 0;
	font-size: var(--text-headline);
	font-weight: normal;
	line-height: 1.15;
	letter-spacing: var(--tracking-tight);
}
/* Inline link in running text: always underlined, thicker on hover/focus */
.link {
	color: inherit;
	text-decoration-thickness: 1px;
	text-underline-offset: 6px;
	transition: text-decoration-thickness var(--underline);
}
.link:hover,
.link:focus-visible {
	text-decoration-thickness: 2px;
}

/* Intro entrance on load, staggered like the home hero (header stays still) */
.case-intro,
.ProjectImage {
	animation: rise var(--duration-l) var(--ease-out) both;
}
.ProjectImage {
	animation-delay: 0.15s;
}

/* Cover inside the page margins, like the home covers */
.ProjectImage {
	display: block;
	width: calc(100% - 2 * var(--gutter));
	height: auto;
	margin: 0 auto;
}

/* Index | text, centered as one block so the side space is equal */
.row > .case-layout {
	display: grid;
	grid-template-columns: var(--case-index) minmax(0, var(--case-measure));
	column-gap: var(--case-gap);
	max-width: var(--case-width);
	margin: 0 auto;
	padding-top: var(--space-3xl);
}
.case-layout > .Block {
	grid-column: 2;
}

.case-toc {
	grid-column: 1;
	grid-row: 1 / span 20;
	align-self: start;
	position: sticky;
	top: var(--space-l);
}
/* Mobile-only toggle, hidden on desktop where the full list is visible */
.case-toc__toggle {
	display: none;
}
.case-toc ul {
	margin: 0;
	padding: 0;
	list-style: none;
	border-bottom: var(--line);
}
.case-toc li {
	border-top: var(--line);
}
.case-toc a {
	display: flex;
	align-items: baseline;
	gap: var(--space-xs);
	padding: calc(var(--space-xs) + 2px) 0;
	color: var(--color-text-muted);
	/* Same size as the section headings it points to; muted until current */
	font-size: var(--text-small);
	letter-spacing: var(--tracking-caps-s);
	text-transform: uppercase;
	text-decoration: none;
	transition: color var(--transition);
}
/* Current section: project-color square, like the home cards */
.case-toc a::before {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	background: var(--project-color);
	/* Baseline-aligned, then lifted by half the cap height minus half its
	   own size: centred on the capitals (first line if an entry wraps) */
	translate: 0 calc(4px - 0.5cap);
	opacity: 0;
	transition: opacity var(--transition);
}
.case-toc a:hover,
.case-toc a[aria-current="true"] {
	color: var(--color-text);
}
.case-toc a[aria-current="true"]::before {
	opacity: 1;
}

/* Content */
.Block {
	margin-bottom: var(--space-2xl);
}
.case-layout > .Block:last-child {
	margin-bottom: 0;
}
/* The last section of a chapter adds no extra space, so the bridge
   sentence sits exactly halfway between two chapters */
.Block > :last-child {
	margin-bottom: 0;
}
/* Bridge sentence between chapters: a transition, not a heading.
   Smaller than the intro, in the muted tone, so the sections lead */
.TitlePa {
	margin: 0 0 var(--space-2xl);
	color: var(--color-text-muted);
	font-size: var(--text-bridge);
	font-weight: normal;
	line-height: 1.35;
}
.SBlock,
.LastSBlock {
	margin-bottom: var(--space-xl);
	scroll-margin-top: var(--space-l);
}
/* Section heading: styled by .heading-s, only the spacing is local */
.TitleSPa {
	margin: 0 0 var(--space-s);
}
.Pa {
	margin: 0;
	line-height: 1.65;
}
/* Images that accompany paragraphs: same width as the text */
.Pa img,
.LastSBlock > img {
	display: block;
	width: 100%;
	height: auto;
	margin-top: var(--space-m);
}

/* Footer: next project preview (same row pattern as the home cards) + back home */
.case-footer {
	margin-top: var(--space-3xl);
}
.case-next {
	display: grid;
	grid-template-columns: 1fr 1fr;
	border-top: var(--line);
}
.case-next__text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-s);
	padding: var(--space-l) var(--space-m) var(--space-l) 0;
	border-right: var(--line);
}
.case-next__text .heading-s {
	margin-bottom: var(--space-m);
}
/* Same index → title distance as the home cards (16 here + 16 flex gap) */
.case-next__text .project__head {
	margin: 0 0 var(--space-s);
}
.case-next__title {
	font-size: var(--text-title);
	line-height: 1.15;
}
.case-next__description {
	max-width: 44ch;
	color: var(--color-text-muted);
}
.case-next__media {
	display: block;
	/* Side by side, the 16:9 cover sits centred on the height of the
	   text column, which is often the taller one */
	align-self: center;
	margin: var(--space-m) 0 var(--space-m) var(--space-m);
	overflow: hidden;
	aspect-ratio: 16 / 9;
}
.case-next__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	margin: 0;
	transition: transform var(--duration-l) var(--ease-out);
	/* Own layer from the start, as on the home covers (avoids a one-frame
	   blank of the button when the zoom begins) */
	will-change: transform;
}
/* Only the button is a link, as in the home cards: it also zooms the cover */
.case-next__cta {
	margin-top: var(--space-s);
}
.case-next:has(.case-next__cta:hover, .case-next__cta:focus-visible)
	.case-next__media img {
	transform: scale(1.04);
}
@media (prefers-reduced-motion: reduce) {
	.case-next__media img {
		transition: none;
	}
}

/* Phones (and phones in landscape up to 939px, too short for a sticky
   index beside the text): single column; the index becomes a sticky bar
   showing the current section, which expands into the full list. Index
   and text sit side by side on tablets (compact index below 940px, rule
   further down) and from 940px as on desktop: 260px index + gap + 52ch
   text fit from ~935px */
@media (max-width: 767px), (max-width: 939px) and (max-height: 500px) {
	.row > .case-layout {
		grid-template-columns: minmax(0, 1fr);
	}
	.case-layout > .Block {
		grid-column: 1;
		max-width: var(--case-measure);
	}
	.case-toc {
		grid-column: 1;
		grid-row: auto;
		top: 0;
		z-index: 5;
		margin: 0 calc(-1 * var(--gutter)) var(--space-l);
		padding: 0 var(--gutter);
		background: var(--color-bg);
		border-bottom: var(--line);
	}
	.case-toc__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-s);
		width: 100%;
		padding: var(--space-s) 0;
		border: 0;
		background: none;
		color: var(--color-text);
		font: inherit;
		font-size: var(--text-small);
		letter-spacing: var(--tracking-caps-s);
		text-align: left;
		text-transform: uppercase;
		cursor: pointer;
	}
	/* Current-section square, same as the desktop index */
	.case-toc__current::before {
		content: "";
		display: inline-block;
		width: 8px;
		height: 8px;
		margin-right: var(--space-xs);
		background: var(--project-color);
		/* Centred on the capitals, as in the list */
		translate: 0 calc(4px - 0.5cap);
	}
	/* Chevron */
	.case-toc__toggle::after {
		content: "";
		flex: none;
		width: 7px;
		height: 7px;
		margin-top: -4px;
		border-right: 1px solid currentColor;
		border-bottom: 1px solid currentColor;
		rotate: 45deg;
		transition:
			rotate var(--transition),
			margin var(--transition);
	}
	.case-toc__toggle[aria-expanded="true"]::after {
		margin-top: 4px;
		rotate: -135deg;
	}
	/* Touch targets */
	.case-toc__toggle,
	.case-toc a {
		min-height: var(--tap-target);
	}
	/* Entries keep the baseline alignment (square on the capitals); with
	   a set line height, the padding centres one line in the tap target */
	.case-toc a {
		line-height: 1.2;
		padding-block: calc((var(--tap-target) - 1.2em) / 2);
	}
	/* The open list overlays the content under the bar instead of pushing
	   the page down, so jumping to a section doesn't shift the layout */
	.case-toc ul {
		display: none;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		max-height: calc(100svh - 100px);
		overflow-y: auto;
		padding: 0 var(--gutter) var(--space-s);
		background: var(--color-bg);
		border-bottom: var(--line);
	}
	.case-toc.is-open ul {
		display: block;
	}
	/* Closed: the bar shows the current section. Open: it becomes the
	   "Index" title and the full list below shows the current entry */
	.case-toc__title {
		display: none;
	}
	.case-toc.is-open .case-toc__title {
		display: inline;
	}
	.case-toc.is-open .case-toc__current,
	.case-toc.is-open .case-toc__toggle .visually-hidden {
		display: none;
	}
}
/* Tablets (768–1099px): the intro is as wide as the text column (half
   the page, as on desktop, would add lines to the h1) */
@media (min-width: 768px) and (max-width: 1099px) {
	.case-intro {
		max-width: var(--case-measure);
	}
}
/* Phones in landscape 768–939px (single column with the index bar): the
   text column is centered; the intro stays on the page margin, like
   breadcrumb and cover; the bar's content is aligned to the text */
@media (min-width: 768px) and (max-width: 939px) and (max-height: 500px) {
	.case-layout > .Block {
		margin-inline: auto;
	}
	/* Bar: % = layout width (the bar bleeds by --gutter on both sides) */
	.case-toc {
		padding-inline: calc(var(--gutter) + (100% - var(--case-measure)) / 2);
	}
	/* Open list: % = full bar width, which already includes the gutters */
	.case-toc ul {
		padding-inline: calc((100% - var(--case-measure)) / 2);
	}
}
/* Portrait tablets (768–939px): compact index beside the text, the two
   columns spanning the full width, aligned with the cover's edges. The
   index takes the spare room (at least 180px); the text keeps its 52ch
   reading measure (~61 characters per line at 768px, 66 from 820px) */
@media (min-width: 768px) and (max-width: 939px) and (min-height: 501px) {
	:root {
		--case-index: 180px;
		--case-gap: var(--space-2xl);
	}
	.row > .case-layout {
		grid-template-columns: minmax(var(--case-index), 1fr) minmax(0, var(--case-measure));
		max-width: none;
	}
}
/* Touch screens with the side index (tablets, touch laptops): entries
   get the tap-target height, one line centred, as in the mobile bar */
@media (pointer: coarse) and (min-width: 768px) and (min-height: 501px) {
	.case-toc a {
		min-height: var(--tap-target);
		line-height: 1.2;
		padding-block: calc((var(--tap-target) - 1.2em) / 2);
	}
}
/* Next project: text first, then the full-width 16:9 cover, up to 939px.
   Side by side from 940px, like index and text, and on phones in
   landscape from 700px (rule further down) */
@media (max-width: 939px) {
	.case-next {
		display: flex;
		flex-direction: column;
	}
	.case-next__text {
		padding: var(--space-m) 0 0;
		border-right: 0;
	}
	.case-next__media {
		align-self: stretch;
		margin: var(--space-m) 0 var(--space-l);
	}
}
@media (max-width: 767px) {
	/* Single column, like the home hero on mobile */
	.case-intro {
		max-width: none;
	}
	#T-flex {
		padding-bottom: var(--space-l);
	}
	.row > .case-layout {
		padding-top: var(--space-l);
	}
}

/* Phones in landscape from 700px: two columns, as the home cards there
   (after the stacking rules above, which would otherwise apply); the
   16:9 cover is centred on the text's height, as on desktop */
@media (max-height: 500px) and (min-width: 700px) and (orientation: landscape) {
	.case-next {
		display: grid;
	}
	.case-next__text {
		padding: var(--space-m) var(--space-m) var(--space-m) 0;
		border-right: var(--line);
	}
	.case-next__media {
		align-self: center;
		margin: var(--space-m) 0 var(--space-m) var(--space-m);
	}
}

/* Images in the text open full screen, on screens with a mouse only (the
   buttons are added by case-study.js). Hovering with intent shows a dark
   circle that follows the pointer, with "Click to expand" inside */
@media (hover: hover) and (pointer: fine) and (min-width: 940px) {
	.case-zoom {
		display: block;
		width: 100%;
		margin-top: var(--space-m);
		padding: 0;
		border: 0;
		background: none;
		/* Normal arrow until the circle shows, then the circle replaces it */
		cursor: default;
	}
	.case-zoom.is-zooming {
		cursor: none;
	}
	.case-zoom img {
		display: block;
		width: 100%;
		height: auto;
		margin-top: 0;
	}
	.zoom-cue {
		position: fixed;
		top: 0;
		left: 0;
		z-index: 20;
		pointer-events: none;
		opacity: 0;
		transition: opacity var(--duration-s) var(--ease-out);
		/* Moves on its own compositor layer, ready before it shows */
		will-change: translate;
	}
	.zoom-cue.is-on {
		opacity: 1;
	}
	/* Slate disc at 85%: the image shows through faintly, no blur (cheap
	   to draw while it moves); white text well above 4.5:1 over any image */
	.zoom-cue__circle {
		display: grid;
		place-items: center;
		width: 88px;
		height: 88px;
		margin: -44px 0 0 -44px;
		border-radius: 50%;
		background: color-mix(in srgb, var(--color-text) 85%, transparent);
		/* Entrance: grows from a dot (~10px) into the full circle */
		scale: 0.11;
		transition: scale var(--duration-s) var(--ease-out);
	}
	.zoom-cue.is-on .zoom-cue__circle {
		scale: 1;
		transition-duration: var(--duration-m);
	}
	.zoom-cue__label {
		max-width: 92px;
		color: var(--color-bg);
		font-size: var(--text-label);
		letter-spacing: var(--tracking-caps);
		line-height: 1.2;
		text-align: center;
		text-transform: uppercase;
		/* Fades in once the circle has almost formed */
		opacity: 0;
		transition: opacity var(--duration-s) var(--ease-out);
	}
	.zoom-cue.is-on .zoom-cue__label {
		opacity: 1;
		transition-delay: 0.15s;
	}
}

/* Full-screen image on the white page, whole and uncropped */
.lightbox {
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	margin: 0;
	padding: var(--space-l) var(--gutter);
	border: 0;
	background: var(--color-bg);
	cursor: zoom-out;
}
.lightbox[open] {
	display: flex;
	animation: lightbox-in var(--duration-m) var(--ease-out);
}
.lightbox::backdrop {
	background: none;
}
.lightbox__image {
	width: 100%;
	height: 100%;
	object-fit: contain;
}
/* Close: an X drawn with two 1px lines, like the index chevron, set off
   from the corner (a page margin from the right, 16px from the top) */
.lightbox__close {
	position: absolute;
	top: var(--space-s);
	right: var(--gutter);
	width: var(--tap-target);
	height: var(--tap-target);
	padding: 0;
	border: 0;
	background: none;
	color: var(--color-text);
	cursor: pointer;
}
.lightbox__close::before,
.lightbox__close::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 12px;
	width: 20px;
	border-top: 1px solid currentColor;
	rotate: 45deg;
}
.lightbox__close::after {
	rotate: -45deg;
}
/* The page behind doesn't scroll while the image is open */
html:has(.lightbox[open]) {
	overflow: hidden;
}
@keyframes lightbox-in {
	from {
		opacity: 0;
	}
}
