/*
Theme Name: Strand THP
Theme URI: https://www.trendyhairpicks.com/
Author: Trendy Hair Picks
Description: Editorial "Strand" theme for Trendy Hair Picks - a magazine about haircuts and hairstyles. Warm-paper canvas, Playfair Display headlines, Libre Franklin UI, zero radius, no shadows, one antique-gold accent. Classic PHP theme built from the Strand design system.
Version: 2.0.0
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: strand-thp
Tags: blog, editorial, magazine, one-column, custom-menu, featured-images, translation-ready
*/

/* ==========================================================================
   1. Design tokens  (Strand - see DESIGN.md; these values are final)
   ========================================================================== */

:root {
	/* Colors - every one has exactly one job. Never #000 / #FFF. */
	--thp-ink: #1a1917;         /* headlines, primary button fill, logo */
	--thp-espresso: #3a3733;    /* body copy on light surfaces */
	--thp-taupe: #8a847a;       /* metadata, bylines, captions, placeholders */
	--thp-brass: #8a6a3b;       /* THE accent - links, slashes, kickers */
	--thp-champagne: #f0e8da;   /* brass tint - pull quotes, active tags */
	--thp-hairline: #e4e0d8;    /* all borders and rules on light */
	--thp-alabaster: #f4f1eb;   /* raised surface, alternating bands */
	--thp-paper: #fcfbf8;       /* page canvas */
	--thp-bone: #edeae2;        /* text and rules on dark sections */
	--thp-carbon: #1c1b19;      /* dark editorial sections, footer */

	/* Dark-section rule: the one value DESIGN.md gives for the footer. */
	--thp-hairline-dark: #33312d;

	/* Fonts */
	--thp-font-display: "Playfair Display", Georgia, "Times New Roman", serif;
	--thp-font-ui: "Libre Franklin", "Helvetica Neue", Arial, sans-serif;

	/* Type scale */
	--thp-text-overline: 11px;
	--thp-text-micro: 12px;
	--thp-text-caption: 13px;
	--thp-text-body-sm: 15px;
	--thp-text-body: 17px;
	--thp-text-body-lg: 21px;
	--thp-text-subheading: 28px;
	--thp-text-heading-sm: 36px;
	--thp-text-heading: 52px;
	--thp-text-heading-lg: 72px;
	--thp-text-display: 96px;

	/* Spacing scale - 4px base */
	--thp-4: 4px;
	--thp-8: 8px;
	--thp-12: 12px;
	--thp-16: 16px;
	--thp-24: 24px;
	--thp-32: 32px;
	--thp-48: 48px;
	--thp-64: 64px;
	--thp-96: 96px;
	--thp-128: 128px;

	/* Layout constants */
	--thp-max: 1200px;
	--thp-read: 680px;          /* article measure - wider text blocks are banned */
	--thp-read-wide: 1000px;    /* article images break out to this */
	--thp-section-gap: 96px;
	--thp-section-gap-lg: 128px;
	--thp-gutter: clamp(24px, 4vw, 48px);
	--thp-gutter-grid: 32px;
	--thp-card-pad: 24px;
	--thp-nav-h: 72px;

	/* THE container. Applied as padding-inline to every full-width block, it
	   centres content to --thp-max while letting the block's own background
	   bleed to the viewport edge (needed for Alabaster bands and Carbon
	   sections). Below 1200px + gutters it degrades to a plain gutter, so
	   content never touches the edge. Sections carry this instead of an inner
	   wrapper div because the templates have no such wrapper. */
	--thp-inset: max(var(--thp-gutter), calc((100% - var(--thp-max)) / 2));

	/* Same idea, but centring on the narrower 1000px measure (FAQ, wide media). */
	--thp-inset-wide: max(var(--thp-gutter), calc((100% - var(--thp-read-wide)) / 2));

	/* Shape - zero everywhere, avatars excepted. */
	--thp-radius: 0;
	--thp-radius-avatar: 9999px;

	/* Elevation is a tone shift plus a hairline. Never a shadow. */
	--thp-border: 1px solid var(--thp-hairline);
	--thp-focus: 0 0 0 1px var(--thp-ink);
}

/* ==========================================================================
   2. Base
   ========================================================================== */

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

body {
	margin: 0;
	background: var(--thp-paper);
	font-family: var(--thp-font-ui);
	font-weight: 400;
	font-size: var(--thp-text-body);
	line-height: 1.75;
	color: var(--thp-espresso);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

a {
	color: var(--thp-brass);
	text-decoration: none;
	transition: color 150ms ease;
}

/* Text link: no underline at rest, underline on hover. */
a:hover,
a:focus-visible {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

/* Block-level anchors wrap whole blocks (card, expert row, featured item...),
   so everything inside them inherits Brass from the rule above unless it sets
   its own colour - which turned bios and excerpts gold. Reset to body colour
   here and let the pieces that are meant to be Brass opt in. Brass is
   punctuation, not paint. */
a.thp-card,
a.thp-topic,
a.thp-expert-row,
a.thp-featured__inner,
a.thp-author-box__inner,
a.thp-byline__author {
	color: var(--thp-espresso);
}

/* The only box-shadow the system allows. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
	outline: none;
	box-shadow: var(--thp-focus);
}

img {
	max-width: 100%;
	height: auto;
	border-radius: var(--thp-radius);
	display: block;
}

hr {
	border: none;
	border-top: var(--thp-border);
	margin: var(--thp-48) 0;
}

::selection {
	background: var(--thp-champagne);
	color: var(--thp-ink);
}

.thp-screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.thp-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--thp-ink);
	color: var(--thp-paper);
	padding: var(--thp-12) var(--thp-24);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.thp-skip-link:focus {
	left: var(--thp-gutter);
	top: var(--thp-8);
}

/* Page shell. No max-width here: backgrounds (Alabaster bands, Carbon sections)
   must reach the viewport edge. Content is centred by --thp-inset instead. */
.thp-page {
	max-width: 100%;
	overflow-x: clip;
}

/* .thp-body is a TYPOGRAPHY class, not a container - templates put it on <p>
   (see page-about.php, author.php, the newsletter copy). Body copy is 17px/1.75. */
.thp-body {
	font-family: var(--thp-font-ui);
	font-weight: 400;
	font-size: var(--thp-text-body);
	line-height: 1.75;
	color: var(--thp-espresso);
}

/* THE layout rule.
   Every top-level block in <main> is inset to the container by default. This is
   structural on purpose: the templates have no wrapper div, and an opt-in list
   of class names silently misses blocks (page-blog's chips/featured/grid/
   pagination, the bare wrappers emitted by strand_thp_stats() and
   strand_thp_newsletter(), and anything a future template adds), which is what
   left content flush to the viewport edge. Opting out is explicit, below.
   NOTE: any rule that sets `padding` shorthand on one of these blocks clobbers
   this - set padding-top/padding-bottom there, never the shorthand. */
main > *,
.thp-related {
	padding-left: var(--thp-inset);
	padding-right: var(--thp-inset);
}

/* Opt-out. <article> manages its own children: the reading column, the hero and
   the author box all size themselves, and .thp-related re-applies the inset. */
main > article {
	padding-left: 0;
	padding-right: 0;
}

/* Blocks centred on a narrower measure than --thp-max. */
main > .thp-faq {
	padding-left: var(--thp-inset-wide);
	padding-right: var(--thp-inset-wide);
}

/* The reading-width blocks size themselves via width:min(), so no inset. */
main > .thp-comments,
main > .thp-page-content {
	padding-left: 0;
	padding-right: 0;
}

.thp-section {
	padding-top: var(--thp-section-gap);
	padding-bottom: var(--thp-section-gap);
}

/* Alternating band: background bleeds full width, content stays inset. */
.thp-section--alabaster {
	background: var(--thp-alabaster);
}

/* ==========================================================================
   3. Typography primitives
   ========================================================================== */

/* Playfair is never set below 24px and never used for UI. */
.thp-h1,
.thp-h2,
h1,
h2,
h3 {
	font-family: var(--thp-font-display);
	font-weight: 700;
	color: var(--thp-ink);
	margin: 0;
}

/* Bare headings need explicit sizes from the scale. Without these they fall back
   to the browser defaults (h3 = 1.17em = ~19.9px) while still inheriting
   Playfair, which breaks the 24px floor - as .thp-how h3 and
   .thp-promise__card h3 did. */
h1 {
	font-size: var(--thp-text-heading);
	line-height: 1.08;
	letter-spacing: -0.01em;
}

h2 {
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	letter-spacing: -0.01em;
}

h3 {
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
}

/* h4 is below Playfair's floor, so it drops to the UI face rather than shrinking
   the serif. */
h4 {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body);
	font-weight: 600;
	line-height: 1.5;
	color: var(--thp-ink);
	margin: 0;
}

.thp-h1 {
	font-size: var(--thp-text-heading);
	line-height: 1.08;
	letter-spacing: -0.01em;
}

.thp-h2 {
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	letter-spacing: -0.01em;
}

/* Emphasis inside a headline is italic 500 - the system's voice. */
.thp-h1 em,
.thp-h2 em,
h1 em,
h2 em {
	font-style: italic;
	font-weight: 500;
}

/* Overline: the workhorse label style. */
.thp-label,
.thp-kicker,
.thp-card__cat,
.thp-footer__heading,
.thp-author-box__label {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* The signature glyph: category labels are prefixed "/ " in Brass. */
.thp-kicker,
.thp-card__cat {
	color: var(--thp-brass);
}

.thp-kicker::before,
.thp-card__cat::before {
	content: "/ ";
}

.thp-label {
	color: var(--thp-taupe);
}

/* Section header: kicker -> 12px -> Playfair title -> 24px -> hairline rule. */
.thp-section-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--thp-24);
	flex-wrap: wrap;
	margin-bottom: var(--thp-48);
	padding-bottom: var(--thp-24);
	border-bottom: var(--thp-border);
}

.thp-section-head .thp-kicker {
	order: 1;
}

.thp-section-head .thp-btn-text {
	order: 1;
	margin-left: auto;
}

.thp-section-head .thp-h2 {
	order: 2;
	flex: 1 1 100%;
	margin-top: var(--thp-12);
}

.thp-breadcrumb,
.thp-byline,
.thp-card__byline,
.thp-topic__meta {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-caption);
	font-weight: 400;
	line-height: 1.55;
	color: var(--thp-taupe);
}

.thp-breadcrumb a,
.thp-byline a,
.thp-card__byline a {
	color: inherit;
}

.thp-breadcrumb a:hover,
.thp-byline a:hover {
	color: var(--thp-brass);
}

/* Pull quote: Playfair italic 500 at 28px, hairline rules, 560px measure. */
/* The type lives on .thp-quote itself, not on a `> p` / `> em` child. The quote
   is stored as raw text with inline emphasis ("... explained <em>why</em> ..."),
   so there is no <p> to hook and the old `.thp-quote p` rule matched nothing -
   the quote rendered as plain sans body copy. */
.thp-quote {
	max-width: 560px;
	margin: var(--thp-64) auto;
	padding: var(--thp-48) var(--thp-24);
	border-top: var(--thp-border);
	border-bottom: var(--thp-border);
	text-align: center;
	font-family: var(--thp-font-display);
	font-style: italic;
	font-weight: 500;
	font-size: var(--thp-text-subheading);
	line-height: 1.4;
	color: var(--thp-ink);
}

/* Inherit, for the case where the quote does arrive wrapped in a <p>. */
.thp-quote p {
	margin: 0;
	font: inherit;
	color: inherit;
	max-width: none;
}

/* Emphasis must INHERIT its colour. The old rule gave `> em` its own Ink, which
   painted "why" dark-on-dark inside the Carbon band - an invisible word. */
.thp-quote em,
.thp-quote strong {
	font-style: italic;
	font-weight: 500;
	color: inherit;
}

.thp-quote__attr {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe);
	margin-top: var(--thp-16);
}

/* ==========================================================================
   4. Buttons
   ========================================================================== */

.thp-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-micro);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	line-height: 1;
	padding: var(--thp-16) var(--thp-32);
	border: none;
	border-radius: var(--thp-radius);
	background: var(--thp-ink);
	color: var(--thp-paper);
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}

/* The only Brass fill in the system. */
.thp-btn:hover,
.thp-btn:focus-visible {
	background: var(--thp-brass);
	color: var(--thp-paper);
	text-decoration: none;
}

/* Secondary: transparent, 1px Ink border. Padding compensates for the border. */
.thp-btn--invert {
	background: transparent;
	color: var(--thp-ink);
	border: 1px solid var(--thp-ink);
	padding: 15px 31px;
}

.thp-btn--invert:hover,
.thp-btn--invert:focus-visible {
	background: var(--thp-ink);
	color: var(--thp-paper);
}

/* On Carbon the secondary flips to Bone. */
.thp-ink-section .thp-btn--invert,
.thp-footer .thp-btn--invert {
	color: var(--thp-bone);
	border-color: var(--thp-bone);
}

.thp-ink-section .thp-btn--invert:hover,
.thp-footer .thp-btn--invert:hover {
	background: var(--thp-bone);
	color: var(--thp-carbon);
}

.thp-btn-text {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body-sm);
	font-weight: 500;
	color: var(--thp-brass);
}

.thp-btn-text--sm {
	font-size: var(--thp-text-caption);
}

/* ==========================================================================
   5. Header  (sticky, 72px, hairline border - no shadow when stuck)
   ========================================================================== */

.thp-header {
	position: sticky;
	top: 0;
	z-index: 20;
	height: var(--thp-nav-h);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--thp-24);
	padding: 0 var(--thp-gutter);
	background: var(--thp-paper);
	border-bottom: var(--thp-border);
}

.thp-wordmark {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: 24px;
	line-height: 1;
	letter-spacing: 0;
	color: var(--thp-ink);
	white-space: nowrap;
	flex: none;
}

/* The wordmark is a link, so the base `a { color: Brass }` rule beats the Ink it
   would otherwise inherit from .thp-wordmark. The logo is Ink, always. */
.thp-wordmark a {
	color: var(--thp-ink);
}

.thp-wordmark a:hover {
	color: var(--thp-ink);
	text-decoration: none;
}

.thp-wordmark img {
	max-height: 44px;
	width: auto;
}

.thp-header__nav,
.thp-header__actions {
	display: flex;
	align-items: center;
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	flex: 1 1 0;
}

.thp-header__nav {
	gap: var(--thp-32);
}

.thp-header__actions {
	gap: var(--thp-24);
	justify-content: flex-end;
}

.thp-header__nav ul,
.thp-header__actions ul {
	display: flex;
	align-items: center;
	gap: var(--thp-32);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* :not(.thp-btn) matters: these selectors outrank .thp-btn on specificity, and
   without it the Subscribe button renders Ink-on-Ink. */
.thp-header__nav a:not(.thp-btn),
.thp-header__actions a:not(.thp-btn) {
	color: var(--thp-ink);
}

.thp-header__nav a:not(.thp-btn):hover,
.thp-header__actions a:not(.thp-btn):hover {
	color: var(--thp-brass);
	text-decoration: none;
}

/* Active nav state is Brass. */
.thp-header .current-menu-item > a,
.thp-header .current_page_item > a,
.thp-header .current-menu-ancestor > a {
	color: var(--thp-brass);
}

/* Compact Subscribe button in the nav. */
.thp-header .thp-btn {
	padding: var(--thp-12) var(--thp-24);
	flex: none;
}

.thp-header__search {
	display: inline-flex;
	align-items: center;
	color: var(--thp-ink);
	flex: none;
}

.thp-header__search svg {
	width: 20px;
	height: 20px;
}

.thp-nav-toggle {
	display: none;
	background: none;
	border: none;
	padding: var(--thp-8);
	cursor: pointer;
	color: var(--thp-ink);
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.thp-nav-toggle svg {
	width: 24px;
	height: 24px;
}

/* State comes from assets/js/theme.js: it flips aria-expanded on the toggle and
   adds .is-open to the panel. */
.thp-nav-toggle__close {
	display: none;
}

.thp-nav-toggle[aria-expanded="true"] .thp-nav-toggle__open {
	display: none;
}

.thp-nav-toggle[aria-expanded="true"] .thp-nav-toggle__close {
	display: block;
}

.thp-mobile-nav {
	display: none;
	position: fixed;
	top: var(--thp-nav-h);
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 19;
	background: var(--thp-paper);
	border-top: var(--thp-border);
	padding: var(--thp-48) var(--thp-gutter);
	overflow-y: auto;
}

.thp-mobile-nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--thp-24);
}

/* :not(.thp-btn) for the same reason as the header: this outranks .thp-btn, and
   without it the Subscribe button inside the open mobile nav is Ink-on-Ink. */
.thp-mobile-nav a:not(.thp-btn) {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	color: var(--thp-ink);
}

.thp-mobile-nav .thp-btn {
	margin-top: var(--thp-32);
}

/* ==========================================================================
   6. Media / placeholders
   ========================================================================== */

.thp-media {
	position: relative;
	overflow: hidden;
	background: var(--thp-alabaster);
	aspect-ratio: 4 / 3;
	border-radius: var(--thp-radius);
}

.thp-media--3x4 {
	aspect-ratio: 3 / 4;
}

.thp-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: opacity 150ms ease;
}

/* The author photos are mixed orientations (Priya 468x572 portrait, Ryan
   574x381 landscape), so a 3:4 box has to crop. Anchor to the top: centred
   cover cuts the head off the landscape ones. */
.thp-media--3x4 img,
.thp-bio-hero__portrait img {
	object-position: center top;
}

/* Placeholder: a flat Alabaster field, hairline, label. No gradient. */
.thp-media--ph,
.thp-media--empty {
	background: var(--thp-alabaster);
	border: var(--thp-border);
	display: flex;
	align-items: center;
	justify-content: center;
}

.thp-media__label {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe);
	text-align: center;
	padding: var(--thp-16);
}

/* Avatars are the single radius exception in the whole system. */
.thp-avatar,
.thp-author-box img,
.thp-byline__author img {
	border-radius: var(--thp-radius-avatar);
	object-fit: cover;
}

/* ==========================================================================
   7. Cards & grids
   ========================================================================== */

.thp-grid {
	display: grid;
	gap: var(--thp-gutter-grid);
}

.thp-grid--3 {
	grid-template-columns: repeat(3, 1fr);
}

.thp-grid--4 {
	grid-template-columns: repeat(4, 1fr);
}

/* No container box on Paper: image and text sit open, text to the image edge. */
.thp-card {
	display: flex;
	flex-direction: column;
	background: none;
	border: none;
	padding: 0;
}

.thp-card .thp-media {
	margin-bottom: var(--thp-16);
}

.thp-card__cat {
	margin: 0 0 var(--thp-8);
}

.thp-card__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	color: var(--thp-ink);
	margin: 0 0 var(--thp-8);
}

.thp-card__title a {
	color: inherit;
}

/* Card hover: image dims slightly, title underlines. */
.thp-card:hover .thp-media img {
	opacity: 0.92;
}

.thp-card:hover .thp-card__title a {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 4px;
}

.thp-card__byline {
	margin: 0;
}

/* Boxes appear only on Alabaster bands and inside Carbon sections. */
.thp-section--alabaster .thp-card,
.thp-ink-section .thp-card {
	background: var(--thp-paper);
	border: var(--thp-border);
	padding: var(--thp-card-pad);
}

/* Badges / tags: 0 radius, overline type, never Ink-filled. */
.thp-tags,
.thp-chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--thp-12);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* The category chip bar renders as a top-level block on the journal and archive
   templates, so it needs the container inset back - the `padding: 0` reset above
   clobbers the one from `main > *`. The margin keeps the chips off the grid
   below; the reset above zeroes it. */
main > .thp-chips {
	padding-left: var(--thp-inset);
	padding-right: var(--thp-inset);
	margin-bottom: var(--thp-48);
}

.thp-tag,
.thp-chip {
	display: inline-block;
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-espresso);
	background: transparent;
	border: var(--thp-border);
	border-radius: var(--thp-radius);
	padding: 6px var(--thp-12);
	transition: background-color 150ms ease, color 150ms ease;
}

.thp-tag:hover,
.thp-chip:hover,
.thp-chip[aria-current="true"],
.thp-chip--active {
	background: var(--thp-champagne);
	color: var(--thp-brass);
	border-color: transparent;
	padding: 7px 13px;
	text-decoration: none;
}

/* ==========================================================================
   8. Carbon (dark) editorial sections
   ========================================================================== */

/* Full-bleed Carbon background; content held to the container by --thp-inset. */
.thp-ink-section {
	background: var(--thp-carbon);
	color: var(--thp-bone);
	padding-top: var(--thp-section-gap-lg);
	padding-bottom: var(--thp-section-gap-lg);
}

.thp-ink-section h1,
.thp-ink-section h2,
.thp-ink-section h3,
.thp-ink-section .thp-h1,
.thp-ink-section .thp-h2,
.thp-ink-section .thp-card__title {
	color: var(--thp-bone);
}

/* Body copy on Carbon sits at 80%. */
.thp-ink-section p {
	color: var(--thp-bone);
	opacity: 0.8;
}

.thp-ink-section .thp-kicker {
	color: var(--thp-brass);
	opacity: 1;
}

.thp-ink-section .thp-label,
.thp-ink-section .thp-card__byline {
	color: var(--thp-taupe);
}

.thp-ink-section .thp-section-head {
	border-bottom-color: var(--thp-hairline-dark);
}

/* Pull quote on Carbon: Bone type, and the rules drop to the dark hairline -
   the light #E4E0D8 is far too loud against #1C1B19. */
.thp-ink-section .thp-quote {
	color: var(--thp-bone);
	border-top-color: var(--thp-hairline-dark);
	border-bottom-color: var(--thp-hairline-dark);
}

/* Beat `.thp-ink-section p { opacity: .8 }` - a pull quote is not body copy. */
.thp-ink-section .thp-quote p {
	color: inherit;
	opacity: 1;
}

/* Centering is allowed on dark bands (and for hero headlines and pull quotes).
   Everything else left-aligns inside its column. */
.thp-ink-section--center {
	text-align: center;
}

.thp-ink-section--center .thp-body > * {
	margin-left: auto;
	margin-right: auto;
}

.thp-ink-section--center p {
	max-width: var(--thp-read);
}

/* ==========================================================================
   9. Footer
   ========================================================================== */

.thp-footer {
	background: var(--thp-carbon);
	color: var(--thp-bone);
	padding: var(--thp-96) var(--thp-inset) var(--thp-48);
}

.thp-footer__cols {
	margin: 0 auto;
}

.thp-footer__cols {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	gap: var(--thp-32);
	flex-wrap: wrap;
}

.thp-footer__brand {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: 32px;
	line-height: 1.1;
	color: var(--thp-bone);
}

.thp-footer__blurb {
	font-size: var(--thp-text-body-sm);
	line-height: 1.6;
	color: var(--thp-bone);
	opacity: 0.8;
	max-width: 320px;
	margin-top: var(--thp-16);
}

.thp-footer__heading {
	color: var(--thp-taupe);
	margin-bottom: var(--thp-12);
}

.thp-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--thp-12);
}

.thp-footer__list a,
.thp-footer__contact,
.thp-footer__hours {
	font-size: var(--thp-text-caption);
	color: var(--thp-bone);
}

.thp-footer__list a:hover {
	color: var(--thp-brass);
}

.thp-footer__extra {
	margin-top: var(--thp-48);
}

.thp-footer__legal {
	margin: var(--thp-64) auto 0;
	padding-top: var(--thp-24);
	border-top: 1px solid var(--thp-hairline-dark);
	display: flex;
	justify-content: space-between;
	gap: var(--thp-24);
	flex-wrap: wrap;
	font-size: var(--thp-text-micro);
	color: var(--thp-taupe);
}

.thp-footer__legal a {
	color: var(--thp-brass);
}

/* Footer newsletter input: transparent fill, 1px Bone border. */
.thp-footer input[type="email"],
.thp-footer input[type="text"] {
	background: transparent;
	border: 1px solid var(--thp-bone);
	color: var(--thp-bone);
}

.thp-footer input::placeholder {
	color: var(--thp-taupe);
}

/* ==========================================================================
   10. Home
   ========================================================================== */

/* Spam honeypot (inc/forms.php) - "hp", not "home page". Must never be visible:
   it is decoy input, and a real user who fills it gets their submission
   rejected. Kept in the DOM and off-screen rather than display:none, which some
   bots detect. */
.thp-hp {
	position: absolute !important;
	left: -9999px;
	width: 0;
	height: 0;
	opacity: 0;
	overflow: hidden;
}

/* Hero: one display headline - max once per page. 128px gap around it.
   Horizontal padding comes from the `main > *` inset in section 2. */
.thp-hero {
	padding-top: var(--thp-section-gap-lg);
	padding-bottom: var(--thp-section-gap-lg);
}

.thp-hero__copy {
	max-width: 900px;
}

/* 3:2, and held to the 1200 container rather than bled to the viewport edge.
   DESIGN.md says heroes may bleed full width, but the real photography here is
   1200x800 (the pipeline's hero crop, see CLAUDE.md STEP 5); a full-bleed 21:9
   band crops that to a letterbox strip and promises an epic panorama the site
   does not have. Without an explicit aspect-ratio it inherits .thp-media's 4:3
   and renders a ~900px-tall slab. */
.thp-hero__media {
	aspect-ratio: 3 / 2;
	margin-top: var(--thp-64);
}

@media (max-width: 760px) {
	.thp-hero__media {
		aspect-ratio: 4 / 3;
		margin-top: var(--thp-32);
	}
}

.thp-hero__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: clamp(52px, 8vw, var(--thp-text-display));
	line-height: 0.98;
	letter-spacing: -0.02em;
	color: var(--thp-ink);
	max-width: 900px;
	margin: var(--thp-24) 0 var(--thp-32);
}

.thp-hero__lede {
	font-size: var(--thp-text-body-lg);
	line-height: 1.6;
	letter-spacing: -0.005em;
	max-width: var(--thp-read);
	margin: 0;
}

.thp-hero__ctas {
	display: flex;
	gap: var(--thp-16);
	flex-wrap: wrap;
	margin-top: var(--thp-32);
}

/* Featured row: large image + stacked text.
   The margin keeps it off the card grid that follows it on the journal and
   archive templates - neither block has padding of its own. */
.thp-featured {
	margin-bottom: var(--thp-64);
}

.thp-featured__inner {
	display: grid;
	grid-template-columns: 1.4fr 1fr;
	gap: var(--thp-64);
	align-items: center;
}

.thp-featured__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	letter-spacing: -0.01em;
	color: var(--thp-ink);
	margin: var(--thp-8) 0 var(--thp-16);
}

.thp-featured__excerpt {
	margin: 0 0 var(--thp-16);
}

.thp-featured__meta {
	font-size: var(--thp-text-caption);
	color: var(--thp-taupe);
}

/* Topics */
.thp-topics {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--thp-gutter-grid);
}

.thp-topic {
	display: flex;
	flex-direction: column;
	gap: var(--thp-8);
}

.thp-topic__name {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	color: var(--thp-ink);
}

.thp-topic:hover .thp-topic__name {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 4px;
}

/* Stats / glance / promise / how - flat panels, hairline separated. */
/* auto-fit rather than a fixed count: the strip is 3 stats now that the
   "0 Sponsored rankings" tile is gone, and this survives the next change. */
.thp-stats,
.thp-glance {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: var(--thp-32);
	border-top: var(--thp-border);
	padding-top: var(--thp-48);
}

.thp-stats__num,
.thp-glance__num {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	color: var(--thp-ink);
}

.thp-stats__cap,
.thp-glance__cap {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe);
	margin-top: var(--thp-8);
}

.thp-stats--ink {
	border-top-color: var(--thp-hairline-dark);
}

.thp-stats--ink .thp-stats__num {
	color: var(--thp-bone);
}

.thp-promise {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--thp-gutter-grid);
}

.thp-promise__card {
	background: var(--thp-paper);
	border: var(--thp-border);
	padding: var(--thp-48);
}

.thp-how {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--thp-gutter-grid);
}

/* Ink, not Brass: three 36px Brass numerals in a row is paint, not punctuation. */
.thp-how__num {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading-sm);
	color: var(--thp-ink);
	margin-bottom: var(--thp-8);
}

.thp-story__copy {
	max-width: var(--thp-read);
}

/* ==========================================================================
   11. Forms
   ========================================================================== */

input[type="text"],
input[type="email"],
input[type="search"],
input[type="url"],
input[type="tel"],
textarea,
select {
	width: 100%;
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body-sm);
	font-weight: 400;
	line-height: 1.6;
	color: var(--thp-espresso);
	background: var(--thp-paper);
	border: var(--thp-border);
	border-radius: var(--thp-radius);
	padding: 14px var(--thp-16);
	transition: border-color 150ms ease;
}

input::placeholder,
textarea::placeholder {
	color: var(--thp-taupe);
}

/* Focus turns the border Ink. No glow. */
input:focus,
textarea:focus,
select:focus {
	outline: none;
	border-color: var(--thp-ink);
	box-shadow: none;
}

.thp-form__row {
	display: flex;
	flex-direction: column;
	gap: var(--thp-8);
	margin-bottom: var(--thp-24);
}

.thp-form label {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-espresso);
}

/* Newsletter: input and button joined flush, no gap. */
.thp-newsletter__form,
.thp-searchform {
	display: flex;
	max-width: 520px;
}

.thp-newsletter__form input,
.thp-searchform input {
	flex: 1;
	border-right: none;
}

.thp-newsletter__form .thp-btn,
.thp-newsletter__form button,
.thp-searchform .thp-btn,
.thp-searchform button {
	flex: none;
	padding: var(--thp-16) var(--thp-24);
}

/* A section in its own right (it closes the home page, above the footer), so it
   carries the section rhythm - it has no .thp-section class to get it from. */
.thp-newsletter {
	text-align: center;
	padding-top: var(--thp-section-gap);
	padding-bottom: var(--thp-section-gap);
}

.thp-newsletter .thp-newsletter__form {
	margin: var(--thp-24) auto 0;
}

/* Newsletter on Carbon: Bone-filled button against the Bone-bordered input. */
.thp-ink-section .thp-newsletter__form .thp-btn,
.thp-ink-section .thp-newsletter__form button,
.thp-footer .thp-newsletter__form .thp-btn,
.thp-footer .thp-newsletter__form button {
	background: var(--thp-bone);
	color: var(--thp-carbon);
}

.thp-ink-section .thp-newsletter__form .thp-btn:hover,
.thp-ink-section .thp-newsletter__form button:hover,
.thp-footer .thp-newsletter__form .thp-btn:hover,
.thp-footer .thp-newsletter__form button:hover {
	background: var(--thp-brass);
	color: var(--thp-paper);
}

.thp-notice {
	border: var(--thp-border);
	background: var(--thp-alabaster);
	padding: var(--thp-16);
	font-size: var(--thp-text-body-sm);
	margin-bottom: var(--thp-24);
}

/* ==========================================================================
   12. Blog listing
   ========================================================================== */

.thp-archive-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--thp-64) var(--thp-gutter-grid);
}

/* padding-top/bottom, never the `padding` shorthand: it would clobber the
   container inset set by `main > *`. */
.thp-page-header {
	padding-top: var(--thp-section-gap-lg);
	padding-bottom: var(--thp-48);
	border-bottom: var(--thp-border);
	margin-bottom: var(--thp-64);
}

.thp-page-header__lede {
	font-size: var(--thp-text-body-lg);
	line-height: 1.6;
	max-width: var(--thp-read);
	margin: var(--thp-16) 0 0;
}

/* The search form on 404 / search results. Needs its own air: without it the
   form butts straight up against the lede above. */
.thp-page-header__search {
	margin-top: var(--thp-32);
}

/* margin-bottom matters: pagination is the last block on the journal, archive
   and search templates, so without it the page butts straight into the footer. */
.thp-pagination {
	display: flex;
	gap: var(--thp-8);
	justify-content: center;
	margin-top: var(--thp-96);
	margin-bottom: var(--thp-section-gap);
	padding-top: var(--thp-48);
	border-top: var(--thp-border);
}

.thp-pagination .page-numbers {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-micro);
	font-weight: 600;
	letter-spacing: 0.16em;
	color: var(--thp-espresso);
	border: var(--thp-border);
	border-radius: var(--thp-radius);
	padding: var(--thp-12) var(--thp-16);
	min-width: 44px;
	text-align: center;
}

.thp-pagination .page-numbers:hover,
.thp-pagination .page-numbers.current {
	background: var(--thp-ink);
	color: var(--thp-paper);
	border-color: var(--thp-ink);
	text-decoration: none;
}

/* Rendered as a top-level block on empty archives, so no padding shorthand. */
.thp-empty {
	padding-top: var(--thp-96);
	padding-bottom: var(--thp-96);
	text-align: center;
	color: var(--thp-taupe);
}

/* ==========================================================================
   13. Article (single)
   ========================================================================== */

/* The reading column never touches the viewport edge. */
.thp-article-header,
.thp-article-body,
.thp-author-box,
.thp-comments {
	width: min(100% - 2 * var(--thp-gutter), var(--thp-read));
	margin-left: auto;
	margin-right: auto;
}

.thp-article-header {
	padding-top: var(--thp-64);
	padding-bottom: var(--thp-48);
	text-align: left;
}

.thp-article-header__breadcrumb {
	margin-bottom: var(--thp-16);
}

.thp-article-header__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading);
	line-height: 1.08;
	letter-spacing: -0.01em;
	color: var(--thp-ink);
	margin: 0 0 var(--thp-16);
}

.thp-article-header__dek {
	font-size: var(--thp-text-body-lg);
	line-height: 1.6;
	letter-spacing: -0.005em;
	color: var(--thp-espresso);
	margin: 0 0 var(--thp-24);
}

.thp-byline {
	display: flex;
	align-items: center;
	gap: var(--thp-12);
	flex-wrap: wrap;
	padding-top: var(--thp-16);
	border-top: var(--thp-border);
}

.thp-byline__author {
	display: flex;
	align-items: center;
	gap: var(--thp-12);
}

.thp-byline__author img {
	width: 40px;
	height: 40px;
}

.thp-byline__name {
	font-weight: 500;
	color: var(--thp-espresso);
}

/* "Medically reviewed by" - renders only when the meta is really set. */
.thp-reviewed {
	display: inline-flex;
	align-items: center;
	gap: var(--thp-8);
	margin-top: var(--thp-16);
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	background: var(--thp-champagne);
	color: var(--thp-brass);
	padding: 6px var(--thp-12);
	border-radius: var(--thp-radius);
}

/* The tick is a 14px glyph. An inline <svg> with only a viewBox and no
   width/height stretches to fill its container, which turned this pill into a
   huge square check mark. */
.thp-reviewed svg {
	width: 14px;
	height: 14px;
	flex: none;
}

/* The article's featured image. 3:2 to match the pipeline's 1200x800 hero crop,
   and held to the same 1000px width that in-body images break out to, so it
   reads as a photograph rather than a full-width canvas. */
.thp-article-hero {
	aspect-ratio: 3 / 2;
	width: min(100% - 2 * var(--thp-gutter), var(--thp-read-wide));
	margin: 0 auto var(--thp-96);
}

@media (max-width: 760px) {
	.thp-article-hero {
		aspect-ratio: 4 / 3;
		margin-bottom: var(--thp-64);
	}
}

/* The reading column: 17px/1.75 in a 680px measure. */
.thp-article-body {
	font-size: var(--thp-text-body);
	line-height: 1.75;
	color: var(--thp-espresso);
}

.thp-article-body p {
	margin: 0 0 var(--thp-24);
}

.thp-article-body h2 {
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	letter-spacing: -0.01em;
	margin: var(--thp-64) 0 var(--thp-16);
}

.thp-article-body h3 {
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	margin: var(--thp-48) 0 var(--thp-12);
}

/* Playfair must never render below 24px, so h4 drops to the UI face. */
.thp-article-body h4 {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body);
	font-weight: 600;
	line-height: 1.5;
	margin: var(--thp-32) 0 var(--thp-8);
}

.thp-article-body ul,
.thp-article-body ol {
	margin: 0 0 var(--thp-24);
	padding-left: var(--thp-24);
}

.thp-article-body li {
	margin-bottom: var(--thp-8);
}

.thp-article-body strong {
	font-weight: 600;
	color: var(--thp-ink);
}

/* Inline article links keep a permanent Brass underline. */
.thp-article-body a {
	color: var(--thp-espresso);
	text-decoration: underline;
	text-decoration-color: var(--thp-brass);
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

.thp-article-body a:hover {
	color: var(--thp-brass);
}

/* Article images break OUT of the 680px measure to 1000px, so they need to
   escape the column rather than just cap their width inside it. */
.thp-article-body img {
	display: block;
	width: min(100vw - 2 * var(--thp-gutter), var(--thp-read-wide));
	max-width: none;
	height: auto;
	margin: var(--thp-48) 0;
	margin-left: 50%;
	transform: translateX(-50%);
	border-radius: var(--thp-radius);
}

/* Portrait gallery images stay readable on desktop. This replaces the old
   72vh cap that lived in core Additional CSS (stored per theme slug, so it
   does not follow a theme switch). Portraits stay centred on the measure
   rather than breaking out - a 3:4 crop at 1000px wide is taller than the
   viewport. */
@media (min-width: 900px) {
	.thp-article-body img[height="1000"],
	.thp-article-body img[width="800"] {
		max-height: 72vh;
		width: auto;
		max-width: 100%;
		margin-left: auto;
		margin-right: auto;
		transform: none;
	}
}

.thp-article-body figcaption {
	font-size: var(--thp-text-caption);
	color: var(--thp-taupe);
	margin-top: var(--thp-8);
	text-align: left;
}

.thp-article-body blockquote {
	margin: var(--thp-48) 0;
	padding: var(--thp-48) var(--thp-24);
	background: var(--thp-champagne);
	border: none;
	text-align: center;
}

.thp-article-body blockquote p {
	font-family: var(--thp-font-display);
	font-style: italic;
	font-weight: 500;
	font-size: var(--thp-text-subheading);
	line-height: 1.4;
	color: var(--thp-ink);
	max-width: 560px;
	margin: 0 auto;
}

/* The disclaimer <em> that closes every pipeline article. */
.thp-article-body > p:last-child > em:only-child {
	display: block;
	font-size: var(--thp-text-caption);
	line-height: 1.55;
	color: var(--thp-taupe);
	padding-top: var(--thp-24);
	border-top: var(--thp-border);
}

/* --- Data layer / tables --------------------------------------------------
   The ~250 already-published pipeline articles hard-code cool-grey table
   styling inline (#ddd borders, #f2f2f2 header fills). Inline styles can
   only be beaten with !important, so the data layer is re-warmed to the
   Strand palette here rather than by rewriting live post content.
   New articles emit these colors natively - see CLAUDE.md STEP 5.
   -------------------------------------------------------------------------- */

/* Wide data tables break out to 1000px like images, and scroll below that.
   The wrapper is added by strand_thp_wrap_tables() in inc/legacy-content.php. */
.thp-table-scroll {
	overflow-x: auto;
	width: min(100vw - 2 * var(--thp-gutter), var(--thp-read-wide));
	margin: var(--thp-48) 0;
	margin-left: 50%;
	transform: translateX(-50%);
}

.thp-article-body table {
	width: 100% !important;
	border-collapse: collapse !important;
	border-radius: var(--thp-radius);
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body-sm);
	line-height: 1.6;
	margin: var(--thp-48) 0;
}

.thp-article-body table th,
.thp-article-body table td {
	border: 1px solid var(--thp-hairline) !important;
	padding: var(--thp-12) !important;
	text-align: left;
	vertical-align: top;
	color: var(--thp-espresso);
	background-color: transparent;
}

/* Header rows: the pipeline marks them as <th>, as a #f2f2f2 <tr>, or as
   bold <td>. All three resolve to the same Alabaster overline treatment. */
.thp-article-body table th,
.thp-article-body table tr[style*="f2f2f2"] td,
.thp-article-body table tr[style*="F2F2F2"] td,
.thp-article-body table td[style*="font-weight:bold"] {
	background-color: var(--thp-alabaster) !important;
	font-size: var(--thp-text-overline);
	font-weight: 600 !important;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--thp-ink) !important;
}

.thp-tags {
	margin-top: var(--thp-48);
	padding-top: var(--thp-24);
	border-top: var(--thp-border);
}

/* Author box */
.thp-author-box {
	max-width: var(--thp-read);
	margin: var(--thp-96) auto 0;
	padding-top: var(--thp-48);
	border-top: var(--thp-border);
}

.thp-author-box__inner {
	display: flex;
	gap: var(--thp-24);
	align-items: flex-start;
}

.thp-author-box img {
	width: 88px;
	height: 88px;
	flex: none;
}

.thp-author-box__label {
	color: var(--thp-taupe);
	margin-bottom: var(--thp-8);
}

.thp-author-box__name {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	color: var(--thp-ink);
	margin: 0 0 var(--thp-8);
}

.thp-author-box__bio {
	font-size: var(--thp-text-body-sm);
	line-height: 1.6;
	margin: 0;
}

.thp-related {
	padding-top: var(--thp-96);
	padding-bottom: var(--thp-96);
}

/* .thp-related normally closes the article and supplies the air above the
   footer. When a post has no related posts it does not render at all, leaving
   the author box flush against the footer. */
main > article > .thp-author-box:last-child {
	margin-bottom: var(--thp-section-gap);
}

/* comments.php puts .thp-section on this same element; its inset padding would
   sit INSIDE the 680 measure, so zero it - the width rule already centres.
   The bottom margin matters because comments are the last block before the
   footer whenever a post has them. */
.thp-comments {
	margin: var(--thp-96) auto var(--thp-section-gap);
	padding: var(--thp-48) 0 0;
	border-top: var(--thp-border);
}

.thp-comment-list {
	list-style: none;
	margin: 0 0 var(--thp-48);
	padding: 0;
}

.thp-comment-list li {
	padding: var(--thp-24) 0;
	border-bottom: var(--thp-border);
}

/* ==========================================================================
   14. Experts index
   ========================================================================== */

.thp-expert-rows {
	display: flex;
	flex-direction: column;
}

.thp-expert-row {
	display: grid;
	grid-template-columns: 200px 1fr;
	gap: var(--thp-48);
	align-items: start;
	padding: var(--thp-48) 0;
	border-bottom: var(--thp-border);
}

.thp-expert-row:first-child {
	border-top: var(--thp-border);
}

.thp-expert-row__name,
.thp-author-card__name {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	color: var(--thp-ink);
	margin: 0 0 var(--thp-4);
}

/* Roles are metadata, so Taupe - not Brass. Brass's spec'd jobs are text links,
   category slash-labels, active nav and filled badges; a 4-up author grid of
   Brass roles also breaks "never two Brass elements within 200px". */
.thp-expert-row__role,
.thp-author-card__role {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe);
	margin: 0 0 var(--thp-16);
}

.thp-expert-row__bio {
	font-size: var(--thp-text-body-sm);
	line-height: 1.6;
	margin: 0;
	max-width: var(--thp-read);
}

/* ==========================================================================
   15. Author / expert bio page
   ========================================================================== */

.thp-bio-hero {
	display: grid;
	grid-template-columns: 320px 1fr;
	gap: var(--thp-64);
	align-items: start;
	padding-top: var(--thp-section-gap-lg);
	padding-bottom: var(--thp-96);
}

.thp-bio-hero__portrait {
	aspect-ratio: 3 / 4;
	background: var(--thp-alabaster);
	border: var(--thp-border);
	overflow: hidden;
}

.thp-bio-hero__portrait img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.thp-bio-hero__name {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading);
	line-height: 1.08;
	letter-spacing: -0.01em;
	color: var(--thp-ink);
	margin: var(--thp-8) 0 var(--thp-12);
}

.thp-bio-hero__role {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe); /* metadata, not an accent - see .thp-author-card__role */
}

.thp-bio-hero__copy {
	font-size: var(--thp-text-body);
	line-height: 1.75;
	max-width: var(--thp-read);
}

.thp-bio-hero__social {
	display: flex;
	gap: var(--thp-16);
	margin-top: var(--thp-24);
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.thp-credentials {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--thp-32);
	border-top: var(--thp-border);
	padding-top: var(--thp-48);
	margin-top: var(--thp-48);
}

.thp-credentials__col h3 {
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--thp-taupe);
	margin-bottom: var(--thp-12);
}

.thp-credentials__col ul {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--thp-text-body-sm);
	line-height: 1.6;
}

.thp-credentials__col li {
	padding: var(--thp-8) 0;
	border-bottom: var(--thp-border);
}

/* ==========================================================================
   16. About
   ========================================================================== */

.thp-about-hero {
	padding-top: var(--thp-section-gap-lg);
	padding-bottom: var(--thp-96);
}

.thp-about-hero__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: clamp(52px, 7vw, var(--thp-text-heading-lg));
	line-height: 1.02;
	letter-spacing: -0.02em;
	color: var(--thp-ink);
	max-width: 900px;
	margin: var(--thp-24) 0 var(--thp-32);
}

.thp-about-hero__lede {
	font-size: var(--thp-text-body-lg);
	line-height: 1.6;
	letter-spacing: -0.005em;
	max-width: var(--thp-read);
	margin: 0;
}

/* ==========================================================================
   17. Contact
   ========================================================================== */

.thp-contact {
	display: grid;
	grid-template-columns: 1fr 1.2fr;
	gap: var(--thp-64);
	align-items: start;
	padding-top: var(--thp-96);
	padding-bottom: var(--thp-96);
}

.thp-contact__title {
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-heading-sm);
	line-height: 1.15;
	letter-spacing: -0.01em;
	color: var(--thp-ink);
	margin: var(--thp-8) 0 var(--thp-16);
}

.thp-contact__lede {
	font-size: var(--thp-text-body);
	line-height: 1.75;
	margin: 0 0 var(--thp-32);
}

.thp-contact__block {
	padding: var(--thp-24) 0;
	border-top: var(--thp-border);
}

.thp-contact__email {
	font-size: var(--thp-text-body);
	color: var(--thp-brass);
}

.thp-contact__pull {
	font-family: var(--thp-font-display);
	font-style: italic;
	font-weight: 500;
	font-size: var(--thp-text-subheading);
	line-height: 1.4;
	color: var(--thp-ink);
}

.thp-contact__social {
	display: flex;
	gap: var(--thp-16);
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-overline);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* ==========================================================================
   18. FAQ accordion
   ========================================================================== */

/* Horizontal centring comes from --thp-inset-wide in section 2. */
.thp-faq__item {
	border-bottom: var(--thp-border);
}

.thp-faq__item:first-child {
	border-top: var(--thp-border);
}

.thp-faq__q {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--thp-24);
	width: 100%;
	background: none;
	border: none;
	border-radius: var(--thp-radius);
	padding: var(--thp-24) 0;
	cursor: pointer;
	text-align: left;
	font-family: var(--thp-font-display);
	font-weight: 700;
	font-size: var(--thp-text-subheading);
	line-height: 1.25;
	color: var(--thp-ink);
	transition: color 150ms ease;
}

.thp-faq__q:hover {
	color: var(--thp-brass);
}

/* Taupe at rest, Brass only when open/hovered: a stack of 8 Brass "+" glyphs
   would put accents well inside the 200px minimum. Brass marks the active one. */
.thp-faq__sign {
	flex: none;
	font-family: var(--thp-font-ui);
	font-size: var(--thp-text-body-lg);
	font-weight: 400;
	line-height: 1;
	color: var(--thp-taupe);
	transition: color 150ms ease;
}

.thp-faq__q:hover .thp-faq__sign,
.thp-faq__q[aria-expanded="true"] .thp-faq__sign {
	color: var(--thp-brass);
}

/* State comes from assets/js/theme.js: aria-expanded on the button, .is-open
   plus aria-hidden on the panel. It avoids the `hidden` attribute on purpose so
   the max-height transition below can run. */
.thp-faq__sign-minus {
	display: none;
}

.thp-faq__q[aria-expanded="true"] .thp-faq__sign-plus {
	display: none;
}

.thp-faq__q[aria-expanded="true"] .thp-faq__sign-minus {
	display: inline;
}

.thp-faq__a {
	max-width: var(--thp-read);
	max-height: 0;
	overflow: hidden;
	font-size: var(--thp-text-body);
	line-height: 1.75;
	color: var(--thp-espresso);
	transition: max-height 150ms ease;
}

.thp-faq__a.is-open {
	/* A ceiling, not a measurement: tall enough for any answer, and the only
	   value max-height can transition to. */
	max-height: 60rem;
	padding-bottom: var(--thp-32);
}

/* ==========================================================================
   19. Page / policy content
   ========================================================================== */

.thp-page-content {
	width: min(100% - 2 * var(--thp-gutter), var(--thp-read));
	margin: 0 auto;
	padding-top: var(--thp-64);
	padding-bottom: var(--thp-96);
}

.thp-page-content h2 {
	font-size: var(--thp-text-heading-sm);
	margin: var(--thp-64) 0 var(--thp-16);
}

.thp-page-content h3 {
	font-size: var(--thp-text-subheading);
	margin: var(--thp-48) 0 var(--thp-12);
}

.thp-page-content p {
	margin: 0 0 var(--thp-24);
}

.thp-page-content a {
	color: var(--thp-espresso);
	text-decoration: underline;
	text-decoration-color: var(--thp-brass);
	text-underline-offset: 3px;
}

/* ==========================================================================
   20. Search / 404
   ========================================================================== */

/* Nothing of their own: 404.php and search.php both open with
   .thp-page-header, which section 12 already styles. */

/* ==========================================================================
   21. Responsive
   ========================================================================== */

@media (max-width: 1180px) {
	.thp-featured__inner {
		gap: var(--thp-48);
	}

	.thp-bio-hero {
		grid-template-columns: 260px 1fr;
		gap: var(--thp-48);
	}
}

@media (max-width: 1024px) {
	:root {
		--thp-section-gap: 72px;
		--thp-section-gap-lg: 96px;
	}

	.thp-grid--4 {
		grid-template-columns: repeat(2, 1fr);
	}

	/* .thp-stats / .thp-glance reflow on their own via auto-fit. */
	.thp-credentials {
		grid-template-columns: 1fr;
		gap: var(--thp-32);
	}
}

@media (max-width: 900px) {
	/* The bar collapses to wordmark + Subscribe + toggle. */
	.thp-header__nav,
	.thp-header__actions ul,
	.thp-header__search {
		display: none;
	}

	.thp-header__actions {
		flex: none;
	}

	.thp-nav-toggle {
		display: inline-flex;
	}

	.thp-mobile-nav.is-open {
		display: block;
	}

	.thp-grid--3,
	.thp-archive-grid,
	.thp-topics,
	.thp-promise,
	.thp-how {
		grid-template-columns: repeat(2, 1fr);
	}

	.thp-featured__inner,
	.thp-contact,
	.thp-bio-hero {
		grid-template-columns: 1fr;
		gap: var(--thp-32);
	}

	.thp-bio-hero__portrait {
		max-width: 280px;
	}

	.thp-expert-row {
		grid-template-columns: 140px 1fr;
		gap: var(--thp-24);
	}

	/* Playfair scales down but never below its 24px floor. */
	.thp-article-header__title,
	.thp-h1,
	.thp-bio-hero__name {
		font-size: var(--thp-text-heading-sm);
	}
}

@media (max-width: 760px) {
	.thp-grid--3,
	.thp-grid--4,
	.thp-archive-grid,
	.thp-topics,
	.thp-promise,
	.thp-how {
		grid-template-columns: 1fr;
	}

	.thp-footer__cols {
		flex-direction: column;
		gap: var(--thp-48);
	}

	.thp-expert-row {
		grid-template-columns: 1fr;
	}

	.thp-article-body h2 {
		font-size: var(--thp-text-subheading);
		margin-top: var(--thp-48);
	}

	.thp-article-body h3,
	.thp-card__title,
	.thp-faq__q {
		font-size: 24px; /* Playfair's absolute floor */
	}

	.thp-newsletter__form,
	.thp-searchform {
		flex-direction: column;
	}

	.thp-newsletter__form input,
	.thp-searchform input {
		border-right: var(--thp-border);
		margin-bottom: var(--thp-8);
	}

	.thp-footer .thp-newsletter__form input {
		border-right: 1px solid var(--thp-bone);
	}
}

@media (max-width: 560px) {
	.thp-author-box__inner {
		flex-direction: column;
	}

	.thp-quote {
		padding: var(--thp-32) 0;
	}

	.thp-promise__card {
		padding: var(--thp-24);
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   22. Print
   ========================================================================== */

@media print {
	.thp-header,
	.thp-mobile-nav,
	.thp-footer,
	.thp-related,
	.thp-newsletter,
	.thp-comments,
	.thp-skip-link {
		display: none !important;
	}

	/* The warm-neutral rule is a screen rule. On paper the canvas is already
	   white and the ink is already black, so pure values are correct here. */
	body {
		background: #fff;
		color: #000;
		font-size: 12pt;
	}

	.thp-article-body {
		max-width: 100%;
	}

	.thp-article-body a {
		text-decoration: underline;
	}
}
