/*
Theme Name:   JoJo Pierre Child
Theme URI:    https://jojopierrebooks.com
Description:  Child theme for jojopierrebooks.com. All custom code lives here; the parent
              theme (Extendable) is never edited. Signature element is The Shelf.
Author:       JoJo Pierre Books
Template:     extendable
Version:      1.0.0
Text Domain:  jojopierre-child
*/

/* ==========================================================================
   1. TOKENS
   Locked. Dark ink for hero and shelf, warm paper for reading sections,
   gold for hairline rules and single accents only — never a fill, never a
   gradient.
   ========================================================================== */

:root {
	--jp-ink:   #101A2B;
	--jp-gold:  #C9962F;
	--jp-teal:  #2E6E75;
	--jp-paper: #FBF7EF;
	--jp-cloud: #F3EDE1;   /* warmed 16 Aug — was #F5F7FA, a cold blue-grey */
	/* Warm bronze-brown. Added 16 Aug for the shelf heading — the palette had no
	   brown. Chosen to sit between the gold and the navy rather than fight either:
	   contrast 5.58:1 on ink, comfortably past the 3:1 large-text floor, and warm
	   enough to read as brown rather than as a dimmer gold. */
	--jp-bronze: #C08552;
	--jp-text:  #1B1F27;

	--jp-font-display: "Newsreader", Georgia, "Times New Roman", serif;
	--jp-font-body:    "Karla", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--jp-font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

	/* the one motion curve used site-wide */
	--jp-ease: cubic-bezier(0.2, 0, 0, 1);

	/* two-layer shadow: contact plus ambient. Never one soft blur. */
	--jp-shadow: 0 1px 2px rgba(16, 26, 43, 0.18),
	             0 12px 28px rgba(16, 26, 43, 0.12);
	--jp-shadow-lift: 0 2px 4px rgba(16, 26, 43, 0.22),
	                  0 24px 48px rgba(16, 26, 43, 0.18);
}

/* ==========================================================================
   2. SURFACES
   ========================================================================== */

.jp-surface-ink {
	background-color: var(--jp-ink);
	color: var(--jp-paper);
}

.jp-surface-paper {
	background-color: var(--jp-paper);
	color: var(--jp-text);
}

.jp-surface-cloud {
	background-color: var(--jp-cloud);
	color: var(--jp-text);
}

/* The only permitted use of gold as a shape: a hairline rule. */
.jp-rule {
	border: 0;
	border-top: 1px solid var(--jp-gold);
	width: 4rem;
	margin: 2rem 0;
	opacity: 1;
}

.jp-rule--center { margin-inline: auto; }

.jp-eyebrow {
	font-family: var(--jp-font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	margin: 0 0 0.75rem;
}

/* ==========================================================================
   3. WORDMARK — header and footer. No image logo in navigation.
   ========================================================================== */

.jp-wordmark {
	font-family: var(--jp-font-display);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	line-height: 1.1;
	text-decoration: none;
	color: inherit;
	display: inline-block;
}

.jp-wordmark--header { font-size: clamp(1rem, 1.6vw, 1.25rem); }
.jp-wordmark--footer { font-size: 1rem; }

.jp-wordmark:hover,
.jp-wordmark:focus-visible { color: var(--jp-gold); }

/* ==========================================================================
   4. HERO — the thesis line is the hero. No image behind it.
   ========================================================================== */

.jp-hero {
	background-color: var(--jp-ink);
	color: var(--jp-paper);
	padding: clamp(4rem, 12vh, 8rem) clamp(1.25rem, 5vw, 4rem);
}

.jp-hero__inner { max-width: 62rem; margin-inline: auto; }

.jp-hero__thesis {
	font-family: var(--jp-font-display);
	font-weight: 400;
	font-size: clamp(2.5rem, 7.5vw, 5.5rem);
	line-height: 1.04;
	letter-spacing: -0.015em;
	margin: 0 0 1.5rem;
	text-wrap: balance;
}

.jp-hero__subhead {
	font-family: var(--jp-font-body);
	font-size: clamp(1rem, 1.6vw, 1.175rem);
	line-height: 1.6;
	max-width: 34rem;
	margin: 0 0 2.25rem;
	color: rgba(251, 247, 239, 0.78);
}

.jp-cta {
	display: inline-block;
	font-family: var(--jp-font-body);
	font-weight: 700;
	font-size: 1rem;
	letter-spacing: 0.01em;
	padding: 0.875rem 1.75rem;
	border-radius: 2px;
	text-decoration: none;
	transition: background-color 200ms var(--jp-ease),
	            color 200ms var(--jp-ease),
	            border-color 200ms var(--jp-ease);
}

.jp-cta--primary {
	background-color: var(--jp-paper);
	color: var(--jp-ink);
	border: 1px solid var(--jp-paper);
}

.jp-cta--primary:hover,
.jp-cta--primary:focus-visible {
	background-color: var(--jp-gold);
	border-color: var(--jp-gold);
	color: var(--jp-ink);
}

.jp-cta--ghost {
	background-color: transparent;
	color: var(--jp-ink);
	border: 1px solid rgba(16, 26, 43, 0.35);
}

.jp-cta--ghost:hover,
.jp-cta--ghost:focus-visible { border-color: var(--jp-gold); }

/* ==========================================================================
   5. THE SHELF — the signature element.
   Covers are physical objects: shallow perspective, two-layer contact shadow,
   slight overlap at rest, separating on hover.
   Hard ceilings: rotateY <= 6deg, translateZ <= 40px. Do not raise them.
   ========================================================================== */

.jp-shelf-section {
	background-color: var(--jp-ink);
	color: var(--jp-paper);
	padding: clamp(3.5rem, 9vh, 6rem) clamp(1.25rem, 5vw, 4rem);
}

/* --------------------------------------------------------------------------
   Genre groups on the shelf.

   The catalogue spans five genres — Christian devotionals, children's,
   business, relationship, motivational — so the shelf is grouped rather than
   one continuous row. Each group owns its own .shelf, which restarts the
   overlap and the lead-cover sizing per genre instead of letting one run of
   covers stretch across unrelated titles.

   A genre with no published title is simply absent from the page. Do not
   render an empty genre heading: a heading with nothing under it reads as a
   catalogue with holes in it, which is worse than a shorter shelf.
   -------------------------------------------------------------------------- */

/* ==========================================================================
   TITLE CARD — added 16 Aug 2026, replaces the overlapping shelf row for any
   title that carries a blurb or a signup form.

   Why the row was abandoned for these: an overlapping perspective row of covers
   is a browsing device. It works when each item is a cover and a two-line
   caption, which is what Safe Travels is. It cannot hold a 40-word blurb and an
   embedded third-party form under a 14rem-wide cover without becoming the mess
   the owner photographed — and at phone width the row collapses to a single
   column anyway, so the overlap buys nothing there.

   The card mirrors the .jp-featured block that the owner named as the quality
   bar: cover on one side, everything else on the other, generous even spacing,
   stacking to one column on small screens. Same rhythm, dark ground.
   ========================================================================== */

.jp-titlecard {
	display: grid;
	grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
	gap: clamp(1.5rem, 4vw, 3rem);
	align-items: start;
	padding: clamp(1.5rem, 3.5vw, 2.5rem);
	background-color: rgba(251, 247, 239, 0.035);
	border: 1px solid rgba(201, 150, 47, 0.22);
	border-radius: 3px;
}

.jp-titlecard + .jp-titlecard { margin-top: clamp(1.25rem, 3vh, 2rem); }

/* One cap for every cover on the page, so Safe Travels, TJ, Universal and Faith
   are all the same size regardless of category or aspect ratio. 22rem = 352px,
   inside the 300-360px the owner asked for. */
.jp-titlecard__cover { margin: 0; max-width: 22rem; }

/* No aspect-ratio and no cropping: portrait novels and the square picture book
   both render whole, each at its own intrinsic ratio. */
.jp-titlecard__cover img {
	display: block;
	width: 100%;
	height: auto;
	object-fit: contain;
	box-shadow: var(--jp-shadow);
	border-radius: 2px;
}

.jp-titlecard__cover a { display: block; }
.jp-titlecard__cover a:focus-visible { outline: 2px solid var(--jp-gold); outline-offset: 4px; }

/* Edition label. Each edition is now its own self-contained card, so the label
   sits under the shared title to keep the two reading as siblings rather than as
   two unrelated books — the shared title and subtitle do the rest. */
.jp-titlecard__ed {
	display: block;
	font-family: var(--jp-font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--jp-gold);
	margin: 0 0 0.5rem;
}

.jp-titlecard__panel { min-width: 0; }

.jp-titlecard__title {
	font-family: var(--jp-font-display);
	font-weight: 400;
	font-size: clamp(1.375rem, 2.6vw, 1.875rem);
	line-height: 1.15;
	margin: 0 0 0.5rem;
	color: var(--jp-paper);
	text-wrap: balance;
}

.jp-titlecard__sub {
	font-family: var(--jp-font-body);
	font-size: 1rem;
	line-height: 1.5;
	margin: 0 0 0.75rem;
	color: rgba(251, 247, 239, 0.78);
}

.jp-titlecard__meta {
	font-family: var(--jp-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: rgba(251, 247, 239, 0.6);
	margin: 0 0 1rem;
}

.jp-titlecard__blurb {
	font-family: var(--jp-font-body);
	font-size: 0.9375rem;
	line-height: 1.65;
	color: rgba(251, 247, 239, 0.86);
	margin: 0 0 1.25rem;
	max-width: 38rem;
}

/* Belly band, now a badge in the panel rather than a strip across the artwork.
   Over the cover it sat on top of the illustration and competed with the title;
   here it reads as status and never obscures the book. */
.jp-band {
	display: inline-block;
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--jp-ink);
	background-color: var(--jp-gold);
	padding: 0.375rem 0.75rem;
	border-radius: 2px;
	margin: 0 0 1rem;
}

.jp-band--out { background-color: var(--jp-paper); }

/* Edition labels under the paired covers. */
/* --------------------------------------------------------------------------
   Kit form container.

   The forms arrive with their own light styling, which is why they read as
   "empty white boxes" dropped onto the ink ground. Rather than fight Kit's
   markup — which would break the next time the form is edited in Kit — the
   container gives the form a deliberate paper panel to sit in, so the light
   background looks intended instead of accidental.
   -------------------------------------------------------------------------- */

.jp-notify {
	margin: 0;
	max-width: 30rem;
	background-color: var(--jp-paper);
	color: var(--jp-text);
	border-radius: 3px;
	padding: clamp(0.875rem, 2vw, 1.25rem);
}

.jp-notify > * { max-width: 100%; }

.jp-notify input[type="email"],
.jp-notify input[type="text"] {
	width: 100%;
	box-sizing: border-box;
}

/* Badge handling moved out of this block and unscoped — see "KIT BADGE" at the
   foot of this stylesheet. Scoping it to .jp-notify was the bug: the forms
   inserted as Gutenberg blocks are not inside that wrapper. */

/* Section header. Stands alone — no eyebrow above it, no slogan beneath it. */
.jp-shelf-heading {
	max-width: 68rem;
	margin: 0 auto clamp(2rem, 5vh, 3.25rem);
	font-family: var(--jp-font-display);
	font-weight: 500;
	font-size: clamp(2.25rem, 6vw, 3.5rem);
	line-height: 1.04;
	letter-spacing: -0.015em;
	color: var(--jp-bronze);
}

/* --------------------------------------------------------------------------
   Responsive. One column below 768px, cover centred and capped so it does not
   fill a phone screen, and the same spacing rhythm as desktop rather than a
   tighter one — the shelf read cramped at phone width, not just on desktop.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
	.jp-titlecard {
		grid-template-columns: 1fr;
		gap: 1.5rem;
		padding: 1.5rem 1.25rem;
	}

	.jp-titlecard__cover { max-width: 13rem; margin-inline: auto; }

	.jp-titlecard + .jp-titlecard { margin-top: 1.5rem; }

	.jp-genre + .jp-genre { margin-top: 3rem; }

	.jp-notify { max-width: 100%; }

	/* Home-page teaser row: drop the overlap and the perspective tilt on small
	   screens. Overlapping covers at 320px hide more than they show. */
	.shelf { flex-wrap: wrap; gap: 1.5rem; justify-content: center; }
	.shelf__cover + .shelf__cover { margin-left: 0; }
	.shelf__cover { transform: none; width: clamp(8rem, 40vw, 11rem); }
}

.jp-genre { max-width: 68rem; margin: 0 auto; }

.jp-genre + .jp-genre { margin-top: clamp(2.75rem, 6vh, 4.5rem); }

.jp-genre__head {
	display: flex;
	align-items: baseline;
	gap: 0.875rem;
	margin: 0 0 1.25rem;
}

.jp-genre__name {
	font-family: var(--jp-font-display);
	font-weight: 500;
	font-size: clamp(1.125rem, 2.4vw, 1.5rem);
	line-height: 1.2;
	margin: 0;
	color: var(--jp-paper);
}

/* Hairline that runs out from the genre name to the edge of the measure.
   Gold, one pixel, no fill — the accent rule from the token block. */
.jp-genre__head::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: rgba(201, 150, 47, 0.35);
}

.jp-genre__count {
	font-family: var(--jp-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(251, 247, 239, 0.55);
	white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Edition pair. One product, two editions, one cover.

   Boardroom to Boarding Pass ships as a Universal Edition and a Faith Edition
   sharing a single cover. The owner's rule: show them as a pair, distinguished
   by an edition line — never as two unrelated books.

   So the pair is ONE .shelf__cover, not two. A single cover, the shared title,
   then the two edition lines bracketed beneath it in gold. Two covers side by
   side would read as two books no matter what the labels said, and a reader who
   bought one would be left wondering whether they bought the wrong one.
   -------------------------------------------------------------------------- */

.shelf__cover--pair { width: clamp(18rem, 36vw, 28rem); }

/* The pair is one shelf item, so it must not pick up the neighbour-overlap
   that single covers use — it would slide a cover under the previous genre. */
.shelf__cover--pair + .shelf__cover,
.shelf__cover + .shelf__cover--pair { margin-left: 0; }

.jp-pair {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(0.5rem, 1.5vw, 1rem);
	align-items: start;
}

.jp-pair__item {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	min-width: 0;
}

.jp-pair__item img {
	display: block;
	width: 100%;
	height: auto;
	object-fit: contain;
}

/* The edition name carries the entire distinction between the two products,
   so it is the one thing set apart from the surrounding metadata. */
.jp-pair__edition-name {
	display: block;
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--jp-gold);
	text-align: center;
	padding-top: 0.4375rem;
	border-top: 1px solid rgba(201, 150, 47, 0.45);
}

.jp-pair__note {
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--jp-gold);
	margin: 0.5rem 0 0;
}

.jp-pair__blurbs {
	list-style: none;
	margin: 0.75rem 0 0;
	padding: 0;
	display: grid;
	gap: 0.625rem;
}

.jp-pair__blurbs li {
	font-family: var(--jp-font-body);
	font-size: 0.8125rem;
	line-height: 1.45;
	color: rgba(251, 247, 239, 0.82);
	padding-left: 0.75rem;
	border-left: 2px solid rgba(201, 150, 47, 0.4);
}

.jp-pair__blurbs strong {
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--jp-gold);
	display: block;
	font-weight: 400;
	margin-bottom: 0.1875rem;
}

.shelf {
	perspective: 1600px;
	display: flex;
	align-items: flex-end;
	justify-content: flex-start;
	gap: 0;
	max-width: 68rem;
	margin-inline: auto;
	padding-bottom: 1.5rem;
	list-style: none;
}

/* the shelf itself — a single hairline the covers sit on */
.shelf::after {
	content: "";
	display: block;
}

.shelf__cover {
	position: relative;
	flex: 0 0 auto;
	width: clamp(9rem, 17vw, 14rem);
	transform: rotateY(6deg) translateZ(0);
	transform-style: preserve-3d;
	box-shadow: var(--jp-shadow);
	transition: transform 240ms var(--jp-ease),
	            box-shadow 240ms var(--jp-ease),
	            opacity 240ms var(--jp-ease);
	background-color: var(--jp-cloud);
}

/* slight overlap at rest, from the second cover onward */
.shelf__cover + .shelf__cover { margin-left: -2.5rem; }

/* FIXED 16 Aug 2026 — this rule was cropping every cover on the site.
 *
 * It forced a 2/3 box with object-fit:cover, so any cover whose real ratio was
 * not exactly 0.667 had its edges cut to fill. Actual ratios in the catalogue:
 * Safe Travels 0.638, Boardroom Universal 0.648, Boardroom Faith 0.627, and
 * TJ 0.971 — a square picture book. Safe Travels survived because it is close
 * to 2/3; TJ lost the top of its title outright.
 *
 * No forced ratio now. Each cover renders at its own intrinsic size and is
 * never cropped, which is the only rule that can hold both a portrait novel
 * and a square picture book. Covers are bottom-aligned on the shelf, so
 * different heights still sit on one baseline. */
.shelf__cover img,
.shelf__cover .shelf__stub {
	display: block;
	width: 100%;
	height: auto;
	object-fit: contain;
}

/* Stubs have no intrinsic size, so they alone still need a box to occupy. */
.shelf__cover .shelf__stub { aspect-ratio: 2 / 3; }
.shelf__cover--square .shelf__stub { aspect-ratio: 1 / 1; }

.shelf__cover:hover,
.shelf__cover:focus-within {
	transform: rotateY(0deg) translateZ(40px);
	box-shadow: var(--jp-shadow-lift);
	z-index: 2;
}

/* neighbours recede a touch */
.shelf:hover .shelf__cover:not(:hover) { opacity: 0.72; }

/* nearest-to-launch title sits leftmost with the most visual weight */
.shelf__cover--lead { width: clamp(10.5rem, 20vw, 16.5rem); z-index: 3; }

.shelf__cover a { display: block; text-decoration: none; color: inherit; }

.shelf__cover a:focus-visible { outline: 2px solid var(--jp-gold); outline-offset: 4px; }

.shelf__meta {
	padding: 0.875rem 0 0;
	font-family: var(--jp-font-body);
	font-size: 0.875rem;
	line-height: 1.4;
	color: rgba(251, 247, 239, 0.86);
}

.shelf__title {
	font-family: var(--jp-font-display);
	font-size: 1.0625rem;
	font-weight: 500;
	margin: 0 0 0.125rem;
	color: var(--jp-paper);
}

.shelf__format {
	font-family: var(--jp-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: rgba(251, 247, 239, 0.6);
}

/* Blurb under a coming title. Body face, sentence case — deliberately not the
   mono metadata treatment, because this is copy to be read, not a spec line. */
.shelf__blurb {
	font-family: var(--jp-font-body);
	font-size: 0.8125rem;
	line-height: 1.45;
	color: rgba(251, 247, 239, 0.82);
	margin: 0.5rem 0 0;
	text-transform: none;
	letter-spacing: 0;
}

/* --- Belly band (obi) — coming-soon titles, same shelf ------------------- */

.shelf__band {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 33.333%;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--jp-paper);
	color: var(--jp-ink);
	font-family: var(--jp-font-mono);
	font-size: clamp(0.5625rem, 0.85vw, 0.75rem);
	letter-spacing: 0.24em;
	text-transform: uppercase;
	text-align: center;
	padding: 0 0.5rem;
	border-top: 1px solid var(--jp-gold);
	box-shadow: 0 -1px 2px rgba(16, 26, 43, 0.12);
}

/* --- Cover stub — used only while assets/covers/ is empty ---------------- */

.shelf__stub {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 1.25rem;
	background-color: var(--jp-cloud);
	color: var(--jp-ink);
	text-align: center;
}

/* Placeholder for a title whose artwork does not exist yet.

   Deliberately NOT stand-in art. A generic stock image in a cover slot reads as
   the real cover to anyone scrolling, and it is worse than an honest blank —
   the reader learns the cover is wrong only after they have formed an
   impression of the book. So this is a typographic card that says what it is
   and when the artwork is due, on the ink ground so it recedes behind the one
   real cover on the shelf rather than competing with it. */
.shelf__stub--coming {
	background-color: #16223a;
	color: var(--jp-paper);
	border: 1px solid rgba(201, 150, 47, 0.4);
}

.shelf__stub--coming .shelf__stub-title { color: var(--jp-paper); }

.shelf__stub--coming .shelf__stub-note {
	color: var(--jp-gold);
	border-top: 1px solid rgba(201, 150, 47, 0.3);
	padding-top: 0.5rem;
	margin-top: 0.25rem;
}

.shelf__stub-title {
	font-family: var(--jp-font-display);
	font-size: clamp(0.9375rem, 1.5vw, 1.125rem);
	line-height: 1.25;
	font-weight: 500;
}

.shelf__stub-note {
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(16, 26, 43, 0.55);
}

/* --- Mobile: drop the perspective entirely, stack, keep the shadow ------- */

@media (max-width: 767px) {
	.shelf {
		perspective: none;
		display: grid;
		grid-template-columns: 1fr;
		gap: 2rem;
		justify-items: center;
	}

	.shelf__cover,
	.shelf__cover--lead {
		width: min(62vw, 15rem);
		transform: none;
		box-shadow: var(--jp-shadow);
	}

	.shelf__cover + .shelf__cover { margin-left: 0; }

	.shelf__cover:hover,
	.shelf__cover:focus-within { transform: none; box-shadow: var(--jp-shadow); }

	.shelf:hover .shelf__cover:not(:hover) { opacity: 1; }
}

/* ==========================================================================
   6. FEATURED TITLE PANEL
   Large cover left, quiet metadata panel right. No spin, no carousel.
   ========================================================================== */

.jp-featured {
	background-color: var(--jp-paper);
	color: var(--jp-text);
	padding: clamp(3.5rem, 9vh, 6rem) clamp(1.25rem, 5vw, 4rem);
}

.jp-featured__inner {
	display: grid;
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: center;
	max-width: 68rem;
	margin-inline: auto;
}

/* Same crop bug as .shelf__cover img, missed on 16 Aug and fixed here: a forced
   2/3 box cut every cover that was not exactly 0.667. No forced ratio now. */
.jp-featured__cover img,
.jp-featured__cover .shelf__stub {
	display: block;
	width: 100%;
	height: auto;
	object-fit: contain;
	box-shadow: var(--jp-shadow);
}

.jp-featured__cover .shelf__stub { aspect-ratio: 2 / 3; }

/* Hard cap. Without it the cover takes its whole grid column, which on a wide
   screen is ~28rem and reads as a poster rather than a book. */
.jp-featured__cover { max-width: 22rem; }

.jp-featured__title {
	font-family: var(--jp-font-display);
	font-size: clamp(1.875rem, 4vw, 2.75rem);
	line-height: 1.1;
	font-weight: 400;
	margin: 0 0 0.5rem;
}

.jp-featured__desc {
	font-family: var(--jp-font-body);
	font-size: 1.0625rem;
	line-height: 1.65;
	max-width: 34rem;
	margin: 0 0 1.75rem;
}

.jp-buys { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.jp-buy {
	display: inline-block;
	font-family: var(--jp-font-body);
	font-weight: 700;
	font-size: 0.9375rem;
	padding: 0.8125rem 1.5rem;
	border-radius: 2px;
	text-decoration: none;
	background-color: var(--jp-ink);
	color: var(--jp-paper);
	border: 1px solid var(--jp-ink);
	transition: background-color 200ms var(--jp-ease), color 200ms var(--jp-ease);
}

.jp-buy:hover,
.jp-buy:focus-visible { background-color: var(--jp-teal); border-color: var(--jp-teal); }

.jp-buy--secondary {
	background-color: transparent;
	color: var(--jp-ink);
}

.jp-buy--secondary:hover,
.jp-buy--secondary:focus-visible { background-color: var(--jp-ink); color: var(--jp-paper); }

@media (max-width: 767px) {
	.jp-featured__inner { grid-template-columns: 1fr; }
	.jp-featured__cover { max-width: 15rem; margin-inline: auto; }
}

/* ==========================================================================
   7. HERO SETTLE — one orchestrated page-load moment, the only motion
   on the homepage. Thesis sets first, then the covers settle in.
   ========================================================================== */

@keyframes jp-settle-line {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: translateY(0); }
}

@keyframes jp-settle-cover {
	from { opacity: 0; transform: translateY(24px) rotateY(6deg); }
	to   { opacity: 1; transform: translateY(0) rotateY(6deg); }
}

.jp-settle .jp-hero__thesis {
	animation: jp-settle-line 320ms var(--jp-ease) both;
}

.jp-settle .jp-hero__subhead,
.jp-settle .jp-hero__cta {
	animation: jp-settle-line 320ms var(--jp-ease) both;
	animation-delay: 160ms;
}

/* three covers arrive on a 60ms stagger, 700ms total, then everything is still */
.jp-settle .shelf__cover {
	animation: jp-settle-cover 380ms var(--jp-ease) both;
}

.jp-settle .shelf__cover:nth-child(1) { animation-delay: 320ms; }
.jp-settle .shelf__cover:nth-child(2) { animation-delay: 380ms; }
.jp-settle .shelf__cover:nth-child(3) { animation-delay: 440ms; }

/* ==========================================================================
   8. THE PASS CARD — /boarding-pass back issues.
   The ticket survives as a shape, not an animation. Nothing here moves.
   ========================================================================== */

.jp-pass-archive {
	background-color: var(--jp-ink);
	color: var(--jp-paper);
	padding: clamp(3.5rem, 9vh, 6rem) clamp(1.25rem, 5vw, 4rem);
}

.jp-pass-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
	gap: 1.5rem;
	max-width: 68rem;
	margin-inline: auto;
	list-style: none;
	padding: 0;
}

.jp-pass {
	position: relative;
	display: grid;
	grid-template-columns: 4.5rem 1fr;
	background-color: var(--jp-paper);
	color: var(--jp-text);
	min-height: 11rem;
	box-shadow: var(--jp-shadow);
	overflow: hidden;
}

/* perforation notches down the tear line — CSS only, no image */
.jp-pass::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 4.5rem;
	width: 1px;
	background-image: radial-gradient(circle at 0.5px 50%,
	                  var(--jp-ink) 0 0.5px, transparent 0.5px);
	background-size: 1px 7px;
	background-repeat: repeat-y;
	opacity: 0.45;
}

/* the stub edge */
.jp-pass__stub {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.25rem;
	padding: 1rem 0.5rem;
	border-right: 1px solid rgba(16, 26, 43, 0.12);
	text-align: center;
}

.jp-pass__no {
	font-family: var(--jp-font-mono);
	font-size: 1.25rem;
	letter-spacing: 0.06em;
	font-weight: 500;
}

.jp-pass__season {
	font-family: var(--jp-font-mono);
	font-size: 0.5625rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(16, 26, 43, 0.6);
}

.jp-pass__body { padding: 1.25rem 1.5rem; }

.jp-pass__theme {
	font-family: var(--jp-font-display);
	font-size: 1.375rem;
	line-height: 1.2;
	font-weight: 500;
	margin: 0 0 0.5rem;
}

/* the single accent on the card */
.jp-pass__body .jp-rule { width: 2.5rem; margin: 0.75rem 0; }

.jp-pass__territory {
	font-family: var(--jp-font-body);
	font-size: 0.9375rem;
	line-height: 1.55;
	margin: 0;
	color: rgba(27, 31, 39, 0.82);
}

.jp-pass--empty { background-color: rgba(251, 247, 239, 0.06); color: var(--jp-paper); }
.jp-pass--empty .jp-pass__stub { border-right-color: rgba(251, 247, 239, 0.16); }
.jp-pass--empty .jp-pass__season,
.jp-pass--empty .jp-pass__territory { color: rgba(251, 247, 239, 0.68); }
.jp-pass--empty::before { background-image: radial-gradient(circle at 0.5px 50%,
	var(--jp-paper) 0 0.5px, transparent 0.5px); opacity: 0.35; }

/* ==========================================================================
   9. READING SECTIONS — About and long-form, on warm paper.
   ========================================================================== */

.jp-reading {
	background-color: var(--jp-paper);
	color: var(--jp-text);
	padding: clamp(3.5rem, 9vh, 6rem) clamp(1.25rem, 5vw, 4rem);
}

.jp-reading__inner { max-width: 42rem; margin-inline: auto; }

.jp-reading h1 {
	font-family: var(--jp-font-display);
	font-size: clamp(2rem, 5.5vw, 3.25rem);
	line-height: 1.08;
	font-weight: 400;
	letter-spacing: -0.01em;
	margin: 0 0 1.5rem;
	text-wrap: balance;
}

.jp-reading h2 {
	font-family: var(--jp-font-display);
	font-size: clamp(1.375rem, 3vw, 1.875rem);
	line-height: 1.2;
	font-weight: 500;
	margin: 3rem 0 1rem;
}

.jp-reading h3 {
	font-family: var(--jp-font-display);
	font-size: 1.25rem;
	font-weight: 500;
	margin: 2rem 0 0.5rem;
}

.jp-reading p,
.jp-reading li {
	font-family: var(--jp-font-body);
	font-size: 1.0625rem;
	line-height: 1.7;
}

.jp-reading a { color: var(--jp-teal); text-underline-offset: 0.15em; }

/* --------------------------------------------------------------------------
   Author photo. About page only. Sits in the reading column, above the
   opening line, at the same 42rem measure. Portrait crop is the file's own —
   the image is published exactly as supplied, no crop and no filter, so
   nothing here touches its tone or framing.
   -------------------------------------------------------------------------- */

.jp-author-photo {
	margin: 0 0 2rem;
}

.jp-author-photo img {
	display: block;
	width: 320px;
	max-width: 100%;
	height: auto;
	aspect-ratio: 1125 / 1197;   /* the file's intrinsic ratio — reserves space, never crops */
	object-fit: contain;
	border-radius: 2px;
}

/* ==========================================================================
   10. SIGNATURE AND SEAL
   Signature: bare, About page and end of a Boarding Pass issue. Never in
   the header. Seal: 180px and above only; below that, the JPB monogram.
   The -6deg tilt is applied here, at the point of use — never baked in.
   ========================================================================== */

.jp-signature {
	display: block;
	width: 280px;
	max-width: 70%;
	height: auto;
	margin: 2.5rem 0 0;
}

.jp-signature--invitation { width: 240px; margin-top: 2rem; }

/* Reverse artwork on dark surfaces. */
.jp-surface-ink .jp-signature { filter: none; }

.jp-seal {
	display: block;
	width: 180px;   /* floor. Below 180px the ring text stops being legible. */
	height: auto;
	transform: rotate(-6deg);
	transform-origin: center;
}

.jp-seal--lg { width: 220px; }

/* One seal per surface. If a second appears, the markup is wrong, not the CSS. */

/* ==========================================================================
   11. SIGNUP BANDS AND FORMS
   ========================================================================== */

.jp-offer-band {
	background-color: var(--jp-ink);
	color: var(--jp-paper);
	padding: clamp(3rem, 8vh, 5rem) clamp(1.25rem, 5vw, 4rem);
}

.jp-offer-band__inner { max-width: 44rem; margin-inline: auto; text-align: center; }

.jp-offer-band__title {
	font-family: var(--jp-font-display);
	font-size: clamp(1.625rem, 4vw, 2.5rem);
	line-height: 1.15;
	font-weight: 400;
	margin: 0 0 1rem;
}

.jp-offer-band__body {
	font-family: var(--jp-font-body);
	font-size: 1.0625rem;
	line-height: 1.65;
	color: rgba(251, 247, 239, 0.82);
	margin: 0 0 2rem;
}

.jp-form-note {
	font-family: var(--jp-font-body);
	font-size: 0.8125rem;
	line-height: 1.5;
	opacity: 0.72;
	margin-top: 1rem;
}

/* ==========================================================================
   12. FOOTER
   ========================================================================== */

.jp-footer {
	background-color: var(--jp-ink);
	color: rgba(251, 247, 239, 0.8);
	padding: clamp(3rem, 7vh, 4.5rem) clamp(1.25rem, 5vw, 4rem) 2rem;
	font-family: var(--jp-font-body);
	font-size: 0.9375rem;
}

.jp-footer__inner {
	max-width: 68rem;
	margin-inline: auto;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
	gap: 2.5rem;
}

.jp-footer a { color: rgba(251, 247, 239, 0.8); text-decoration: none; }
.jp-footer a:hover,
.jp-footer a:focus-visible { color: var(--jp-gold); text-decoration: underline; }

.jp-footer__col h2 {
	font-family: var(--jp-font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(251, 247, 239, 0.55);
	margin: 0 0 0.875rem;
	font-weight: 400;
}

/* Kit form slots embedded inside Custom HTML blocks.

   Kit ships its own form styling, so this deliberately styles the CONTAINER only
   and leaves the form's internals alone — overriding Kit's markup here would
   break the moment the form is edited in Kit, which is where it should be edited.
   The container just gives the form room and keeps it inside the shelf card. */
.jp-footer__list { list-style: none; margin: 0; padding: 0; }
.jp-footer__list li { margin-bottom: 0.5rem; }

/* CAN-SPAM postal address.

   Legally required in every commercial email, and it belongs on the site for the
   same reason: the address in the email footer and the address on the site must
   agree, or the disclosure reads as evasive. <address> is the correct element —
   it is for contact details of the page's owner, which is exactly this. Browsers
   italicise it by default; that is undone here because this is a disclosure, not
   an aside, and it should read as plainly as the copyright line. */
.jp-footer__address,
.jp-legal-address {
	font-family: var(--jp-font-body);
	font-size: 0.8125rem;
	line-height: 1.6;
	font-style: normal;
	margin-top: 1rem;
	opacity: 0.72;
}

/* On the paper-surface privacy policy the same block sits on light ground, where
   the footer's translucency would wash it out. */
.jp-legal-address {
	opacity: 1;
	color: var(--jp-text);
	margin-top: 1.25rem;
}

.jp-footer__bottom {
	max-width: 68rem;
	margin: 2.5rem auto 0;
	padding-top: 1.5rem;
	border-top: 1px solid rgba(201, 150, 47, 0.35);
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 1.5rem;
	justify-content: space-between;
	font-size: 0.8125rem;
	color: rgba(251, 247, 239, 0.6);
}

/* ==========================================================================
   13. ACCESSIBILITY AND MOTION
   ========================================================================== */

a:focus-visible,
button:focus-visible,
input:focus-visible {
	outline: 2px solid var(--jp-gold);
	outline-offset: 3px;
}

.jp-visually-hidden {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

@media (prefers-reduced-motion: reduce) {
	/* Shelf: no transform transition. Shadow and layout stay. */
	.shelf__cover {
		transition: box-shadow 240ms var(--jp-ease);
	}

	.shelf__cover:hover,
	.shelf__cover:focus-within {
		transform: rotateY(6deg) translateZ(0);
		box-shadow: var(--jp-shadow-lift);
	}

	/* Hero settle: render the final state immediately, no sequence. */
	.jp-settle .jp-hero__thesis,
	.jp-settle .jp-hero__subhead,
	.jp-settle .jp-hero__cta,
	.jp-settle .shelf__cover {
		animation: none !important;
		opacity: 1;
		transform: none;
	}

	.jp-settle .shelf__cover { transform: rotateY(6deg) translateZ(0); }

	*, *::before, *::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
	}
}

/* ==========================================================================
   14. NO HORIZONTAL SCROLL — checked at 375 / 768 / 1440
   ========================================================================== */

html, body { overflow-x: hidden; }
img, svg, video { max-width: 100%; }


/* ==========================================================================
   THE MAP WALL — About page only. Added 16 Aug 2026.

   A dot-matrix world map in gold, sitting between the cream ground and the
   text. It is texture, not a feature: at the shipped opacity you should notice
   it only once you go looking.

   The artwork is generated, not sourced. assets/patterns/world-dots.svg is
   rasterised from coarse coastline polygons authored for this build, so there
   is no third-party file and nothing to licence. It is a stylised
   approximation, not a survey-accurate map.

   Scoping: body.jp-page-about, added in functions.php on is_page('about').
   Nothing here can apply anywhere else on the site.

   Construction: <main> carries the cream and the map; the page's own paper
   sections are made transparent so the map is not painted over by them. Text
   sits in .jp-reading__inner above the overlay, so nothing renders through the
   glyphs themselves.

   Contrast, measured against the live copy (#1B1F27 on #FBF7EF, 15.45:1 clean):
     0.025  worst case 15.19:1
     0.045  worst case 14.93:1
     0.070  worst case 14.56:1
   Worst case = a glyph sitting directly on a dot. All three stay AAA, so the
   choice is aesthetic, not an accessibility trade.
   ========================================================================== */

body.jp-page-about { --jp-map-opacity: 0.16; }   /* PEAK of the sheen; troughs ~45% of this */

body.jp-page-about main {
	position: relative;
	isolation: isolate;
	background-color: var(--jp-paper);
}

/* The sections would otherwise paint their own cream over the map. */
body.jp-page-about main .jp-surface-paper { background-color: transparent; }

body.jp-page-about main::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: url("assets/patterns/world-dots.svg");
	background-repeat: no-repeat;
	background-position: center 6rem;
	background-size: min(130%, 82rem) auto;
	opacity: var(--jp-map-opacity);
	pointer-events: none;
	z-index: 0;

	/* SHEEN.
	   A flat tint of gold reads as ink, not as gold — real gilding is only ever
	   read as metal because the light across it is uneven. So rather than
	   brighten the whole map, the layer is masked with a diagonal gradient: the
	   dots stay one colour, but their strength rises and falls across the page
	   as if a light were raking over foil.

	   Deliberately STATIC. The brand allows exactly one piece of motion, the
	   homepage settle; an animated shimmer behind body copy would also be the
	   sort of thing a reader cannot switch off. The sheen is in the geometry,
	   not in time.

	   Peak sits at --jp-map-opacity, troughs at roughly 45% of it, so the
	   brightest bands match the level already approved and the rest falls away. */
	-webkit-mask-image: linear-gradient(112deg,
		rgba(0, 0, 0, 0.45) 0%,
		rgba(0, 0, 0, 1)    26%,
		rgba(0, 0, 0, 0.5)  44%,
		rgba(0, 0, 0, 1)    64%,
		rgba(0, 0, 0, 0.6)  82%,
		rgba(0, 0, 0, 0.45) 100%);
	mask-image: linear-gradient(112deg,
		rgba(0, 0, 0, 0.45) 0%,
		rgba(0, 0, 0, 1)    26%,
		rgba(0, 0, 0, 0.5)  44%,
		rgba(0, 0, 0, 1)    64%,
		rgba(0, 0, 0, 0.6)  82%,
		rgba(0, 0, 0, 0.45) 100%);
}

/* Copy sits above the wall. */
body.jp-page-about main .jp-reading__inner { position: relative; z-index: 1; }

@media (max-width: 767px) {
	body.jp-page-about main::before {
		background-size: 180% auto;
		background-position: center 4rem;
	}
}

/* A background flourish is exactly the thing to drop when a reader has asked
   for less. */
@media (prefers-contrast: more) {
	body.jp-page-about main::before { display: none; }
}


/* --------------------------------------------------------------------------
   Remove Extendable's pale-lavender page-title band on the About page.

   It comes from templates/page-with-title.html, which wraps wp:post-title in a
   full-width group with backgroundColor "tertiary" — #F2F2FA in Extendable's
   palette. Against the cream it reads as a cold purple strip.

   It is also a DUPLICATE H1: the band prints the page title as an h1, and the
   About copy opens with its own h1 ("Most of what I write, I wrote in an
   airport."). Two h1s on one page is a real structural fault, not only a
   clash — which is why this uses display:none rather than a colour override.
   display:none removes the element from the accessibility tree as well as the
   render, so the duplicate heading goes away for screen readers too.

   The cleaner permanent fix is to switch the page to the plain "Page"
   template, which never renders the band at all. This rule is here so the
   clash is gone either way.
   -------------------------------------------------------------------------- */

body.jp-page-about main > .has-tertiary-background-color { display: none; }


/* ==========================================================================
   WARMTH PASS — site-wide, 16 Aug 2026.

   Brief: everything should belong to the world of the bookshelf hero. Warm
   lighting, dark wood, gold lettering, cream pages. No pure white, no cold
   grey, no blank gaps between sections.

   ONE CONSTRAINT WORTH RECORDING, because it decides half the choices below:
   #C08552 measures 2.93:1 on cream. That is below the 3:1 floor for large text
   and nowhere near the 4.5:1 for body, so the bronze that reads beautifully on
   navy cannot carry text on cream. Two browns are therefore needed, not one:
   the light bronze for ink grounds, a deeper brown for cream grounds. Using one
   brown everywhere would have meant unreadable headings on half the site.
   ========================================================================== */

:root {
	/* Warm neutrals and browns. Contrast, measured:
	   --jp-bronze       on ink   5.58:1   |  on cream 2.93:1  (ink only)
	   --jp-bronze-deep  on cream 5.42:1   -> safe for body text
	   --jp-bronze-dark  on cream 7.71:1   -> safe for anything */
	--jp-bronze-deep: #8C5A33;
	--jp-bronze-dark: #6F4522;

	/* Hairlines. Every section gets one, so no two surfaces ever meet on a
	   cold blank seam. */
	--jp-hairline-ink:   rgba(201, 150, 47, 0.30);
	--jp-hairline-paper: rgba(140,  90, 51, 0.22);
}

/* --------------------------------------------------------------------------
   1. NO PURE WHITE ANYWHERE
   Extendable ships background #ffffff and tertiary #F2F2FA, a cold lavender.
   Both are overridden at the custom-property level so every block that
   references a preset inherits the warm value rather than each one needing a
   rule of its own.
   -------------------------------------------------------------------------- */

:root,
body,
.editor-styles-wrapper {
	--wp--preset--color--background: #FBF7EF;
	--wp--preset--color--tertiary:   #F3EDE1;
}

html,
body { background-color: var(--jp-paper); }

/* Anything still asking for the white preset explicitly. */
.has-background-background-color { background-color: var(--jp-paper) !important; }

/* --------------------------------------------------------------------------
   2. DEPTH ON THE DARK SURFACES
   Flat navy reads as a slab. Two layers give it the feel of a lit room: a warm
   gold bloom falling from above, then a slow vertical settle into shadow.
   Both are extremely low alpha — this should register as atmosphere, not as a
   gradient anyone can point at.
   -------------------------------------------------------------------------- */

.jp-surface-ink,
.jp-hero,
.jp-shelf-section,
.jp-offer-band,
.jp-pass-archive {
	background-color: var(--jp-ink);
	background-image:
		radial-gradient(120% 90% at 50% -10%, rgba(201, 150, 47, 0.075) 0%, rgba(201, 150, 47, 0) 58%),
		linear-gradient(180deg, rgba(251, 247, 239, 0.035) 0%, rgba(0, 0, 0, 0.14) 100%);
}

/* --------------------------------------------------------------------------
   3. WARMTH ON THE CREAM SURFACES
   A faint bronze bloom from the top edge, so cream reads as lit paper rather
   than as an empty panel.
   -------------------------------------------------------------------------- */

.jp-surface-paper,
.jp-reading,
.jp-featured {
	background-color: var(--jp-paper);
	background-image:
		radial-gradient(120% 80% at 50% 0%, rgba(140, 90, 51, 0.055) 0%, rgba(140, 90, 51, 0) 62%);
}

/* --------------------------------------------------------------------------
   4. SECTION TRANSITIONS
   A hairline on every section, tuned to the ground it sits on. No section ever
   butts against the next on a bare seam.
   -------------------------------------------------------------------------- */

.jp-hero,
.jp-shelf-section,
.jp-offer-band,
.jp-pass-archive { border-top: 1px solid var(--jp-hairline-ink); }

.jp-reading,
.jp-featured { border-top: 1px solid var(--jp-hairline-paper); }

/* --------------------------------------------------------------------------
   5. BROWN AND GOLD AS THE ACCENT SYSTEM
   Eyebrows carry the brown, since they are the most repeated small element on
   the site. Each ground gets the brown that is legible on it.
   -------------------------------------------------------------------------- */

.jp-surface-paper .jp-eyebrow,
.jp-reading .jp-eyebrow,
.jp-featured .jp-eyebrow { color: var(--jp-bronze-deep); }

.jp-surface-ink .jp-eyebrow,
.jp-shelf-section .jp-eyebrow,
.jp-offer-band .jp-eyebrow,
.jp-pass-archive .jp-eyebrow,
.jp-hero .jp-eyebrow { color: var(--jp-bronze); }

/* Headings on cream pick up the deepest brown — warm, and still 7.71:1. */
.jp-reading h2,
.jp-reading h3,
.jp-featured__title { color: var(--jp-bronze-dark); }

/* Borders and cards warm up rather than sitting on neutral grey. */
.jp-titlecard { border-color: rgba(201, 150, 47, 0.26); }
.jp-notify { border: 1px solid rgba(140, 90, 51, 0.18); }
.jp-cta--ghost { border-color: rgba(140, 90, 51, 0.45); }

/* The signature stays ink — it is a signature, not an accent. */


/* ==========================================================================
   HERO PHOTOGRAPH — Home only. Added 16 Aug 2026.

   The bookshelf-with-ladder image is the site's visual identity and is
   permanent. It is referenced from content/pages/home.html so it survives a
   re-paste; these rules make it safe to put text on.

   THE SCRIM IS NOT DECORATION. Cream text over an unknown photograph has no
   guaranteed contrast — a bright patch of shelf behind a word makes that word
   vanish. The overlay is set so that even the worst possible case, a pure-white
   pixel, still leaves cream text at 8:1. Measured:
       scrim 0.70 -> 6.02:1   AA
       scrim 0.80 -> ~8.7:1   AAA   <- shipped
       scrim 0.90 -> 12.26:1  AAA
   Below 0.70 the photograph starts deciding whether the headline is readable,
   which is not a thing to leave to chance.

   NOTE ON THE FILE: it is 1470x2205, a PORTRAIT image in a landscape band. With
   object-fit: cover most of its height is cropped away on desktop. A landscape
   export would show far more of the shelf; object-position is centred so the
   crop takes from top and bottom evenly.
   ========================================================================== */

.jp-hero--photo {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	min-height: clamp(26rem, 68vh, 42rem);
	display: flex;
	align-items: center;
}

.jp-hero__media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	z-index: 0;
}

.jp-hero--photo::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(180deg,
		rgba(16, 26, 43, 0.80) 0%,
		rgba(16, 26, 43, 0.86) 55%,
		rgba(16, 26, 43, 0.93) 100%);
}

.jp-hero--photo .jp-hero__inner {
	position: relative;
	z-index: 2;
	width: 100%;
}

/* Portrait source, portrait viewport: the crop is far kinder on a phone, so the
   band can be taller and show more of the shelf. */
@media (max-width: 767px) {
	.jp-hero--photo { min-height: clamp(24rem, 76vh, 34rem); }
}


/* ==========================================================================
   KIT BADGE — "Built with Kit"

   RESOLVED 17 Aug 2026 by reading Kit's own form JavaScript at
   https://jojo-pierre-books.kit.com/<uid>/index.js, which injects both the form
   markup and its own <style> block.

   THE BADGE IS NOT STYLED TEXT — IT IS AN IMAGE. Kit renders it as a white
   rounded pill carrying an SVG wordmark as a background-image:

       .formkit-powered-by-convertkit[data-variant="dark"] {
           background-color:#ffffff; background-image:url("data:image/svg+xml,...")
       }

   That is why every earlier attempt failed to make a visible difference: setting
   font-size and font-weight does nothing to a background image. The white pill
   was the "bold and prominent" thing on the page, not the type.

   The good news from the same file: Kit uses **no !important** anywhere in those
   eight badge rules. So !important here wins outright — the earlier problem was
   never specificity, it was targeting the wrong property.

   So: kill the pill and the SVG, and let the anchor's real text content
   ("Built with Kit", which is present in the markup) show at small size. That
   leaves the attribution legible and clickable, which is what the free plan
   requires, without a white box shouting from a cream page.
   ========================================================================== */

.formkit-powered-by-convertkit-container {
	opacity: 0.45 !important;
	margin: 0 !important;
	padding: 2px 0 !important;
	width: 100% !important;
	display: block !important;
	text-align: center !important;
	background: none !important;
	border: none !important;
	box-shadow: none !important;
}

.formkit-powered-by-convertkit-container a,
a.formkit-powered-by-convertkit,
[data-element="powered-by"] {
	/* the pill and the wordmark image */
	background: none !important;
	background-color: transparent !important;
	background-image: none !important;
	border: none !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	transform: none !important;

	/* let the real text render, at a whisper */
	font-size: 0.625rem !important;
	font-weight: 400 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	text-indent: 0 !important;
	text-decoration: none !important;
	color: inherit !important;
	opacity: 0.45 !important;

	/* Kit sizes the pill explicitly; release it so it shrinks to the text */
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: 0 auto !important;
	overflow: visible !important;
	display: inline !important;
}

.formkit-powered-by-convertkit-container a:hover,
.formkit-powered-by-convertkit-container a:focus-visible { opacity: 0.8 !important; }


/* ==========================================================================
   COMING-SOON CAROUSEL — the sliding shelf. /books/ only. 17 Aug 2026.

   Built on native scroll-snap rather than a carousel library. That is a
   deliberate choice, not a shortcut:
     - it drags, swipes and flicks correctly on touch for free
     - it is keyboard-scrollable and screen-reader traversable by default
     - it degrades to a plain scrollable row if the JS never loads
     - it adds no dependency to a site that currently ships none
   The arrows are an enhancement layered on top, not the mechanism.

   The next card deliberately PEEKS at the right edge. A row that ends flush
   with the container looks finished; a sliver of the next cover is the only
   honest signal that there is more to slide to.
   ========================================================================== */

.jp-carousel { position: relative; max-width: 68rem; margin: 0 auto; }

.jp-carousel__head {
	display: flex;
	align-items: baseline;
	gap: 0.875rem;
	margin: 0 0 1.25rem;
}

.jp-carousel__title {
	font-family: var(--jp-font-display);
	font-weight: 500;
	font-size: clamp(1.25rem, 2.6vw, 1.625rem);
	margin: 0;
	color: var(--jp-bronze);
}

.jp-carousel__head::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: rgba(201, 150, 47, 0.35);
}

.jp-carousel__rail {
	display: flex;
	gap: clamp(1rem, 2.5vw, 1.75rem);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scroll-padding-left: 0;
	padding: 0.25rem 0 1.5rem;
	margin: 0;
	list-style: none;
	/* room for the peek */
	scrollbar-width: thin;
	scrollbar-color: rgba(201, 150, 47, 0.45) transparent;
	-webkit-overflow-scrolling: touch;
}

.jp-carousel__rail::-webkit-scrollbar { height: 6px; }
.jp-carousel__rail::-webkit-scrollbar-track { background: rgba(251, 247, 239, 0.06); border-radius: 3px; }
.jp-carousel__rail::-webkit-scrollbar-thumb { background: rgba(201, 150, 47, 0.45); border-radius: 3px; }

.jp-carousel__card {
	scroll-snap-align: start;
	flex: 0 0 auto;
	/* 88% on a phone leaves the next card peeking; capped so it never sprawls */
	width: clamp(15rem, 78vw, 21rem);
	display: flex;
	flex-direction: column;
	background-color: rgba(251, 247, 239, 0.045);
	border: 1px solid rgba(201, 150, 47, 0.24);
	border-radius: 3px;
	padding: clamp(1.25rem, 2.5vw, 1.5rem);
	transition: border-color 240ms var(--jp-ease), transform 240ms var(--jp-ease);
}

.jp-carousel__card:hover,
.jp-carousel__card:focus-within {
	border-color: rgba(201, 150, 47, 0.55);
	transform: translateY(-3px);
}

.jp-carousel__cover { margin: 0 0 1.125rem; }

/* No forced ratio — the square picture book and the portrait titles both show
   whole, the same rule that fixed the cropping elsewhere. */
.jp-carousel__cover img {
	display: block;
	width: 100%;
	height: auto;
	object-fit: contain;
	box-shadow: var(--jp-shadow);
	border-radius: 2px;
}

.jp-carousel__genre {
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(251, 247, 239, 0.55);
	margin: 0 0 0.5rem;
}

.jp-carousel__name {
	font-family: var(--jp-font-display);
	font-weight: 400;
	font-size: clamp(1.125rem, 2.2vw, 1.375rem);
	line-height: 1.2;
	margin: 0 0 0.375rem;
	color: var(--jp-paper);
}

.jp-carousel__ed {
	display: block;
	font-family: var(--jp-font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--jp-gold);
	margin: 0 0 0.5rem;
}

.jp-carousel__blurb {
	font-family: var(--jp-font-body);
	font-size: 0.875rem;
	line-height: 1.6;
	color: rgba(251, 247, 239, 0.84);
	margin: 0 0 1.125rem;
}

/* Pushes the signup to the bottom so every card's form lines up, whatever the
   blurb length. Without this the rail looks ragged. */
.jp-carousel__card .jp-notify { margin-top: auto; }

/* --- arrows ------------------------------------------------------------ */

.jp-carousel__nav {
	display: flex;
	gap: 0.5rem;
	justify-content: flex-end;
	margin-top: 0.25rem;
}

.jp-carousel__btn {
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	border: 1px solid rgba(201, 150, 47, 0.5);
	background: transparent;
	color: var(--jp-gold);
	font-size: 1rem;
	line-height: 1;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: background-color 200ms var(--jp-ease), opacity 200ms var(--jp-ease);
}

.jp-carousel__btn:hover { background-color: rgba(201, 150, 47, 0.16); }
.jp-carousel__btn:focus-visible { outline: 2px solid var(--jp-gold); outline-offset: 3px; }

/* Disabled rather than hidden — a control that vanishes at the end of a rail
   makes the row jump. Dimmed and inert keeps the layout still. */
.jp-carousel__btn[disabled] { opacity: 0.3; cursor: default; }

@media (prefers-reduced-motion: reduce) {
	.jp-carousel__rail { scroll-behavior: auto; }
	.jp-carousel__card { transition: none; }
	.jp-carousel__card:hover, .jp-carousel__card:focus-within { transform: none; }
}


/* ==========================================================================
   CAROUSEL PEEK — refined 17 Aug 2026.

   The peek was doing its job on desktop (signalling "there is more") and
   failing on a phone, where a card sliced through the middle of a sentence
   reads as a broken layout rather than as an affordance. Two changes:

   1. A fade over the right edge, so the cut looks deliberate. A hard vertical
      slice through type looks like clipping; type dissolving into the ground
      looks like a rail continuing.
   2. A much larger card on small screens — 88vw — so what peeks is a sliver of
      the NEXT card's edge rather than half of the current card's paragraph.
      One card at a time is the right reading unit on a phone anyway.
   ========================================================================== */

.jp-carousel__rail {
	/* lets the final card clear the fade instead of sitting under it */
	padding-right: 2.5rem;
	scroll-padding-right: 2.5rem;
}

.jp-carousel::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 2.75rem;
	width: clamp(2rem, 6vw, 4rem);
	pointer-events: none;
	background: linear-gradient(90deg,
		rgba(16, 26, 43, 0) 0%,
		rgba(16, 26, 43, 0.85) 65%,
		var(--jp-ink) 100%);
}

@media (max-width: 767px) {
	/* One card at a time, with a sliver of the next showing. */
	.jp-carousel__card { width: 88vw; max-width: 24rem; }

	.jp-carousel__rail {
		padding-right: 1.5rem;
		scroll-padding-right: 1.5rem;
		gap: 0.875rem;
	}

	.jp-carousel::after { width: 1.75rem; bottom: 2.25rem; }

	/* Nothing inside a card should ever be the thing that overflows. */
	.jp-carousel__name,
	.jp-carousel__blurb,
	.jp-carousel__genre { overflow-wrap: break-word; }
}


/* ==========================================================================
   MOBILE: NO HORIZONTAL RAIL AT ALL — 17 Aug 2026.

   Two attempts at tuning the peek on phones both left text clipped mid-word.
   Rather than guess a third time at a rendering I cannot see, this removes the
   mechanism that makes clipping possible: below 768px the rail stops being a
   horizontal scroller and becomes a plain vertical stack.

   Nothing can be cut off horizontally if nothing extends horizontally. Each
   card is full width, in normal flow, wrapping like any other block of text.

   This is not a downgrade. A three-item horizontal rail on a phone forces a
   gesture to discover items two and three; a stack shows all three to anyone
   who scrolls, which they are already doing. The slide stays on tablet and
   desktop, where the width actually buys something.

   Overrides every horizontal property explicitly rather than relying on
   shorthand, because the desktop rules above set several of them.
   ========================================================================== */

@media (max-width: 767px) {
	.jp-carousel__rail {
		display: block;
		overflow: visible;
		overflow-x: visible;
		scroll-snap-type: none;
		padding-right: 0;
		scroll-padding-right: 0;
		gap: 0;
	}

	.jp-carousel__card {
		width: auto;
		max-width: none;
		flex: none;
		scroll-snap-align: none;
		margin: 0 0 1rem;
	}

	.jp-carousel__card:last-child { margin-bottom: 0; }

	/* The fade and the arrows only mean anything on a scroller. */
	.jp-carousel::after { display: none; }
	.jp-carousel__nav { display: none; }

	/* Belt and braces: nothing inside a card may exceed it. */
	.jp-carousel__card * { max-width: 100%; }
	.jp-carousel__card img { width: 100%; height: auto; }
}
