/* Quentin by Hermansyah — the accent face. Used only on a single word or short
   phrase, never for body, nav or labels; that restraint is what stops a script
   face reading as decoration. Note it has no ellipsis glyph. */
@font-face {
	font-family: "Quentin";
	src: url("fonts/quentin.woff2") format("woff2"),
	     url("fonts/quentin.woff") format("woff");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

/* ==========================================================================
   Tessaverse lore section.
   Tokens are taken verbatim from the design handoff. Radius is 0 everywhere
   except circular portraits and pill badges; there are no shadows anywhere.
   ========================================================================== */

/* Tokens live on :root, not on .tv — the newsletter block and the 18+ notice sit
   outside .tv in the footer, and scoping the tokens to .tv left them with no
   gutter and no palette. */
:root {
	/* Light palette, taken from the Karla reference: white ground, warm
	   off-white and sand for raised surfaces, near-black for headings. The gold
	   is deepened to a bronze — the old value was chosen to glow on black and
	   is illegible as text on white. */
	--tv-bg:            #ffffff;
	--tv-panel:         #f6f4f2;
	--tv-panel-raised:  #e5e2d7;
	--tv-hairline:      #e6e2dc;
	--tv-border:        #cfc9bf;
	--tv-text:          #212121;
	--tv-text-2:        #3d3d3d;
	--tv-muted:         #767676;
	--tv-link:          #212121;

	/* Overridden per world from the World's accent fields.
	   No gold. The reference has no chromatic accent at all — its highlight and
	   its button fill are both near-black, and the only colour in the palette
	   comes from the sand and sage surfaces. Gold on this ground read as a
	   leftover from the dark theme, which is exactly what it was. */
	--tv-accent:        #212121;
	--tv-accent-2:      #767676;
	--tv-sand:          #e5e2d7;
	--tv-sage:          #dbded7;
	--tv-script-ink:    #767676;

	/* Reserved for the Patreon button and nothing else. A deep olive that sits
	   with the sage, so it reads as part of the palette while still being the
	   only coloured control on the page. The moment it appears on a second
	   button it stops signalling anything — which is exactly how the old gold
	   ended up everywhere. */
	--tv-patreon:       #4A5D3A;
	--tv-tint:          #f6f4f2;

	--tv-gutter:        44px;
	--tv-placeholder:   repeating-linear-gradient(135deg,
	                      #efece7 0 7px,
	                      #f6f4f2 7px 14px);

	/* One family across the whole site — Roboto, the face wp-rocket.me sets its
	   text in. Headings, nav, labels and body all share it and separate by
	   weight and size alone. Quentin is the accent face, used sparingly. */
	--tv-display:       "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--tv-body:          "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--tv-label:         "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--tv-script:        "Quentin", "Roboto", cursive;
}

.tv {
	background: var(--tv-bg);
	color: var(--tv-text);
	font-family: var(--tv-body);
	font-weight: 400;
	min-height: 100vh;
}

.tv *,
.tv *::before,
.tv *::after { box-sizing: border-box; }

.tv a { color: var(--tv-link); text-decoration: none; }
.tv a:hover { text-decoration: underline; text-underline-offset: 3px; }

.tv-wrap { max-width: 1400px; margin: 0 auto; padding: 0 var(--tv-gutter); }

/* ---------------------------------------------------------------- type */

/* wp-rocket.me's headings declare weight 400, but the file they serve under the
   name "Gotham" is already a bold cut, so 400 there renders heavy. Roboto has
   real weights, so matching that look means asking for 700 outright — and with
   one family site-wide, weight is what separates a heading from body copy. */
.tv h1, .tv h2, .tv h3 {
	font-family: var(--tv-display);
	font-weight: 700;
	margin: 0;
	color: var(--tv-text);
}
.tv h1 { font-size: clamp(40px, 6vw, 76px); letter-spacing: -0.02em; line-height: 1.02; }
.tv h2 { font-size: clamp(30px, 4vw, 62px); letter-spacing: -0.02em; line-height: 1.08; }
.tv h3 { font-size: 30px; line-height: 1.15; }

.tv-eyebrow {
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13px;
	color: var(--tv-muted);
}

.tv-label {
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
}

/* The combination that makes the lore readable — do not "tidy" these values.
   Weight is 400, not Light: these were first tuned while Barlow was silently
   failing to load, so 300 was really the system sans at 400. Real Barlow Light
   at 19px on this background is too thin to read at length. */
.tv-prose {
	font-size: 19px;
	line-height: 1.68;
	font-weight: 400;
	color: var(--tv-text-2);
	text-wrap: pretty;
	max-width: 68ch;
}
.tv-prose p { margin: 0 0 1.1em; }
.tv-prose em { font-style: italic; }

/* -------------------------------------------------------------- badges */

.tv-badge {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	border-radius: 999px;
	border: 1px solid var(--tv-border);
	padding: 6px 14px;
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-text-2);
	background: color-mix(in oklab, var(--tv-panel) 70%, transparent);
}
.tv-badge--accent { color: var(--tv-accent); border-color: color-mix(in oklab, var(--tv-accent) 45%, transparent); }
.tv-badge--fated  { color: var(--tv-accent);  border-color: color-mix(in oklab, var(--tv-accent) 45%, transparent); }
.tv-badge--mated  { color: var(--tv-accent-2); border-color: color-mix(in oklab, var(--tv-accent-2) 45%, transparent); }

/* ---------------------------------------------------------- placeholder */

.tv-placeholder { background: var(--tv-placeholder); }

.tv-norecord {
	font-family: var(--tv-label);
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
}

/* --------------------------------------------------------- character hero */

.tv-hero {
	position: relative;
	/* 520px is the design minimum. On wide screens the box has to grow or a
	   portrait gets cropped to a band across the top of the head. */
	min-height: clamp(520px, 40vw, 860px);
	display: flex;
	align-items: flex-end;
	background: var(--tv-panel);
	overflow: hidden;
}
.tv-hero__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Overridden per character by the Portrait framing field. */
	object-position: var(--tv-focus, center 32%);
}
.tv-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(to right,
		color-mix(in oklab, var(--tv-bg) 96%, transparent) 6%,
		color-mix(in oklab, var(--tv-bg) 42%, transparent) 58%,
		transparent);
}
.tv-hero__body { position: relative; padding: 56px 0; width: 100%; }
.tv-hero__badges { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.tv-hero__name { margin-bottom: 10px; }
.tv-hero__titles { font-family: var(--tv-label); text-transform: none;
	font-size: 13px; color: var(--tv-accent); }

/* ---------------------------------------------------------- facts strip */

.tv-facts {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 1px;
	background: var(--tv-hairline);
	border-block: 1px solid var(--tv-hairline);
	margin-top: 0;
}
.tv-facts__cell { background: var(--tv-bg); padding: 20px 22px; min-width: 0; }
.tv-facts__label { margin-bottom: 7px; }
.tv-facts__value { font-family: var(--tv-display); font-weight: 600; font-size: 19px; line-height: 1.3; }

/* --------------------------------------------------------------- layout */

.tv-two-col {
	display: grid;
	grid-template-columns: 1fr 340px;
	gap: 48px;
	padding: 48px 0 80px;
	align-items: start;
}

.tv-panel {
	background: var(--tv-panel);
	border: 1px solid var(--tv-hairline);
	padding: 22px;
	margin-bottom: 20px;
}
.tv-panel h3 { font-size: 22px; margin-bottom: 14px; }

.tv-deflist { display: grid; gap: 12px; }
.tv-deflist__row { display: grid; gap: 3px; }
.tv-deflist__val { font-size: 15px; color: var(--tv-text); }

/* narrated sections */
.tv-narrator {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 16px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--tv-hairline);
}
.tv-narrator__portrait {
	width: 44px; height: 44px; border-radius: 50%;
	object-fit: cover; flex: none; background: var(--tv-placeholder);
}
.tv-narrator__name { font-family: var(--tv-display); font-weight: 600; font-size: 17px; }

.tv-pullquote {
	border-left: 2px solid var(--tv-accent);
	background: var(--tv-tint);
	padding: 20px 24px;
	margin: 28px 0;
	font-family: var(--tv-display); font-weight: 600;
	font-size: 22px;
	line-height: 1.45;
	color: var(--tv-text);
}

/* spoiler reveal */
.tv-spoiler { border: 1px solid var(--tv-border); margin: 28px 0; }
.tv-spoiler > summary {
	cursor: pointer; list-style: none; padding: 14px 18px;
	background: var(--tv-panel-raised);
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-accent);
}
.tv-spoiler > summary::-webkit-details-marker { display: none; }
.tv-spoiler[open] > summary { border-bottom: 1px solid var(--tv-border); }
.tv-spoiler__body { padding: 20px 18px; }

/* ---------------------------------------------------------------- index */

/* Filter pills, after wp-rocket.me's buttons: full pill, solid fill, no border,
   bold sentence case, generous padding. Outlines read as thin and unfinished at
   this size, so the resting state is a raised panel rather than a hairline. */
.tv-chips { display: flex; flex-wrap: wrap; gap: 10px; margin: 26px 0 36px; }
.tv-chip {
	display: inline-flex; align-items: center; gap: 8px;
	border: 0; border-radius: 999px;
	padding: 13px 24px;
	font-family: var(--tv-body);
	font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 15px;
	line-height: 1.1;
	color: var(--tv-text); background: var(--tv-panel-raised);
	transition: background-color 0.15s ease, color 0.15s ease;
}
.tv .tv-chip { color: var(--tv-text); }
.tv-chip:hover { background: color-mix(in oklab, var(--tv-accent) 22%, var(--tv-panel-raised)); text-decoration: none; }
.tv .tv-chip:hover { color: var(--tv-text); }
.tv-chip[aria-current="true"],
.tv .tv-chip[aria-current="true"] { color: var(--tv-bg); background: var(--tv-accent); }
.tv-chip[aria-current="true"]:hover { background: var(--tv-accent); }
.tv-chip__count {
	font-size: 13px; font-weight: 700; margin-left: 0;
	padding: 2px 8px; border-radius: 999px;
	background: color-mix(in oklab, var(--tv-text) 12%, transparent);
	color: var(--tv-text-2);
}
.tv-chip[aria-current="true"] .tv-chip__count {
	background: color-mix(in oklab, var(--tv-bg) 20%, transparent);
	color: color-mix(in oklab, var(--tv-bg) 78%, transparent);
}

.tv-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }

.tv-card { position: relative; display: block; aspect-ratio: 3 / 4; overflow: hidden; background: var(--tv-panel); }
.tv-card img { width: 100%; height: 100%; object-fit: cover; }
.tv-card__fill { width: 100%; height: 100%; background: var(--tv-placeholder); }
.tv-card__overlay {
	position: absolute; inset: auto 0 0 0; padding: 18px 16px 15px;
	background: linear-gradient(to top,
		color-mix(in oklab, var(--tv-bg) 97%, transparent) 22%,
		color-mix(in oklab, var(--tv-bg) 55%, transparent) 62%,
		transparent);
}
.tv-card__name {
	display: block;
	font-family: var(--tv-display); font-weight: 600; font-size: 22px; line-height: 1.15;
	color: var(--tv-text);
}
.tv-card__meta {
	display: block;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; line-height: 1.4;
	color: var(--tv-text-2); margin-top: 7px;
}

/* A–Z table */
.tv-table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.tv-table th {
	text-align: left; padding: 10px 14px;
	border-bottom: 1px solid var(--tv-border);
	font-family: var(--tv-label); font-weight: 600; text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
}
.tv-table td { padding: 13px 14px; border-bottom: 1px solid var(--tv-hairline); font-size: 15px; vertical-align: baseline; }
.tv-table__name { font-family: var(--tv-display); font-weight: 600; font-size: 19px; }
.tv-table col.c1 { width: 28%; } .tv-table col.c2 { width: 20%; }
.tv-table col.c3 { width: 24%; } .tv-table col.c4 { width: 18%; }
.tv-table col.c5 { width: 10%; }

.tv-alpha { font-family: var(--tv-display); font-weight: 600; font-size: 26px; color: var(--tv-accent);
	padding: 26px 14px 8px; border-bottom: 1px solid var(--tv-border); }

/* heat, as jalapenos */
.tv-heat { display: inline-flex; gap: 3px; align-items: center; }
.tv-pepper { display: inline-flex; width: 20px; height: 20px; }
.tv-pepper__icon { width: 100%; height: 100%; display: block; }

/* Unlit peppers are outlines, so five of them read as a scale rather than clutter. */
.tv-pepper .tv-pepper__body { fill: none; stroke: var(--tv-border); stroke-width: 1.3; }
.tv-pepper .tv-pepper__stem { fill: none; stroke: var(--tv-border); stroke-width: 1.3; }

.tv-pepper.is-on .tv-pepper__body { fill: oklch(0.58 0.20 27); stroke: none; }
.tv-pepper.is-on .tv-pepper__stem { fill: oklch(0.62 0.13 145); stroke: none; }

/* ----------------------------------------------------------- responsive */

@media (max-width: 1100px) {
	.tv-two-col { grid-template-columns: 1fr; gap: 32px; }
	.tv-grid-4 { grid-template-columns: repeat(3, 1fr); }
	.tv-facts { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 760px) {
	.tv { --tv-gutter: 20px; }
	.tv-grid-4 { grid-template-columns: repeat(2, 1fr); }
	.tv-facts { grid-template-columns: repeat(2, 1fr); }
	.tv-hero { min-height: 420px; }
	.tv-table col.c2, .tv-table col.c4 { width: 0; }
	.tv-table .hide-sm { display: none; }
}

/* ==========================================================================
   Split hero — wide band behind, portrait in its own box overlapping it.
   The portrait keeps its own 3:4 shape at every width, so it never crops.
   ========================================================================== */

.tv-hero2 { position: relative; }

.tv-hero2__band {
	position: relative;
	height: clamp(220px, 20vw, 360px);
	overflow: hidden;
	background: var(--tv-panel);
}
.tv-hero2__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 35%;
}
/* When the band falls back to the character's own portrait, blur it so it reads
   as atmosphere rather than a second, badly-cropped copy of the same picture. */
.tv-hero2__bg--echo { filter: blur(28px) saturate(0.75); transform: scale(1.12); }

.tv-hero2__scrim {
	position: absolute;
	inset: 0;
	/* Only a vertical fade, so the band dissolves into the page behind the
	   portrait. The old second gradient washed 82% white across the left 70% of
	   the image — it existed to carry the character's name when that sat on the
	   band, and the name has since moved below it. On a dark ground it read as
	   atmosphere; on white it just bleached the artwork. */
	background: linear-gradient(to top,
		var(--tv-bg) 1%,
		color-mix(in oklab, var(--tv-bg) 45%, transparent) 38%,
		transparent 80%);
}

.tv-hero2__row {
	position: relative;
	display: grid;
	grid-template-columns: clamp(230px, 22vw, 320px) 1fr;
	gap: clamp(24px, 3vw, 44px);
	align-items: end;
	margin-top: clamp(-190px, -14vw, -110px);
	padding-bottom: 34px;
}

.tv-hero2__portrait {
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-border);
}
.tv-hero2__portrait img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--tv-focus, center 32%);
	display: block;
}

.tv-hero2__meta { padding-bottom: 6px; min-width: 0; }
.tv-hero2__badges { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.tv-hero2__meta h1 { margin-bottom: 8px; }

@media (max-width: 760px) {
	.tv-hero2__band { height: 200px; }
	.tv-hero2__row {
		grid-template-columns: 1fr;
		gap: 20px;
		margin-top: -110px;
		padding-bottom: 26px;
	}
	.tv-hero2__portrait { width: min(210px, 55%); }
	.tv-hero2__meta { padding-bottom: 0; }
}

/* ------------------------------------------------------------------ sigils */

.tv-sigil {
	display: inline-block;
	width: var(--sz, 56px);
	height: var(--sz, 56px);
	border: 2px solid var(--tv-accent);
	flex: none;
}
.tv-sigil--circle  { border-radius: 50%; }
.tv-sigil--ring    { border-radius: 50%; border-width: 6px; }
.tv-sigil--diamond { transform: rotate(45deg); }
.tv-sigil--square  { border-radius: 0; }
.tv-sigil--dim     { border-color: var(--tv-border); }

/* -------------------------------------------------------------- house page */

.tv-house-head { display: flex; align-items: center; gap: 24px; padding: 56px 0 8px; }
.tv-house-head__meta { min-width: 0; }

.tv-gen { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--tv-hairline);
	border: 1px solid var(--tv-hairline); margin: 28px 0; }
.tv-gen__cell { background: var(--tv-bg); padding: 18px 20px; }
.tv-gen__role { margin-bottom: 6px; }
.tv-gen__name { font-family: var(--tv-display); font-weight: 600; font-size: 20px; line-height: 1.25; }

/* A button should read as a thing you press. The label face — condensed,
   uppercase, widely tracked — belongs on eyebrows and field labels; using it here
   made every action look like a caption. */
/* Buttons. The colour rules are written as `.tv a.tv-btn` because the generic
   `.tv a` link colour (0-1-1) otherwise outranks a single button class and
   painted solid buttons link-blue on gold. */
.tv-btn,
.tv a.tv-btn {
	display: inline-block;
	font-family: var(--tv-body);
	font-weight: 700;
	font-size: 16px;
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: none;
	padding: 16px 30px;
	border: 2px solid transparent;
	border-radius: 999px;
	color: var(--tv-bg);
	background: var(--tv-accent);
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, filter 0.15s ease;
}
.tv-btn:hover,
.tv a.tv-btn:hover { background: var(--tv-accent); color: var(--tv-bg); text-decoration: none; filter: brightness(1.08); }

.tv-btn--solid,
.tv a.tv-btn--solid {
	background: var(--tv-accent);
	border-color: var(--tv-accent);
	color: var(--tv-bg);
}
.tv-btn--solid:hover,
.tv a.tv-btn--solid:hover { background: var(--tv-accent); color: var(--tv-bg); filter: brightness(1.08); }

.tv-btn--ghost,
.tv a.tv-btn--ghost { border-color: var(--tv-border); background: transparent; color: var(--tv-text); }
.tv-btn--ghost:hover,
.tv a.tv-btn--ghost:hover { border-color: var(--tv-accent); background: transparent; color: var(--tv-accent); filter: none; }

.tv-btn--dashed,
.tv a.tv-btn--dashed { border-style: dashed; border-color: var(--tv-border); background: transparent; color: var(--tv-muted); }
.tv-btn--block { display: block; text-align: center; }
.tv-btn--sm,
.tv a.tv-btn--sm { font-size: 14px; padding: 11px 22px; }

/* ------------------------------------------------------------ houses index */

.tv-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

.tv-hcard {
	display: block;
	border: 1px solid var(--tv-hairline);
	background: var(--tv-panel);
	padding: 26px;
}
.tv-hcard--lead { grid-column: span 1; padding: 32px; background: var(--tv-tint); }
.tv-hcard__top { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.tv-hcard__name { font-family: var(--tv-display); font-weight: 600; font-size: 26px; line-height: 1.15; }
.tv-hcard__count { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); }

.tv-hrow {
	display: flex; align-items: center; gap: 16px;
	padding: 16px 18px; border: 1px solid var(--tv-hairline); margin-bottom: -1px;
	background: var(--tv-panel);
}
.tv-hrow--empty { border-style: dashed; background: transparent; }
.tv-hrow__name { font-family: var(--tv-display); font-weight: 600; font-size: 20px; flex: 1; min-width: 0; }

/* ------------------------------------------------------------- place rosters */

.tv-roster { width: 100%; border-collapse: collapse; margin-bottom: 28px; }
.tv-roster th { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--tv-border);
	font-family: var(--tv-label); font-weight: 600; text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); }
.tv-roster td { padding: 12px; border-bottom: 1px solid var(--tv-hairline); font-size: 15px; }
.tv-roster td:first-child { font-family: var(--tv-display); font-weight: 600; font-size: 18px; }

.tv-note {
	background: var(--tv-sand);
	border: 1px solid transparent;
	border-left: 2px solid var(--tv-accent);
	background: var(--tv-tint);
	padding: 18px 20px;
	margin: 24px 0;
	font-size: 16px;
	line-height: 1.6;
	color: var(--tv-text-2);
}

@media (max-width: 1100px) { .tv-grid-3 { grid-template-columns: repeat(2, 1fr); } .tv-gen { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px)  { .tv-grid-3 { grid-template-columns: 1fr; } .tv-gen { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------- books */

.tv-two-col--left { grid-template-columns: 340px 1fr; }
@media (max-width: 1100px) { .tv-two-col--left { grid-template-columns: 1fr; } }

/* Capped so that when the layout collapses to one column the cover — and above
   all an empty cover placeholder — cannot grow to fill the viewport and push the
   whole page below the fold. */
.tv-cover {
	width: 100%;
	max-width: 340px;
	display: block;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-hairline);
	aspect-ratio: 2 / 3;
	object-fit: cover;
}
.tv-buys { display: grid; gap: 8px; margin-top: 18px; max-width: 340px; }

@media (max-width: 1100px) {
	/* Cover and buy stack sit side by side once they are no longer a column. */
	.tv-two-col--left > aside { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
	.tv-two-col--left > aside .tv-cover { max-width: 260px; }
	.tv-two-col--left > aside .tv-buys { margin-top: 0; flex: 1; min-width: 200px; }
}
@media (max-width: 560px) {
	.tv-two-col--left > aside { display: block; }
	.tv-two-col--left > aside .tv-cover { max-width: 190px; }
	.tv-two-col--left > aside .tv-buys { margin-top: 16px; }
}

.tv-standfirst { font-size: 20px; font-weight: 300; line-height: 1.55; color: var(--tv-text-2); margin: 14px 0 0; max-width: 62ch; }

.tv-chipset { display: flex; flex-wrap: wrap; gap: 7px; margin: 22px 0; }
.tv-tag {
	display: inline-block;
	border: 0; border-radius: 999px;
	padding: 8px 16px;
	background: var(--tv-panel-raised);
	font-family: var(--tv-body); font-weight: 600; text-transform: none;
	letter-spacing: 0; font-size: 13.5px; line-height: 1.2; color: var(--tv-text-2);
	transition: background-color 0.15s ease, color 0.15s ease;
}
.tv a.tv-tag { color: var(--tv-text-2); }
.tv a.tv-tag:hover {
	background: color-mix(in oklab, var(--tv-accent) 22%, var(--tv-panel-raised));
	color: var(--tv-text); text-decoration: none;
}

.tv-facts--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1100px) { .tv-facts--4 { grid-template-columns: repeat(2, 1fr); } }

/* reading order */
/* auto-fill rather than a fixed three, so the list reads properly whether it has
   the full page or sits beside a sidebar. */
.tv-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 1px;
	background: var(--tv-hairline); border: 1px solid var(--tv-hairline); margin-top: 20px; }
.tv-shelf__row { background: var(--tv-bg); padding: 13px 16px; display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.tv-shelf__body { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.tv-shelf__badges { display: flex; gap: 6px; flex-wrap: wrap; }
.tv-shelf__row.is-read { background: var(--tv-tint); }
.tv-shelf__box { width: 17px; height: 17px; flex: none; accent-color: var(--tv-accent); cursor: pointer; margin-top: 4px; }
.tv-shelf__num { font-family: var(--tv-label); font-size: 11px; letter-spacing: 0.08em; color: var(--tv-muted);
	flex: none; width: 22px; line-height: 1.5; padding-top: 3px; }
.tv-shelf__title { font-family: var(--tv-display); font-weight: 600; font-size: 18px; line-height: 1.25; }
.tv-shelf__badge { font-family: var(--tv-label); font-size: 13.5px; text-transform: none; padding: 3px 8px; border: 1px solid currentColor; flex: none; }
.tv-shelf__badge--prequel { color: var(--tv-accent); }
.tv-shelf__badge--jump    { color: var(--tv-accent-2); }
.tv-shelf__badge--same    { color: var(--tv-muted); }

.tv-progress { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 26px; }
.tv-progress__count { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); }

/* auto-fill handles the narrowing; no breakpoint needed. */

/* ------------------------------------------------------------- worlds door */

.tv-worlds { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 18px; margin-top: 34px; }
.tv-worlds--even { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

.tv-world {
	position: relative;
	display: block;
	min-height: 420px;
	overflow: hidden;
	background: var(--tv-panel);
	border: 1px solid var(--tv-hairline);
}
.tv-world img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tv-world__fill { position: absolute; inset: 0; background: var(--tv-placeholder); }
.tv-world__panel {
	position: absolute; inset: auto 0 0 0; padding: 26px 24px 24px;
	/* A white veil over the photograph, not a panel beneath it. It only has to
	   be deep enough to carry the name and description — the counts sit below
	   them, on the solid part, so the veil never has to stretch up to reach the
	   smallest text. That reordering is what let it come down from 46% to 32%
	   and give the image back. */
	min-height: 32%;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	background: linear-gradient(to top,
		var(--tv-bg) 0%,
		var(--tv-bg) 34%,
		color-mix(in oklab, var(--tv-bg) 80%, transparent) 70%,
		transparent 100%);
}
.tv-world__name    { order: 1; }
.tv-world__desc    { order: 2; }
.tv-world__eyebrow { order: 3; margin-top: 10px; }
.tv-world__status  { order: 4; }
.tv-world__eyebrow { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); }
.tv-world__name { font-family: var(--tv-display); font-weight: 600; font-size: clamp(30px, 3vw, 44px);
	line-height: 1.08; color: var(--tv-text); margin: 0 0 6px; display: block; }
.tv-world__desc { font-size: 15px; line-height: 1.55; color: var(--tv-text-2); display: block; }
.tv-world__status { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); margin-top: 10px; display: block; }
/* --------------------------------------------------------------- world hub */

.tv-doors { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
	background: var(--tv-hairline); border: 1px solid var(--tv-hairline); margin-top: 32px; }
.tv-door { background: var(--tv-bg); padding: 30px 24px 34px; display: block; min-height: 190px; }
.tv-door:hover { background: var(--tv-tint); text-decoration: none; }
.tv-door__num { font-family: var(--tv-label); font-size: 11px; letter-spacing: 0.2em; color: var(--tv-accent); }
.tv-door__name { font-family: var(--tv-display); font-weight: 600; font-size: 28px; line-height: 1.15; color: var(--tv-text); margin: 14px 0 8px; display: block; }
.tv-door__count { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); display: block; }

@media (max-width: 1100px) {
	.tv-worlds { grid-template-columns: 1fr 1fr; }
	.tv-doors  { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
	.tv-worlds { grid-template-columns: 1fr; }
	.tv-doors  { grid-template-columns: 1fr; }
	.tv-world  { min-height: 320px; }
}

/* ==========================================================================
   Family tree.
   Every branch is sized by its own leaf count, so a tier's column split always
   matches the tier above it. Getting that wrong made readers assume the wrong
   parent, which is the one thing this screen must not do.
   ========================================================================== */

.tv-tree-scroll { overflow-x: auto; padding: 30px 0 40px; }
/* margin auto rather than justify-content: a centred flex row overflows equally
   both ways, and the left overflow is then unreachable inside a scroller. */
.tv-tree { display: flex; min-width: min-content; margin: 0 auto; }

.tv-tree__node {
	--mate-pad: 0px; display: flex; flex-direction: column; align-items: center;
	position: relative; padding: 0 5px; min-width: 0;
}

/* The mate sits outside the flow so it cannot shift the node's centre. If it did,
   the descent connector would land between a child and their mate, and the mate
   reads as another child of the parent above. */
.tv-tree__pair {
	position: relative; display: flex; flex-direction: column;
	align-items: center;
}
/* Stacked couples: no horizontal space is reserved beside a partner. */
.tv-tree__node.has-mate { --mate-pad: 0px; }
.tv-tree__mate-wrap {
	display: flex; flex-direction: column; align-items: center;
}

.tv-tree__card {
	display: flex; flex-direction: column; justify-content: center;
	border: 1px solid var(--tv-border); background: var(--tv-panel);
	padding: 9px 11px; min-width: 112px; min-height: 62px;
	text-align: center; position: relative; border-radius: 3px;
}
.tv-tree__card:hover { background: var(--tv-panel-raised); text-decoration: none; }

.tv-tree__card.is-blood  { border-style: solid; }
.tv-tree__card.is-joined { border-style: dashed; opacity: 0.82; }
.tv-tree__card.is-root   {
	border: 2px solid var(--tv-accent); padding: 13px 20px; min-height: 70px;
}
.tv-tree__card.is-blank  { opacity: 0.62; }
.tv-tree__card.is-firstborn { border-left: 2px solid var(--tv-accent); }
.tv-tree__card.is-mate   { min-width: 112px; }

.tv-tree__name {
	font-family: var(--tv-display); font-weight: 600; font-size: 15.5px;
	line-height: 1.2; color: var(--tv-text); display: block;
}
.tv-tree__card.is-root .tv-tree__name { font-size: 19px; }
.tv-tree__sub {
	font-family: var(--tv-label); text-transform: none; font-size: 11.5px;
	line-height: 1.25; color: var(--tv-muted); display: block; margin-top: 3px;
}

/* Title-holders get a rotated square. */
.tv-tree__mark {
	position: absolute; top: -5px; left: 50%; margin-left: -4px;
	width: 8px; height: 8px; background: var(--tv-accent); transform: rotate(45deg);
}

/* Mating is a join, not descent — dashed, like the cards it connects. */
.tv-tree__bond {
	width: 0; height: 12px; border-left: 1px dashed var(--tv-border); flex: none;
}

/* ------------------------------------------------------------- connectors */

.tv-tree__kids {
	display: flex; width: 100%; padding-top: 30px; position: relative;
}

.tv-tree__node.has-kids > .tv-tree__kids::before {
	content: ''; position: absolute; top: 0; left: 50%;
	width: 1px; height: 18px; background: var(--tv-border);
}
.tv-tree__kids > .tv-tree__node::before {
	content: ''; position: absolute; top: -18px;
	left: calc( 50% - var( --mate-pad ) / 2 );
	width: 1px; height: 18px; background: var(--tv-border);
}
.tv-tree__kids > .tv-tree__node::after {
	content: ''; position: absolute; top: -18px; left: 0; right: 0;
	height: 1px; background: var(--tv-border);
}
.tv-tree__kids > .tv-tree__node:first-child::after { left: calc( 50% - var( --mate-pad ) / 2 ); }
.tv-tree__kids > .tv-tree__node:last-child::after  { right: calc( 50% + var( --mate-pad ) / 2 ); }
.tv-tree__kids > .tv-tree__node:only-child::after  { display: none; }

/* ----------------------------------------------------------------- legend */

.tv-legend { display: flex; flex-wrap: wrap; gap: 26px; margin-top: 8px; padding: 20px 0; border-top: 1px solid var(--tv-hairline); }
.tv-legend__item { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--tv-text-2); }
.tv-legend__swatch { width: 30px; height: 16px; border: 1px solid var(--tv-border); flex: none; }
.tv-legend__swatch--joined { border-style: dashed; }
.tv-legend__swatch--root { border: 2px solid var(--tv-accent); }
.tv-legend__swatch--first { border-left: 2px solid var(--tv-accent); }
.tv-legend__square { width: 9px; height: 9px; background: var(--tv-accent); transform: rotate(45deg); flex: none; margin: 0 10px; }

/* ---------------------------------------------------------------- timeline */

.tv-tracks { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; margin-top: 34px; }

.tv-track__head { padding-bottom: 12px; border-bottom: 1px solid var(--tv-border); margin-bottom: 4px; }
.tv-track__title { font-family: var(--tv-display); font-weight: 600; font-size: 28px; line-height: 1.2; }
.tv-track__note { font-size: 14px; color: var(--tv-muted); margin-top: 6px; line-height: 1.5; }

.tv-entry {
	position: relative;
	border-left: 1px solid var(--tv-hairline);
	padding: 20px 0 20px 26px;
	margin-left: 5px;
}
.tv-entry::before {
	content: ''; position: absolute; left: -5px; top: 27px;
	width: 9px; height: 9px; border-radius: 50%;
	background: var(--tv-bg); border: 1px solid var(--tv-border);
}
.tv-entry.is-marked::before { background: var(--tv-accent); border-color: var(--tv-accent); }
.tv-entry:last-child { border-left-color: transparent; }

.tv-entry__when { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-accent); }
.tv-entry__title { font-family: var(--tv-display); font-weight: 600; font-size: 21px; line-height: 1.25; display: block; margin: 6px 0 4px; }
.tv-entry__meta { font-size: 14px; color: var(--tv-muted); line-height: 1.5; }
.tv-entry__body { font-size: 15px; line-height: 1.6; color: var(--tv-text-2); margin-top: 8px; max-width: 52ch; }

.tv-gap {
	position: relative;
	margin-left: 5px;
	border-left: 1px dashed var(--tv-border);
	padding: 14px 0 14px 26px;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
}

.tv-outseq {
	display: inline-block; margin-top: 6px;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px;
	color: var(--tv-accent-2);
	border: 1px solid currentColor; padding: 3px 8px;
}

@media (max-width: 900px) { .tv-tracks { grid-template-columns: 1fr; gap: 40px; } }

/* -------------------------------------------------------------------- maps */

.tv-maplayout { display: grid; grid-template-columns: 1fr 320px; gap: 40px; align-items: start; margin-top: 30px; }

.tv-map {
	position: relative;
	aspect-ratio: 4 / 3;
	border: 1px solid var(--tv-border);
	background: var(--tv-placeholder);
	overflow: hidden;
}
.tv-map img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.tv-pin {
	position: absolute;
	transform: translate(-50%, -50%);
	display: flex;
	align-items: center;
	gap: 8px;
	white-space: nowrap;
}
.tv-pin__dot {
	width: 24px; height: 24px; border-radius: 50%;
	background: var(--tv-accent); color: var(--tv-bg);
	display: grid; place-items: center;
	font-family: var(--tv-label); font-size: 11px; font-weight: 600;
	flex: none;
}
/* The only shadow anywhere on the site — pin labels sit over artwork and need it. */
.tv-pin__label {
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-text);
	text-shadow: 0 1px 3px rgba(255, 255, 255, 0.95), 0 0 10px rgba(255, 255, 255, 0.85);
}
.tv-pin:hover .tv-pin__dot { background: var(--tv-text); }
.tv-pin.is-active .tv-pin__dot { outline: 2px solid var(--tv-text); outline-offset: 2px; }

.tv-pinlist { counter-reset: pin; }
.tv-pinlist__item {
	display: flex; align-items: baseline; gap: 12px;
	padding: 11px 0; border-bottom: 1px solid var(--tv-hairline);
}
.tv-pinlist__num {
	font-family: var(--tv-label); font-size: 11px; color: var(--tv-accent);
	width: 22px; flex: none;
}
.tv-pinlist__name { font-family: var(--tv-display); font-weight: 600; font-size: 18px; line-height: 1.25; }
.tv-pinlist__sub { font-size: 13px; color: var(--tv-muted); display: block; margin-top: 2px; }

.tv-mapcard {
	display: block; border: 1px solid var(--tv-hairline);
	background: var(--tv-panel); overflow: hidden;
}
.tv-mapcard__img { aspect-ratio: 4 / 3; background: var(--tv-placeholder); position: relative; }
.tv-mapcard__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tv-mapcard__body { padding: 18px 20px; }

@media (max-width: 1000px) { .tv-maplayout { grid-template-columns: 1fr; gap: 26px; } }
@media (max-width: 620px) { .tv-pin__label { display: none; } }

/* ----------------------------------------------------------- reader features */

.tv-request__count {
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
	margin: 10px 0 0; text-align: center;
}
.tv-request .tv-btn[disabled] {
	border-color: var(--tv-border); color: var(--tv-muted);
	background: transparent; cursor: default;
}

.tv-new {
	display: inline-block;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px;
	color: var(--tv-bg); background: var(--tv-accent);
	padding: 3px 8px; border-radius: 999px;
	vertical-align: middle;
}

/* 18+ — a notice in the footer of every page, deliberately not a gate. */
.tv-adult {
	background: var(--tv-bg);
	border-top: 1px solid var(--tv-hairline);
	padding: 18px 0;
	font-family: var(--tv-body);
	font-size: 14px;
	line-height: 1.55;
	color: var(--tv-muted);
}
.tv-adult .tv-wrap { display: flex; align-items: baseline; gap: 14px; max-width: 1400px; }
.tv-adult__mark {
	font-family: var(--tv-label);
	font-weight: 600; letter-spacing: 0.08em; font-size: 12px;
	color: var(--tv-accent);
	border: 1px solid currentColor; padding: 3px 9px; flex: none;
}

/* ---------------------------------------------------------------- changelog */

.tv-log__day { font-family: var(--tv-display); font-weight: 600; font-size: 26px; margin: 40px 0 6px; color: var(--tv-accent); }
.tv-log__row {
	display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
	padding: 13px 0; border-bottom: 1px solid var(--tv-hairline);
}
.tv-log__type {
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
	width: 84px; flex: none;
}
.tv-log__name { font-family: var(--tv-display); font-weight: 600; font-size: 19px; }

/* ---------------------------------------------------------------- pairings */

.tv-pairs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 34px; }

.tv-pair {
	border: 1px solid var(--tv-hairline);
	background: var(--tv-panel);
	display: flex;
	flex-direction: column;
}

.tv-pair__faces { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--tv-hairline); }
.tv-pair__face { aspect-ratio: 1 / 1; background: var(--tv-placeholder); overflow: hidden; position: relative; }
.tv-pair__face img { width: 100%; height: 100%; object-fit: cover; object-position: center 28%; display: block; }

.tv-pair__body { padding: 22px; flex: 1; display: flex; flex-direction: column; }
.tv-pair__names { font-family: var(--tv-display); font-weight: 600; font-size: 26px; line-height: 1.15; }
.tv-pair__names a { color: var(--tv-text); }
.tv-pair__badge { margin: 12px 0 0; }
.tv-pair__desc { font-size: 16px; line-height: 1.6; color: var(--tv-text-2); margin: 14px 0 0; }

.tv-pair__table { margin-top: 18px; border-top: 1px solid var(--tv-hairline); }
.tv-pair__row {
	display: flex; align-items: baseline; gap: 14px;
	padding: 10px 0; border-bottom: 1px solid var(--tv-hairline);
}
.tv-pair__key { font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted); width: 78px; flex: none; }
.tv-pair__val { font-size: 15px; line-height: 1.5; }
.tv-pair__val .tv-muted { color: var(--tv-muted); }

@media (max-width: 900px) { .tv-pairs { grid-template-columns: 1fr; } }

/* ==========================================================================
   Divi header and footer, dressed to match the lore section.
   Scoped by Divi's own ids so specificity holds without !important. If a Theme
   Builder header is ever assigned, it replaces this markup and none of the below
   applies — which is the intended escape hatch.
   ========================================================================== */

body { background: var(--tv-bg); }

/* ---------------------------------------------------------------- header */

#main-header,
#main-header.et-fixed-header {
	background: var(--tv-bg);
	border-bottom: 1px solid var(--tv-hairline);
	box-shadow: none;
}

#logo { max-height: 46px; }

/* Until a real logo is uploaded, show the site name set properly rather than
   Divi's placeholder mark. */
body.tv-no-logo #logo { display: none; }

/* The wordmark is rendered on Divi's existing home link rather than on the
   container, so it is a real clickable target back to the front page. The text
   sits in normal flow so the anchor actually takes the width of the name. */
body.tv-no-logo .logo_container > a {
	display: inline-flex;
	align-items: center;
	height: 100%;
	text-decoration: none;
}
body.tv-no-logo .logo_container > a::after {
	content: attr(data-site);
	/* The wordmark is the one place the script face earns its keep — the same
	   move the reference makes, where everything is sans except the logo. */
	font-family: var(--tv-script);
	font-weight: 400;
	font-size: 40px;
	letter-spacing: 0;
	/* Grey, not black. The reference sets every script word at #767676 — at
	   this size black reads as a heavy blot rather than a flourish. */
	/* Quentin sits high on its body with a deep descender, so it needs a larger
	   size to read at nav scale and a nudge down to sit level with the menu. */
	line-height: 1;
	position: relative;
	top: 3px;
	color: var(--tv-script-ink);
	white-space: nowrap;
	transition: color 0.15s ease;
}
body.tv-no-logo .logo_container > a:hover::after { color: var(--tv-accent); }

#top-menu li a,
#et-top-navigation .et-cart-info,
#et_top_search .et-search-field {
	font-family: var(--tv-body);
	font-weight: 500;
	text-transform: none;
	letter-spacing: 0;
	font-size: 16px;
	color: var(--tv-text-2);
	opacity: 1;
	white-space: nowrap;
}
/* Divi's default item padding is generous for sentence-case menus; this one is
   uppercase and letterspaced, so it needs less. */
#top-menu > li { padding-right: 26px; }
#top-menu > li:last-child { padding-right: 0; }
.logo_container { min-width: 190px; }
#top-menu li a:hover { color: var(--tv-accent); opacity: 1; }

/* One menu item drawn as a pill button — "Bonus scenes", the way the old
   tessastone.com header carried "Free Bonus Scenes". Set by the menu item's
   CSS class `tv-menu-btn`, so it is a menu decision, not a template one. */
#top-menu > li.tv-menu-btn > a {
	display: inline-block;
	padding: 9px 18px !important;
	border-radius: 999px;
	background: var(--tv-text);
	color: var(--tv-bg) !important;
	font-weight: 700;
	line-height: 1.2;
	transition: background .15s ease;
}
#top-menu > li.tv-menu-btn > a:hover,
#top-menu > li.tv-menu-btn.current-menu-item > a { background: var(--tv-muted); color: var(--tv-bg) !important; }
#main-header .et_mobile_menu li.tv-menu-btn > a {
	display: inline-block;
	margin: 8px 0 4px;
	padding: 10px 18px !important;
	border-radius: 999px;
	background: var(--tv-text);
	color: var(--tv-bg) !important;
	font-weight: 700;
}
#top-menu li.current-menu-item > a,
#top-menu li.current_page_item > a { color: var(--tv-accent); }

/* dropdowns */
#top-menu li ul.sub-menu {
	background: var(--tv-panel);
	border: 1px solid var(--tv-hairline);
	border-top-color: var(--tv-accent);
	box-shadow: none;
	padding: 6px 0;
}
#top-menu li ul.sub-menu li a { color: var(--tv-text-2); font-size: 15px; text-transform: none; letter-spacing: 0; }
#top-menu li ul.sub-menu li a:hover { background: var(--tv-panel-raised); color: var(--tv-accent); }

#et_top_search .et-search-field { color: var(--tv-text); }
#et_search_icon::before { color: var(--tv-text-2); }
#et_search_icon:hover::before { color: var(--tv-accent); }

/* Mobile menu.
   Divi colours these from its own generated stylesheet at #main-header specificity,
   so matching that is required — otherwise the links stay near-black on the dark
   panel and the menu looks empty. */
#main-header #et_mobile_nav_menu .mobile_menu_bar::before,
#et_mobile_nav_menu .mobile_menu_bar::before { color: var(--tv-text-2); }

#main-header .et_mobile_menu,
.et_mobile_menu {
	background: var(--tv-panel);
	border-top: 1px solid var(--tv-accent);
}

#main-header .et_mobile_menu li a,
#main-header .et_mobile_menu li li a,
.et_mobile_menu li a {
	color: var(--tv-text);
	border-bottom: 1px solid var(--tv-hairline);
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 14px;
	padding: 13px 5%;
	opacity: 1;
}
#main-header .et_mobile_menu li a:hover,
#main-header .et_mobile_menu li.current-menu-item > a {
	color: var(--tv-accent);
	background: var(--tv-panel-raised);
	opacity: 1;
}

/* Sub-items indented and quieter, so the two levels read apart. */
#main-header .et_mobile_menu .sub-menu li a {
	padding-left: 11%;
	font-size: 12.5px;
	color: var(--tv-muted);
}
#main-header .et_mobile_menu .menu-item-has-children > a { font-weight: 700; }

/* ---------------------------------------------------------------- footer */

#main-footer {
	background: var(--tv-bg);
	border-top: 1px solid var(--tv-hairline);
}

#footer-widgets { padding: 44px 0 20px; }
#footer-widgets .footer-widget h4,
#footer-widgets .footer-widget h4 a {
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
}
#footer-widgets .footer-widget,
#footer-widgets .footer-widget li,
#footer-widgets .footer-widget li a {
	font-family: var(--tv-body);
	font-weight: 400;
	font-size: 15px;
	color: var(--tv-text-2);
}
#footer-widgets .footer-widget li a:hover { color: var(--tv-accent); }
#footer-widgets .footer-widget li::before { border-color: var(--tv-border); }

#footer-bottom {
	background: var(--tv-bg);
	border-top: 1px solid var(--tv-hairline);
	padding: 16px 0;
}
#footer-info, #footer-info a {
	font-family: var(--tv-body);
	font-size: 13px;
	color: var(--tv-muted);
}
#footer-info a:hover { color: var(--tv-accent); }
.et-social-icons li a { color: var(--tv-muted); }
.et-social-icons li a:hover { color: var(--tv-accent); }

/* The 18+ notice sits below everything, against the same ground. */
.tv-adult { border-top: 1px solid var(--tv-hairline); }

/* Block-based widgets carry different markup to Divi's classic ones. */
#footer-widgets .widget_block h1,
#footer-widgets .widget_block h2,
#footer-widgets .widget_block h3,
#footer-widgets .wp-block-heading {
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
}
#footer-widgets .widget_block a,
#footer-widgets .wp-block-list a,
#footer-widgets a {
	color: var(--tv-text-2);
	font-family: var(--tv-body);
	font-weight: 400;
}
#footer-widgets a:hover { color: var(--tv-accent); }

/* Footer menu */
#footer-bottom .bottom-nav li a {
	font-family: var(--tv-label);
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
	opacity: 1;
}
#footer-bottom .bottom-nav li a:hover { color: var(--tv-accent); }

/* Divi's credit line and social icons, removed outright — not wanted. */
#footer-info,
.et-social-icons { display: none; }

/* With those gone the bar holds only the footer menu, so it no longer needs
   Divi's two-column footprint. */
#footer-bottom { padding: 14px 0; }
#footer-bottom .container { display: flex; justify-content: center; }
#footer-bottom .bottom-nav { float: none; padding: 0; }

/* Social icons: Instagram, Facebook, Amazon, Goodreads, in the far right
   corner of the footer menu row. inc/social.php appends them to the footer
   menu; the row that is actually visible is the child theme's `.tv-footernav`
   (Divi's own bar is hidden), so the rules target that. The menu stays
   centred on the full width and the icons sit in the corner. Under 900px they
   drop beneath the menu, centred, since the corner has no room. */
.tv-footernav .tv-wrap { position: relative; }

/*
 * The icons sit on their own line, always.
 *
 * They used to be absolutely positioned in the right-hand corner with 150px of
 * padding reserved on the menu to keep links clear of them. Six icons are about
 * 212px wide, so the reservation was never big enough — it only became visible
 * once the menu reached eleven items and the last one ran under them. With this
 * many links a single row was never going to hold both.
 */
.tv-footernav__list .tv-social {
	position: static;
	transform: none;
	flex-basis: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 4px;
	margin: 10px 0 0;
	padding: 0;
	line-height: 0;
}

.tv-social__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 999px;
	color: var(--tv-muted);
	transition: color .15s ease, background .15s ease;
}
.tv-social__link svg { width: 20px; height: 20px; display: block; }
.tv-social__link:hover { color: var(--tv-text); background: var(--tv-panel); }
.tv-social .screen-reader-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }


/* The shortcode version, e.g. on the Links page: a plain centred row. */
.tv-social--inline {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	margin: 18px 0 0;
	line-height: 0;
}
.tv-social--inline .tv-social__link { width: 40px; height: 40px; color: var(--tv-text-2); }
.tv-social--inline .tv-social__link svg { width: 22px; height: 22px; }
.tv-social--inline .tv-social__link:hover { color: var(--tv-text); background: var(--tv-panel); }
.tv-social--left { justify-content: flex-start; }

/* Divi's hidden bar also carries the menu (and so the icons): never show. */
#footer-bottom .tv-social { display: none; }

/* ---------------------------------------------------------------------------
   Bonus scenes (page-bonus-scenes.php)
   A grid of covers, each with one button per free scene. Carried over from
   tessastone.com, which stacked them in one long column; a grid keeps the
   whole shelf in view.
   --------------------------------------------------------------------------- */
.tv-bonus__intro { margin-top: 18px; max-width: 62ch; }
.tv-bonus {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
	gap: 36px 24px;
	margin-top: 36px;
}
.tv-bonus__card { min-width: 0; display: flex; flex-direction: column; }
.tv-bonus__cover {
	display: block;
	aspect-ratio: 2 / 3;
	overflow: hidden;
	position: relative;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-hairline);
}
.tv-bonus__cover img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.tv-bonus__cover:hover img { transform: scale(1.03); }
/* `.tv h2` sets 30px at (0,1,1); this has to outrank it or every card title
   renders at page-heading size. */
.tv h2.tv-bonus__title {
	margin: 14px 0 10px;
	font-family: var(--tv-display);
	font-size: 18px;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: 0;
}
.tv .tv-bonus__title a { color: var(--tv-text); }
.tv .tv-bonus__title a:hover { color: var(--tv-muted); text-decoration: none; }
.tv-bonus__links { display: flex; flex-direction: column; gap: 8px; margin-top: auto; }
.tv-bonus__btn { font-size: 14.5px; }
.tv-bonus__btn--soon { color: var(--tv-muted); border-color: var(--tv-hairline); background: var(--tv-panel); cursor: default; }
.tv-bonus__note {
	margin: 40px 0 0;
	max-width: 62ch;
	font-size: 15px;
	line-height: 1.6;
	color: var(--tv-muted);
}
@media (max-width: 600px) {
	.tv-bonus { grid-template-columns: repeat(2, 1fr); gap: 28px 16px; }
	.tv h2.tv-bonus__title { font-size: 16px; }
}

/* ---------------------------------------------------------------------------
   ARC team and street team pages (page-arcs.php, page-street-team.php)
   Prose on the left, the form in a panel on the right; stacks under 900px.
   --------------------------------------------------------------------------- */
.tv-team {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 380px;
	gap: 48px;
	margin-top: 24px;
	align-items: start;
}
.tv-team__main { min-width: 0; max-width: 64ch; }
.tv .tv-team__h {
	margin: 34px 0 12px;
	font-family: var(--tv-display);
	font-size: 22px;
	font-weight: 700;
	line-height: 1.25;
}
.tv-team__steps, .tv-team__list, .tv-team__perks {
	margin: 0;
	padding-left: 22px;
	font-size: 16.5px;
	line-height: 1.65;
	color: var(--tv-text-2);
}
.tv .tv-team__steps { list-style: decimal; }
.tv .tv-team__list { list-style: disc; }
.tv-team__steps li, .tv-team__list li, .tv-team__perks li { margin: 0 0 10px; padding-left: 4px; }
.tv-team__steps li::marker { font-weight: 700; color: var(--tv-text); }
.tv-team__list li::marker { color: var(--tv-muted); }
.tv-team__steps li strong { color: var(--tv-text); }
.tv-team__perks {
	list-style: none;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 10px 18px;
}
.tv-team__perks li {
	margin: 0;
	padding: 12px 14px;
	background: var(--tv-sage);
	font-size: 15.5px;
	line-height: 1.5;
	color: var(--tv-text);
}
.tv-team__cross { margin: 34px 0 0; font-size: 15px; color: var(--tv-muted); }
.tv-team__cross a { color: var(--tv-text); text-decoration: underline; }
.tv-team__aside { position: sticky; top: 24px; }
.tv-team__card { background: var(--tv-panel); }
.tv-team__next { margin: 0 0 16px; font-size: 15px; color: var(--tv-text); }
.tv-team__next .tv-label { display: block; margin-bottom: 2px; }
.tv-team__note { margin: 0 0 16px; font-size: 14.5px; line-height: 1.5; color: var(--tv-muted); }
.tv-team__form { display: flex; flex-direction: column; gap: 12px; }
.tv-team__field { display: flex; flex-direction: column; gap: 5px; }
.tv-team__field > span { font-family: var(--tv-label); font-size: 13px; font-weight: 600; color: var(--tv-muted); }
.tv-team__field input, .tv-team__field textarea {
	width: 100%;
	padding: 12px 14px;
	border: 1px solid var(--tv-border);
	border-radius: 6px;
	background: var(--tv-bg);
	color: var(--tv-text);
	font: 400 15.5px/1.4 var(--tv-body);
}
.tv-team__field textarea { resize: vertical; }
.tv-team__field input::placeholder { color: var(--tv-muted); }
.tv-team__field input:focus-visible, .tv-team__field textarea:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: -2px; }
.tv-team__form .tv-btn { margin-top: 4px; cursor: pointer; }
.tv-team__form .tv-btn[disabled] { opacity: .6; cursor: default; }
.tv-team__form .tv-signup__status { margin: 0; }
.tv-team__form[data-state="done"] .tv-signup__status { color: var(--tv-patreon); }
.tv-team__sprout { margin-top: 12px; }
.tv-team__fine { margin: 2px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--tv-muted); }
.tv-team__open { margin: 0 0 22px; padding: 0 0 20px; border-bottom: 1px solid var(--tv-border); }
.tv-team__open .tv-label { display: block; margin-bottom: 8px; color: var(--tv-patreon); }
.tv-team__open .tv-team__note { margin: 10px 0 0; }
@media (max-width: 900px) {
	.tv-team { grid-template-columns: 1fr; gap: 32px; }
	.tv-team__aside { position: static; }
}

/* ---------------------------------------------------------------------------
   Street team room (page-street-team-room.php)
   Password-gated page: notes + chat on the left, release kits on the right.
   --------------------------------------------------------------------------- */
.tv-room__gate { max-width: 52ch; margin-top: 18px; }
.tv-pwform { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.tv-pwform label { display: flex; flex-direction: column; gap: 6px; font-family: var(--tv-label); font-size: 13px; font-weight: 600; color: var(--tv-muted); }
.tv-pwform input[type="password"] {
	width: 260px; max-width: 100%; padding: 12px 14px;
	border: 1px solid var(--tv-border); border-radius: 6px;
	background: var(--tv-bg); color: var(--tv-text); font: 400 15.5px/1.4 var(--tv-body);
}
.tv-pwform input[type="password"]:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: -2px; }
.tv-pwform .tv-btn { cursor: pointer; }
.tv-room { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 48px; margin-top: 24px; align-items: start; }
.tv-room__main { min-width: 0; max-width: 70ch; }
.tv-room__notes .tv-prose { margin-top: 0; }
.tv-room__chat { margin-top: 40px; }
.tv-room__chat .tv-comments { margin-top: 18px; }
.tv-room__aside { position: sticky; top: 24px; }
/* Jennifer's release threads, pinned at the top of the room's chat. */
.tv-comment--pinned > .tv-comment__body { padding: 14px 16px; background: var(--tv-sage); }
.tv-comment--pinned > .tv-comment__body .tv-comment__head::before {
	content: "Pinned";
	display: inline-block; margin-right: 8px; padding: 1px 7px;
	border-radius: 999px; background: var(--tv-text); color: var(--tv-bg);
	font-family: var(--tv-label); font-size: 11px; font-weight: 700; letter-spacing: .02em; vertical-align: 1px;
}
.tv-kit { padding: 18px; background: var(--tv-panel); margin-bottom: 16px; }
.tv-kit__art { display: block; margin: 0 0 12px; }
.tv-kit__art img { display: block; width: 100%; height: auto; }
.tv .tv-kit__title { margin: 0 0 2px; font-family: var(--tv-display); font-size: 18px; font-weight: 700; line-height: 1.25; }
.tv-kit__when { margin: 0 0 10px; font-family: var(--tv-label); font-size: 13px; color: var(--tv-muted); }
.tv-kit__caption textarea {
	width: 100%; padding: 10px 12px; margin: 0 0 8px;
	border: 1px solid var(--tv-border); border-radius: 6px;
	background: var(--tv-bg); color: var(--tv-text-2); font: 400 14px/1.5 var(--tv-body); resize: vertical;
}
.tv-kit__links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
@media (max-width: 900px) {
	.tv-room { grid-template-columns: 1fr; gap: 32px; }
	.tv-room__aside { position: static; }
}

/* ------------------------------------------------------------- catalogue */

.tv-cat__series {
	font-family: var(--tv-label); font-weight: 600;
	text-transform: none; font-size: 16px;
	color: var(--tv-accent); margin: 0 0 14px;
	padding-bottom: 9px; border-bottom: 1px solid var(--tv-hairline);
	line-height: 1.4;
}
/* `.tv h3` sets the display face at (0,1,1); this needs to outrank it. */
.tv .tv-cat__series,
.tv h3.tv-cat__series,
.tv h4.tv-cat__series {
	font-family: var(--tv-label); font-weight: 600;
	text-transform: none; font-size: 16px;
	color: var(--tv-accent); line-height: 1.4;
}

.tv-shelfrow { margin-top: 34px; }

/* Each world is a separate universe; the catalogue should not run them
   together. Set here rather than inline — see tessaverse_world_attr(). */
.tv-worldsec { margin-top: 56px; }
.tv-worldsec + .tv-worldsec {
	margin-top: 88px;
	padding-top: 64px;
	border-top: 1px solid var(--tv-hairline);
}
.tv-worldsec__name { font-size: 38px; margin-bottom: 4px; }
.tv-cotw--spaced { margin-top: 20px; }

.tv-covers {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
	gap: 26px 20px;
}

.tv-book { display: block; }
.tv-book__art {
	display: block;
	aspect-ratio: 2 / 3;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-hairline);
	overflow: hidden;
	position: relative;
}
.tv-book__art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tv-book:hover .tv-book__art { border-color: var(--tv-accent); }

/* A book with no cover yet says so, rather than looking broken. */
.tv-book__empty {
	position: absolute; inset: 0;
	display: flex; align-items: center; justify-content: center;
	padding: 12px; text-align: center;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
}

.tv-book__title {
	display: block; margin-top: 10px;
	font-family: var(--tv-display); font-weight: 600; font-size: 16px; line-height: 1.25;
	color: var(--tv-text);
}
.tv-book:hover .tv-book__title { color: var(--tv-accent); }
.tv-book__num {
	font-family: var(--tv-label); font-size: 10px; letter-spacing: 0.08em;
	color: var(--tv-muted); display: block; margin-top: 3px;
}

@media (max-width: 640px) { .tv-covers { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 20px 14px; } }


/* Panels side by side rather than stacked in a column beside short content —
   a tall sidebar next to a short main column leaves a dead gap the height of
   the sidebar. */
.tv-panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 20px; align-items: start; }
.tv-panels .tv-panel { margin-bottom: 0; }

/* ------------------------------------------------------- world narrators */

.tv-narrators { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 22px; }
.tv-narrators__label { flex: none; }
.tv-narrators__list { display: flex; gap: 10px; flex-wrap: wrap; }

.tv-narrator-chip {
	display: inline-flex; align-items: center; gap: 10px;
	border: 1px solid var(--tv-border); border-radius: 999px;
	padding: 6px 16px 6px 6px;
	background: color-mix(in oklab, var(--tv-panel) 70%, transparent);
}
.tv-narrator-chip:hover { border-color: var(--tv-accent); text-decoration: none; }
.tv-narrator-chip img,
.tv-narrator-chip .tv-narrator-chip__fill {
	width: 34px; height: 34px; border-radius: 50%; object-fit: cover;
	object-position: center 28%; flex: none; display: block;
	background: var(--tv-placeholder);
}
.tv-narrator-chip__name { font-family: var(--tv-display); font-weight: 600; font-size: 17px; color: var(--tv-text); }
.tv-narrator-chip:hover .tv-narrator-chip__name { color: var(--tv-accent); }

/* --------------------------------------------------------------- creator */

.tv-creator { padding-top: 64px; padding-bottom: 90px; max-width: 1100px; }

.tv-creator__head {
	display: grid;
	grid-template-columns: 300px 1fr;
	gap: 48px;
	align-items: center;
}
.tv-creator__portrait {
	aspect-ratio: 1 / 1;
	border-radius: 50%;
	overflow: hidden;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-hairline);
}
.tv-creator__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tv-creator__intro h1 { margin-bottom: 4px; }
.tv-creator__lead {
	font-size: 22px;
	font-weight: 300;
	line-height: 1.6;
	color: var(--tv-text-2);
	margin-top: 16px;
	max-width: 48ch;
	text-wrap: pretty;
}
.tv-creator__lead p { margin: 0 0 0.8em; }

.tv-creator__body { margin-top: 46px; max-width: 68ch; }

.tv-creator__doors {
	display: flex; gap: 10px; flex-wrap: wrap;
	margin-top: 48px; padding-top: 34px;
	border-top: 1px solid var(--tv-hairline);
}

@media (max-width: 860px) {
	.tv-creator__head { grid-template-columns: 1fr; gap: 28px; }
	.tv-creator__portrait { max-width: 220px; }
	.tv-creator__lead { font-size: 19px; }
}

/* ---------------------------------------------------------- breadcrumbs */

.tv-crumbs {
	border-bottom: 1px solid var(--tv-hairline);
	background: color-mix(in oklab, var(--tv-panel) 45%, var(--tv-bg));
}
.tv-crumbs ol {
	display: flex; flex-wrap: wrap; align-items: center;
	gap: 0 8px; margin: 0; padding: 12px 0; list-style: none;
}
.tv-crumbs li { display: flex; align-items: center; gap: 8px; }
.tv-crumbs li + li::before {
	content: '';
	width: 5px; height: 5px;
	border-top: 1px solid var(--tv-muted);
	border-right: 1px solid var(--tv-muted);
	transform: rotate(45deg);
	flex: none;
	opacity: 0.7;
}
.tv-crumbs a,
.tv-crumbs span {
	font-family: var(--tv-label);
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
	white-space: nowrap;
}
.tv-crumbs a:hover { color: var(--tv-accent); text-decoration: none; }
.tv-crumbs [aria-current="page"] { color: var(--tv-text-2); }

@media (max-width: 560px) {
	/* Keep the immediate parent and the current page; drop the middle. */
	.tv-crumbs li:not(:first-child):not(:last-child):not(:nth-last-child(2)) { display: none; }
}

.tv-creator__section { margin-top: 56px; }
.tv-creator__section h2 { font-size: 32px; }
.tv-creator__note { font-size: 15px; color: var(--tv-muted); margin: 8px 0 22px; }

.tv-wip { position: relative; }
.tv-wip__badge { position: absolute; top: 10px; left: 10px; right: 10px; display: flex; }
.tv-wip__badge .tv-badge {
	background: color-mix(in oklab, var(--tv-bg) 88%, transparent);
	backdrop-filter: blur(2px);
	white-space: nowrap;
	max-width: 100%;
	font-size: 11px;
	padding: 5px 12px;
}

/* ------------------------------------------------------------------ blog */

/* ---------------------------------------------------------------------------
   The Journal listing
   Karla's "Blog inline Layout", measured off the reference on 2026-09-04:
   a 283px 16:10 photograph on the left, vertically centred against the
   writing; a bold title; "By Karla | date | Category" in grey with pipe
   separators; an 18px excerpt; "Read article" alone on the right. Entries
   sit ~40px apart with no rules or boxes. Two departures, both standing
   rulings: titles are sentence case, and the face is Roboto throughout.
   --------------------------------------------------------------------------- */
.tv-posts {
	display: flex;
	flex-direction: column;
	gap: 64px;
	margin-top: 40px;
}

.tv-post {
	position: relative;
	display: block;
}

.tv-post__art {
	position: relative;
	display: block;
	/* Banner on top, not beside. The featured art is a wide cinematic header
	   (~2.6:1) and Patreon post headers are the same shape, so the ratio matches
	   the source rather than cropping it. Kept identical at every width — a
	   taller ratio on mobile would crop the sides and cut the composition. */
	aspect-ratio: 2.6 / 1;
	width: 100%;
	margin-bottom: 20px;
	overflow: hidden;
	background: var(--tv-placeholder);
	border-radius: 0;
}

.tv-post__art img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .4s ease;
}

.tv-post:hover .tv-post__art img {
	transform: scale(1.03);
}

.tv-post__noart {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--tv-label);
	font-size: 13.5px;
	color: var(--tv-muted);
}

.tv-post__body {
	min-width: 0;
	padding: 8px 0;
}

.tv-post__title {
	margin: 0 0 8px;
	font-family: var(--tv-display);
	font-size: 24px;
	font-weight: 700;
	line-height: 1.25;
	/* Sentence case, not the reference's uppercase — the site dropped every
	   uppercase heading deliberately. */
	text-transform: none;
	letter-spacing: 0;
}

.tv-post__title a {
	color: var(--tv-text);
}

.tv-post__title a:hover {
	color: var(--tv-accent);
	text-decoration: none;
}

/* Stretches the title's link across the whole card, so clicking anywhere works
   without nesting anchors or repeating the destination for screen readers. */
.tv-post__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.tv-post__meta {
	margin: 0 0 14px;
	font-family: var(--tv-label);
	font-size: 15px;
	color: var(--tv-muted);
}

.tv-post__meta span + span::before {
	content: "|";
	margin: 0 8px;
	color: var(--tv-muted);
}

.tv-post__excerpt {
	margin: 0;
	font-size: 17px;
	line-height: 1.65;
	color: var(--tv-text);
}

/* Karla sets "READ ARTICLE" alone on the right of the excerpt, plain text. */
.tv-post__more {
	display: block;
	margin-top: 18px;
	text-align: right;
	font-family: var(--tv-label);
	font-size: 15px;
	font-weight: 700;
	color: var(--tv-text);
	transition: color .2s ease;
}

.tv-post:hover .tv-post__more {
	color: var(--tv-muted);
}

@media (max-width: 820px) {
	.tv-posts {
		gap: 36px;
	}

	.tv-post__title {
		font-size: 22px;
	}
}

@media (max-width: 600px) {
	/* The banner keeps its 2.6:1 ratio here too — a taller ratio on a phone
	   would crop the sides and cut the composition in half. */
	.tv-post__art {
		margin-bottom: 16px;
	}

	.tv-post__body {
		padding: 0;
	}

	.tv-post__title {
		font-size: 21px;
	}

	.tv-post__excerpt {
		font-size: 16px;
	}
}

/* ---------------------------------------------------------------------------
   The Journal's featured strip — "veil cards"
   Chosen 2026-09-04 from three options (magazine hero, peek carousel, veil
   cards). Up to four tall 3:4 cards, three across on desktop, with the title
   sitting on the photograph under the same white veil the world cards use.
   CSS scroll-snap does the moving; journal.js drives the two arrows by the
   label and hides them when everything fits. No autoplay.
   --------------------------------------------------------------------------- */
.tv-featured {
	--tv-fgap: 24px;
	--tv-fcols: 3;
	margin-top: 40px;
	padding-bottom: 44px;
	border-bottom: 1px solid var(--tv-hairline);
}

.tv-featured__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 14px;
}

.tv-featured__nav {
	display: flex;
	gap: 8px;
}

.tv-featured__btn {
	width: 40px;
	height: 40px;
	border: 1px solid var(--tv-border);
	border-radius: 999px;
	background: var(--tv-bg);
	color: var(--tv-text);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
	transition: background .15s ease, border-color .15s ease, opacity .15s ease;
}

.tv-featured__btn:hover:not(:disabled) {
	background: var(--tv-text);
	border-color: var(--tv-text);
	color: var(--tv-bg);
}

.tv-featured__btn:disabled {
	opacity: .3;
	cursor: default;
}

/* Everything fits: no need for the arrows. */
.tv-featured--static .tv-featured__nav {
	display: none;
}

.tv-featured__track {
	display: flex;
	gap: var(--tv-fgap);
	margin: 0;
	padding: 0 0 4px;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.tv-featured__track::-webkit-scrollbar {
	display: none;
}

.tv-fcard {
	flex: 0 0 calc((100% - (var(--tv-fcols) - 1) * var(--tv-fgap)) / var(--tv-fcols));
	scroll-snap-align: start;
	margin: 0;
}

.tv-fcard__link {
	position: relative;
	display: block;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background: var(--tv-placeholder);
	color: var(--tv-text);
	text-decoration: none;
}

.tv-fcard__link img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 15%;
	transition: transform .5s ease;
}

.tv-fcard__link:hover img {
	transform: scale(1.04);
}

/* The veil: opaque where the text sits, fading up into the picture. The
   min-height is the floor that keeps a short title from stranding the meta
   line on bare image — the world-card lesson. */
.tv-fcard__panel {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	min-height: 34%;
	padding: 34px 22px 20px;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	gap: 6px;
	background: linear-gradient(to top,
		rgba(255, 255, 255, .96) 0%,
		rgba(255, 255, 255, .96) 40%,
		rgba(255, 255, 255, 0) 100%);
}

.tv-fcard__meta {
	font-family: var(--tv-label);
	font-size: 12.5px;
	font-weight: 600;
	color: var(--tv-muted);
}

.tv-fcard__meta span + span::before {
	content: "|";
	margin: 0 7px;
}

.tv-fcard__title {
	margin: 0;
	font-family: var(--tv-display);
	font-size: 22px;
	font-weight: 700;
	line-height: 1.2;
}

.tv-fcard__link:hover .tv-fcard__title {
	color: var(--tv-text-2);
}

.tv-fcard .tv-post__noart {
	inset: 0 0 34% 0;
}

@media (max-width: 900px) {
	.tv-featured {
		--tv-fcols: 2;
	}

	.tv-fcard__title {
		font-size: 20px;
	}
}

@media (max-width: 600px) {
	.tv-featured {
		--tv-fcols: 1.22;
		--tv-fgap: 16px;
		padding-bottom: 32px;
	}

	.tv-fcard__title {
		font-size: 19px;
	}

	.tv-fcard__panel {
		padding: 28px 18px 16px;
	}
}

/* pagination, shared by the blog and the fallback archives */
.tv .pagination { margin-top: 8px; }
.tv .pagination .screen-reader-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.tv .nav-links { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.tv .nav-links .dots { border-color: transparent; }
.tv .nav-links .page-numbers {
	border: 1px solid var(--tv-border); padding: 8px 14px;
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-text-2);
}
.tv .nav-links .page-numbers.current { background: var(--tv-accent); color: var(--tv-bg); border-color: var(--tv-accent); }
.tv .nav-links a.page-numbers:hover { border-color: var(--tv-accent); color: var(--tv-accent); text-decoration: none; }

/* A featured image on an article: a banner, never a tower. */
.tv-hero-img {
	margin: 28px 0 0;
	max-width: 820px;
	overflow: hidden;
	background: var(--tv-placeholder);
	border: 1px solid var(--tv-hairline);
}

/*
 * The image keeps its own shape and is only capped in height. A forced 3/2 here
 * cropped the sides off a 2.5:1 banner — on art composed with a figure at each
 * edge that removes both of them. The cap still solves what the fixed ratio was
 * for: a portrait would otherwise render past 1,200px and bury the article.
 */
.tv-hero-img img {
	width: 100%;
	height: auto;
	max-height: 560px;
	object-fit: cover;
	object-position: center;
	display: block;
}

@media (max-width: 620px) { .tv-hero-img img { max-height: 380px; } }

/* Content written in the editor, inside our prose column. */
.tv-prose img { max-width: 100%; height: auto; display: block; margin: 22px 0; border: 1px solid var(--tv-hairline); }
.tv-prose h2 { font-size: 30px; margin: 34px 0 12px; }
.tv-prose h3 { font-size: 23px; margin: 28px 0 10px; }
.tv-prose ul, .tv-prose ol { margin: 0 0 1.1em 1.2em; }
.tv-prose li { margin-bottom: 0.4em; }
.tv-prose blockquote {
	border-left: 2px solid var(--tv-accent);
	background: var(--tv-tint);
	margin: 26px 0; padding: 18px 22px;
	font-family: var(--tv-display); font-weight: 600; font-size: 21px; line-height: 1.5; color: var(--tv-text);
}
.tv-prose a { text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------------- buy links */

.tv-buys { display: grid; gap: 12px; margin-top: 16px; max-width: 340px; }
.tv-buys__group { display: grid; gap: 5px; }
.tv-buys__format { display: block; font-size: 12px; margin-bottom: 2px; }

/* Compact: a column of links should not out-measure the cover beside it. */
.tv .tv-buys a.tv-btn { padding: 12px 20px; font-size: 14px; letter-spacing: 0; }

/* The direct sale gets the one frame — it is the link the author actually wants
   taken, and a second box for special editions doubled the weight for no gain. */
.tv-buys__group.is-direct {
	border: 1px solid color-mix(in oklab, var(--tv-accent) 45%, transparent);
	background: var(--tv-tint);
	padding: 11px;
	gap: 6px;
}
.tv-buys__group.is-direct .tv-buys__format { color: var(--tv-accent); }

/* --------------------------------------------------------------- newsletter */

.tv-signup .tv-wrap,
.tv-adult .tv-wrap { max-width: 1400px; margin: 0 auto; padding: 0 var(--tv-gutter); }

.tv-signup {
	background: var(--tv-sand);
	border-top: 1px solid transparent;
	padding: 40px 0;
	font-family: var(--tv-body);
}
.tv-signup__inner {
	display: grid;
	grid-template-columns: 1fr minmax(320px, 460px);
	gap: 40px;
	align-items: center;
	max-width: 1400px;
}
.tv-signup__heading {
	font-family: var(--tv-display);
	font-weight: 600;
	font-size: 28px;
	line-height: 1.15;
	color: var(--tv-text);
	margin: 0;
}
.tv-signup__blurb {
	font-size: 16px; font-weight: 400; line-height: 1.6;
	color: var(--tv-text-2);
	margin: 10px 0 0; max-width: 46ch;
}

.tv-signup__form { display: flex; gap: 8px; flex-wrap: wrap; align-items: stretch; position: relative; }
.tv-signup__field { flex: 1; min-width: 180px; display: flex; }
.tv-signup__field input {
	width: 100%;
	background: var(--tv-bg);
	border: 1px solid var(--tv-border);
	color: var(--tv-text);
	padding: 15px 22px;
	font-family: var(--tv-body);
	font-size: 16px;          /* 16px stops iOS zooming the page on focus */
	border-radius: 999px;
}
.tv-signup__field input::placeholder { color: var(--tv-muted); }
.tv-signup__field input:focus-visible { outline: 2px solid var(--tv-accent); outline-offset: -2px; }

.tv-signup__form .tv-btn { flex: none; cursor: pointer; }
.tv-signup__form .tv-btn[disabled] { opacity: 0.6; cursor: default; }

.tv-signup__status {
	flex: 1 0 100%;
	margin: 0;
	font-family: var(--tv-label);
	text-transform: none;
	font-size: 13.5px;
	color: var(--tv-muted);
	min-height: 0;
}
.tv-signup__form[data-state="done"] .tv-signup__status { color: var(--tv-accent); min-height: 1.4em; }

.screen-reader-text {
	position: absolute; width: 1px; height: 1px;
	overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@media (max-width: 860px) {
	.tv-signup__inner { grid-template-columns: 1fr; gap: 22px; }
	.tv-signup__heading { font-size: 26px; }
}

/* ------------------------------------------------------------------ patreon */

.tv-patreon { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 20px; }
.tv-signup--patreon-only .tv-patreon { margin-top: 0; }

/* Patreon keeps its own brand colour, but is a solid pill like every other
   button — it inherits the accent fill from .tv-btn otherwise, which left red
   text sitting on gold. */
.tv-patreon__btn,
.tv .tv-patreon__btn {
	background: var(--tv-patreon);
	border-color: var(--tv-patreon);
	color: #ffffff;
	flex: none;
}
.tv-patreon__btn:hover,
.tv .tv-patreon__btn:hover {
	background: var(--tv-patreon);
	border-color: var(--tv-patreon);
	color: #ffffff;
	filter: brightness(1.15);
	text-decoration: none;
}
.tv-patreon__note {
	font-family: var(--tv-body);
	font-weight: 400;
	font-size: 14px;
	line-height: 1.5;
	color: var(--tv-muted);
	max-width: 40ch;
}

/* On its own, the strip does not need two columns. */
.tv-signup--patreon-only .tv-signup__inner { grid-template-columns: 1fr; }

/* --------------------------------------------------------------- footer nav */

/* Divi's own footer bar is emptied out: its menu is re-rendered below the
   newsletter, and its social icons and credit were removed earlier. An empty
   bar is worse than none. */
#footer-bottom { display: none; }
#main-footer:not(:has(.widget)) { display: none; }

.tv-footernav {
	background: var(--tv-bg);
	border-top: 1px solid var(--tv-hairline);
	padding: 16px 0;
}
.tv-footernav .tv-wrap { max-width: 1400px; margin: 0 auto; padding: 0 var(--tv-gutter); }
.tv-footernav__list {
	display: flex; flex-wrap: wrap; justify-content: center;
	gap: 8px 26px; margin: 0; padding: 0; list-style: none;
}
.tv-footernav__list a {
	font-family: var(--tv-label);
	font-weight: 600;
	text-transform: none;
	font-size: 13px;
	color: var(--tv-muted);
}
.tv-footernav__list a:hover { color: var(--tv-accent); text-decoration: none; }
.tv-footernav__list .current-menu-item a { color: var(--tv-text-2); }

/* ------------------------------------------------- home: this week + social */

.tv-homerow {
	display: grid;
	grid-template-columns: 1fr 320px;
	gap: 20px;
	margin-top: 20px;
	align-items: stretch;
}

.tv-cotw {
	border: 1px solid transparent;
	background: var(--tv-sage);
	display: grid;
	/* The portrait was 220px inside a 1253px block, with the bio filling barely
	   400px of the remaining 1000 — a sliver of character against a field of
	   empty sage. Give the image real width and hold the block to a width the
	   text can actually fill. */
	/* A fixed portrait rather than a percentage. At 34% of a wide container the
	   image drove the band to ~590px tall to carry ~150px of text, and the
	   emptiness that left was worse than the sliver it replaced. */
	grid-template-columns: 300px 1fr;
	gap: 40px;
}
.tv-cotw__art { display: block; background: var(--tv-placeholder); overflow: hidden;
	aspect-ratio: 3 / 4; }
.tv-cotw__art img { width: 100%; height: 100%; object-fit: cover; object-position: center 25%; display: block; }
.tv-cotw__body { display: flex; flex-direction: column; justify-content: center; padding: 26px 26px 26px 0; min-width: 0; }
.tv-cotw__name {
	font-family: var(--tv-display); font-weight: 600; font-size: 34px; line-height: 1.1;
	color: var(--tv-text); display: block; margin: 10px 0 6px;
}
.tv-cotw__name:hover { color: var(--tv-accent); text-decoration: none; }
.tv-cotw__art:hover { opacity: 0.92; }
.tv-cotw__meta {
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-accent); display: block;
}
.tv-cotw__bio { font-size: 16px; line-height: 1.7; color: var(--tv-text-2); margin: 14px 0 0; max-width: 60ch; }

.tv-ig {
	border: 1px solid var(--tv-hairline);
	background: var(--tv-panel);
	padding: 26px;
	display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 6px;
}
.tv-ig__handle { font-family: var(--tv-display); font-weight: 600; font-size: 26px; line-height: 1.15; color: var(--tv-text); }
.tv-ig:hover .tv-ig__handle { color: var(--tv-accent); }
.tv-ig__note { font-size: 14px; line-height: 1.55; color: var(--tv-muted); margin: 4px 0 14px; }

@media (max-width: 1000px) {
	.tv-homerow { grid-template-columns: 1fr; }
	.tv-cotw { grid-template-columns: 170px 1fr; gap: 20px; }
	.tv-cotw__body { padding: 20px 20px 20px 0; }
	.tv-cotw__name { font-size: 28px; }
}
@media (max-width: 560px) {
	.tv-cotw { grid-template-columns: 1fr; }
	.tv-cotw__art { aspect-ratio: 3 / 2; }
	.tv-cotw__body { padding: 20px; }
}

/* ------------------------------------------------------------ instagram feed */

.tv-igfeed { margin-top: 40px; }
.tv-igfeed__head {
	display: flex; align-items: flex-end; justify-content: space-between;
	gap: 20px; flex-wrap: wrap;
	padding-bottom: 14px; margin-bottom: 20px;
	border-bottom: 1px solid var(--tv-hairline);
}
.tv-igfeed__feed { min-height: 60px; }

/* The plugin ships its own light styling; keep it on our ground. */
.tv-igfeed__feed #sb_instagram { padding-bottom: 0 !important; background: transparent !important; }
.tv-igfeed__feed #sb_instagram .sbi_header_text,
.tv-igfeed__feed #sb_instagram .sbi_bio,
.tv-igfeed__feed #sb_instagram h3 { color: var(--tv-text) !important; }
.tv-igfeed__feed .sbi_follow_btn a { border-radius: 0 !important; }

/* The plugin lays its posts out with CSS grid and a fixed four columns. Across a
   full-width page that makes every tile ~350px, so the column count is raised here
   — setting item widths does nothing useful against a grid. */
.tv-igfeed__feed #sb_instagram #sbi_images { grid-template-columns: repeat(4, 1fr) !important; }
@media (min-width: 900px)  { .tv-igfeed__feed #sb_instagram #sbi_images { grid-template-columns: repeat(5, 1fr) !important; } }
@media (min-width: 1200px) { .tv-igfeed__feed #sb_instagram #sbi_images { grid-template-columns: repeat(6, 1fr) !important; } }
@media (max-width: 620px)  { .tv-igfeed__feed #sb_instagram #sbi_images { grid-template-columns: repeat(3, 1fr) !important; } }
.tv-igfeed__feed #sb_instagram #sbi_images .sbi_item { width: auto !important; }

/* The plugin breaks its feed out to the full viewport width, so it ran edge to
   edge while everything above it stayed inside the page gutters. Pin it back to
   the column it was given. */
.tv-igfeed__feed,
.tv-igfeed__feed #sb_instagram,
.tv-igfeed__feed #sbi_images {
	position: static !important;
	width: 100% !important;
	max-width: 100% !important;
	left: auto !important;
	right: auto !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
	box-sizing: border-box !important;
}
.tv-igfeed__feed { overflow: hidden; }

/* --------------------------------------------------------- reading order */

.tv-readingorder__note { font-size: 16px; line-height: 1.6; color: var(--tv-text-2); margin: 10px 0 0; max-width: 60ch; }

.tv-readingorder__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 18px;
	margin-top: 26px;
}
.tv-readingorder__img {
	display: block;
	border: 1px solid var(--tv-hairline);
	background: var(--tv-placeholder);
	overflow: hidden;
}
.tv-readingorder__img img { width: 100%; height: auto; display: block; }
.tv-readingorder__img:hover { border-color: var(--tv-accent); }

.tv-readingorder__get {
	display: flex; align-items: center; justify-content: center;
	gap: 16px; flex-wrap: wrap; margin: 32px 0 0; text-align: center;
}
.tv-readingorder__hint {
	font-family: var(--tv-label); text-transform: none;
	font-size: 13.5px; color: var(--tv-muted);
}

/* A title says what it is rather than only showing the marker — the heir and the
   alpha are the point of the drawing. */
.tv-tree__sub--title { color: var(--tv-accent); }

/* Claimed into the household, not descended: no blood line, lighter card. */
.tv-tree__card.is-claimed { border-style: dashed; opacity: 0.78; }

/* The tree is wider than any laptop, so make it read as pannable rather than
   looking like it has simply been cut off. */
.tv-tree-scroll { position: relative; scrollbar-width: thin; }
.tv-tree-wrap { position: relative; }
.tv-tree-wrap::before,
.tv-tree-wrap::after {
	content: ''; position: absolute; top: 0; bottom: 0; width: 44px;
	pointer-events: none; z-index: 2; opacity: 0; transition: opacity 0.2s ease;
}
.tv-tree-wrap::before { left: 0; background: linear-gradient(to right, var(--tv-bg), transparent); }
.tv-tree-wrap::after { right: 0; background: linear-gradient(to left, var(--tv-bg), transparent); }
.tv-tree-wrap.can-left::before { opacity: 1; }
.tv-tree-wrap.can-right::after { opacity: 1; }

/* ==========================================================================
   Family tree, block layout.
   A single connected drawing could not hold this house on a laptop — it came to
   2622px against a 1312px window. The first two tiers stay a connected trunk;
   every branch below is a block that reflows to the width available, so nothing
   is ever off-screen and it keeps working as the cast grows.
   ========================================================================== */

.tv-fam { margin-top: 26px; }

.tv-fam__trunk { display: flex; flex-direction: column; align-items: center; padding-bottom: 6px; }
.tv-fam__root { position: relative; padding-bottom: 26px; }
.tv-fam__root::after {
	content: ''; position: absolute; left: 50%; bottom: 0;
	width: 1px; height: 26px; background: var(--tv-border);
}
.tv-fam__founders { display: flex; gap: 56px; position: relative; padding-top: 26px; }
/* The sibling rule joins the founders, and stops at the outermost card centres. */
.tv-fam__founders::before {
	content: ''; position: absolute; top: 0; left: 25%; right: 25%;
	height: 1px; background: var(--tv-border);
}
.tv-fam__founder { position: relative; padding-top: 0; }
.tv-fam__founder::before {
	content: ''; position: absolute; left: 50%; top: -26px;
	width: 1px; height: 26px; background: var(--tv-border);
}
.tv-fam__founders:only-child::before,
.tv-fam__founder:only-child::before { display: none; }

.tv-fam__branch { margin-top: 54px; }
.tv-fam__branchname {
	font-size: 22px; margin: 0 0 18px;
	padding-bottom: 10px; border-bottom: 1px solid var(--tv-hairline);
}

.tv-fam__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
	gap: 18px;
}

.tv-fam__block {
	border: 1px solid var(--tv-hairline);
	background: var(--tv-panel);
	border-radius: 3px;
	padding: 18px;
}
.tv-fam__couple { display: flex; align-items: stretch; justify-content: center; gap: 0; }
.tv-fam__bond {
	align-self: center; width: 18px; height: 0;
	border-top: 1px dashed var(--tv-border); flex: none;
}

.tv-fam__kids {
	display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
	margin-top: 22px; padding-top: 20px; position: relative;
}
/* One descent line from the couple down into the children. */
.tv-fam__kids::before {
	content: ''; position: absolute; top: 0; left: 50%;
	width: 1px; height: 20px; background: var(--tv-border);
}
.tv-fam__kid { display: flex; flex-direction: column; align-items: center; gap: 8px; }
/* Twins share a bracket. */
.tv-fam__kid.is-twin .tv-tree__card { border-top: 2px solid var(--tv-accent-2); }
.tv-fam__sub { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }

.tv-fam__none { margin: 18px 0 0; font-size: 14px; color: var(--tv-muted); text-align: center; }

/* The block layout supplies its own frame, so cards inside it size to content. */
.tv-fam .tv-tree__card { min-width: 132px; }
.tv-fam .tv-tree__card.is-root { min-width: 180px; }

@media (max-width: 700px) {
	.tv-fam__grid { grid-template-columns: 1fr; }
	.tv-fam__founders { gap: 26px; }
	.tv-fam .tv-tree__card { min-width: 118px; }
}
.tv-fam__founder.is-twin .tv-tree__card { border-top: 2px solid var(--tv-accent-2); }
.tv-legend__swatch--twin { border: 0; border-top: 2px solid var(--tv-accent-2); background: transparent; }

/* ==========================================================================
   Rules of the world.
   Each rule carries the books it was drawn from; those citations are the proof
   the rule is real, so they stay on the page but sit back out of the way.
   ========================================================================== */

.tv-rules { list-style: none; margin: 28px 0 0; padding: 0; max-width: 72ch; }
.tv-rules > li {
	position: relative;
	padding: 16px 0 16px 0;
	border-bottom: 1px solid var(--tv-hairline);
	font-size: 17px;
	line-height: 1.6;
	color: var(--tv-text-2);
}
.tv-rules > li:last-child { border-bottom: 0; }
.tv-rules > li > strong:first-child {
	color: var(--tv-accent);
	font-weight: 700;
	margin-right: 6px;
}
.tv-rules strong { color: var(--tv-text); font-weight: 600; }

/* The source books, set quiet and pushed onto their own line. */
.tv-cite {
	display: inline-block;
	margin-top: 6px;
	font-size: 13px;
	line-height: 1.45;
	color: var(--tv-muted);
}
.tv-cite + .tv-cite { margin-left: 0; }
.tv-cite::before { content: '· '; }
.tv-cite:first-of-type::before { content: ''; }

/* The two leads read first and larger; the supporting cast sits under them. */
.tv-cast__label { margin: 0 0 12px; }
.tv-cast__leads { margin-bottom: 34px; }
.tv-cast__leads .tv-card__art { aspect-ratio: 3 / 4; }
.tv-cast .tv-cast__label + .tv-grid-4 { margin-top: 0; }
.tv-cast > .tv-cast__label:not(:first-child) {
	margin-top: 6px; padding-top: 22px;
	border-top: 1px solid var(--tv-hairline);
}
@media (min-width: 900px) {
	/* Two cards, not four across — the couple should not look like extras. */
	.tv-cast__leads { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 560px; }
}

/* Story-bible blocks placed inside the Divi builder.
   A Divi row is capped at 1080px; these sections are full-bleed by design, so
   they step outside the row and span the viewport instead. */
.tv-breakout {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* Votes in the last 30 days, beside the running total. */
.tv-trend {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 7px;
	border-radius: 999px;
	background: color-mix(in oklab, var(--tv-accent) 22%, transparent);
	color: var(--tv-accent);
	font-size: 12px;
	font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Divi's header search
   Divi builds this form for a light header: it hardcodes the field and the
   close icon to rgba(0,0,0,.6) and the face to Open Sans. Against this header
   that is black on near-black, in the one typeface the site does not use — so
   the field looked broken when opened, and anything typed was invisible.
   --------------------------------------------------------------------------- */
.et-search-form input.et-search-field,
#et_top_search .et-search-form input,
.et_search_form_container input {
	color: var(--tv-text) !important;
	font-family: var(--tv-body) !important;
	font-size: 17px;
	font-weight: 400;
	border-bottom: 1px solid var(--tv-border) !important;
	padding-bottom: 6px;
}

.et-search-form input.et-search-field::placeholder {
	color: var(--tv-muted);
	opacity: 1;
}

.et-search-form input.et-search-field:focus {
	border-bottom-color: var(--tv-accent) !important;
	outline: none;
}

/* The close "x" is drawn as a :after glyph and inherits the same black. */
.et_close_search_field:after {
	color: var(--tv-text) !important;
}

/* ---------------------------------------------------------------------------
   Site search bar
   Sits on the page, under the title and above the list it searches. It was
   tried twice as site furniture first — as a band beneath the header, which cut
   the breadcrumb off from the page title, and inside the header bar, which
   crowded the menu and needed brittle overrides against Divi's floated,
   absolutely positioned header. Neither is worth it: on a reference site the
   place people reach for search is the page they are already browsing.
   --------------------------------------------------------------------------- */
.tv-searchbar {
	margin: 0 0 26px;
}

.tv-searchbar__form {
	display: flex;
	align-items: center;
	gap: 10px;
	max-width: 460px;
	/* Room for the button to sit inside the capsule on the right. */
	padding: 5px 5px 5px 20px;
	background: var(--tv-panel);
	border: 1px solid var(--tv-border);
	border-radius: 999px;
	transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}

.tv-searchbar__form:hover {
	border-color: color-mix(in oklab, var(--tv-accent) 40%, var(--tv-border));
}

.tv-searchbar__form:focus-within {
	background: var(--tv-panel-raised);
	border-color: var(--tv-accent);
	box-shadow: 0 0 0 3px color-mix(in oklab, var(--tv-accent) 16%, transparent);
}

.tv-searchbar input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	margin: 0;
	padding: 7px 0;
	border: 0;
	background: none;
	color: var(--tv-text);
	font-family: var(--tv-body);
	/* 16px minimum: iOS Safari zooms the page on focus for anything smaller. */
	font-size: 16px;
	line-height: 1.3;
	-webkit-appearance: none;
	appearance: none;
}

.tv-searchbar input[type="search"]::placeholder {
	color: var(--tv-muted);
	opacity: 1;
}

.tv-searchbar input[type="search"]:focus {
	outline: none;
}

/* Safari draws its own clear affordance that fights the capsule. */
.tv-searchbar input[type="search"]::-webkit-search-decoration,
.tv-searchbar input[type="search"]::-webkit-search-cancel-button {
	-webkit-appearance: none;
}

.tv-searchbar__go {
	flex: 0 0 auto;
	/* 44px is the comfortable tap target on a phone. */
	min-height: 44px;
	padding: 12px 24px;
	border: 0;
	border-radius: 999px;
	background: var(--tv-accent);
	color: var(--tv-bg);
	font-family: var(--tv-body);
	font-size: 15px;
	font-weight: 700;
	line-height: 1;
	cursor: pointer;
	transition: filter .15s ease;
}

.tv-searchbar__go:hover {
	filter: brightness(1.08);
}

@media (max-width: 600px) {
	.tv-searchbar {
		margin-bottom: 22px;
	}

	.tv-searchbar__form {
		max-width: none;
		padding-left: 18px;
	}
}

/* On the narrowest phones still in use (320px) the full label squeezes the
   field to 150px and clips the placeholder. The field is the scarce thing —
   shorten the label instead, not the space someone has to type in. */
@media (max-width: 400px) {
	.tv-searchbar__form {
		gap: 6px;
		padding-left: 16px;
	}

	.tv-searchbar__go {
		padding: 12px 18px;
		font-size: 0;
	}

	.tv-searchbar__go::after {
		content: "Go";
		font-size: 15px;
	}
}

/* ---------------------------------------------------------------------------
   Script accent
   One word, set large, alongside the sans heading — the pattern the reference
   uses. Applied deliberately, not as a default for headings.
   --------------------------------------------------------------------------- */
.tv-script {
	font-family: var(--tv-script);
	font-weight: 400;
	/* The script sits high on its body and carries long descenders, so it needs
	   room and a nudge to sit level with sans type beside it. */
	line-height: 0.9;
	letter-spacing: 0.01em;
	color: var(--tv-script-ink);
}

/* The Instagram feed gets its own warm band, so the run of white between the
   worlds and the footer is broken. */
.tv-igfeed {
	background: var(--tv-panel);
	padding: 40px var(--tv-gutter) 46px;
	margin-left: calc(var(--tv-gutter) * -1);
	margin-right: calc(var(--tv-gutter) * -1);
}
/* No breakpoint override here on purpose: the base rule uses var(--tv-gutter),
   which already changes to 20px on small screens. Hardcoding 22px made the band
   4px wider than the viewport and gave the whole page a horizontal scrollbar. */

/* ---------------------------------------------------------------------------
   Comments on Journal entries
   Native, not Jetpack's iframe, so it inherits the site's type and palette.
   --------------------------------------------------------------------------- */
.tv-comments {
	max-width: 76ch;
	margin-top: 64px;
	padding-top: 40px;
	border-top: 1px solid var(--tv-hairline);
}

.tv-comments__heading {
	font-family: var(--tv-display);
	font-size: 26px;
	font-weight: 700;
	margin: 0 0 26px;
}

.tv-comments__heading--form {
	margin-top: 48px;
}

.tv-comments__list,
.tv-comments__list .children {
	list-style: none;
	margin: 0;
	padding: 0;
}

.tv-comment {
	margin: 0 0 30px;
}

/* Replies step in behind a hairline, so a thread reads as a thread without
   needing avatars or connector graphics. */
.tv-comments__list .children {
	margin: 24px 0 0 0;
	padding-left: 22px;
	border-left: 2px solid var(--tv-hairline);
}

.tv-comment__head {
	display: flex;
	align-items: baseline;
	gap: 12px;
	margin-bottom: 8px;
}

.tv-comment__author {
	font-family: var(--tv-display);
	font-weight: 700;
	font-size: 17px;
	color: var(--tv-text);
}

.tv-comment__date {
	font-family: var(--tv-label);
	font-size: 13.5px;
	color: var(--tv-muted);
}

.tv-comment__text {
	font-size: 16.5px;
	line-height: 1.7;
	color: var(--tv-text-2);
}

.tv-comment__text p { margin: 0 0 0.9em; }
.tv-comment__text p:last-child { margin-bottom: 0; }

.tv-comment__pending {
	margin: 0 0 10px;
	font-family: var(--tv-label);
	font-size: 14px;
	color: var(--tv-accent);
}

.tv-comment__reply {
	display: inline-block;
	margin-top: 10px;
}

/* Divi draws .comment-reply-link as a bordered button. A reply is a quiet
   action on a small thread, not a call to action — make it read as a link. */
.tv-comment__reply a,
.tv-comments .comment-reply-link {
	display: inline;
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--tv-label);
	font-size: 14px;
	font-weight: 700;
	color: var(--tv-accent);
	line-height: inherit;
}

.tv-comment__reply a:hover,
.tv-comments .comment-reply-link:hover {
	background: none;
	text-decoration: underline;
}

.tv-comments__closed {
	font-family: var(--tv-label);
	font-size: 14.5px;
	color: var(--tv-muted);
}

/* -------------------------------------------------------------- the form
   The form is deliberately not called #commentform — see comments.php. That
   name is what Divi's comment script and its ID-level CSS look for, and both
   damage the form. With a different id these plain class rules are enough. */

.tv-cform .tv-cform__row {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin: 0 0 18px;
}

.tv-cform .tv-cform__row label {
	display: block;
	font-family: var(--tv-label);
	font-size: 14px;
	font-weight: 400;
	color: var(--tv-muted);
	text-transform: none;
	letter-spacing: 0;
}

.tv-cform .tv-cform__row input,
.tv-cform .tv-cform__row textarea {
	width: 100%;
	background: var(--tv-bg);
	border: 1px solid var(--tv-border);
	color: var(--tv-text);
	font-family: var(--tv-body);
	/* 16px stops iOS zooming the page when the field is focused. */
	font-size: 16px;
	line-height: 1.6;
	padding: 13px 18px;
	border-radius: 14px;
	box-shadow: none;
}

.tv-cform .tv-cform__row textarea {
	resize: vertical;
	min-height: 150px;
}

.tv-cform .tv-cform__row input:focus-visible,
.tv-cform .tv-cform__row textarea:focus-visible {
	outline: 2px solid var(--tv-accent);
	outline-offset: -2px;
}

/* Name and email share a line on anything wider than a phone. */
.tv-cform {
	display: flex;
	flex-wrap: wrap;
	gap: 0 20px;
}

.tv-cform > * { flex: 1 0 100%; }

@media (min-width: 620px) {
	.tv-cform .tv-cform__row--half { flex: 1 1 calc(50% - 10px); }
}

.tv-cform__note {
	margin: 0 0 18px;
	font-family: var(--tv-label);
	font-size: 13.5px;
	color: var(--tv-muted);
}

.tv-cform .comment-form-cookies-consent {
	display: flex;
	align-items: center;
	gap: 9px;
	margin: 0 0 20px;
	font-family: var(--tv-label);
	font-size: 13.5px;
	color: var(--tv-muted);
}

.tv-cform .comment-form-cookies-consent input { width: auto; }

.tv-cform .form-submit { margin: 0; text-align: left; }
.tv-cform .form-submit input[type="submit"] { cursor: pointer; float: none; }

.tv-cform #cancel-comment-reply-link {
	font-family: var(--tv-label);
	font-size: 14px;
	margin-left: 10px;
}

/* The reader group, offered at the end of the ARC and street team sidebars. */
.tv-team__group {
	margin-top: 22px;
	padding-top: 20px;
	border-top: 1px solid var(--tv-hairline);
}
