/**
 * Single blog post — table of contents rail and CTA card.
 *
 * Scoped to `.single-post` throughout so nothing here can reach another
 * template. The layout itself is Tailwind utilities in single.php; this file
 * exists for the two things utilities cannot reach:
 *
 *   1. Easy Table of Contents renders its own markup with its own IDs and
 *      class names, so the rail has to be styled by targeting the plugin's
 *      output rather than by putting classes on it.
 *   2. The CTA card's layered gradient is a single custom background.
 */

/* -------------------------------------------------------------------------
 * Banner
 *
 * The featured image fills the banner behind the title, with an overlay
 * between the two. Two schemes are offered per post because the readable text
 * colour depends on the photograph, which the theme cannot know: `light` keeps
 * the original pale gradient and dark type, `dark` inverts to white type over a
 * heavier scrim. Both are applied to the same markup.
 * ---------------------------------------------------------------------- */

.single-post .obt-banner {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	/* The gradient shows through wherever a post has no featured image, and
	   tints the image where it does. */
	background: linear-gradient(90deg, #fff 0%, #d7cdf9 48%, #a187ff 100%);
}

.single-post .obt-banner--dark {
	background: linear-gradient(90deg, #17122b 0%, #241a45 48%, #3b2a72 100%);
}

.single-post .obt-banner__media,
.single-post .obt-banner__overlay {
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
}

.single-post .obt-banner__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/*
 * Light banners keep dark type, so the image is lightened and the left side —
 * where the title sits — is faded hardest. Dark banners do the opposite.
 */
.single-post .obt-banner--light .obt-banner__image {
	opacity: 0.55;
}

.single-post .obt-banner--light .obt-banner__overlay {
	background:
		linear-gradient(90deg, rgba(255, 255, 255, 0.92) 0%, rgba(255, 255, 255, 0.6) 42%, rgba(255, 255, 255, 0.15) 100%);
}

.single-post .obt-banner--dark .obt-banner__image {
	opacity: 0.5;
}

.single-post .obt-banner--dark .obt-banner__overlay {
	background:
		linear-gradient(90deg, rgba(12, 8, 26, 0.9) 0%, rgba(12, 8, 26, 0.72) 45%, rgba(12, 8, 26, 0.44) 100%);
}

/*
 * The scrims above fade left-to-right, which suits a wide banner where the text
 * occupies the left half. Narrow screens have text across the full width, so
 * the gradient runs top-to-bottom there instead.
 */
@media (max-width: 1023px) {
	.single-post .obt-banner--light .obt-banner__overlay {
		background:
			linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0.78) 60%, rgba(255, 255, 255, 0.6) 100%);
	}

	.single-post .obt-banner--dark .obt-banner__overlay {
		background:
			linear-gradient(180deg, rgba(12, 8, 26, 0.88) 0%, rgba(12, 8, 26, 0.78) 60%, rgba(12, 8, 26, 0.66) 100%);
	}
}

/* Text colours. The utilities these replace were hardcoded to the light
   scheme, so both schemes are stated explicitly. */
.single-post .obt-banner--light :is(.obt-banner__title, .obt-banner__excerpt, .obt-banner__meta) {
	color: #1b1533;
}

.single-post .obt-banner--dark :is(.obt-banner__title, .obt-banner__excerpt, .obt-banner__meta) {
	color: #fff;
}

.single-post .obt-banner--dark .obt-banner__excerpt,
.single-post .obt-banner--dark .obt-banner__meta {
	color: rgba(255, 255, 255, 0.82);
}

/* Breadcrumbs come from a shared template part, so they are reached by
   descendant rather than by a class of their own. */
.single-post .obt-banner--dark :is(.obt-banner__meta a, .obt-banner__meta strong) {
	color: inherit;
}

.single-post .obt-banner--dark nav a,
.single-post .obt-banner--dark nav span {
	color: rgba(255, 255, 255, 0.75);
}

.single-post .obt-banner--dark nav a:hover {
	color: #fff;
}

/* Category pills */
.single-post .obt-banner__cat {
	background: rgba(255, 255, 255, 0.7);
	color: var(--color-primary, #6d28d9);
}

.single-post .obt-banner__cat:hover {
	background: #fff;
}

.single-post .obt-banner--dark .obt-banner__cat {
	background: rgba(255, 255, 255, 0.12);
	border: 1px solid rgba(255, 255, 255, 0.25);
	color: #fff;
}

.single-post .obt-banner--dark .obt-banner__cat:hover {
	background: rgba(255, 255, 255, 0.22);
}

/* -------------------------------------------------------------------------
 * Layout
 * ---------------------------------------------------------------------- */

/*
 * Single column by default; the rails join as there is room for them. Written
 * as real CSS because the prebuilt Tailwind stylesheet has no build step and
 * does not contain the tracks or spans this layout needs.
 */
.single-post .obt-post-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 2.5rem;
	align-items: start;
}

/* Tablet and small desktop: article plus CTA rail, TOC still hidden. */
@media (min-width: 1024px) {
	.single-post .obt-post-grid {
		grid-template-columns: minmax(0, 1fr) 300px;
		gap: 3rem;
	}
}

/* Full three-column layout. */
@media (min-width: 1280px) {
	.single-post .obt-post-grid {
		grid-template-columns: 250px minmax(0, 1fr) 300px;
	}
}

/*
 * A grid item's default min-width is auto, so a wide table or code block in the
 * article would push the column past its track and squeeze the rails.
 */
.single-post .entry-content {
	min-width: 0;
}

/* The TOC rail only earns a column once all three fit. */
.single-post .obt-toc {
	display: none;
}

@media (min-width: 1280px) {
	.single-post .obt-toc {
		display: block;
		/*
		 * A sticky child can only travel within its own parent, and the grid's
		 * `align-items: start` would shrink this column to the height of the
		 * list. Stretching it to the row gives the rail the full article to
		 * move through.
		 */
		align-self: stretch;
	}

	.single-post .obt-toc-inner {
		position: sticky;
		top: 10.5rem;
	}
}

/* Both rails stack under the article until there is room beside it. */
@media (min-width: 1024px) {
	.single-post .obt-cta-rail {
		align-self: stretch;
	}

	.single-post .obt-cta-inner {
		position: sticky;
		top: 10.5rem;
	}
}

/* Wide content scrolls within the column rather than widening the page. */
.single-post .entry-content :is(pre, table) {
	display: block;
	max-width: 100%;
	overflow-x: auto;
}

/* -------------------------------------------------------------------------
 * Table of contents
 * ---------------------------------------------------------------------- */

/*
 * Auto-insert has to stay on: it is what makes the plugin inject the heading
 * anchors its own links point at. The list it prints into the article is the
 * side effect — the sidebar copy is the one readers use, so the in-content one
 * is hidden rather than turned off.
 */
.single-post .entry-content #ez-toc-container {
	display: none;
}

.single-post .obt-toc #ez-toc-container {
	background: none;
	border: 0;
	box-shadow: none;
	padding: 0;
	margin: 0;
	width: 100%;
	font-size: inherit;
}

/* The plugin can be configured to print its own heading; the template already
   renders one, so any duplicate is hidden rather than fought with margins. */
.single-post .obt-toc #ez-toc-container .ez-toc-title-container {
	display: none;
}

/* Long posts scroll the list inside the sticky box instead of running past the
   viewport. Only above the xl breakpoint, where the rail is actually visible. */
@media (min-width: 1280px) {
	.single-post .obt-toc #ez-toc-container nav {
		max-height: calc(100vh - 18rem);
		overflow-y: auto;
		overscroll-behavior: contain;
		/* Room for the active marker, which sits at -2px and would otherwise
		   be clipped by the scroll container. */
		padding-left: 2px;
		scrollbar-width: thin;
		scrollbar-color: #d4d4d8 transparent;
	}

	.single-post .obt-toc #ez-toc-container nav::-webkit-scrollbar {
		width: 4px;
	}

	.single-post .obt-toc #ez-toc-container nav::-webkit-scrollbar-thumb {
		background: #d4d4d8;
		border-radius: 4px;
	}
}

/* The plugin ships `list-style: disc !important` on these, so the reset needs
   the same weight to win. */
.single-post .obt-toc #ez-toc-container ul.ez-toc-list {
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
	border-left: 2px solid #e5e7eb;
}

.single-post .obt-toc #ez-toc-container ul.ez-toc-list li {
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
	line-height: 1.5;
}

/* Nested (h3) entries indent under their parent. */
.single-post .obt-toc #ez-toc-container ul.ez-toc-list li ul {
	border-left: 0;
	margin-left: 0.75rem !important;
}

.single-post .obt-toc #ez-toc-container a.ez-toc-link {
	display: block;
	/* Pulled 2px left so the active border lands exactly on the rail above
	   rather than beside it. */
	margin-left: -2px;
	border-left: 2px solid transparent;
	padding: 0.375rem 0 0.375rem 0.875rem;
	font-size: 0.875rem;
	font-weight: 400;
	color: #52525b;
	text-decoration: none;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.single-post .obt-toc #ez-toc-container a.ez-toc-link:hover {
	color: var(--color-primary, #6d28d9);
}

.single-post .obt-toc #ez-toc-container a.ez-toc-link.active,
.single-post .obt-toc #ez-toc-container a.ez-toc-link.ez-toc-active,
.single-post .obt-toc #ez-toc-container a.ez-toc-link:focus-visible {
	color: var(--color-primary, #6d28d9);
	border-left-color: var(--color-primary, #6d28d9);
	font-weight: 600;
}

/*
 * Clears the 144px fixed site header, so a heading jumped to from the rail is
 * not hidden underneath it.
 *
 * The plugin's anchor is an empty `span.ez-toc-section` inside the heading, and
 * that span — not the h2 — is what the browser scrolls to, so the margin has to
 * sit on it. The span is inline and would ignore the property, hence the
 * block display.
 */
.single-post .entry-content .ez-toc-section {
	display: block;
	scroll-margin-top: 10.5rem;
}

.single-post .entry-content :is(h2, h3) {
	scroll-margin-top: 10.5rem;
}

/* -------------------------------------------------------------------------
 * CTA card
 * ---------------------------------------------------------------------- */

.single-post .obt-cta-card {
	background:
		radial-gradient(120% 90% at 88% -6%, rgba(161, 135, 255, 0.55) 0%, rgba(161, 135, 255, 0) 52%),
		radial-gradient(90% 70% at -10% 110%, rgba(109, 40, 217, 0.35) 0%, rgba(109, 40, 217, 0) 55%),
		linear-gradient(180deg, #1b1533 0%, #0b0817 100%);
	border: 1px solid rgba(255, 255, 255, 0.08);
	box-shadow:
		0 30px 60px -32px rgba(109, 40, 217, 0.45),
		0 18px 40px -30px rgba(12, 10, 30, 0.6);
}

@media (prefers-reduced-motion: reduce) {
	.single-post .obt-toc #ez-toc-container a.ez-toc-link {
		transition: none;
	}
}
