/*
 * Batch 2 — Homepage opening + Selected Work (KAI-STAGE-001 + KAI-INDEX-001
 * foundation). Loaded only on the front page (see functions.php). Mobile
 * first; the 1200px breakpoint matches the shell's rail/header switch so the
 * whole page changes register together, not at mismatched widths.
 *
 * No card radius, no shadows, no pills, no gradients, no fixed board
 * heights — every dimension below is a real responsive value (%, clamp(),
 * aspect-ratio), not a copy of the design canvas's fixed 1440x980 mockup.
 */

/* ---------- utility (Batch 4) ---------- */

.kts-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ---------- Work Index head (Batch 4) ---------- */

.kts-work-index-head {
	margin-bottom: var(--kts-space-48);
}

.kts-work-index-head__title {
	margin: 0;
}

/* ---------- opening ---------- */

.kts-opening {
	display: flex;
	flex-direction: column;
	gap: var(--kts-space-32);
}

.kts-opening__text {
	max-width: 32ch;
}

.kts-opening__statement {
	margin: 0;
	font-family: var(--kts-font-serif);
	font-weight: 400; /* Batch 4: explicit, since this is now a real <h1>/<h2>
		element in places (browser default h1 weight is bold) — keeps the
		already-approved appearance unchanged after the semantic fix. */
	font-size: var(--kts-text-hero);
	line-height: 1.18;
	letter-spacing: -0.02em;
	color: var(--kts-ink-black);
	text-wrap: pretty;
}

/* ---------- stage (KAI-STAGE-001) ---------- */

.kts-stage {
	position: relative;
	width: 100%;
	aspect-ratio: 342 / 400;
	background: var(--kts-surface-sunken);
	overflow: hidden;
}

.kts-stage__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
}

.kts-stage__image.is-active {
	opacity: 1;
}

/* Only the default/ambient image is ever meaningful below 1200px — the
   per-project images exist in the DOM for the desktop hover interaction
   but stay inert (opacity 0, no transition cost) on mobile. */

/* ---------- selected work: shared head ---------- */

.kts-selected-work {
	margin-top: var(--kts-space-64);
}

.kts-selected-work__head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	margin-bottom: var(--kts-space-16);
	font-size: 0.7rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--kts-text-muted);
}

.kts-selected-work__label {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	color: inherit;
}

/* ---------- selected work: mobile rows (own image, no hover) ---------- */

.kts-work-rows {
	display: none;
}

.kts-work-rows-mobile {
	display: flex;
	flex-direction: column;
	gap: var(--kts-space-32);
}

.kts-work-row-mobile {
	border-top: 2px solid var(--kts-border-default);
	padding-top: var(--kts-space-16);
}

.kts-work-row-mobile[data-accent="olive"] {
	border-top-color: var(--kts-deep-olive);
}

.kts-work-row-mobile[data-accent="blue"] {
	border-top-color: var(--kts-mineral-blue);
}

.kts-work-row-mobile__link {
	display: block;
	color: inherit;
	text-decoration: none;
}

.kts-work-row-mobile__head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--kts-space-16);
}

.kts-work-row-mobile__title {
	font-family: var(--kts-font-serif);
	font-size: clamp(1.5rem, 1.2rem + 1.2vw, 1.85rem);
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
}

.kts-work-row-mobile[data-accent="olive"] .kts-work-row-mobile__number {
	color: var(--kts-deep-olive);
}

.kts-work-row-mobile[data-accent="blue"] .kts-work-row-mobile__number {
	color: var(--kts-mineral-blue);
}

.kts-work-row-mobile__year {
	flex: 0 0 auto;
	font-size: 0.75rem;
	color: var(--kts-text-muted);
}

.kts-work-row-mobile__discipline {
	margin-top: var(--kts-space-4);
	font-size: 0.7rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kts-text-secondary);
}

.kts-work-row-mobile__image {
	width: 100%;
	height: clamp(180px, 52vw, 260px);
	object-fit: cover;
	margin-top: var(--kts-space-16);
}

/* ---------- Work 0.8.0: inline editorial dossiers ---------- */

.kts-work-dossier {
	scroll-margin-top: calc(var(--kts-space-96) + var(--kts-space-16));
	border-bottom: 1px solid var(--kts-border-default);
}

.kts-work-dossier:first-child {
	border-top: 1px solid var(--kts-border-default);
}

.kts-work-dossier__summary {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	grid-template-areas:
		"number title year"
		"discipline discipline action"
		"preview preview preview";
	gap: var(--kts-space-8) var(--kts-space-12);
	align-items: baseline;
	padding: var(--kts-space-16) 0 var(--kts-space-24);
	list-style: none;
	cursor: pointer;
	color: inherit;
}

.kts-work-dossier__summary::-webkit-details-marker {
	display: none;
}

.kts-work-dossier__summary .kts-work-row__number {
	grid-area: number;
	font-size: 0.75rem;
	letter-spacing: 0.12em;
	color: var(--kts-text-muted);
}

.kts-work-dossier__summary .kts-work-row__title {
	grid-area: title;
	font-family: var(--kts-font-serif);
	font-size: clamp(1.5rem, 1.2rem + 1.2vw, 1.85rem);
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
}

.kts-work-dossier__summary .kts-work-row__discipline {
	grid-area: discipline;
	font-size: 0.7rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kts-text-secondary);
}

.kts-work-dossier__summary .kts-work-row__year {
	grid-area: year;
	font-size: 0.75rem;
	color: var(--kts-text-muted);
}

.kts-work-dossier__action {
	grid-area: action;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	justify-self: end;
	min-height: 36px;
	padding: var(--kts-space-8) var(--kts-space-12);
	border: 1px solid var(--kts-deep-olive);
	border-radius: var(--kts-radius-sm);
	background: transparent;
	font-size: 0.68rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--kts-deep-olive);
	white-space: nowrap;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.kts-work-dossier__action::after {
	content: "+";
	margin-left: var(--kts-space-8);
	font-size: 0.9rem;
	font-weight: 400;
	line-height: 1;
}

.kts-work-dossier__action-close {
	display: none;
}

.kts-work-dossier[open] .kts-work-dossier__action-view {
	display: none;
}

.kts-work-dossier[open] .kts-work-dossier__action-close {
	display: inline;
}

.kts-work-dossier[open] .kts-work-dossier__action::after {
	content: "−";
}

.kts-work-dossier__summary:hover .kts-work-dossier__action,
.kts-work-dossier__summary:focus-visible .kts-work-dossier__action {
	background: var(--kts-row-accent, var(--kts-deep-olive));
	border-color: var(--kts-row-accent, var(--kts-deep-olive));
	color: var(--kts-off-white);
}

.kts-work-dossier__preview {
	grid-area: preview;
	display: block;
	margin-top: var(--kts-space-8);
	overflow: hidden;
	background: var(--kts-surface-sunken);
}

.kts-work-dossier__preview img {
	display: block;
	width: 100%;
	height: clamp(190px, 54vw, 280px);
	object-fit: cover;
}

.kts-work-dossier__content {
	padding: var(--kts-space-32) 0 var(--kts-space-64);
	border-top: 1px solid var(--kts-hairline);
}

.kts-work-dossier__masthead {
	margin-bottom: var(--kts-space-32);
}

.kts-case__visit {
	display: inline-block;
	margin-top: var(--kts-space-16);
	color: var(--kts-deep-olive);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
}

.kts-work-dossier[data-accent="blue"] .kts-case__visit {
	color: var(--kts-mineral-blue);
}

.kts-case__visit:hover,
.kts-case__visit:focus-visible {
	color: var(--kts-ink-black);
}

.kts-work-dossier[data-accent="olive"][open] > .kts-work-dossier__summary {
	border-top-color: var(--kts-deep-olive);
}

.kts-work-dossier[data-accent="blue"][open] > .kts-work-dossier__summary {
	border-top-color: var(--kts-mineral-blue);
}

/* Work-only intermediate shell: avoid turning the shared stage into a
   viewport-tall portrait at tablet widths. Home remains visually locked. */
@media (min-width: 768px) and (max-width: 1199px) {
	.kts-work-page .kts-stage {
		aspect-ratio: 16 / 9;
	}
}

/* ---------- 1200px and up ---------- */

@media (min-width: 1200px) {
	.kts-opening {
		flex-direction: row;
		align-items: flex-start;
		gap: var(--kts-space-48);
	}

	.kts-opening__text {
		flex: 1;
		padding-top: var(--kts-space-48);
	}

	.kts-stage {
		flex: 0 0 var(--kts-stage-width);
		width: var(--kts-stage-width);
		aspect-ratio: 480 / 566;
		position: sticky;
		top: var(--kts-space-32);
		border: 1px solid transparent;
		box-sizing: border-box;
		transition: border-color 300ms ease;
	}

	.kts-stage[data-active-accent="olive"] {
		border-color: var(--kts-deep-olive);
	}

	.kts-stage[data-active-accent="blue"] {
		border-color: var(--kts-mineral-blue);
	}

	.kts-stage__image {
		transition: opacity 300ms ease;
	}

	.kts-work-rows {
		display: block;
	}

	.kts-work-rows-mobile {
		display: none;
	}

	.kts-work-row {
		display: grid;
		grid-template-columns: 70px minmax(0, 1fr) 330px 70px;
		align-items: center;
		height: 88px;
		color: inherit;
		text-decoration: none;
		cursor: pointer;
		border-top: 1px solid var(--kts-border-default);
		transition: border-color 300ms ease;
	}

	.kts-work-dossier__summary {
		grid-template-columns: 70px minmax(0, 1fr) 250px 70px 100px;
		grid-template-areas: none;
		gap: 0;
		padding: 0;
	}


	/* Reset the mobile named areas with equal specificity, then place each
	   semantic field in an explicit desktop column. The former generic
	   `.summary > *` reset lost the cascade to the mobile class selectors,
	   creating implicit grid columns and stacking title/discipline/year at
	   the far right on real staging. */
	.kts-work-dossier__summary .kts-work-row__number {
		grid-area: auto;
		grid-column: 1;
	}

	.kts-work-dossier__summary .kts-work-row__title {
		grid-area: auto;
		grid-column: 2;
	}

	.kts-work-dossier__summary .kts-work-row__discipline {
		grid-area: auto;
		grid-column: 3;
	}

	.kts-work-dossier__summary .kts-work-row__year {
		grid-area: auto;
		grid-column: 4;
	}

	.kts-work-dossier__summary .kts-work-dossier__action {
		grid-area: auto;
		grid-column: 5;
	}

	.kts-work-dossier__summary .kts-work-row__number,
	.kts-work-dossier__summary .kts-work-row__title,
	.kts-work-dossier__summary .kts-work-row__discipline,
	.kts-work-dossier__summary .kts-work-row__year,
	.kts-work-dossier__summary .kts-work-dossier__action {
		grid-row: 1;
		min-width: 0;
	}

	.kts-work-dossier__preview {
		display: none;
	}

	.kts-work-dossier__action {
		width: calc(100% - var(--kts-space-8));
	}

	.kts-work-dossier__content {
		padding-left: 70px;
		max-width: 900px;
	}

	.kts-work-row:last-child {
		border-bottom: 1px solid var(--kts-border-default);
	}

	.kts-work-row[data-accent="olive"] {
		--kts-row-accent: var(--kts-deep-olive);
	}

	.kts-work-row[data-accent="blue"] {
		--kts-row-accent: var(--kts-mineral-blue);
	}

	.kts-work-row:hover,
	.kts-work-row:focus-visible,
	.kts-work-row.is-active {
		border-top-color: var(--kts-row-accent, var(--kts-deep-olive));
	}

	.kts-work-row__number {
		font-size: 0.75rem;
		letter-spacing: 0.12em;
		color: var(--kts-text-muted);
		transition: color 300ms ease;
	}

	.kts-work-row:hover .kts-work-row__number,
	.kts-work-row:focus-visible .kts-work-row__number,
	.kts-work-row.is-active .kts-work-row__number {
		color: var(--kts-row-accent, var(--kts-deep-olive));
	}

	.kts-work-row__title {
		font-family: var(--kts-font-serif);
		font-size: var(--kts-text-row-title);
		letter-spacing: -0.01em;
		color: var(--kts-ink-black);
		transition: color 300ms ease, transform 300ms ease;
	}

	.kts-work-row:hover .kts-work-row__title,
	.kts-work-row:focus-visible .kts-work-row__title,
	.kts-work-row.is-active .kts-work-row__title {
		color: var(--kts-row-accent, var(--kts-deep-olive));
		transform: translateX(6px);
	}

	.kts-work-row__discipline {
		font-size: 0.7rem;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--kts-text-secondary);
	}

	.kts-work-row__year {
		font-size: 0.75rem;
		color: var(--kts-text-muted);
		text-align: right;
	}
}

/* =====================================================================
 * Batch 4.1 — Work Index desktop composition correction.
 *
 * Scoped to the explicit `.kts-work-page` template wrapper. WordPress does
 * not guarantee a page-slug body class, so relying on `.page-work` left
 * these rules inert on real staging. Home reuses the same opening/rows/
 * .kts-stage markup and was NOT reported as narrow, so it keeps its
 * current (already-approved) uncapped behaviour untouched here —
 * touching the shared bare selectors would have re-opened Home's
 * desktop composition, which this batch is explicitly not scoped to do.
 *
 * Problem this fixes: Work Index's .kts-main got only the ordinary 72ch
 * editorial cap (no kts-main--wide), so on desktop the whole page —
 * intro copy, stage, project rows — was squeezed into ~700px regardless
 * of viewport. header.php now gives Work Index kts-main--wide (removes
 * that blanket cap); the rules below give the two content groups their
 * own governed ceiling instead of letting them stretch uncapped to the
 * rail edge, which is what "materially wider, not full-width cards"
 * asks for.
 * ===================================================================== */

@media (min-width: 1200px) {
	.kts-work-page .kts-opening,
	.kts-work-page .kts-selected-work {
		/* 900px ceiling: with the 32ch text column (~280px) + 48px gap,
		   the enlarged stage below fits alongside it with little to no
		   leftover void — the complaint that motivated this pass — while
		   .kts-work-row's fixed 70/330/70 columns keep the 760-900px
		   target range on ordinary desktop widths. */
		max-width: 900px;
	}

	.kts-work-page .kts-stage {
		/* Wider than the shared --kts-stage-width token (480px ceiling),
		   which stays unchanged for Home. Curated website captures are
		   supplied at 1125–1200px wide, so this does not upscale them. */
		flex-basis: clamp(340px, 36vw, 560px);
		width: clamp(340px, 36vw, 560px);
	}
}

/* =====================================================================
 * Batch 3 — homepage continuation below Selected Work.
 * KAI-REGISTER-001: gutter-label + full-width-rule register, reused as
 * plain semantic markup for Capability / How to start / Journal / Studio /
 * Contact — no separate micro-component per register. Mobile-first: label
 * sits above its body by default; at >=1200px it moves into a 150px gutter
 * beside the body, matching the approved System Expansion composition.
 * ===================================================================== */

.kts-register {
	padding: var(--kts-space-48) 0;
	border-top: 1px solid var(--kts-border-default);
}

.kts-register__label {
	margin: 0 0 var(--kts-space-16);
	font-size: 0.7rem;
	font-weight: 400;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--kts-text-muted);
}

.kts-register__more {
	display: inline-block;
	margin-top: var(--kts-space-24);
	font-size: 0.9rem;
	color: var(--kts-deep-olive);
	text-decoration: none;
	border-bottom: 1px solid var(--kts-deep-olive);
	padding-bottom: 2px;
}

/* ---------- capability ---------- */

.kts-capability-row {
	display: flex;
	flex-direction: column;
	gap: var(--kts-space-8);
	/* Batch 3.1: more vertical air on mobile between the three items. */
	padding: var(--kts-space-24) 0;
	border-top: 1px solid var(--kts-hairline);
}

.kts-capability-row:first-child {
	border-top: 0;
}

.kts-capability-row__name {
	font-family: var(--kts-font-serif);
	font-size: clamp(1.5rem, 1.3rem + 0.85vw, 2rem);
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
}

.kts-capability-row__description {
	font-size: 0.95rem;
	line-height: 1.65;
	color: var(--kts-ink-black);
	max-width: 52ch;
}

.kts-capability-row__tags {
	font-size: 0.75rem;
	line-height: 1.6;
	color: var(--kts-text-secondary);
}

/* ---------- how to start ---------- */

.kts-offer {
	display: flex;
	flex-direction: column;
	gap: var(--kts-space-24);
}

.kts-offer__statement {
	margin: 0;
	font-family: var(--kts-font-serif);
	font-size: clamp(1.4rem, 1.15rem + 1.1vw, 1.9rem);
	line-height: 1.3;
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
	max-width: 46ch;
	text-wrap: pretty;
}

.kts-offer__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--kts-space-16);
	margin: 0;
	font-size: 0.9rem;
	line-height: 1.7;
	color: var(--kts-text-secondary);
}

.kts-offer__grid p {
	margin: 0;
}

.kts-offer__action {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--kts-space-16);
}

.kts-offer__cta {
	font-size: 0.9rem;
	color: var(--kts-deep-olive);
	text-decoration: none;
	border-bottom: 1px solid var(--kts-deep-olive);
	padding-bottom: 2px;
}

.kts-offer__note {
	font-size: 0.75rem;
	color: var(--kts-text-muted);
}

.kts-offer__image {
	width: 100%;
	max-width: 260px;
	height: auto;
	aspect-ratio: 230 / 300;
	object-fit: cover;
	object-position: top center;
}

/* ---------- interlude (Batch 3.1) ---------- */

.kts-interlude {
	margin: var(--kts-space-32) 0;
	border-top: 1px solid var(--kts-hairline);
	border-bottom: 1px solid var(--kts-hairline);
	background: var(--kts-surface-sunken);
}

.kts-interlude__image {
	display: block;
	width: 100%;
	/* Batch 4.1: below 768px the <picture> above swaps in the dedicated
	   ~4:5 portrait crop (kai-night-bridge-mobile.jpg) -- give it room to
	   read as an intentional portrait plate instead of squeezing it into
	   the same short landscape band used on desktop. */
	aspect-ratio: 4 / 5;
	object-fit: cover;
	object-position: center;
}

@media (min-width: 768px) {
	.kts-interlude__image {
		/* Unchanged from Batch 3.1: restrained, non-full-screen landscape
		   plate (dimensions/height untouched). Sprint A Gate 0: shifted
		   object-position from center 65% to center 35% -- 65% put the
		   crop's weight on the water/reflection, with the bridge and its
		   lamps only barely in frame at the top edge. 35% keeps the full
		   bridge span and both lamps as the primary subject while still
		   showing a reflection band at the bottom for depth. Chosen after
		   visually comparing 30/35/40% side by side; 35% was the cleanest
		   balance of the three. */
		aspect-ratio: auto;
		height: clamp(160px, 32vw, 320px);
		object-position: center 35%;
	}
}

/* ---------- journal ---------- */

.kts-journal-rows {
	display: flex;
	flex-direction: column;
}

.kts-journal-row {
	display: flex;
	flex-direction: column;
	gap: var(--kts-space-4);
	padding: var(--kts-space-16) 0;
	border-top: 1px solid var(--kts-hairline);
	color: inherit;
	text-decoration: none;
}

.kts-journal-row:first-child {
	border-top: 0;
}

.kts-journal-row__date {
	font-size: 0.75rem;
	color: var(--kts-text-muted);
	order: 2;
}

.kts-journal-row__category {
	font-size: 0.7rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kts-text-secondary);
	order: 1;
}

.kts-journal-row__title {
	font-family: var(--kts-font-serif);
	font-size: clamp(1.15rem, 1rem + 0.6vw, 1.4rem);
	color: var(--kts-ink-black);
	order: 3;
	/* Sprint A2: long Vietnamese titles must not break the row layout. */
	overflow-wrap: anywhere;
}

.kts-journal-row:hover .kts-journal-row__title,
.kts-journal-row:focus-visible .kts-journal-row__title {
	color: var(--kts-deep-olive);
}

/* =====================================================================
 * 0.6.1 — Journal Index (/blog/), Art Direction Correction.
 *
 * Replaces the 0.6.0 flat single-column row list (too sparse/dissolved
 * into the off-white surface, per Product Owner staging review) with a
 * lead feature surface + a 3-column editorial grid, translating the
 * PORTO ROCHA reference principle (strong lead surface, denser feed
 * beneath, panels rather than loose text) into Kaitago's own system --
 * .kts-surface-tint "paper slab" cards, no radius/shadow/pill, same
 * restrained language as the Studio Rail v2 nav states. Same real
 * WP_Query data (kts_get_journal_index()); presentation only.
 * ===================================================================== */

.kts-journal-index-head {
	margin-bottom: var(--kts-space-48);
}

.kts-journal-index-head__title {
	margin: 0;
}

.kts-journal-index-head__intro {
	margin: var(--kts-space-16) 0 0;
	max-width: 60ch;
	font-size: 0.95rem;
	line-height: 1.7;
	color: var(--kts-text-secondary);
}

/* ---------- lead feature ----------
 * 0.6.3: rebuilt on a MEDIA REGION + CONTENT REGION structure instead of
 * the 0.6.2 negative-margin bleed trick -- that made image and copy read
 * as two separately-joined blocks rather than one editorial object, and
 * left copy relying entirely on the outer padding for its bottom space.
 * Now: .kts-journal-feature is a plain rounded shell (radius + overflow:
 * hidden ONLY here, height:auto, no padding of its own); the image is a
 * true edge-to-edge media region with no padding around it; ALL copy
 * lives in .kts-journal-feature__content, its own padded wrapper, so
 * bottom spacing is guaranteed regardless of what the image does. Image-
 * first DOM order (page-blog.php) unchanged from 0.6.2 -- IMAGE, then
 * date/category, then title, then excerpt. No image: content region
 * still gets its own comfortable padding, typography carries the card. */

.kts-journal-feature {
	display: block;
	color: inherit;
	text-decoration: none;
	margin-bottom: var(--kts-space-32);
	background: var(--kts-surface-tint);
	border-top: 2px solid var(--kts-deep-olive);
	border-radius: var(--kts-radius-sm);
	overflow: hidden;
	height: auto;
}

.kts-journal-feature__image {
	display: block;
	width: 100%;
	height: clamp(220px, 46vw, 460px);
	object-fit: cover;
}

.kts-journal-feature__content {
	padding: var(--kts-space-24);
}

.kts-journal-feature__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kts-space-12);
	font-size: 0.7rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kts-text-muted);
}

.kts-journal-feature__title {
	display: block;
	margin: var(--kts-space-12) 0 0;
	font-family: var(--kts-font-serif);
	font-size: clamp(1.6rem, 1.3rem + 1.6vw, 2.4rem);
	line-height: 1.15;
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
	overflow-wrap: anywhere;
}

.kts-journal-feature:hover .kts-journal-feature__title,
.kts-journal-feature:focus-visible .kts-journal-feature__title {
	color: var(--kts-deep-olive);
}

.kts-journal-feature__excerpt {
	margin: var(--kts-space-16) 0 0;
	max-width: 62ch;
	font-size: 1rem;
	line-height: 1.65;
	color: var(--kts-text-secondary);
}

/* ---------- 3-column grid ----------
 * 0.6.2: gap tightened 16px -> 8px (measured off the PORTO ROCHA
 * reference's own card grid) for a denser "active publication" rhythm.
 * Heights deliberately vary card-to-card (image presence, title/excerpt
 * length) -- no min-height, no max-height, no forced equalization;
 * native grid auto-rows already gives the approved irregular rhythm
 * while keeping real chronological DOM order intact for screen readers.
 *
 * 0.6.3: same media-region + content-region rebuild as the feature above
 * -- .kts-journal-card is now a plain rounded shell with height:auto and
 * no padding of its own; the image is edge-to-edge with no text padding
 * around it (aspect-ratio instead of a fixed height, so it doesn't force
 * the whole card's proportions); .kts-journal-card__content is the one
 * padded wrapper (~16px) holding meta/title/excerpt, so copy always gets
 * real, comfortable bottom padding and is never visually clipped. */

.kts-journal-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--kts-space-8);
	/*
	 * 0.6.3 fix: CSS Grid items stretch to fill their row's height by
	 * default (align-items:stretch), which overrides a shorter card's own
	 * height:auto to match the tallest card sharing its row -- exactly
	 * the "forced equal-height rows" the instruction rules out, and it
	 * left short text-only cards with a large empty gap at the bottom
	 * instead of ending at their own content. align-items:start lets
	 * every card size to its own content regardless of its row-mates.
	 */
	align-items: start;
}

.kts-journal-card {
	display: block;
	color: inherit;
	text-decoration: none;
	background: var(--kts-surface-tint);
	border-radius: var(--kts-radius-sm);
	overflow: hidden;
	height: auto;
}

.kts-journal-card__image {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

.kts-journal-card__content {
	padding: var(--kts-space-16);
}

.kts-journal-card__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--kts-space-8);
	font-size: 0.68rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--kts-text-muted);
}

.kts-journal-card__title {
	display: block;
	margin: var(--kts-space-8) 0 0;
	font-family: var(--kts-font-serif);
	font-size: 1.15rem;
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: var(--kts-ink-black);
	overflow-wrap: anywhere;
}

.kts-journal-card:hover .kts-journal-card__title,
.kts-journal-card:focus-visible .kts-journal-card__title {
	color: var(--kts-deep-olive);
}

.kts-journal-card__excerpt {
	margin: var(--kts-space-8) 0 0;
	font-size: 0.85rem;
	line-height: 1.6;
	color: var(--kts-text-secondary);
}

@media (min-width: 768px) {
	.kts-journal-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1200px) {
	.kts-journal-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.kts-journal-feature__content {
		padding: var(--kts-space-48);
	}

	.kts-journal-feature__image {
		height: clamp(300px, 34vw, 520px);
	}
}

/* ---------- studio / about ---------- */

.kts-studio__statement {
	margin: 0;
	font-family: var(--kts-font-serif);
	font-size: clamp(1.4rem, 1.15rem + 1.1vw, 1.85rem);
	line-height: 1.3;
	letter-spacing: -0.015em;
	color: var(--kts-ink-black);
	max-width: 40ch;
}

.kts-studio__body {
	margin: var(--kts-space-16) 0 0;
	font-size: 0.95rem;
	line-height: 1.75;
	color: var(--kts-text-secondary);
	max-width: 60ch;
}

/* ---------- contact ---------- */

.kts-register--contact {
	padding-bottom: var(--kts-space-64);
}

.kts-contact__statement {
	margin: 0;
	font-family: var(--kts-font-serif);
	font-size: clamp(1.6rem, 1.3rem + 1.3vw, 2.3rem);
	line-height: 1.25;
	letter-spacing: -0.02em;
	color: var(--kts-ink-black);
	max-width: 34ch;
	text-wrap: pretty;
}

.kts-contact__row {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--kts-space-24);
	margin-top: var(--kts-space-24);
}

/* Signal orange: the one rare accent, on the single action of the page. */
.kts-contact__email {
	font-size: 1.05rem;
	color: var(--kts-ink-black);
	text-decoration: none;
	border-bottom: 1px solid var(--kts-signal-orange);
	padding-bottom: 3px;
}

.kts-contact__location {
	font-size: 0.85rem;
	color: var(--kts-text-secondary);
}

.kts-contact__meta {
	margin-top: var(--kts-space-48);
	padding-top: var(--kts-space-16);
	border-top: 1px solid var(--kts-hairline);
	font-size: 0.65rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--kts-text-muted);
}

/* ---------- 1200px and up ---------- */

@media (min-width: 1200px) {
	.kts-register {
		display: grid;
		grid-template-columns: 150px minmax(0, 1fr);
		padding: var(--kts-space-64) 0;
	}

	.kts-register__label {
		margin: 0;
		padding-top: 2px;
	}

	.kts-capability-row {
		display: grid;
		/*
		 * Sprint A Gate 0: description column was minmax(0, 1fr). CSS Grid
		 * lets the two minmax(min,max) tracks either side of a 1fr track
		 * grow toward their OWN max before the 1fr track gets anything --
		 * with the name/tags columns' combined minimum (140+200=340px)
		 * plus gaps close to the container width, the fr track could
		 * compute to as little as 0px, wrapping the description one word
		 * per line. Invisible on Home (its .kts-register has always been
		 * wide enough that this never triggered) but reproduced exactly
		 * this way on the new Services page (page-design-print-digital.php),
		 * which is narrower. Floor of 160px keeps a readable minimum in
		 * any container this row is ever placed in, with no visible
		 * change at the widths Home already renders it at.
		 */
		grid-template-columns: minmax(140px, 200px) minmax(160px, 1fr) minmax(200px, 300px);
		gap: var(--kts-space-32);
		align-items: baseline;
		padding: var(--kts-space-16) 0;
	}

	.kts-offer {
		flex-direction: row;
		align-items: flex-start;
		gap: var(--kts-space-48);
	}

	.kts-offer__text {
		flex: 1;
		min-width: 0;
	}

	.kts-offer__grid {
		grid-template-columns: 1fr 1fr;
	}

	.kts-offer__image {
		flex: 0 0 230px;
	}

	.kts-journal-row {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: baseline;
		gap: var(--kts-space-24);
	}

	.kts-journal-row__date {
		flex: 0 0 90px;
		order: 0;
	}

	.kts-journal-row__category {
		flex: 0 0 130px;
		order: 0;
	}

	.kts-journal-row__title {
		flex: 1;
		min-width: 0;
		order: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.kts-stage,
	.kts-stage__image,
	.kts-work-row,
	.kts-work-row__number,
	.kts-work-row__title,
	.kts-work-dossier__action {
		transition: none;
	}
}
