/* ==========================================================================
   Ebook Theme - Main stylesheet
   Loaded after the inlined critical CSS. Tokens live in critical.css.

   Contents
   1.  Typography blocks
   2.  Section headers
   3.  Cards
   4.  Product / book cards
   5.  Badges, ratings, price
   6.  Forms + inputs
   7.  Mobile navigation + drawers
   8.  Mega menu
   9.  Search overlay
   10. Marketing sections
   11. Blog + single post
   12. Comments
   13. Pagination + breadcrumbs
   14. Footer
   15. Widgets
   16. Notices + toasts
   17. 404 / empty states
   18. Block editor output
   19. Print
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Typography blocks
   -------------------------------------------------------------------------- */
.bl-prose {
	max-width: 68ch;
	font-size: var(--bl-fs-lg);
	line-height: 1.75;
}

.bl-prose > * + * {
	margin-block-start: 1.25em;
}

.bl-prose h2 {
	margin-block-start: 2em;
	margin-block-end: 0.6em;
}

.bl-prose h3 {
	margin-block-start: 1.75em;
	margin-block-end: 0.5em;
}

.bl-prose h4 {
	margin-block-start: 1.5em;
	margin-block-end: 0.4em;
}

.bl-prose ul,
.bl-prose ol {
	padding-inline-start: 1.4em;
}

.bl-prose li + li {
	margin-block-start: 0.4em;
}

.bl-prose img,
.bl-prose figure {
	border-radius: var(--bl-r);
}

.bl-prose figcaption {
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	text-align: center;
}

.bl-prose blockquote {
	margin-inline: 0;
	padding-inline-start: var(--bl-s5);
	border-inline-start: 3px solid var(--bl-highlight);
	color: var(--bl-ink);
	font-size: var(--bl-fs-xl);
	font-style: normal;
	font-weight: 500;
}

.bl-prose code {
	padding: 0.15em 0.4em;
	border-radius: var(--bl-r-xs);
	background: var(--bl-surface-3);
	font-family: var(--bl-font-mono);
	font-size: 0.875em;
}

.bl-prose pre {
	padding: var(--bl-s5);
	border-radius: var(--bl-r);
	background: var(--bl-ink);
	color: #e2e8f0;
	overflow-x: auto;
	font-size: var(--bl-fs-md);
}

.bl-prose pre code {
	padding: 0;
	background: none;
	color: inherit;
}

.bl-prose table {
	font-size: var(--bl-fs-md);
}

.bl-prose th,
.bl-prose td {
	padding: var(--bl-s3);
	border-block-end: 1px solid var(--bl-border);
	text-align: start;
}

.bl-prose th {
	color: var(--bl-ink);
	font-weight: 600;
}

.bl-lede {
	font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
	color: var(--bl-muted);
	line-height: 1.6;
}

/* --------------------------------------------------------------------------
   2. Section headers
   -------------------------------------------------------------------------- */
.bl-section-head {
	margin-block-end: var(--bl-s10);
	max-width: 62ch;
}

.bl-section-head--center {
	margin-inline: auto;
	text-align: center;
}

.bl-section-head--center .bl-eyebrow {
	justify-content: center;
}

.bl-section-head__title {
	font-size: var(--bl-fs-h2);
}

.bl-section-head__text {
	margin-block-start: var(--bl-s3);
	color: var(--bl-muted);
	font-size: var(--bl-fs-lg);
}

/* A heading beside a "see all" link. The link does not wrap, so on a narrow
   phone the pair cannot fit on one line: it overhung a 320px screen by 83px,
   which widened the layout viewport and took the fixed search overlay with
   it. Wrapping puts the link on its own line instead. */
.bl-section-head--split {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--bl-s4) var(--bl-s6);
	max-width: none;
}

/* --------------------------------------------------------------------------
   3. Cards
   -------------------------------------------------------------------------- */
.bl-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--bl-surface);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	overflow: hidden;
	transition: border-color var(--bl-t), box-shadow var(--bl-t), transform var(--bl-t);
}

.bl-card--hover:hover {
	border-color: var(--bl-border-strong);
	box-shadow: var(--bl-shadow-md);
	transform: translateY(-2px);
}

.bl-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	gap: var(--bl-s2);
	padding: var(--bl-s5);
}

.bl-card__title {
	font-size: var(--bl-fs-h4);
	letter-spacing: -0.01em;
}

.bl-card__title a {
	color: inherit;
	text-decoration: none;
}

.bl-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

.bl-card__text {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
}

.bl-card__footer {
	margin-block-start: auto;
	padding-block-start: var(--bl-s3);
}

.bl-card__media {
	position: relative;
	display: block;
	overflow: hidden;
	background: var(--bl-surface-3);
}

.bl-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--bl-t-slow);
}

.bl-card--hover:hover .bl-card__media img {
	transform: scale(1.03);
}

/* Four reasons, laid out as plainly as the page allows. No border and no
   card ground: the sections either side are both rows of bordered cards, and
   a third in the middle turns the page into a wall of boxes. */
.bl-features {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--bl-s8) var(--bl-s6);
}

@media (min-width: 600px) {
	.bl-features {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.bl-features {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.bl-feature {
	max-width: 34ch;
}

.bl-feature__icon {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	margin-block-end: var(--bl-s4);
	border-radius: var(--bl-r);
	background: var(--bl-highlight-soft);
	color: var(--bl-ink);
}

.bl-feature__title {
	margin-block-end: var(--bl-s2);
	font-size: var(--bl-fs-h4);
}

.bl-feature__text {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
}

/* --------------------------------------------------------------------------
   4. Product / book cards
   -------------------------------------------------------------------------- */
.bl-book {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--bl-s3);
}

.bl-book__cover {
	position: relative;
	display: block;
	aspect-ratio: 2 / 3;
	border-radius: var(--bl-r);
	overflow: hidden;
	background: var(--bl-surface-3);
	box-shadow: var(--bl-shadow-sm);
	transition: transform var(--bl-t-slow), box-shadow var(--bl-t-slow);
}

/* Subtle spine highlight - reads as a physical book without heavy 3D effects */
.bl-book__cover::after {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 8%;
	background: linear-gradient(90deg, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.04) 60%, transparent);
	pointer-events: none;
}

.bl-book:hover .bl-book__cover {
	transform: translateY(-4px);
	box-shadow: var(--bl-shadow-lg);
}

.bl-book__cover img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* A cover that has not been uploaded yet should still look like a cover.
   Centred grey text in a grey box reads as a missing image - which, on a shop
   whose covers are the product, is the cheapest a page can look. Setting the
   title the way a jacket would, and adding the spine the hero already uses for
   the same case, makes the placeholder deliberate instead. */
.bl-book__placeholder {
	position: relative;
	display: flex;
	/* Foot of the jacket, because the badges own the top-left corner and a
	   title running under them is worse than no title at all. */
	align-items: flex-end;
	width: 100%;
	height: 100%;
	padding: var(--bl-s5) var(--bl-s5) var(--bl-s6) calc(var(--bl-s5) + 8px);
	background: linear-gradient(155deg, var(--bl-surface-2), var(--bl-surface-3));
	color: var(--bl-ink);
	font-family: var(--bl-font-display);
	font-size: clamp(0.95rem, 1.5vw, 1.2rem);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.2;
	text-align: start;
	text-wrap: balance;
}

/* The spine. One cue is enough. */
.bl-book__placeholder::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 8px;
	background: var(--bl-border-strong);
}

.bl-book__body {
	display: flex;
	flex-direction: column;
	gap: var(--bl-s1);
}

.bl-book__title {
	font-size: var(--bl-fs-md);
	font-weight: 600;
	line-height: var(--bl-lh-snug);
	letter-spacing: -0.005em;
}

.bl-book__title a {
	color: var(--bl-ink);
	text-decoration: none;
}

.bl-book__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.bl-book__title a:hover {
	color: var(--bl-ink);
	text-decoration: underline;
	text-decoration-color: var(--bl-highlight);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

.bl-book__author {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

.bl-book__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bl-s2);
	margin-block-start: var(--bl-s1);
}

/* Buttons inside a card need to sit above the stretched title link */
.bl-book__actions {
	position: relative;
	z-index: 2;
	margin-block-start: var(--bl-s2);
}

.bl-book__actions .bl-btn {
	width: 100%;
}

/* Quick-add button that reveals on hover, but is always reachable by keyboard */
.bl-book__quick {
	position: absolute;
	inset-block-end: var(--bl-s3);
	inset-inline: var(--bl-s3);
	z-index: 3;
	opacity: 0;
	transform: translateY(6px);
	transition: opacity var(--bl-t), transform var(--bl-t);
}

.bl-book:hover .bl-book__quick,
.bl-book__quick:focus-within {
	opacity: 1;
	transform: translateY(0);
}

@media (hover: none) {
	.bl-book__quick {
		position: static;
		opacity: 1;
		transform: none;
	}
}

/* Horizontal variant used in the mini-cart and related lists */
.bl-book--row {
	flex-direction: row;
	gap: var(--bl-s4);
	align-items: flex-start;
}

.bl-book--row .bl-book__cover {
	flex: 0 0 56px;
	width: 56px;
}

/* --------------------------------------------------------------------------
   5. Badges, ratings, price
   -------------------------------------------------------------------------- */
.bl-badges {
	position: absolute;
	inset-block-start: var(--bl-s2);
	inset-inline-start: var(--bl-s2);
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--bl-s1);
	pointer-events: none;
}

.bl-badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 3px var(--bl-s2);
	border-radius: var(--bl-r-sm);
	background: var(--bl-ink);
	color: var(--bl-bg);
	font-size: var(--bl-fs-xs);
	font-weight: 700;
	letter-spacing: 0.02em;
	line-height: 1.4;
	text-transform: uppercase;
}

/* Badges carry no hue of their own beyond the brand yellow and the gold
   already used for stars. A saving is not an error and free is not a success
   message, so neither borrows the red or the green those states own - on a
   shelf of covers those two colours were most of the colour on the page. */
.bl-badge--sale { background: var(--bl-ink); color: var(--bl-bg); }
.bl-badge--free { background: var(--bl-highlight); color: var(--bl-highlight-ink); }
.bl-badge--best { background: var(--bl-highlight); color: var(--bl-highlight-ink); }
.bl-badge--new,
.bl-badge--bundle { background: var(--bl-surface); color: var(--bl-ink); border: 1px solid var(--bl-border-strong); }

.bl-rating {
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s1);
	font-size: var(--bl-fs-sm);
	color: var(--bl-muted);
}

.bl-rating__stars {
	display: inline-flex;
	gap: 1px;
	color: var(--bl-star);
}

.bl-rating__stars svg {
	fill: currentColor;
	stroke: none;
}

.bl-rating__stars .is-empty {
	color: var(--bl-border-strong);
}

.bl-price {
	display: inline-flex;
	align-items: baseline;
	gap: var(--bl-s2);
	color: var(--bl-ink);
	font-size: var(--bl-fs-base);
	font-weight: 700;
	letter-spacing: -0.01em;
}

.bl-price del,
.bl-price .bl-price__was {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 500;
	text-decoration: line-through;
}

.bl-price ins {
	text-decoration: none;
}

.bl-price--lg {
	font-size: clamp(1.5rem, 1.3rem + 1vw, 2rem);
}

.bl-price--free {
	color: var(--bl-success-text);
}

/* --------------------------------------------------------------------------
   6. Forms + inputs
   -------------------------------------------------------------------------- */
.bl-field {
	display: flex;
	flex-direction: column;
	gap: var(--bl-s2);
}

.bl-label,
label {
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
	font-weight: 500;
}

.bl-required {
	color: var(--bl-danger);
}

input[type="text"],
input[type="email"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="tel"],
input[type="date"],
select,
textarea,
.bl-input {
	width: 100%;
	min-height: 46px;
	padding: 0.625rem var(--bl-s4);
	border: 1px solid var(--bl-border-strong);
	border-radius: var(--bl-r);
	background: var(--bl-surface);
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
	transition: border-color var(--bl-t), box-shadow var(--bl-t);
	appearance: none;
}

textarea {
	min-height: 140px;
	resize: vertical;
	line-height: 1.6;
}

select {
	padding-inline-end: var(--bl-s10);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--bl-s4) center;
	cursor: pointer;
}

[dir="rtl"] select {
	background-position: left var(--bl-s4) center;
}

input:focus,
select:focus,
textarea:focus {
	outline: none;
	border-color: var(--bl-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--bl-accent) 18%, transparent);
}

input::placeholder,
textarea::placeholder {
	color: var(--bl-muted);
	opacity: 1;
}

input[aria-invalid="true"],
.bl-field--error input {
	border-color: var(--bl-danger);
}

.bl-field__error {
	color: var(--bl-danger);
	font-size: var(--bl-fs-sm);
}

.bl-field__hint {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

/* Checkbox + radio */
/* 24px, not 20: WCAG 2.5.8 puts the floor for a target at 24x24, and the
   terms checkbox on checkout was the smallest thing a buyer has to hit on a
   phone before they can pay. */
input[type="checkbox"],
input[type="radio"] {
	/* Without this the browser keeps drawing its own control and every rule
	   below is ignored - the size, the border, the brand checked state and the
	   tick in ::before were all being painted over by the native widget. */
	-webkit-appearance: none;
	appearance: none;
	width: 24px;
	height: 24px;
	min-height: 0;
	padding: 0;
	margin-inline-end: var(--bl-s2);
	border: 1.5px solid var(--bl-border-strong);
	background: var(--bl-surface);
	cursor: pointer;
	flex-shrink: 0;
	display: inline-grid;
	place-content: center;
	vertical-align: -4px;
}

input[type="checkbox"] {
	border-radius: var(--bl-r-xs);
}

input[type="radio"] {
	border-radius: 50%;
}

input[type="checkbox"]::before {
	content: "";
	width: 10px;
	height: 10px;
	transform: scale(0);
	transition: transform 90ms var(--bl-ease);
	box-shadow: inset 1em 1em var(--bl-accent-contrast);
	clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

input[type="radio"]::before {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 50%;
	transform: scale(0);
	transition: transform 90ms var(--bl-ease);
	box-shadow: inset 1em 1em var(--bl-accent-contrast);
}

input[type="checkbox"]:checked,
input[type="radio"]:checked {
	background: var(--bl-accent);
	border-color: var(--bl-accent);
}

input[type="checkbox"]:checked::before,
input[type="radio"]:checked::before {
	transform: scale(1);
}

.bl-checkbox {
	display: flex;
	align-items: flex-start;
	gap: var(--bl-s1);
	font-size: var(--bl-fs-md);
	font-weight: 400;
	cursor: pointer;
}

/* Search form */
.bl-searchform {
	display: flex;
	gap: var(--bl-s2);
	width: 100%;
}

.bl-searchform__field {
	position: relative;
	flex: 1;
	/* A flex item defaults to min-width:auto, which refuses to shrink past the
	   input's intrinsic width. Without this the field sets a floor the whole
	   panel has to be wide enough for. */
	min-width: 0;
}

.bl-searchform__field svg {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: var(--bl-s4);
	transform: translateY(-50%);
	color: var(--bl-muted);
	pointer-events: none;
}

.bl-searchform input[type="search"] {
	padding-inline-start: var(--bl-s10);
}

input[type="search"]::-webkit-search-cancel-button {
	cursor: pointer;
}

/* Newsletter inline form */
.bl-subscribe {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bl-s2);
	max-width: 480px;
}

.bl-subscribe input[type="email"] {
	flex: 1 1 220px;
}

.bl-subscribe .bl-btn {
	flex-shrink: 0;
}

.bl-subscribe__note {
	flex-basis: 100%;
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

/* --------------------------------------------------------------------------
   7. Mobile navigation + drawers
   -------------------------------------------------------------------------- */
.bl-drawer {
	position: fixed;
	inset: 0;
	z-index: 1000;
	visibility: hidden;
	pointer-events: none;
}

.bl-drawer.is-open {
	visibility: visible;
	pointer-events: auto;
}

.bl-drawer__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(11, 18, 32, 0.5);
	opacity: 0;
	transition: opacity var(--bl-t-slow);
}

.bl-drawer.is-open .bl-drawer__backdrop {
	opacity: 1;
}

.bl-drawer__panel {
	position: absolute;
	inset-block: 0;
	inset-inline-end: 0;
	display: flex;
	flex-direction: column;
	width: min(400px, 92vw);
	background: var(--bl-bg);
	box-shadow: var(--bl-shadow-lg);
	transform: translateX(100%);
	transition: transform var(--bl-t-slow);
}

[dir="rtl"] .bl-drawer__panel {
	transform: translateX(-100%);
}

.bl-drawer--start .bl-drawer__panel {
	inset-inline-end: auto;
	inset-inline-start: 0;
	transform: translateX(-100%);
}

.bl-drawer.is-open .bl-drawer__panel {
	transform: translateX(0);
}

.bl-drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bl-s4);
	padding: var(--bl-s4) var(--bl-s5);
	border-block-end: 1px solid var(--bl-border);
	min-height: var(--bl-header-h);
}

.bl-drawer__title {
	font-size: var(--bl-fs-lg);
	font-weight: 700;
}

.bl-drawer__body {
	flex: 1;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: var(--bl-s5);
}

.bl-drawer__foot {
	padding: var(--bl-s5);
	border-block-start: 1px solid var(--bl-border);
	background: var(--bl-surface-2);
}

/* Mobile menu list */
.bl-mobilenav ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.bl-mobilenav li {
	border-block-end: 1px solid var(--bl-border);
}

.bl-mobilenav a {
	display: block;
	padding: var(--bl-s4) 0;
	color: var(--bl-ink);
	font-size: var(--bl-fs-lg);
	font-weight: 500;
	text-decoration: none;
}

.bl-mobilenav a:hover {
	color: var(--bl-accent);
}

.bl-mobilenav .sub-menu {
	padding-inline-start: var(--bl-s4);
	padding-block-end: var(--bl-s2);
}

.bl-mobilenav .sub-menu li {
	border: 0;
}

.bl-mobilenav .sub-menu a {
	padding-block: var(--bl-s2);
	font-size: var(--bl-fs-md);
	color: var(--bl-muted);
}

/* Submenu toggle button injected by JS */
.bl-submenu-toggle {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	margin-inline-start: auto;
	border-radius: var(--bl-r-sm);
	color: var(--bl-muted);
}

.bl-mobilenav__row {
	display: flex;
	align-items: center;
}

.bl-drawer__theme {
	display: flex;
	align-items: center;
	gap: var(--bl-s2);
	width: 100%;
	margin-block-start: var(--bl-s3);
	padding: var(--bl-s2) var(--bl-s3);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r);
	background: transparent;
	color: var(--bl-text);
	font-size: var(--bl-fs-sm);
	font-weight: 500;
}

.bl-drawer__theme:hover {
	background: var(--bl-surface-2);
	color: var(--bl-ink);
}

.bl-submenu-toggle[aria-expanded="true"] svg {
	transform: rotate(180deg);
}

.bl-submenu-toggle svg {
	transition: transform var(--bl-t);
}

/* --------------------------------------------------------------------------
   8. Mega menu (desktop only)
   -------------------------------------------------------------------------- */
@media (min-width: 1024px) {
	.bl-nav__list li {
		position: relative;
	}

	/* Top-level items fill the header, so a dropdown opens from the
	   header's lower edge rather than from the middle of the link, and
	   the pointer never crosses a gap on its way into the panel. */
	.bl-header__nav {
		align-self: stretch;
	}

	.bl-header__nav > .bl-nav__list,
	.bl-header__nav > .bl-nav__list > li {
		height: 100%;
	}

	.bl-header__nav > .bl-nav__list > li {
		display: flex;
		align-items: center;
	}

	/* Anchored to the header itself, so the panel clears it by the same
	   amount whatever the nav font size happens to be. */
	.bl-header__nav > .bl-nav__list > li > .sub-menu {
		inset-block-start: calc(var(--bl-header-h) + 6px);
	}

	.bl-nav__list .sub-menu {
		position: absolute;
		inset-block-start: calc(100% + 8px);
		inset-inline-start: 0;
		z-index: 950;
		min-width: 230px;
		margin: 0;
		padding: var(--bl-s2);
		list-style: none;
		background: var(--bl-surface);
		border: 1px solid var(--bl-border);
		border-radius: var(--bl-r-lg);
		box-shadow: var(--bl-shadow-lg);
		opacity: 0;
		visibility: hidden;
		transform: translateY(-6px);
		transition: opacity var(--bl-t), transform var(--bl-t), visibility var(--bl-t);
	}

	.bl-nav__list li:hover > .sub-menu,
	.bl-nav__list li:focus-within > .sub-menu,
	.bl-nav__list li > .sub-menu.is-open {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}

	.bl-nav__list .sub-menu a {
		padding: var(--bl-s2) var(--bl-s3);
		border-radius: var(--bl-r-sm);
		font-size: var(--bl-fs-md);
	}

	.bl-nav__list .sub-menu .sub-menu {
		inset-block-start: calc(var(--bl-s2) * -1);
		inset-inline-start: 100%;
	}

	/* The collections panel: ten shelves read faster in two columns than
	   as one long drop, and each one gets its icon and a three-word
	   kicker so the list is scannable rather than just enumerable. */
	.bl-nav__list .sub-menu--mega,
	.bl-nav__list .menu-item.mega > .sub-menu {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 2px;
		width: max-content;
		max-width: min(580px, calc(100vw - (var(--bl-gutter) * 2)));
		padding: var(--bl-s3);
	}

	.sub-menu--mega a,
	.menu-item.mega > .sub-menu a {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 0 var(--bl-s3);
		padding: var(--bl-s2);
	}

	.sub-menu--mega .bl-nav__icon,
	.menu-item.mega .bl-nav__icon {
		display: grid;
		place-items: center;
		flex: 0 0 34px;
		height: 34px;
		border-radius: var(--bl-r-sm);
		background: var(--bl-surface-2);
		color: var(--bl-accent);
		transition: background-color var(--bl-t), color var(--bl-t);
	}

	/* The current collection reads through its tile rather than a rule under
	   the row - the same yellow, attached to something. */
	.sub-menu--mega a[aria-current="page"] .bl-nav__icon,
	.menu-item.mega .current-menu-item > a .bl-nav__icon {
		background: var(--bl-highlight);
		color: var(--bl-highlight-ink);
	}

	.sub-menu--mega a:hover .bl-nav__icon,
	.sub-menu--mega a:focus-visible .bl-nav__icon,
	.menu-item.mega a:hover .bl-nav__icon {
		background: var(--bl-highlight-soft);
	}

	.sub-menu--mega .bl-nav__label,
	.menu-item.mega > .sub-menu .bl-nav__label {
		flex: 1 1 auto;
		font-weight: 600;
	}

	.sub-menu--mega .bl-nav__desc,
	.menu-item.mega > .sub-menu .bl-nav__desc {
		flex-basis: 100%;
		margin-inline-start: calc(34px + var(--bl-s3));
	}

	.sub-menu--mega .bl-nav__viewall {
		grid-column: 1 / -1;
		margin-block-start: var(--bl-s2);
		padding-block-start: var(--bl-s2);
		border-block-start: 1px solid var(--bl-border);
	}

	.sub-menu--mega .bl-nav__viewall a {
		gap: var(--bl-s2);
		color: var(--bl-ink);
		font-weight: 600;
	}

	.sub-menu--mega .bl-nav__viewall .bl-nav__label {
		flex: 0 1 auto;
	}

	/* Menu item description, used by the custom walker for mega menus */
	.bl-nav__desc {
		display: block;
		color: var(--bl-muted);
		font-size: var(--bl-fs-xs);
		font-weight: 400;
		line-height: 1.4;
	}
}

.bl-nav__toggle-icon {
	transition: transform var(--bl-t);
}

/* --------------------------------------------------------------------------
   9. Search overlay
   -------------------------------------------------------------------------- */
/* The explicit column and the min-width:0 below are belt and braces. An auto
   column sizes to the min-content of what it holds, and this form's is the
   field plus a nowrap submit button, so the overlay could set its own floor
   on a narrow screen. (It was not what widened the page - see
   .bl-section-head--split - but inset:0 made it inherit the damage.) */
.bl-searchpanel {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	place-items: start center;
	padding-block-start: clamp(4rem, 12vh, 9rem);
	padding-inline: var(--bl-gutter);
	background: color-mix(in srgb, var(--bl-bg) 92%, transparent);
	backdrop-filter: blur(8px);
	opacity: 0;
	visibility: hidden;
	transition: opacity var(--bl-t), visibility var(--bl-t);
}

.bl-searchpanel.is-open {
	opacity: 1;
	visibility: visible;
}

.bl-searchpanel__inner {
	width: 100%;
	min-width: 0;
	max-width: 640px;
}

.bl-searchpanel input[type="search"] {
	min-height: 60px;
	font-size: var(--bl-fs-xl);
	box-shadow: var(--bl-shadow-lg);
}

.bl-searchpanel__hint {
	margin-block-start: var(--bl-s4);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	text-align: center;
}

.bl-searchpanel__close {
	position: absolute;
	inset-block-start: var(--bl-s5);
	inset-inline-end: var(--bl-s5);
}

/* --------------------------------------------------------------------------
   10. Marketing sections
   -------------------------------------------------------------------------- */

/* Logo strip */
.bl-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(1.5rem, 4vw, 3.5rem);
}

.bl-logos img {
	max-height: 28px;
	width: auto;
	opacity: 0.55;
	filter: grayscale(1);
	transition: opacity var(--bl-t), filter var(--bl-t);
}

.bl-logos img:hover {
	opacity: 1;
	filter: none;
}

.bl-logos__label {
	flex-basis: 100%;
	margin-block-end: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	text-align: center;
}

/* Stats strip */
.bl-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: var(--bl-s6);
	text-align: center;
}

.bl-stat__value {
	display: block;
	color: var(--bl-ink);
	font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1.1;
}

.bl-stat__label {
	display: block;
	margin-block-start: var(--bl-s1);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

/* Collection tiles ---------------------------------------------------------
   The ten marketplace categories. Each tile carries its own accent through
   --bl-c, set inline by ebook_category_style(), so adding an eleventh
   category needs no CSS at all. */
.bl-collections {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--bl-s5);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 600px) {
	.bl-collections {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.bl-collections {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* Cards, not a table. The previous treatment shared one hairline grid between
   ten tiles, which reads as a printed contents page - right for ten, wrong for
   six, where each collection is meant to look worth clicking on its own. */
.bl-collection {
	position: relative;
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	transition: border-color var(--bl-t), box-shadow var(--bl-t), transform var(--bl-t);
}

.bl-collection:hover {
	border-color: var(--bl-border-strong);
	box-shadow: var(--bl-shadow-md);
}

@media (prefers-reduced-motion: no-preference) {
	.bl-collection:hover {
		transform: translateY(-2px);
	}
}

/* The accent is a rule along the top edge that draws in on hover, inside the
   card's radius rather than across it. */
.bl-collection::before {
	content: "";
	position: absolute;
	inset-block-start: 0;
	inset-inline: var(--bl-s5);
	height: 2px;
	border-radius: 0 0 2px 2px;
	background: var(--bl-c, var(--bl-highlight));
	transform: scaleX(0);
	transform-origin: 50% 0;
	transition: transform var(--bl-t-slow);
}

.bl-collection:hover::before,
.bl-collection:focus-within::before {
	transform: scaleX(1);
}

.bl-collection__link {
	display: flex;
	flex-direction: column;
	gap: var(--bl-s3);
	height: 100%;
	padding: var(--bl-s6);
	text-decoration: none;
}

/* The icon sits in a tinted tile: at 22px a line icon needs a ground to read
   as an emblem rather than as a stray mark. */
.bl-collection__icon {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	margin-block-end: var(--bl-s1);
	border-radius: var(--bl-r);
	background: var(--bl-c-soft, var(--bl-surface-2));
	color: var(--bl-c, var(--bl-ink));
}

.bl-collection__name {
	font-size: var(--bl-fs-h4);
	color: var(--bl-ink);
}

.bl-collection__text {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	line-height: 1.55;
}

.bl-collection__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bl-s3);
	margin-block-start: auto;
	padding-block-start: var(--bl-s5);
}

.bl-collection__count {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-variant-numeric: tabular-nums;
}

.bl-collection__arrow {
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	border-radius: var(--bl-r-full);
	background: var(--bl-surface-2);
	color: var(--bl-ink);
	transition: background-color var(--bl-t), color var(--bl-t), transform var(--bl-t);
}

.bl-collection:hover .bl-collection__arrow,
.bl-collection:focus-within .bl-collection__arrow {
	background: var(--bl-ink);
	color: var(--bl-bg);
	transform: translateX(3px);
}
/* ---- How it works -------------------------------------------------------
   Numbered by the list itself rather than by markup, so the numbers cannot
   drift out of step with the steps.
   ------------------------------------------------------------------------- */
.bl-steps {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--bl-s6);
	margin: 0;
	padding: 0;
	counter-reset: bl-step;
	list-style: none;
}

@media (min-width: 600px) {
	.bl-steps {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.bl-steps {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.bl-step {
	position: relative;
	counter-increment: bl-step;
	padding-block-start: var(--bl-s10);
}

.bl-step::before {
	content: counter(bl-step, decimal-leading-zero);
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	display: grid;
	place-items: center;
	width: 36px;
	height: 36px;
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-full);
	background: var(--bl-surface);
	color: var(--bl-ink);
	font-family: var(--bl-font-mono);
	font-size: var(--bl-fs-xs);
	font-weight: 600;
}

/* The rule joining one step to the next, on the row only. */
@media (min-width: 600px) {
	.bl-step:not(:last-child)::after {
		content: "";
		position: absolute;
		inset-block-start: 18px;
		inset-inline-start: 44px;
		inset-inline-end: calc(var(--bl-s6) * -1);
		height: 1px;
		background: var(--bl-border);
	}
}

.bl-step__title {
	margin-block-end: var(--bl-s2);
	font-size: var(--bl-fs-h4);
	color: var(--bl-ink);
}

.bl-step__text {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	line-height: 1.6;
}

/* ---- Testimonials -------------------------------------------------------
   A quote is a card with a mark, not a card with quotation glyphs pasted on
   either end of the text: the mark sits behind the words and stays out of the
   way of selecting them.
   ------------------------------------------------------------------------- */
/* A row that scrolls when it runs out of room, rather than a carousel. No
   slider library, no autoplay, no arrows to maintain: scroll-snap does the
   snapping and the browser does the rest, so a trackpad, a touchscreen, a
   scrollbar and the arrow keys all work without being taught to. */
.bl-quotes {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: min(84vw, 380px);
	gap: var(--bl-s5);
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x proximity;
	scroll-padding-inline-start: var(--bl-gutter);
	scrollbar-width: thin;

	/* Bleed to the viewport edge so the row reads as continuing off-screen,
	   while the first card still lines up with the container. */
	margin-inline: calc(var(--bl-gutter) * -1);
	padding: 2px var(--bl-gutter) var(--bl-s5);
}

.bl-quotes > * {
	scroll-snap-align: start;
}

/* Focus lands on the region itself when it is scrollable, so it needs to be
   visible - the cards inside give no clue that the container has focus. */
.bl-quotes:focus-visible {
	outline: 2px solid var(--bl-accent);
	outline-offset: 4px;
	border-radius: var(--bl-r);
}
.bl-quote {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--bl-s4);
	height: 100%;
	margin: 0;
	padding: var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	overflow: hidden;
}

.bl-quote::before {
	content: "\201C";
	position: absolute;
	/* A quote glyph sits high in its em box, so the box must start inside the
	   card or the card's overflow clips the mark in half. */
	inset-block-start: 0;
	inset-inline-end: var(--bl-s4);
	color: var(--bl-highlight);
	font-family: var(--bl-font-display);
	font-size: 5rem;
	line-height: 1;
	opacity: 0.5;
	pointer-events: none;
	user-select: none;
}

.bl-quote__text {
	position: relative;
	margin: 0;
	color: var(--bl-text);
	font-size: var(--bl-fs-lg);
	line-height: 1.6;
	text-wrap: pretty;
}

.bl-quote__text p {
	margin: 0;
}

.bl-quote__author {
	display: flex;
	align-items: center;
	gap: var(--bl-s3);
	margin-block-start: auto;
	padding-block-start: var(--bl-s2);
}

.bl-quote__avatar {
	width: 44px;
	height: 44px;
	flex-shrink: 0;
	border-radius: var(--bl-r-full);
	object-fit: cover;
}

/* Initials keep a testimonial without a photograph the same shape as one
   with a photograph, so a row of them does not come out ragged. */
.bl-quote__avatar--initials {
	display: grid;
	place-items: center;
	background: var(--bl-surface-2);
	border: 1px solid var(--bl-border);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 700;
	letter-spacing: 0.02em;
}

.bl-quote__who {
	display: grid;
	gap: 1px;
	min-width: 0;
}

.bl-quote__name {
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
	font-weight: 600;
}

.bl-quote__role {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

/* ---- FAQ ----------------------------------------------------------------
   <details> does the work. No JavaScript, keyboard support for free, and the
   content is in the page for search engines whether or not it is open.
   ------------------------------------------------------------------------- */
.bl-faq {
	/* Aligned left under its heading rather than centred: every other
	   section on the page starts at the container edge. */
	max-width: 900px;
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	overflow: hidden;
}

.bl-faq__item + .bl-faq__item {
	border-block-start: 1px solid var(--bl-border);
}

.bl-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bl-s4);
	padding: var(--bl-s5) var(--bl-s6);
	color: var(--bl-ink);
	font-size: var(--bl-fs-lg);
	font-weight: 600;
	line-height: 1.4;
	cursor: pointer;
	list-style: none;
	transition: background-color var(--bl-t);
}

/* Safari draws its own triangle unless both of these are set. */
.bl-faq__q::-webkit-details-marker {
	display: none;
}

.bl-faq__q::marker {
	content: "";
}

.bl-faq__q:hover {
	background: var(--bl-surface-2);
}

.bl-faq__q:focus-visible {
	outline: 2px solid var(--bl-accent);
	outline-offset: -2px;
}

.bl-faq__icon {
	flex-shrink: 0;
	color: var(--bl-muted);
	transition: transform var(--bl-t), color var(--bl-t);
}

.bl-faq__item[open] .bl-faq__icon {
	transform: rotate(45deg);
	color: var(--bl-ink);
}

.bl-faq__a {
	padding: 0 var(--bl-s6) var(--bl-s5);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	line-height: 1.65;
}

.bl-faq__a > :last-child {
	margin-block-end: 0;
}

/* ---- Product rail -------------------------------------------------------
   A scrolling row rather than a grid, for sections where the point is that
   there is more than fits. Cards keep a fixed width: with grid columns of
   1fr a section holding a single product stretched that one card across the
   whole container, and a 2:3 cover turned it into a 2000px tall section.
   ------------------------------------------------------------------------- */
.bl-rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: min(74vw, 280px);
	gap: var(--bl-s5);
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x proximity;
	scroll-padding-inline-start: var(--bl-gutter);
	scrollbar-width: thin;

	/* Bleed to the viewport edge so the row reads as continuing off-screen,
	   while the first card still lines up with the container. */
	margin-inline: calc(var(--bl-gutter) * -1);
	padding: 2px var(--bl-gutter) var(--bl-s4);
}

.bl-rail > * {
	scroll-snap-align: start;
}

/* ---- Trust row ----------------------------------------------------------
   The guarantee line under the hero buttons. Section 22 refines the spacing
   and case; these are the rules it refines.
   ------------------------------------------------------------------------- */
.bl-trust {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bl-s3) var(--bl-s6);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-trust__item {
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 500;
}

.bl-trust__item svg {
	flex-shrink: 0;
	color: var(--bl-success);
}

/* ---- Closing call to action --------------------------------------------- */
.bl-cta {
	padding: clamp(2.5rem, 2rem + 3vw, 4.5rem) var(--bl-gutter);
	border-radius: var(--bl-r-xl);
	background: var(--bl-secondary);
	color: #ffffff;
	text-align: center;
}

/* The colour above is inherited, and inheritance loses to the element rule
   h1-h6 { color: var(--bl-ink) } in critical.css - so the heading on this
   dark band was near-black on near-black, 1.29:1. Anything that sets its
   own dark surface has to say so for its headings too. */
.bl-cta :is(h1, h2, h3, h4, h5, h6) {
	color: inherit;
}

.bl-cta__text {
	max-width: 52ch;
	margin: var(--bl-s4) auto 0;
	color: rgba(255, 255, 255, 0.78);
	font-size: var(--bl-fs-lg);
	line-height: 1.6;
}

.bl-cta .bl-cluster {
	justify-content: center;
	margin-block-start: var(--bl-s8);
}

.bl-cta .bl-btn--secondary {
	background: transparent;
	border-color: rgba(255, 255, 255, 0.28);
	color: #ffffff;
}

.bl-cta .bl-btn--secondary:hover {
	background: rgba(255, 255, 255, 0.1);
	border-color: rgba(255, 255, 255, 0.5);
	color: #ffffff;
}

/* --------------------------------------------------------------------------
   11. Blog + single post
   -------------------------------------------------------------------------- */
.bl-page-header {
	padding-block: clamp(2rem, 1.5rem + 3vw, 4rem);
	border-block-end: 1px solid var(--bl-border);
}

.bl-page-header__title {
	font-size: var(--bl-fs-h1);
}

.bl-page-header__text {
	margin-block-start: var(--bl-s4);
	max-width: 60ch;
	color: var(--bl-muted);
	font-size: var(--bl-fs-lg);
}

.bl-entry-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bl-s3);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

.bl-entry-meta__sep {
	opacity: 0.5;
}

.bl-entry-meta a {
	color: inherit;
	text-decoration: none;
}

.bl-entry-meta a:hover {
	color: var(--bl-accent);
}

.bl-post-card__cat {
	/* inline-flex with a minimum height so the small-caps label is a target
	   you can hit, without changing how it looks. */
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	color: var(--bl-accent);
	font-size: var(--bl-fs-xs);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
}

.bl-single__header {
	max-width: 760px;
	margin-inline: auto;
	padding-block: clamp(2rem, 1.5rem + 3vw, 3.5rem);
	text-align: center;
}

.bl-single__title {
	margin-block: var(--bl-s4);
}

.bl-single__media {
	max-width: 1100px;
	margin-inline: auto;
	margin-block-end: var(--bl-s10);
}

.bl-single__media img {
	width: 100%;
	border-radius: var(--bl-r-lg);
}

/* Content 8 columns, sidebar 4 - the grid does the sizing, so there is no
   magic 300px to keep in sync with anything. */
.bl-single__layout {
	align-items: start;
	row-gap: var(--bl-s10);
}

@media (min-width: 1024px) {
	.bl-single__layout--sidebar .bl-sidebar {
		position: sticky;
		inset-block-start: calc(var(--bl-header-h) + var(--bl-s6));
	}
}

.bl-single__content {
	margin-inline: auto;
}

.bl-share {
	display: flex;
	align-items: center;
	gap: var(--bl-s2);
	margin-block-start: var(--bl-s8);
	padding-block-start: var(--bl-s6);
	border-block-start: 1px solid var(--bl-border);
}

.bl-share__label {
	margin-inline-end: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 600;
}

.bl-tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bl-s2);
}

.bl-tag {
	padding: var(--bl-s1) var(--bl-s3);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-sm);
	background: var(--bl-surface-2);
	color: var(--bl-text);
	font-size: var(--bl-fs-sm);
	text-decoration: none;
	transition: border-color var(--bl-t), color var(--bl-t);
}

.bl-tag:hover {
	border-color: var(--bl-accent);
	color: var(--bl-accent);
}

.bl-author-box {
	display: flex;
	gap: var(--bl-s5);
	margin-block-start: var(--bl-s10);
	padding: var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface-2);
}

.bl-author-box img {
	width: 56px;
	height: 56px;
	border-radius: var(--bl-r-full);
	flex-shrink: 0;
}

.bl-author-box__name {
	font-size: var(--bl-fs-h4);
}

.bl-author-box__bio {
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
}

/* Reading progress bar */
.bl-progress {
	position: fixed;
	inset-block-start: 0;
	inset-inline-start: 0;
	z-index: 950;
	height: 3px;
	width: 100%;
	transform-origin: 0 50%;
	transform: scaleX(0);
	background: var(--bl-highlight);
	pointer-events: none;
}

/* --------------------------------------------------------------------------
   12. Comments
   -------------------------------------------------------------------------- */
.bl-comments {
	max-width: 760px;
	margin-inline: auto;
	margin-block-start: var(--bl-s16);
	padding-block-start: var(--bl-s10);
	border-block-start: 1px solid var(--bl-border);
}

.bl-comments__title {
	margin-block-end: var(--bl-s8);
	font-size: var(--bl-fs-h3);
}

.bl-comments ol {
	list-style: none;
	margin: 0;
	padding: 0;
}

.bl-comments .children {
	margin-inline-start: var(--bl-s6);
	padding-inline-start: var(--bl-s5);
	border-inline-start: 2px solid var(--bl-border);
}

.bl-comment {
	padding-block: var(--bl-s5);
}

.bl-comment__head {
	display: flex;
	align-items: center;
	gap: var(--bl-s3);
	margin-block-end: var(--bl-s3);
}

.bl-comment__avatar {
	border-radius: var(--bl-r-full);
}

.bl-comment__author {
	color: var(--bl-ink);
	font-weight: 600;
}

.bl-comment__date {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	text-decoration: none;
}

.bl-comment__body {
	font-size: var(--bl-fs-md);
}

.bl-comment__actions {
	margin-block-start: var(--bl-s3);
	font-size: var(--bl-fs-sm);
}

.comment-respond {
	margin-block-start: var(--bl-s10);
	padding: var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface-2);
}

.comment-form {
	display: grid;
	gap: var(--bl-s4);
}

.comment-form p {
	margin: 0;
}

.comment-form .comment-form-cookies-consent {
	display: flex;
	align-items: flex-start;
	gap: var(--bl-s2);
	font-size: var(--bl-fs-sm);
}

.comment-form .submit {
	justify-self: start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0.6875rem var(--bl-s5);
	border: 0;
	border-radius: var(--bl-r);
	background: var(--bl-action);
	color: var(--bl-action-contrast);
	font-size: var(--bl-fs-md);
	font-weight: 600;
	cursor: pointer;
}

.comment-form .submit:hover {
	background: var(--bl-action-hover);
}

/* --------------------------------------------------------------------------
   13. Pagination + breadcrumbs
   -------------------------------------------------------------------------- */
.bl-pagination {
	margin-block-start: var(--bl-s12);
}

.bl-pagination .nav-links,
.bl-pagination .page-numbers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--bl-s1);
	list-style: none;
	padding: 0;
	margin: 0;
}

.bl-pagination .page-numbers {
	display: inline-grid;
	place-items: center;
	min-width: 44px;
	height: 44px;
	padding-inline: var(--bl-s2);
	border: 1px solid transparent;
	border-radius: var(--bl-r);
	color: var(--bl-text);
	font-size: var(--bl-fs-md);
	font-weight: 500;
	text-decoration: none;
	transition: background-color var(--bl-t), border-color var(--bl-t), color var(--bl-t);
}

.bl-pagination a.page-numbers:hover {
	background: var(--bl-surface-2);
	border-color: var(--bl-border);
	color: var(--bl-ink);
}

.bl-pagination .page-numbers.current {
	background: var(--bl-action);
	border-color: var(--bl-action);
	color: var(--bl-action-contrast);
	font-weight: 600;
}

.bl-pagination .page-numbers.dots {
	min-width: 28px;
	color: var(--bl-muted);
}

.bl-breadcrumbs {
	padding-block: var(--bl-s4);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

.bl-breadcrumbs ol {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bl-s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-breadcrumbs a {
	color: inherit;
	text-decoration: none;
}

.bl-breadcrumbs a:hover {
	color: var(--bl-accent);
	text-decoration: underline;
}

.bl-breadcrumbs li:not(:last-child)::after {
	content: "/";
	margin-inline-start: var(--bl-s2);
	opacity: 0.45;
}

.bl-breadcrumbs [aria-current="page"] {
	color: var(--bl-ink);
	font-weight: 500;
}

/* Load-more button */
.bl-loadmore {
	display: flex;
	justify-content: center;
	margin-block-start: var(--bl-s10);
}

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */
.bl-footer {
	flex-shrink: 0;
	margin-block-start: auto;
	background: var(--bl-surface-2);
	border-block-start: 1px solid var(--bl-border);
}

/* The signup band sets the footer's top edge. It used to sit inside the brand
   column, where it made that one column 200px taller than the four link
   columns beside it and left a void across the rest of the footer. Out here it
   distorts nothing, and the form finally has the width to run in one row. */
.bl-footer__cta {
	padding-block: var(--bl-s12);
	border-block-end: 1px solid var(--bl-border);
}

.bl-footer__cta-inner {
	display: grid;
	gap: var(--bl-s6);
	align-items: center;
}

@media (min-width: 900px) {
	.bl-footer__cta-inner {
		grid-template-columns: minmax(0, 1fr) minmax(0, 460px);
		gap: var(--bl-s12);
	}
}

.bl-footer__cta-title {
	margin: 0;
	font-size: var(--bl-fs-h4);
	letter-spacing: -0.01em;
}

.bl-footer__cta-text {
	max-width: 52ch;
	margin-block: var(--bl-s2) 0;
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
}

/* Full width of its column, so the field and button finish flush with the
   link columns underneath rather than stopping short of them. */
.bl-footer__cta-form .bl-subscribe {
	max-width: none;
	width: 100%;
}

/* The band sits on the soft surface, so the field needs the page background
   to read as something you can type into. */
.bl-footer__cta-form input[type="email"] {
	background: var(--bl-surface);
}

.bl-footer__top {
	padding-block: var(--bl-s12) var(--bl-s10);
}

.bl-footer__grid {
	display: grid;
	gap: var(--bl-s10);
	align-items: start;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
}

.bl-footer__brand {
	grid-column: 1 / -1;
	max-width: 340px;
}

/* Brand block, then four link columns. */
@media (min-width: 640px) {
	.bl-footer__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 900px) {
	.bl-footer__grid {
		grid-template-columns: minmax(0, 1.5fr) repeat(4, minmax(0, 1fr));
		gap: var(--bl-s8) var(--bl-s6);
	}

	.bl-footer__brand {
		grid-column: auto;
		max-width: none;
		padding-inline-end: var(--bl-s6);
	}
}

.bl-footer__tagline {
	margin-block: var(--bl-s4);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
}

.bl-footer__heading {
	margin-block-end: var(--bl-s4);
	color: var(--bl-ink);
	font-size: var(--bl-fs-sm);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.bl-footer__menu {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--bl-s3);
}

.bl-footer__menu a {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	text-decoration: none;
	transition: color var(--bl-t);
}

.bl-footer__menu a:hover {
	color: var(--bl-accent);
}

.bl-footer__bottom {
	padding-block: var(--bl-s5);
	border-block-start: 1px solid var(--bl-border);
}

.bl-footer__bottom-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--bl-s4);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
}

.bl-footer__legal {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bl-s4);
	list-style: none;
	margin: 0;
	padding: 0;
}

.bl-footer__legal a {
	color: inherit;
	text-decoration: none;
}

.bl-footer__legal a:hover {
	color: var(--bl-accent);
}

.bl-social {
	display: flex;
	gap: var(--bl-s1);
	/* The list reset was missing, so the global ul padding and a marker were
	   still being drawn - a stray bullet sat to the left of the icons. */
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-social a {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border-radius: var(--bl-r);
	color: var(--bl-muted);
	transition: background-color var(--bl-t), color var(--bl-t);
}

.bl-social a:hover {
	background: var(--bl-surface-3);
	color: var(--bl-accent);
}

.bl-payments {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bl-s2);
}

.bl-payments img,
.bl-payments svg {
	height: 24px;
	width: auto;
	opacity: 0.7;
}

/* Theme toggle */
.bl-theme-toggle .bl-icon--sun { display: none; }
[data-theme="dark"] .bl-theme-toggle .bl-icon--sun { display: block; }
[data-theme="dark"] .bl-theme-toggle .bl-icon--moon { display: none; }

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .bl-theme-toggle .bl-icon--sun { display: block; }
	:root:not([data-theme="light"]) .bl-theme-toggle .bl-icon--moon { display: none; }
}

/* --------------------------------------------------------------------------
   15. Widgets + sidebar
   -------------------------------------------------------------------------- */
.bl-sidebar {
	display: grid;
	gap: var(--bl-s6);
}

.bl-widget {
	padding: var(--bl-s5);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
}

.bl-widget__title {
	margin-block-end: var(--bl-s4);
	font-size: var(--bl-fs-h4);
}

.bl-widget ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--bl-s2);
}

.bl-widget li a {
	color: var(--bl-text);
	font-size: var(--bl-fs-md);
	text-decoration: none;
}

.bl-widget li a:hover {
	color: var(--bl-accent);
}

/* --------------------------------------------------------------------------
   16. Notices + toasts
   -------------------------------------------------------------------------- */
.bl-notice {
	display: flex;
	align-items: flex-start;
	gap: var(--bl-s3);
	padding: var(--bl-s4) var(--bl-s5);
	border: 1px solid var(--bl-border);
	border-inline-start-width: 3px;
	border-radius: var(--bl-r);
	background: var(--bl-surface-2);
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
}

.bl-notice a {
	font-weight: 600;
}

.bl-notice--success { background: var(--bl-success-soft); border-color: var(--bl-success); }
.bl-notice--error { background: var(--bl-danger-soft); border-color: var(--bl-danger); }
.bl-notice--info { background: var(--bl-highlight-soft); border-color: var(--bl-highlight); }
.bl-notice--warning { background: var(--bl-warning-soft); border-color: var(--bl-warning); }

.bl-notice__icon { flex-shrink: 0; margin-block-start: 2px; }
.bl-notice--success .bl-notice__icon { color: var(--bl-success-text); }
.bl-notice--error .bl-notice__icon { color: var(--bl-danger); }
.bl-notice--info .bl-notice__icon { color: var(--bl-accent); }
.bl-notice--warning .bl-notice__icon { color: var(--bl-warning); }

.bl-toasts {
	position: fixed;
	inset-block-end: var(--bl-s5);
	inset-inline-end: var(--bl-s5);
	z-index: 1100;
	display: grid;
	gap: var(--bl-s2);
	width: min(360px, calc(100vw - var(--bl-s8)));
	pointer-events: none;
}

.bl-toast {
	display: flex;
	align-items: center;
	gap: var(--bl-s3);
	padding: var(--bl-s4);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r);
	background: var(--bl-surface);
	box-shadow: var(--bl-shadow-lg);
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
	pointer-events: auto;
	animation: bl-toast-in 220ms var(--bl-ease);
}

.bl-toast.is-leaving {
	animation: bl-toast-out 200ms var(--bl-ease) forwards;
}

/* The card stays neutral; only the glyph carries the state, which keeps three
   kinds of message from putting three more colours on the page. */
.bl-toast__icon { color: var(--bl-success); flex-shrink: 0; }
.bl-toast--success .bl-toast__icon { color: var(--bl-success); }
.bl-toast--warning .bl-toast__icon { color: var(--bl-warning); }
.bl-toast--error .bl-toast__icon { color: var(--bl-danger); }
.bl-toast__action { margin-inline-start: auto; font-size: var(--bl-fs-sm); font-weight: 600; white-space: nowrap; }

@keyframes bl-toast-in {
	from { opacity: 0; transform: translateY(12px); }
	to { opacity: 1; transform: translateY(0); }
}

@keyframes bl-toast-out {
	to { opacity: 0; transform: translateY(8px); }
}

/* Spinner */
.bl-spinner {
	display: inline-block;
	width: 16px;
	height: 16px;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: bl-spin 640ms linear infinite;
}

@keyframes bl-spin {
	to { transform: rotate(360deg); }
}

@keyframes bl-shimmer {
	from { background-position: 100% 50%; }
	to { background-position: 0 50%; }
}

/* --------------------------------------------------------------------------
   17. 404 / empty states
   -------------------------------------------------------------------------- */
.bl-empty {
	max-width: 520px;
	margin-inline: auto;
	padding-block: var(--bl-s16);
	text-align: center;
}

.bl-empty__icon {
	display: grid;
	place-items: center;
	width: 64px;
	height: 64px;
	margin-inline: auto;
	margin-block-end: var(--bl-s6);
	border-radius: var(--bl-r-full);
	background: var(--bl-surface-2);
	color: var(--bl-muted);
}

.bl-empty__title {
	margin-block-end: var(--bl-s3);
	font-size: var(--bl-fs-h3);
}

.bl-empty__text {
	margin-block-end: var(--bl-s6);
	color: var(--bl-muted);
}

.bl-404__code {
	font-size: clamp(4rem, 3rem + 8vw, 7rem);
	font-weight: 800;
	letter-spacing: -0.04em;
	line-height: 1;
	color: var(--bl-accent);
}

/* --------------------------------------------------------------------------
   18. Block editor output (front end)
   -------------------------------------------------------------------------- */
.alignwide {
	width: min(100%, var(--bl-container));
	margin-inline: auto;
	max-width: none;
}

.alignfull {
	width: 100vw;
	max-width: 100vw;
	margin-inline: calc(50% - 50vw);
}

.alignleft {
	float: left;
	margin-inline-end: var(--bl-s6);
	margin-block-end: var(--bl-s4);
}

.alignright {
	float: right;
	margin-inline-start: var(--bl-s6);
	margin-block-end: var(--bl-s4);
}

.aligncenter {
	margin-inline: auto;
	text-align: center;
}

.wp-caption {
	max-width: 100%;
}

.wp-block-image figcaption,
.wp-caption-text {
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	text-align: center;
}

.sticky .bl-card__title::before {
	content: "★ ";
	color: var(--bl-star);
}

.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0.6875rem var(--bl-s5);
	border-radius: var(--bl-r);
	background: var(--bl-action);
	color: var(--bl-action-contrast);
	font-size: var(--bl-fs-md);
	font-weight: 600;
	text-decoration: none;
}

.wp-block-button__link:hover {
	background: var(--bl-action-hover);
	color: var(--bl-action-contrast);
}

.is-style-outline .wp-block-button__link {
	background: transparent;
	border: 1px solid var(--bl-border-strong);
	color: var(--bl-ink);
}

/* --------------------------------------------------------------------------
   19. Print
   -------------------------------------------------------------------------- */
@media print {
	.bl-header,
	.bl-footer,
	.bl-announce,
	.bl-drawer,
	.bl-toasts,
	.bl-share,
	.bl-skip-link,
	.comment-respond {
		display: none !important;
	}

	body {
		background: #fff;
		color: #000;
		font-size: 12pt;
	}

	a::after {
		content: " (" attr(href) ")";
		font-size: 9pt;
		word-break: break-all;
	}
}

/* --------------------------------------------------------------------------
   20. Hero cover stack
   A fanned trio of covers used when the hero shows products instead of an
   image. Kept to a single transform per card - no perspective, no parallax.
   -------------------------------------------------------------------------- */
.bl-hero__stack {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: clamp(260px, 38vw, 420px);
}

.bl-hero__stack-item {
	position: relative;
	display: block;
	width: clamp(130px, 21vw, 210px);
	aspect-ratio: 2 / 3;
	border-radius: var(--bl-r);
	overflow: hidden;
	background: var(--bl-surface-3);
	box-shadow: var(--bl-shadow-lg);
	transition: transform var(--bl-t-slow);
}

.bl-hero__stack-item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.bl-hero__stack-item:nth-child(1) { z-index: 1; transform: rotate(-7deg) translateY(14px); }
.bl-hero__stack-item:nth-child(2) { z-index: 3; margin-inline: -7%; }
.bl-hero__stack-item:nth-child(3) { z-index: 2; transform: rotate(7deg) translateY(14px); }

.bl-hero__stack-item:hover,
.bl-hero__stack-item:focus-visible {
	z-index: 4;
	transform: translateY(-10px) rotate(0deg);
}

.bl-hero__image {
	border-radius: var(--bl-r-lg);
	box-shadow: var(--bl-shadow-lg);
}

/* --------------------------------------------------------------------------
   21. Stats, newsletter, post navigation, checkout progress
   -------------------------------------------------------------------------- */

/* The value reads first even though the label is the <dt>. */
.bl-stat {
	display: flex;
	flex-direction: column-reverse;
}

.bl-newsletter {
	display: grid;
	gap: var(--bl-s6);
	align-items: center;
}

@media (min-width: 900px) {
	.bl-newsletter {
		grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
		gap: var(--bl-s10);
	}
}

.bl-subscribe__note.is-success {
	color: var(--bl-success-text);
	font-weight: 500;
}

.bl-postnav {
	padding-block: var(--bl-s12);
	border-block-start: 1px solid var(--bl-border);
}

.bl-postnav__grid {
	display: grid;
	gap: var(--bl-s4);
	grid-template-columns: 1fr;
}

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

.bl-postnav__link {
	display: flex;
	flex-direction: column;
	gap: var(--bl-s2);
	padding: var(--bl-s5);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	text-decoration: none;
	transition: border-color var(--bl-t), box-shadow var(--bl-t);
}

.bl-postnav__link:hover {
	border-color: var(--bl-border-strong);
	box-shadow: var(--bl-shadow-sm);
}

.bl-postnav__link--next {
	align-items: flex-end;
	text-align: end;
}

.bl-postnav__label {
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s1);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 600;
}

.bl-postnav__title {
	color: var(--bl-ink);
	font-size: var(--bl-fs-lg);
	font-weight: 600;
	line-height: var(--bl-lh-snug);
}

.bl-steps-bar {
	margin-block-end: var(--bl-s8);
}

.bl-steps-bar ol {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--bl-s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-steps-bar__item {
	display: flex;
	align-items: center;
	gap: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	font-weight: 500;
}

.bl-steps-bar__item:not(:last-child)::after {
	content: "";
	width: clamp(16px, 6vw, 56px);
	height: 1px;
	margin-inline-start: var(--bl-s2);
	background: var(--bl-border-strong);
}

.bl-steps-bar__marker {
	display: grid;
	place-items: center;
	width: 28px;
	height: 28px;
	border: 1px solid var(--bl-border-strong);
	border-radius: var(--bl-r-full);
	font-size: var(--bl-fs-xs);
	font-weight: 700;
}

.bl-steps-bar__item.is-current {
	color: var(--bl-ink);
	font-weight: 600;
}

.bl-steps-bar__item.is-current .bl-steps-bar__marker {
	background: var(--bl-accent);
	border-color: var(--bl-accent);
	color: var(--bl-accent-contrast);
}

.bl-steps-bar__item.is-done .bl-steps-bar__marker {
	background: var(--bl-success-soft);
	border-color: var(--bl-success);
	color: var(--bl-success);
}

/* --------------------------------------------------------------------------
   22. Editorial refinements
   The details that separate a knowledge marketplace from a product catalogue:
   hairline section rules, numbered headings, a display measure that is set for
   reading rather than for filling a container.
   -------------------------------------------------------------------------- */
.bl-section-head--start {
	max-width: 44ch;
}

/* Both modifiers apply together whenever a left-aligned heading also carries
   something on the right - a "View all" link, or the carousel arrows. The
   measure above is for a column of text, so the split row opts out of it;
   without this the row is 44ch wide and whatever sits on the right wraps. */
.bl-section-head--start.bl-section-head--split {
	max-width: none;
}

/* A rule above a section is the cheapest editorial signal there is. */
.bl-section--ruled {
	border-block-start: 1px solid var(--bl-border);
}

.bl-prose {
	font-family: var(--bl-font);
}

/* Long-form copy gets the serif, which is where it earns its keep. */
.bl-prose--editorial {
	font-family: var(--bl-font-display);
	font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem);
	line-height: 1.75;
}

.bl-prose--editorial p {
	hanging-punctuation: first last;
}

/* Drop cap on the opening paragraph of an editorial article. */
.bl-prose--editorial > p:first-of-type::first-letter {
	float: inline-start;
	margin-inline-end: 0.08em;
	padding-block-start: 0.06em;
	color: var(--bl-ink);
	font-family: var(--bl-font-display);
	font-size: 3.4em;
	font-weight: var(--bl-display-weight);
	line-height: 0.82;
}

/* Section headings in the display face keep their serif even inside prose. */
.bl-section-head__title,
.bl-hero__title,
.bl-cta__title,
.bl-collection__name,
.bl-card__title,
.bl-book__title {
	font-family: var(--bl-font-display);
	font-weight: var(--bl-display-weight);
	font-style: var(--bl-display-style);
	letter-spacing: var(--bl-display-tracking);
}

/* Product and card titles stay in the sans: at 15px a serif is noise. */
.bl-book__title,
.bl-minicart__name,
.bl-download__title {
	font-family: var(--bl-font);
	font-style: normal;
	font-weight: 600;
	letter-spacing: -0.005em;
}

/* Numbers set in the display face read as a pull-stat, not a metric tile. */
.bl-stat__value {
	font-family: var(--bl-font-display);
	font-weight: var(--bl-display-weight);
	font-style: var(--bl-display-style);
}

/* The positioning line, used in the footer and on the about page. */
.bl-positioning {
	font-family: var(--bl-font-display);
	font-size: var(--bl-fs-h3);
	font-style: var(--bl-display-style);
	font-weight: var(--bl-display-weight);
	letter-spacing: var(--bl-display-tracking);
	color: var(--bl-ink);
	line-height: 1.25;
}

.bl-positioning em {
	font-style: var(--bl-display-style);
	color: var(--bl-accent);
}

/* Trust row reads as a colophon line rather than a badge row. */
.bl-trust {
	gap: var(--bl-s6) var(--bl-s8);
	justify-content: flex-start;
	padding-block-start: var(--bl-s6);
	border-block-start: 1px solid var(--bl-border);
	margin: 0;
	list-style: none;
	padding-inline: 0;
}

.bl-trust__item {
	font-size: var(--bl-fs-xs);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: var(--bl-muted);
}

.bl-section-head--center .bl-trust {
	justify-content: center;
}

/* Six feature cards divide cleanly into three columns; four leaves two
   orphans on the second row. */
@media (min-width: 1024px) {
	.bl-grid--3 {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* A left-aligned section head still wants its intro on a readable measure. */
.bl-section-head--start .bl-section-head__text {
	max-width: 52ch;
}

/* --------------------------------------------------------------------------
   23. Block widgets
   Since WordPress 5.8 widget areas render blocks, so the before_title /
   after_title markup registered in setup.php is never used and the heading
   arrives as a bare <h2 class="wp-block-heading">. Without this it inherits
   the display scale and blows the sidebar apart.
   -------------------------------------------------------------------------- */
.bl-widget .wp-block-heading,
.bl-widget > h2,
.bl-widget > h3,
.bl-sidebar .wp-block-heading,
.bl-drawer__body .wp-block-heading {
	margin-block-end: var(--bl-s4);
	color: var(--bl-ink);
	font-family: var(--bl-font);
	font-size: var(--bl-fs-xs);
	font-weight: 700;
	font-style: normal;
	letter-spacing: var(--bl-eyebrow-tracking);
	line-height: 1.4;
	text-transform: uppercase;
}

/* Long taxonomy names and archive labels must wrap inside a 260px column. */
.bl-widget,
.bl-sidebar,
.bl-shop__sidebar {
	min-width: 0;
	overflow-wrap: anywhere;
}

.bl-widget .wp-block-categories,
.bl-widget .wp-block-archives,
.bl-widget .wp-block-page-list,
.bl-widget .wp-block-latest-posts {
	display: grid;
	gap: var(--bl-s2);
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--bl-fs-md);
}

.bl-widget .wp-block-categories a,
.bl-widget .wp-block-archives a,
.bl-widget .wp-block-latest-posts a {
	color: var(--bl-text);
	text-decoration: none;
}

.bl-widget .wp-block-categories a:hover,
.bl-widget .wp-block-archives a:hover,
.bl-widget .wp-block-latest-posts a:hover {
	color: var(--bl-accent);
}

/* WooCommerce filter widgets in the shop sidebar. */
.bl-widget .wc-block-product-categories-list,
.bl-widget .wc-block-attribute-filter,
.bl-widget .wc-block-price-filter {
	font-size: var(--bl-fs-md);
}

.bl-widget .price_slider_wrapper .ui-slider {
	background: var(--bl-surface-3);
}

.bl-widget .price_slider_wrapper .ui-slider-range {
	background: var(--bl-highlight);
}

/* --------------------------------------------------------------------------
   24. Structural links
   Links carry a yellow underline by default, which is right for links inside
   prose and wrong for anchors that wrap a card, a cover or a tile. Those are
   navigation surfaces, not sentences.
   -------------------------------------------------------------------------- */
.bl-book__cover,
.bl-book__cover:hover,
.bl-collection__link,
.bl-collection__link:hover,
.bl-browse__list a,
.bl-browse__list a:hover,
.bl-postnav__link,
.bl-postnav__link:hover,
.bl-download__title a,
.bl-minicart__name,
.bl-footer__menu a,
.bl-footer__legal a,
.bl-social a,
.bl-widget li a,
.bl-tag,
.bl-chip,
.bl-termbar a,
.bl-entry-meta a,
.bl-post-card__cat,
.bl-share a,
.bl-breadcrumbs a {
	text-decoration: none;
}

/* Prose links keep the underline; these regain one on hover only. */
.bl-footer__menu a:hover,
.bl-widget li a:hover,
.bl-breadcrumbs a:hover,
.bl-entry-meta a:hover {
	text-decoration: underline;
	text-decoration-color: var(--bl-highlight);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

/* --------------------------------------------------------------------------
   Hero composition
   --------------------------------------------------------------------------
   A document preview with two covers leaning on it, two floating cards and a
   few shapes behind. Drawn rather than photographed: no art file to
   commission, nothing to re-export at 2x, and it recolours with the brand for
   free.

   Everything is placed as a percentage of one box with a fixed aspect ratio,
   so the composition scales as a unit instead of coming apart between
   breakpoints. Depth is explicit - back cover, document, front cover, cards -
   because leaving it to document order put the wrong cover in front.
   -------------------------------------------------------------------------- */
.bl-herovis {
	position: relative;
	width: 100%;
	max-width: 440px;
	margin-inline: auto;
	aspect-ratio: 1 / 1.04;
	isolation: isolate;
}

/* ---- Shapes ------------------------------------------------------------- */

.bl-herovis__shapes > * {
	position: absolute;
	z-index: 0;
	pointer-events: none;
}

.bl-herovis__blob {
	inset-block-end: -8%;
	inset-inline-end: -16%;
	width: 64%;
	aspect-ratio: 1;
	border-radius: 50%;
	background: radial-gradient(circle, var(--bl-highlight-soft), transparent 70%);
}

.bl-herovis__dots {
	inset-block-start: 6%;
	inset-inline-start: -5%;
	width: 30%;
	aspect-ratio: 1;
	background-image: radial-gradient(var(--bl-border-strong) 1.5px, transparent 1.5px);
	background-size: 14px 14px;
	opacity: 0.65;
}

.bl-herovis__ring {
	inset-block-start: -5%;
	inset-inline-end: -7%;
	width: 28%;
	aspect-ratio: 1;
	border: 1px solid var(--bl-border-strong);
	border-radius: 50%;
	opacity: 0.55;
}

/* ---- Document preview --------------------------------------------------- */

.bl-herovis__doc {
	position: absolute;
	z-index: 2;
	inset-block-start: 0;
	inset-inline-end: 0;
	width: 68%;
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	box-shadow: var(--bl-shadow-lg);
	overflow: hidden;
	transform: rotate(1.5deg);
}

.bl-herovis__docbar {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: var(--bl-s3) var(--bl-s4);
	border-block-end: 1px solid var(--bl-border);
	background: var(--bl-surface-2);
}

.bl-herovis__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--bl-border-strong);
}

.bl-herovis__tag {
	margin-inline-start: auto;
	padding: 2px var(--bl-s2);
	border-radius: var(--bl-r-xs);
	background: var(--bl-ink);
	color: var(--bl-bg);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.08em;
}

.bl-herovis__page {
	display: grid;
	gap: var(--bl-s3);
	padding: var(--bl-s5);
}

/* Bars, not lorem ipsum: it reads as a page without pretending to be words
   nobody wrote. */
.bl-herovis__line {
	display: block;
	height: 8px;
	border-radius: var(--bl-r-xs);
	background: var(--bl-surface-3);
}

.bl-herovis__line--head {
	width: 62%;
	height: 14px;
	margin-block-end: var(--bl-s2);
	background: var(--bl-ink);
}

.bl-herovis__line--accent {
	width: 46%;
	height: 10px;
	margin-block-start: var(--bl-s2);
	background: var(--bl-highlight);
}

.bl-herovis__checks {
	display: grid;
	gap: var(--bl-s3);
	margin: var(--bl-s2) 0 0;
	padding: 0;
	list-style: none;
}

.bl-herovis__checks li {
	display: flex;
	align-items: center;
	gap: var(--bl-s2);
}

.bl-herovis__checks svg {
	flex-shrink: 0;
	color: var(--bl-success);
}

.bl-herovis__checks .bl-herovis__line {
	height: 7px;
}

/* ---- Covers -------------------------------------------------------------
   Both covers are placed against the composition box rather than against
   each other, because nesting the second one inside the first made its
   position depend on a rotated parent and it kept disappearing behind the
   document. display:contents keeps the wrapper in the markup, where it is
   useful, and out of the layout, where it was not.
   ------------------------------------------------------------------------- */

.bl-herovis__covers {
	display: contents;
}

.bl-herovis__cover {
	position: absolute;
	display: block;
	aspect-ratio: 2 / 3;
	border-radius: var(--bl-r);
	box-shadow: var(--bl-shadow-lg);
	overflow: hidden;
	text-decoration: none;
}

.bl-herovis__cover img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Front: overlapping the document's lower left. Back: leaning out to its
   left, far enough that a third of it is genuinely in view. */
.bl-herovis__cover:nth-child(1) {
	z-index: 3;
	inset-block-end: 0;
	inset-inline-start: 15%;
	width: 40%;
	transform: rotate(-4deg);
}

.bl-herovis__cover:nth-child(2) {
	z-index: 1;
	inset-block-end: 7%;
	inset-inline-start: 0;
	width: 33%;
	transform: rotate(-15deg);
}

/* Without a product image a cover carries its shelf, not an invented title.
   The pair is deliberately one dark and one light: two pale cards read as
   placeholders, and the dark one gives the yellow something to sit on. */
.bl-herovis__cover--shelf {
	display: flex;
	flex-direction: column;
	/* Icon at the top, title at the foot: a cover, not a caption. */
	justify-content: space-between;
	gap: var(--bl-s4);
	padding: var(--bl-s4);
	background: var(--bl-surface-2);
	border: 1px solid var(--bl-border);
	color: var(--bl-ink);
}

/* The strip down the binding edge is what stops a rounded rectangle from
   reading as a card. */
/* A product with no cover image yet gets the same treatment, so a store
   on its launch day shows books rather than blank cards. */
.bl-herovis__cover:has(.bl-book__placeholder) {
	background: linear-gradient(155deg, var(--bl-surface-2), var(--bl-surface));
	border: 1px solid var(--bl-border);
}

.bl-herovis__cover--shelf::before,
.bl-herovis__cover:has(.bl-book__placeholder)::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 7px;
	background: rgba(0, 0, 0, 0.14);
}

.bl-herovis__cover--shelf:nth-child(1) {
	background: linear-gradient(155deg, var(--bl-secondary), #1c1b1a);
	border-color: transparent;
	color: #ffffff;
}

.bl-herovis__cover--shelf:nth-child(1)::before {
	background: rgba(255, 255, 255, 0.14);
}

.bl-herovis__cover--shelf:nth-child(1) svg {
	color: var(--bl-primary);
}

.bl-herovis__cover--shelf:nth-child(2) svg {
	color: var(--bl-muted);
}

.bl-herovis__coverfoot {
	display: grid;
	gap: var(--bl-s2);
}

.bl-herovis__covername {
	font-family: var(--bl-font-display);
	font-size: var(--bl-fs-md);
	font-weight: var(--bl-display-weight);
	letter-spacing: var(--bl-display-tracking);
	line-height: var(--bl-lh-snug);
	text-wrap: balance;
}

.bl-herovis__coverrule {
	width: 28px;
	height: 3px;
	border-radius: 2px;
	background: var(--bl-primary);
}
/* ---- Floating cards ----------------------------------------------------- */

.bl-herovis__chip {
	position: absolute;
	z-index: 4;
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s2);
	padding: var(--bl-s2) var(--bl-s3);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r);
	background: var(--bl-surface);
	box-shadow: var(--bl-shadow-md);
	color: var(--bl-ink);
	font-size: var(--bl-fs-sm);
	font-weight: 600;
	white-space: nowrap;
}

.bl-herovis__chip svg {
	color: var(--bl-accent);
}

.bl-herovis__chip--a {
	inset-block-start: 15%;
	inset-inline-start: -3%;
}

.bl-herovis__chip--b {
	inset-block-end: 27%;
	inset-inline-end: -5%;
}

/* The only movement on the page, and only on the two smallest elements.
   Transform-only, so it stays on the compositor and never triggers layout. */
@media (prefers-reduced-motion: no-preference) {
	.bl-herovis__chip {
		animation: bl-float 7s var(--bl-ease) infinite;
	}

	.bl-herovis__chip--b {
		animation-duration: 9s;
		animation-delay: -3s;
	}
}

@keyframes bl-float {
	0%,
	100% { transform: translateY(0); }
	50%  { transform: translateY(-7px); }
}

/* ---- Small screens ------------------------------------------------------ */

@media (max-width: 599px) {
	.bl-herovis {
		max-width: 330px;
	}

	/* One cover, one card: at this width the full composition is clutter. */
	.bl-herovis__cover:nth-child(2),
	.bl-herovis__chip--a {
		display: none;
	}

	.bl-herovis__page {
		padding: var(--bl-s4);
	}

	.bl-herovis__chip--b {
		inset-block-end: 6%;
		inset-inline-end: 0;
	}
}

/* --------------------------------------------------------------------------
   Trust bar
   --------------------------------------------------------------------------
   One line under the hero naming who the library is for. Typographic rather
   than a row of icons: five short phrases read faster without one, and the
   hero's own trust row directly above already carries icons.
   -------------------------------------------------------------------------- */
.bl-trustbar {
	border-block-end: 1px solid var(--bl-border);
	background: var(--bl-surface-2);
}

.bl-trustbar__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--bl-s3) var(--bl-s6);
	padding-block: var(--bl-s5);
}

.bl-trustbar__label {
	flex-shrink: 0;
	color: var(--bl-muted);
	font-size: var(--bl-fs-xs);
	font-weight: 600;
	letter-spacing: var(--bl-eyebrow-tracking);
	text-transform: uppercase;
}

.bl-trustbar__list {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--bl-s3) var(--bl-s5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-trustbar__item {
	position: relative;
	color: var(--bl-ink);
	font-size: var(--bl-fs-md);
	font-weight: 600;
}

/* A hairline between items rather than a bullet: it holds the row together
   without adding a fifth shape to the page.

   Only above 768px, where the five fit on one line. CSS cannot ask whether an
   item begins a wrapped row, so below that the separator was rendering as a
   stray vertical line floating at the left edge of the second row. Spacing
   does the same job there without the artefact. */
@media (min-width: 768px) {
	.bl-trustbar__item + .bl-trustbar__item::before {
		content: "";
		position: absolute;
		inset-block: 2px;
		inset-inline-start: calc(var(--bl-s5) / -2);
		width: 1px;
		background: var(--bl-border-strong);
	}
}

@media (max-width: 599px) {
	.bl-trustbar__inner {
		gap: var(--bl-s2);
		padding-block: var(--bl-s4);
	}

	.bl-trustbar__list {
		gap: var(--bl-s2) var(--bl-s4);
	}

	.bl-trustbar__item {
		font-size: var(--bl-fs-sm);
	}
}

/* --------------------------------------------------------------------------
   Product grid
   --------------------------------------------------------------------------
   Four across on desktop, two on tablet, one on a small phone. Explicit
   breakpoints rather than auto-fit: auto-fit derives the column count from a
   minimum card width, which lands on three at tablet and one at phone - close
   to the brief but not it. Stating the counts says what is meant.
   -------------------------------------------------------------------------- */
.bl-books {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--bl-s6) var(--bl-s5);
}

@media (min-width: 480px) {
	.bl-books {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	/* Four across, unless the section has fewer than four to show - a row of
	   three in a four-column grid reads as a missing card rather than as a
	   short row. The count comes from the query, not from a guess. */
	.bl-books {
		grid-template-columns: repeat(var(--bl-book-cols, 4), minmax(0, 1fr));
	}
}

/* The collection a book leads with, above the title. */
.bl-book__cat {
	margin-block-end: var(--bl-s1);
	font-size: var(--bl-fs-xs);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.bl-book__cat a {
	color: var(--bl-muted);
	text-decoration: none;
	transition: color var(--bl-t);
}

.bl-book__cat a:hover,
.bl-book__cat a:focus-visible {
	color: var(--bl-ink);
}

/* Two lines, always. A summary that runs longer makes the row of cards
   ragged, and one that runs shorter should not pull the price up to meet it. */
.bl-book__summary {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
	margin-block: var(--bl-s2) 0;
	color: var(--bl-muted);
	font-size: var(--bl-fs-sm);
	line-height: 1.5;
}

/* A wide card and a 2:3 cover make a very tall card: two columns across a
   tablet produced one 800px tall, and three columns on a desktop is not much
   better. Capping the cover keeps the book's proportions and the card's at
   the same time. The text stays aligned to the card rather than to the cover,
   so the column still reads as a column.

   Unset at four columns, where the card is already narrow enough. */
.bl-books .bl-book__cover {
	max-width: var(--bl-cover-max, none);
}

@media (min-width: 600px) {
	.bl-books {
		--bl-cover-max: 240px;
	}
}

@media (min-width: 1024px) {
	.bl-books {
		--bl-cover-max: 300px;
	}
}

/* --------------------------------------------------------------------------
   Bundles
   --------------------------------------------------------------------------
   A bundle sells on arithmetic, not on a cover: what the parts cost, what the
   set costs, and the gap. So the card spends its space on the numbers and the
   contents list, and the section sits on a tinted ground so the argument does
   not read as another row of books.
   -------------------------------------------------------------------------- */
.bl-bundles {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--bl-s5);
}

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

.bl-bundle {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--bl-s5);
	padding: var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface);
	transition: border-color var(--bl-t), box-shadow var(--bl-t);
}

.bl-bundle:hover {
	border-color: var(--bl-border-strong);
	box-shadow: var(--bl-shadow-md);
}

/* The saving is the headline, so it sits above the title in the reading
   order and in the corner visually. Yellow as a fill with ink on top: the
   brand yellow is 1.46:1 on white and cannot carry text itself. */
.bl-bundle__save {
	position: absolute;
	inset-block-start: var(--bl-s6);
	inset-inline-end: var(--bl-s6);
	padding: var(--bl-s1) var(--bl-s3);
	border-radius: var(--bl-r-sm);
	background: var(--bl-highlight);
	color: var(--bl-ink);
	font-size: var(--bl-fs-sm);
	font-weight: 700;
	white-space: nowrap;
}

.bl-bundle__head {
	/* Room for the saving badge, so a long title never runs under it. */
	padding-inline-end: 6.5rem;
}

.bl-bundle__title {
	font-size: var(--bl-fs-h4);
	color: var(--bl-ink);
}

.bl-bundle__title a {
	color: inherit;
	text-decoration: none;
}

.bl-bundle__title a:hover {
	text-decoration: underline;
	text-decoration-color: var(--bl-highlight);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

.bl-bundle__text {
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	line-height: 1.55;
}

.bl-bundle__contents {
	padding: var(--bl-s4) var(--bl-s5);
	border-radius: var(--bl-r);
	background: var(--bl-surface-2);
}

.bl-bundle__count {
	margin-block-end: var(--bl-s3);
	color: var(--bl-ink);
	font-size: var(--bl-fs-xs);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.bl-bundle__list {
	display: grid;
	gap: var(--bl-s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-bundle__list li {
	display: flex;
	align-items: flex-start;
	gap: var(--bl-s2);
	color: var(--bl-text);
	font-size: var(--bl-fs-sm);
	line-height: 1.45;
}

.bl-bundle__list svg {
	flex-shrink: 0;
	margin-block-start: 2px;
	color: var(--bl-success);
}

.bl-bundle__more {
	color: var(--bl-muted);
	font-style: italic;
	padding-inline-start: calc(15px + var(--bl-s2));
}

.bl-bundle__foot {
	margin-block-start: auto;
}

.bl-bundle__prices {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--bl-s3);
	margin-block-end: var(--bl-s4);
}

.bl-bundle__was {
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	text-decoration: line-through;
	text-decoration-thickness: 1px;
}

.bl-bundle__now {
	color: var(--bl-ink);
	font-family: var(--bl-font-display);
	font-size: var(--bl-fs-h3);
	font-weight: var(--bl-display-weight);
	letter-spacing: var(--bl-display-tracking);
	line-height: 1;
}

@media (max-width: 599px) {
	.bl-bundle {
		padding: var(--bl-s5);
	}

	.bl-bundle__save {
		inset-block-start: var(--bl-s5);
		inset-inline-end: var(--bl-s5);
	}
}

/* --------------------------------------------------------------------------
   Free resources: the lead-in panel
   --------------------------------------------------------------------------
   The ask sits directly under the free titles rather than in its own section
   further down the page: a visitor who has just decided not to take one of
   them is the person most worth asking, and they are right here.
   -------------------------------------------------------------------------- */
.bl-leadin {
	display: grid;
	gap: var(--bl-s6);
	margin-block-start: var(--bl-s10);
	padding: var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface-2);
}

@media (min-width: 900px) {
	.bl-leadin {
		grid-template-columns: 1fr minmax(320px, 26rem);
		align-items: center;
		gap: var(--bl-s10);
		padding: var(--bl-s8);
	}
}

.bl-leadin__copy {
	display: flex;
	align-items: flex-start;
	gap: var(--bl-s4);
}

.bl-leadin__icon {
	flex-shrink: 0;
	margin-block-start: 2px;
	color: var(--bl-accent);
}

.bl-leadin__title {
	font-size: var(--bl-fs-h4);
	color: var(--bl-ink);
}

.bl-leadin__text {
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	line-height: 1.55;
	max-width: 46ch;
}

/* On its own ground the form needs its field to read as a field. */
.bl-leadin .bl-subscribe input[type="email"] {
	background: var(--bl-surface);
}

/* --------------------------------------------------------------------------
   Search results
   --------------------------------------------------------------------------
   Three groups rather than one list. A marketplace holds three different kinds
   of thing, and one relevance ranking across unlike things ranks nothing in
   particular.
   -------------------------------------------------------------------------- */
.bl-searchagain {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--bl-s3);
	margin-block-end: var(--bl-s8);
}

.bl-searchagain__icon {
	position: absolute;
	inset-inline-start: var(--bl-s4);
	color: var(--bl-muted);
	pointer-events: none;
}

.bl-searchagain input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	padding-inline-start: calc(var(--bl-s4) * 2 + 18px);
	font-size: var(--bl-fs-lg);
}

/* Collections are links, not results: somewhere to go rather than something
   to read, so they sit above the groups as a row rather than inside one. */
.bl-searchcols {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bl-s3);
	margin-block-end: var(--bl-s8);
	padding-block-end: var(--bl-s6);
	border-block-end: 1px solid var(--bl-border);
}

.bl-searchcols__label {
	color: var(--bl-muted);
	font-size: var(--bl-fs-xs);
	font-weight: 600;
	letter-spacing: var(--bl-eyebrow-tracking);
	text-transform: uppercase;
}

.bl-searchcols ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bl-s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.bl-searchcols a {
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s2);
	padding: var(--bl-s2) var(--bl-s3);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r);
	background: var(--bl-surface);
	color: var(--bl-ink);
	font-size: var(--bl-fs-sm);
	font-weight: 500;
	text-decoration: none;
	transition: border-color var(--bl-t), background-color var(--bl-t);
}

.bl-searchcols a:hover {
	border-color: var(--bl-border-strong);
	background: var(--bl-surface-2);
}

.bl-searchcols svg {
	color: var(--bl-accent);
}

.bl-searchgroup + .bl-searchgroup {
	margin-block-start: var(--bl-s12);
	padding-block-start: var(--bl-s8);
	border-block-start: 1px solid var(--bl-border);
}

.bl-searchgroup__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--bl-s4);
	margin-block-end: var(--bl-s6);
}

.bl-searchgroup__title {
	display: flex;
	align-items: center;
	gap: var(--bl-s3);
	font-size: var(--bl-fs-h3);
	color: var(--bl-ink);
}

/* The count sits with the heading rather than under it: it is part of the
   answer, not a caption. */
.bl-searchgroup__count {
	padding-inline: var(--bl-s2);
	border-radius: var(--bl-r-full);
	background: var(--bl-surface-2);
	color: var(--bl-muted);
	font-family: var(--bl-font);
	font-size: var(--bl-fs-sm);
	font-weight: 600;
	line-height: 1.7;
	letter-spacing: 0;
	font-variant-numeric: tabular-nums;
}

.bl-searchgroup__more {
	display: inline-flex;
	align-items: center;
	gap: var(--bl-s2);
	color: var(--bl-ink);
	font-size: var(--bl-fs-sm);
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

.bl-searchgroup__more:hover {
	text-decoration: underline;
	text-decoration-color: var(--bl-highlight);
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

/* --------------------------------------------------------------------------
   The eBooks under a post
   --------------------------------------------------------------------------
   The blog's job is to be found and to sell the catalogue. This is the second
   half: set apart from the article with a rule and a tint so it reads as an
   offer rather than as more of the piece, but on the same measure so it does
   not feel bolted on.
   -------------------------------------------------------------------------- */
.bl-postshelf {
	margin-block-start: var(--bl-s12);
	padding: var(--bl-s8) var(--bl-s6);
	border: 1px solid var(--bl-border);
	border-radius: var(--bl-r-lg);
	background: var(--bl-surface-2);
}

.bl-postshelf__title {
	font-size: var(--bl-fs-h3);
	color: var(--bl-ink);
}

.bl-postshelf__note {
	margin-block-start: var(--bl-s2);
	color: var(--bl-muted);
	font-size: var(--bl-fs-md);
	max-width: 46ch;
}

.bl-postshelf .bl-books {
	margin-block-start: var(--bl-s6);
}

/* Cards sit on a tinted ground here, so they need their own. */
.bl-postshelf .bl-book__cover {
	background: var(--bl-surface);
}

@media (max-width: 599px) {
	.bl-postshelf {
		padding: var(--bl-s6) var(--bl-s5);
	}
}

/* The smaller heading that sits over a grid - "Keep reading", "Popular right
   now", "Readers are buying". It was three copies of the same two inline
   styles before, one in each template that needed it. */
.bl-section-head--sub {
	margin-block-end: var(--bl-s8);
}

.bl-section-head--sub .bl-section-head__title {
	font-size: var(--bl-fs-h3);
}

/* ==========================================================================
   Carousel

   Layered over the scroll-snap rail. Everything here is scoped to
   .is-enhanced, which JavaScript adds once the controls exist - so with
   scripting off the rail keeps its scrollbar and nothing below applies.
   ========================================================================== */

.bl-carousel {
	position: relative;
}

/* The scrollbar is replaced by the dots, but only once there are dots. */
.bl-carousel.is-enhanced .bl-quotes {
	scrollbar-width: none;
	scroll-snap-type: x mandatory;
	padding-bottom: var(--bl-s2);
}

.bl-carousel.is-enhanced .bl-quotes::-webkit-scrollbar {
	display: none;
}

.bl-carousel.is-enhanced .bl-quotes.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	scroll-behavior: auto;
	user-select: none;
}

/* --------------------------------------------------------------- Controls */

.bl-carousel__bar {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--bl-s4);
	margin-block-start: var(--bl-s5);
}

.bl-carousel__nav {
	display: flex;
	gap: var(--bl-s2);
	flex-shrink: 0;
}

/* Beside a section heading the arrows sit at the end of the row. */
.bl-section-head .bl-carousel__nav {
	margin-inline-start: auto;
}

.bl-carousel__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--bl-border-strong);
	border-radius: 50%;
	background: var(--bl-surface);
	color: var(--bl-ink);
	cursor: pointer;
	transition: border-color var(--bl-t), background var(--bl-t), color var(--bl-t);
}

.bl-carousel__arrow:hover:not(:disabled) {
	border-color: var(--bl-muted);
	background: var(--bl-surface-2);
	color: var(--bl-ink);
}

.bl-carousel__arrow:focus-visible {
	outline: 2px solid var(--bl-accent);
	outline-offset: 2px;
}

.bl-carousel__arrow:disabled {
	opacity: 0.35;
	cursor: default;
}

.bl-carousel__dots {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--bl-s2);
	flex-wrap: wrap;
}

.bl-carousel__dot {
	position: relative;
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--bl-border-strong);
	cursor: pointer;
	transition: width var(--bl-t), background var(--bl-t);
}

/* The touch target is 44px; only the dot itself is 8px. */
.bl-carousel__dot::before {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 44px;
	height: 44px;
	transform: translate(-50%, -50%);
}

.bl-carousel__dot.is-active {
	width: 24px;
	border-radius: 999px;
	background: var(--bl-ink);
}

.bl-carousel__dot:focus-visible {
	outline: 2px solid var(--bl-accent);
	outline-offset: 3px;
}

/* Nothing to page through: hide the controls rather than show dead ones. */
.bl-carousel.is-static .bl-carousel__bar,
.bl-carousel.is-static .bl-carousel__nav {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.bl-carousel__arrow,
	.bl-carousel__dot {
		transition: none;
	}
}

/* ==========================================================================
   Coming soon

   WooCommerce renders this screen as blocks, and leans on the block library
   and the global styles for its centring and spacing. The theme dequeues
   both, so without the rules below the heading sits flush against the left
   edge of the viewport with no gutter - which is how it looked before this
   existed. Styling it here keeps the page on-brand and costs nothing, where
   loading the block library back in for one screen would cost plenty.
   ========================================================================== */

.wp-block-woocommerce-coming-soon {
	display: grid;
	place-items: center;
	min-height: min(70vh, 660px);
	padding-block: var(--bl-s16);
	padding-inline: var(--bl-gutter);
	text-align: center;
}

.wp-block-woocommerce-coming-soon .wp-block-group {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--bl-s5);
	/* Wide enough that the heading gets two lines rather than three; the
	   paragraph sets its own, narrower measure below. */
	max-width: 58ch;
	margin-inline: auto;
}

/* Fixed 100px spacers, sized for a layout this theme does not use. The gap
   above spaces the stack instead, so it stays proportional on a phone. */
.wp-block-woocommerce-coming-soon .wp-block-spacer {
	display: none;
}

.wp-block-woocommerce-coming-soon h1 {
	margin: 0;
	font-family: var(--bl-font-display);
	font-size: var(--bl-fs-h1);
	font-weight: var(--bl-display-weight);
	letter-spacing: var(--bl-display-tracking);
	line-height: 1.05;
	text-wrap: balance;
}

.wp-block-woocommerce-coming-soon p {
	margin: 0;
	max-width: 42ch;
	color: var(--bl-muted);
	font-size: var(--bl-fs-lg);
	line-height: 1.65;
	text-wrap: pretty;
}

/* The rule under the heading is the same gesture the hero uses to mark a
   line as the important one. */
.bl-soon__mark {
	display: block;
	width: 64px;
	height: 4px;
	border-radius: 999px;
	background: var(--bl-primary);
}

.bl-soon__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--bl-s3);
	margin-block-start: var(--bl-s2);
}

@media (max-width: 479px) {
	.bl-soon__actions {
		width: 100%;
	}

	.bl-soon__actions .bl-btn {
		flex: 1 1 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bl-toast,
	.bl-toast.is-leaving {
		animation: none;
	}
}
