/*
 * FRENKEL — content-sections body (project / press / watch_read).
 */

.cf-section {
	padding-block: 20px;
	/* Offset anchor jumps by the sticky header height. */
	scroll-margin-block-start: calc(var(--cf-header-h) + 1rem);
	position: relative;
	z-index: 1;
}
.cf-section:focus {
	outline: none; /* programmatic focus target, not a visual control */
}
/* The External Article Link section carries its spacing on the row itself
   (Padding top / Padding bottom, 2rem each by default), so the generic section
   padding steps aside — otherwise "2rem" would render as 2rem + 20px. Equal
   specificity to .cf-section above, won on source order. */
.cf-section--press_link { padding-block: 0; }

/* --- Section marker (default) ---
   Everywhere except portfolio: a plain heading at the start of the line, no
   number. Printed by frenkel_render_section_marker(). */
.cf-section__marker {
	margin-block-end: var(--cf-marker-gap);
}
.cf-section__marker > * { margin: 0; }
.cf-section__num { display: none; } /* number is portfolio-only */
.cf-section__label {
	font-family: var(--cf-font-display);
	font-weight: 400;
	line-height: 1.1;
	color: var(--cf-dark);
	font-size: var(--cf-h3);
}

/* --- Section marker (portfolio: "01 / ENTRANCE") ---
   Sits in the index column so markers line up under the TOC entries above. */
.cf-project .cf-section__marker {
	position: relative;
	display: grid;
	grid-template-columns: var(--cf-index-col) minmax(0, 1fr);
	align-items: baseline;
	column-gap: var(--cf-gap);
	padding-block: 24px;
	margin-block-end: 0;
}
.cf-project .cf-section__marker > * {
	grid-column: 2;
}
.cf-project .cf-section__num { display: block; }
.cf-project .cf-section__num,
.cf-project .cf-section__label {
	font-family: var(--cf-font-latin);
	font-size: 20px;
	font-weight: 400;
	line-height: 1.2;
	letter-spacing: .08em;
	text-transform: uppercase;
}
.cf-project .cf-section__num {
	font-variant-numeric: tabular-nums;
}

.cf-toc__eyebrow,
.cf-toc__link {
	font-family: var(--cf-font-latin);
	font-size: 20px;
	font-weight: 400;
	line-height: 1.2;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--cf-dark);
}

/* --- Table of contents --- */
.cf-toc {
	padding: 60px 20px;
	display: grid;
	grid-template-columns: var(--cf-index-col) minmax(0, 1fr);
	column-gap: var(--cf-gap);
}
.cf-toc__eyebrow {
	margin: 0 0 1.25rem;
}
.cf-toc__eyebrow--start { grid-column: 1; }
.cf-toc__eyebrow--end   { grid-column: 2; }
.cf-toc__rule {
	grid-column: 1 / -1;
	block-size: 1px;
	background: color-mix(in srgb, var(--cf-dark) 90%, transparent);
	margin-block-end: clamp(1.5rem, 1rem + 2vw, 3rem);
}
.cf-toc__list {
	grid-column: 2;
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
}
/* Each entry sits on its own hairline rule. */
.cf-toc__item {
	border-block-end: 1px solid color-mix(in srgb, var(--cf-dark) 90%, transparent);
}
.cf-toc__link {
	display: grid;
	grid-template-columns: 3.5em minmax(0, 1fr);
	align-items: baseline;
	padding-block: 25px 5px;
	text-decoration: none;
	transition: opacity var(--cf-dur) var(--cf-ease);
}
.cf-toc__link:hover,
.cf-toc__link:focus-visible,
.cf-toc__link.is-active {
	opacity: 1;
}
.cf-toc__num {
	font-variant-numeric: tabular-nums;
	opacity: .9;
}

/* Full-bleed utility: breaks a block out of any container, edge to edge. */
.cf-fullbleed {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* --- Image --- */
.cf-image__figure { margin: 0; }

/*
 * Shape is chosen per section in ACF and arrives as a modifier class, so
 * switching a single image between landscape and portrait is an editor
 * decision rather than a CSS change — which is what the client keeps needing.
 *
 * A ratio rather than a pixel height: the box scales with the column at every
 * width, so there is no breakpoint list to keep in sync.
 */
.cf-image__figure img {
	display: block;
	width: 100%;
	height: auto;
	object-fit: cover;
	object-position: center;
}

.cf-image--landscape .cf-image__figure img { aspect-ratio: 3 / 2; }
.cf-image--portrait .cf-image__figure img { aspect-ratio: 3 / 4; }
.cf-image--square .cf-image__figure img { aspect-ratio: 1 / 1; }
/* No crop at all — the height follows the file. */
.cf-image--original .cf-image__figure img { aspect-ratio: auto; }

/*
 * Half width: exactly one column of a Two Images pair — (100% - gap) / 2, the
 * same arithmetic the pair's grid uses — centred in the container. A single
 * portrait then matches a paired one instead of towering over the page, and
 * because .cf-container is itself centred, the figure lands on the body's
 * centre rule with the grey line continuing above and below it.
 */
.cf-image--half .cf-image__figure {
	inline-size: calc((100% - var(--cf-gap, 1.5rem)) / 2);
	margin-inline: auto;
}

/* A 3:4 portrait is fine in a column, but far too tall once the image spans a
   whole phone screen. */
@media (max-width: 782px) {
	.cf-image--portrait .cf-image__figure img { aspect-ratio: 4 / 5; }
	/* Half of a phone screen is unreadably small, and the centre rule is
	   hidden at this width anyway — so the pair collapses to one column here
	   and a half-width single does the same. */
	.cf-image--half .cf-image__figure { inline-size: 100%; }
}

.cf-image__caption {
	margin-block-start: .6rem;
	font-size: var(--cf-small);
	opacity: .75;
}
.cf-image--full {
	/* Full-bleed break-out of any container. */
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}
.cf-image--full img { width: 100%; }

/* --- Two Images --- */
.cf-two-images {
	display: grid;
	/*
	 * Two equal columns with the gap taken out of the total, so the pair plus
	 * the gap between them spans exactly the width one image would.
	 */
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--cf-gap, 1.5rem);
	align-items: start;
}
/*
 * Grid items are min-width:auto by default, so a large file refuses to shrink
 * below its intrinsic width and pushes its column past half. This is what
 * makes the pair overflow instead of splitting the row evenly.
 */
.cf-two-images__figure {
	margin: 0;
	min-width: 0;
}

/*
 * A pair is always portrait — that is the fixed rule for this section, unlike a
 * single image where the shape is chosen per section. Both images share one
 * ratio, so they are always level whatever the source files are, and a ratio
 * scales with the column instead of needing a pixel height per breakpoint.
 * object-fit: cover fills the box without distorting; the overflow is cropped
 * from the edges, never squashed.
 */
.cf-two-images__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: var(--cf-two-images-ratio, 3 / 4);
	object-fit: cover;
	object-position: center;
}
.cf-two-images__caption {
	margin-block-start: .6rem;
	font-size: var(--cf-small);
	opacity: .75;
}
/*
 * Only one image in the row: hold the column width a pair would have —
 * (100% - gap) / 2, the same arithmetic as the two-column track — and centre
 * the track instead of letting the lone image sit in the left column. Matches
 * .cf-image--half, so a single portrait is the same size and position however
 * the editor arrives at it.
 */
.cf-two-images--single {
	grid-template-columns: minmax(0, calc((100% - var(--cf-gap, 1.5rem)) / 2));
	justify-content: center;
}

/* Full-bleed break-out, matching .cf-image--full exactly. Images need no
   override here — natural height is now the default in both modes. */
.cf-two-images--full {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* One image per row once the pair would be too narrow to read. Full width
   again, so the portrait crop has to relax or one image fills the screen. */
@media (max-width: 782px) {
	.cf-two-images {
		/* minmax(0, …), never a bare 1fr: a bare 1fr is minmax(auto, 1fr) and
		   a large image then refuses to shrink below its intrinsic width. */
		grid-template-columns: minmax(0, 1fr);
		--cf-two-images-ratio: 4 / 5;
	}
}

/* --- Image Grid (any number) --- */
.cf-image-grid {
	display: grid;
	/* Column count and shape are set per section as inline custom properties. */
	grid-template-columns: repeat(var(--cf-grid-cols, 3), minmax(0, 1fr));
	gap: var(--cf-gap, 1.5rem);
	align-items: start;
}
/* Same min-width:auto trap as Two Images — columns must be free to shrink. */
.cf-image-grid__figure {
	margin: 0;
	min-width: 0;
}
.cf-image-grid__link {
	display: block;
	text-decoration: none;
}
.cf-image-grid__img {
	display: block;
	width: 100%;
	height: auto;
	/* `auto` here is the "Original" shape — each file keeps its own ratio. */
	aspect-ratio: var(--cf-grid-ratio, 4 / 3);
	object-fit: cover;
	object-position: center;
}
.cf-image-grid__caption {
	margin-block-start: .6rem;
	font-size: var(--cf-small);
	opacity: .75;
}
.cf-image-grid--full {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* Halve the columns on tablets, then stack. A 2-column section already reads
   fine at tablet width, so only 3+ gets stepped down. */
@media (max-width: 1024px) {
	.cf-image-grid {
		grid-template-columns: repeat(min(var(--cf-grid-cols, 3), 3), minmax(0, 1fr));
	}
}
@media (max-width: 782px) {
	.cf-image-grid {
		grid-template-columns: repeat(min(var(--cf-grid-cols, 3), 2), minmax(0, 1fr));
	}
}
@media (max-width: 540px) {
	.cf-image-grid { grid-template-columns: minmax(0, 1fr); }
}

/* --- Gallery --- */
.cf-gallery {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(var(--cf-cols, 3), minmax(0, 1fr));
	gap: var(--cf-gap);
}
.cf-gallery__item { margin: 0; }
.cf-gallery__link { display: block; }
.cf-gallery__link img { width: 100%; }

/* --- Gallery: slider ---
   A scroll-snap track, so swipe / trackpad / keyboard work natively; the
   arrows just script that same scroll. Without JS it stays a usable
   horizontal scroller. */
.cf-slider { position: relative; }

.cf-gallery--slider {
	/* --cf-cols arrives inline from the editor; --_slides is the value actually
	   used, so the mobile override below can drop to one slide without having
	   to out-specify an inline style. */
	--_slides: var(--cf-cols, 3);

	grid-template-columns: none;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - (var(--_slides) - 1) * var(--cf-gap)) / var(--_slides));
	overflow-x: auto;
	overflow-y: hidden; /* otherwise a visible overflow-y turns into auto too */
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	overscroll-behavior-inline: contain;
	scrollbar-width: none; /* the arrows are the affordance */
}
.cf-gallery--slider::-webkit-scrollbar { display: none; }
.cf-gallery--slider > .cf-gallery__item { scroll-snap-align: start; }
/* All slides take the track's height (set by the tallest image) so the frame
   doesn't jump as you page through mixed portrait / landscape shots. */
.cf-gallery--slider .cf-gallery__link {
	block-size: 100%;
}
.cf-gallery--slider .cf-gallery__link img {
	block-size: 100%;
	object-fit: cover;
}
.cf-gallery--slider:focus-visible {
	outline: 2px solid var(--cf-dark);
	outline-offset: 4px;
}

.cf-slider__nav {
	position: absolute;
	inset-block-start: 50%;
	z-index: 2;
	display: grid;
	place-items: center;
	inline-size: 3.25rem;
	block-size: 3.25rem;
	padding: 0;
	/* Transparent disc, white hairline ring and chevrons. */
	color: #fff;
	background: transparent;
	border: 1px solid #fff;
	border-radius: 50%;
	/* Keeps the outline readable over a blown-out highlight. */
	filter: drop-shadow(0 1px 3px rgba(60, 56, 50, .35));
	cursor: pointer;
	transition:
		background var(--cf-dur) var(--cf-ease),
		color var(--cf-dur) var(--cf-ease),
		opacity var(--cf-dur) var(--cf-ease);
}
.cf-slider__nav:hover,
.cf-slider__nav:focus-visible {
	background: rgba(255, 255, 255, .18);
}
.cf-slider__nav--prev {
	inset-inline-start: 1rem;
	transform: translateY(-50%) rotate(180deg);
}
.cf-slider__nav--next {
	inset-inline-end: 1rem;
	transform: translateY(-50%);
}
/* Dimmed rather than hidden at the ends, so the control never disappears. */
.cf-slider__nav[disabled] {
	opacity: .35;
	cursor: default;
}
.cf-slider__nav[disabled]:hover {
	background: transparent;
}
.cf-icon-chevrons {
	inline-size: 1.375rem;
	block-size: 1.375rem;
	display: block;
}

/* --- Product-tagged image ---
   The plugin positions its markers in % of the image, so the image just has to
   fill the wrapper for the hotspots to stay on target at any width. */
.cf-tagged img { width: 100%; }

/* --- Video --- */
.cf-video { margin: 0; }
.cf-video__embed {
	position: relative;
	aspect-ratio: 16 / 9;
}
.cf-video__embed :is(iframe, video) {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}
.cf-video__file { width: 100%; height: auto; display: block; }

/* Poster facade: full-cover button with the chosen image + play badge. */
.cf-video__facade { cursor: pointer; }
.cf-video__play {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	overflow: hidden;
}
.cf-video__poster {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.cf-video__playicon {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	translate: -50% -50%;
	display: grid;
	place-items: center;
	inline-size: 4.5rem;
	block-size: 4.5rem;
	color: var(--cf-dark);
	background: color-mix(in srgb, var(--cf-cream) 88%, transparent);
	border-radius: 50%;
	transition: background var(--cf-dur) var(--cf-ease), scale var(--cf-dur) var(--cf-ease);
}
.cf-video__facade:hover .cf-video__playicon,
.cf-video__play:focus-visible .cf-video__playicon {
	background: var(--cf-cream);
	scale: 1.06;
}
.cf-video__playicon svg {
	inline-size: 1.75rem;
	block-size: 1.75rem;
	margin-inline-start: .15rem; /* optically centre the triangle */
}
.cf-video__caption {
	margin-block-start: .6rem;
	font-size: var(--cf-small);
	opacity: .75;
}

/* --- Quote --- */
.cf-quote {
	margin: 0;
	text-align: center;
	max-width: 46ch;
	margin-inline: auto;
}
.cf-quote__text {
	font-family: var(--cf-font-display);
	font-size: var(--cf-h3);
	line-height: 1.3;
}
.cf-quote__cite {
	display: block;
	margin-block-start: 1rem;
	font-size: var(--cf-small);
	font-style: normal;
	letter-spacing: .12em;
	text-transform: uppercase;
	opacity: .7;
}

/* --- Two columns --- */
.cf-twocol {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--cf-gap);
	align-items: start;
}

/* --- Responsive --- */
@media (max-width: 782px) {
	.cf-toc,
	.cf-section__marker { grid-template-columns: 1fr; }
	.cf-toc__eyebrow--start { display: none; }
	.cf-toc__eyebrow--end,
	.cf-toc__list,
	.cf-section__marker > * { grid-column: 1; }
	/* The slider keeps its own auto-column track — re-declaring
	   grid-template-columns here would break it. */
	.cf-gallery:not(.cf-gallery--slider) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.cf-gallery--slider { --_slides: 1; }
	.cf-twocol { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
	.cf-gallery:not(.cf-gallery--slider) { grid-template-columns: 1fr; }
}

/* ===== Per-post design overrides (Design meta box, inc/design-controls.php) =====
   The custom properties are set on the <article>, and the sections render
   inside it, so they cascade down here. Fallbacks repeat the values declared
   earlier in this file, so nothing moves until an override is set.
   .cf-project .cf-section__label is more specific and keeps winning on
   portfolio, which has no Design box. */
.cf-section__label {
	/* These two fallbacks said var(--cf-font-he-body) and 700, which is not what
	   the base rule near the top of this file declares — and since this rule wins
	   on source order at equal specificity, it silently restyled every section
	   heading to Heebo 700. That also left the Design row with nowhere to move:
	   setting it to Heebo, or to Bold 700, changed nothing, while size and colour
	   responded normally. They now repeat the base rule, as the note above has
	   always claimed they did. */
	font-family: var(--cf-heading-font, var(--cf-font-display));
	font-size: var(--cf-heading-size, var(--cf-h3));
	font-weight: var(--cf-heading-weight, 400);
	line-height: var(--cf-heading-lh, 1.1);
	color: var(--cf-heading-color, var(--cf-dark));
}

.cf-image__caption,
.cf-two-images__caption,
.cf-image-grid__caption,
.cf-video__caption {
	font-family: var(--cf-caption-font, var(--cf-font-he-body));
	font-size: var(--cf-caption-size, var(--cf-small));
	font-weight: var(--cf-caption-weight, 400);
	line-height: var(--cf-caption-lh, inherit);
	color: var(--cf-caption-color, inherit);
}

/* --- Section body text: the rich text of the Text and Two Columns sections ---
   Both wrappers carry .cf-richtext, so one selector covers them. Scoped to
   .cf-sections so it beats `.cf-text p` in content.css (which loads later)
   without !important, and so portfolio body text is not dragged along by a
   press item's settings. */
.cf-sections .cf-richtext, .cf-sections .cf-richtext em , .cf-sections .cf-richtext p {
	font-family: var(--cf-bodytext-font, inherit)!important;
	font-size: var(--cf-bodytext-size, inherit);
	font-weight: var(--cf-bodytext-weight, inherit);
	line-height: var(--cf-bodytext-lh, inherit);
	color: var(--cf-bodytext-color, inherit);
}
/* .cf-text p carries its own size and line height in content.css, so it has to
   read the same two properties — otherwise an override would reach every rich
   text block except the Text section's. Fallbacks repeat what it already had. */
.cf-sections .cf-text p {
	font-size: var(--cf-bodytext-size, 18px);
	line-height: var(--cf-bodytext-lh, 1.4);
}

/* --- Quote section: the quote itself and its attribution --- */
.cf-sections .cf-quote__text {
	font-family: var(--cf-quote-font, var(--cf-font-display));
	font-size: var(--cf-quote-size, var(--cf-h3));
	font-weight: var(--cf-quote-weight, inherit);
	line-height: var(--cf-quote-lh, 1.3);
	color: var(--cf-quote-color, inherit);
}
.cf-sections .cf-quote__cite {
	font-family: var(--cf-quotecite-font, inherit);
	font-size: var(--cf-quotecite-size, var(--cf-small));
	font-weight: var(--cf-quotecite-weight, inherit);
	line-height: var(--cf-quotecite-lh, inherit);
	/* Muted by its colour rather than by the opacity: .7 declared earlier, so a
	   colour chosen in the Design box renders at full strength instead of being
	   faded to 70% of itself. */
	color: var(--cf-quotecite-color, color-mix(in srgb, currentColor 70%, transparent));
	opacity: 1;
}
