/* ============================================================================
   blog.css — blog index, single post, category archive and search styling.

   Enqueued as `samson-blog` only on the blog templates (see inc/enqueue.php):
   index.php (the Blog posts page), single.php, archive.php, search.php.

   Relies on tokens/utilities already defined in critical.css (:root palette,
   space scale, .wrap/.band/.band--tint/.band--dark, .btn/.btn-outline/.btn-sm,
   .pill) and the shared listing base already shipped in main.css
   (.post-grid, .post-card, .pagination, .post-navigation, .entry-content,
   .entry-meta/.entry-figure, .no-results). This file only ADDS the blog's own
   elevation on top of that base — deliberately not duplicating layout that
   already exists, since blog.css loads after main.css (samson-main is its
   registered dependency) so equal-specificity rules here win the cascade.

   Mobile-first. Breakpoints match the rest of the theme: 640 / 700 / 900 /
   1000 / 1080px.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   Blog/archive/single hero: same uniform, tight navy hero recipe as every
   other inner-page hero (pages.css .page-hero, area.css .area-hero,
   problem.css .problem-hero, service.css .svc-hero). The old rooftops
   backdrop, its cropped-strip treatment and #E4F0FA ground are retired (v2.2
   navy hero restyle); identical padding top and bottom keeps this hero the
   same height as every other page's, so there is no longer a "compact blog
   hero" special case to document here.
   ----------------------------------------------------------------------------- */
.page-hero {
	padding-block: clamp(48px, 6vw, 84px);
}

/* critical.css sets .page-hero__lead to --navy (the light-ground default);
   this hero is now always a .band--dark ground, so the lead needs the dark
   pairing instead. Same override pages.css makes for the designed
   templates' page-hero. */
.page-hero__lead {
	color: var(--on-dark);
}

/* Breadcrumbs (critical.css .breadcrumbs/.breadcrumbs a) default to --slate
   text and --blue links, both tuned for light grounds; this hero is always
   .band--dark now, so light links, white on hover. var(--brand) is
   .band--dark's own light-blue link value (critical.css remap), used here
   exactly as intended rather than reaching for a literal. */
.page-hero .breadcrumbs {
	color: var(--on-dark);
}

.page-hero .breadcrumbs a {
	color: var(--brand);
}

.page-hero .breadcrumbs a:hover {
	color: #FFFFFF;
}

/* -----------------------------------------------------------------------------
   Category filter chips (index, archive, search) — reuses .pill/.is-hq.
   ----------------------------------------------------------------------------- */
.blog-filters {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s3);
	list-style: none;
	margin: 0 0 var(--s8);
	padding: 0;
}

/* -----------------------------------------------------------------------------
   Small chip used over photography (category on cards/feature) — its own
   component, distinct from .pill: it needs a shadow to sit legibly on top of
   an image of unknown tone, where .pill assumes it is sitting on a flat band.
   ----------------------------------------------------------------------------- */
.post-chip {
	display: inline-flex;
	align-items: center;
	background: var(--white);
	color: var(--blue-deep);
	border-radius: var(--r-pill);
	padding: .35em .85em;
	font-weight: 700;
	font-size: .8125rem;
	letter-spacing: .02em;
	text-decoration: none;
	box-shadow: var(--shadow-card);
	transition: background-color .18s ease;
}
.post-chip:hover {
	background: var(--sky);
}

/* -----------------------------------------------------------------------------
   Post meta row (date · category · reading time).
   ----------------------------------------------------------------------------- */
.post-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .5em;
	color: var(--slate);
	font-size: .9rem;
	margin: 0;
}
.post-meta__cat {
	color: var(--blue-deep);
	font-weight: 700;
	text-decoration: none;
}
.post-meta__cat:hover {
	color: var(--blue);
}
.post-meta__sep {
	color: var(--line);
}
.article__meta {
	font-size: .9375rem;
	margin-bottom: var(--s7);
}

/* -----------------------------------------------------------------------------
   Featured lead post (blog index, first page only).
   ----------------------------------------------------------------------------- */
.post-feature {
	position: relative;
	display: grid;
	gap: var(--s6);
	margin-bottom: var(--s9);
	padding-bottom: var(--s9);
	border-bottom: 1px solid var(--line);
}
.post-feature__media {
	position: relative;
	border-radius: var(--r-card);
	overflow: hidden;
	background: var(--sky);
}
.post-feature__media .post-feature__img,
.post-feature__media .samson-img-placeholder {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	transition: transform .45s ease;
}
.post-feature__chip {
	position: absolute;
	top: var(--s4);
	left: var(--s4);
	z-index: 2;
}
.post-feature__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--s3);
}
.post-feature__label {
	color: var(--blue-deep);
}
.post-feature__title {
	margin: 0;
	font-size: clamp(1.75rem, 3.4vw, 2.5rem);
}
.post-feature__link {
	color: var(--navy);
	text-decoration: none;
}
.post-feature__link::after {
	/* Stretched-link: deliberately NOT position:relative on .post-feature__link
	   (or .post-feature__title) itself. An absolutely positioned ::after is a
	   child of its element, so if the link were also position:relative it
	   would become its OWN nearest positioned ancestor, shrinking this overlay
	   down to the tight inline box around the title text instead of the whole
	   card (bug fixed here: the "Read the full story" button, excerpt and
	   photo did not navigate, only the title text itself did, because that
	   was exactly what was happening). Leaving both unpositioned lets the
	   absolute box skip past them to .post-feature (position: relative
	   above), which is the real containing block, so inset: 0 fills the whole
	   card. z-index: 1 keeps it above the card's own (unpositioned) content
	   while .post-feature__chip's z-index: 2 still wins over it, so the
	   category chip stays independently clickable. */
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.post-feature:hover .post-feature__link,
.post-feature:focus-within .post-feature__link {
	color: var(--blue-deep);
}
.post-feature:hover .post-feature__img,
.post-feature:focus-within .post-feature__img {
	transform: scale(1.03);
}
.post-feature:hover .post-feature__cta,
.post-feature:focus-within .post-feature__cta {
	background: var(--blue-deep);
	border-color: var(--blue-deep);
}
.post-feature__excerpt {
	color: var(--slate);
	max-width: 60ch;
}
.post-feature__cta {
	margin-top: var(--s2);
	align-self: flex-start;
	pointer-events: none;
}

@media (min-width: 900px) {
	.post-feature {
		grid-template-columns: 7fr 5fr;
		align-items: center;
		gap: var(--s9);
	}
}

/* -----------------------------------------------------------------------------
   Post card elevation. Base grid/card box already lives in main.css
   (.post-grid, .post-card, .post-card__media img, .post-card__body,
   .post-card__title, .post-card__meta, .post-card__excerpt); this section
   only adds the stretched-link hit target, hover motion, the category chip
   and the decorative CTA button that replace the old bare "Read more" text
   link (no-underline house rule, DESIGN.md section 2).
   ----------------------------------------------------------------------------- */
.post-card {
	position: relative;
	box-shadow: var(--shadow-card);
	transition: box-shadow .2s ease, transform .2s ease;
}
.post-card:hover,
.post-card:focus-within {
	box-shadow: 0 16px 40px -16px rgba(18, 42, 76, .28);
	transform: translateY(-4px);
}
.post-card__media {
	position: relative;
	overflow: hidden;
}
.post-card__media .post-card__img,
.post-card__media .samson-img-placeholder {
	transition: transform .45s ease;
}
.post-card:hover .post-card__img,
.post-card:focus-within .post-card__img {
	transform: scale(1.06);
}
.post-card__chip {
	position: absolute;
	top: var(--s3);
	left: var(--s3);
	z-index: 2;
}
.post-card__title {
	/* Deliberately NOT position:relative. See .post-card__link::after below:
	   that would make this h2 the ::after's containing block instead of
	   .post-card, shrinking the stretched-link hit area back down to just
	   the title. */
}
.post-card__link {
	/* Deliberately NOT position:relative (see .post-card__link::after). */
}
.post-card__link::after {
	/* Stretched-link bugfix: this used to sit on .post-card__link itself
	   (position: relative + z-index: 1), which made the anchor its OWN
	   nearest positioned ancestor for this absolutely positioned pseudo
	   (::after is a child of the element it's attached to). Since the
	   anchor is inline and wraps only the title text, inset: 0 against
	   THAT containing block shrank the overlay down to the title's own
	   tight bounding box — so only the title text (which is the literal
	   <a>, and would have worked with no overlay at all) navigated, while
	   the photo, excerpt and "Read more" button did not, exactly the
	   reported defect. With .post-card__title and .post-card__link left
	   unpositioned, the ::after skips past both to find its containing
	   block at .post-card (position: relative above), so inset: 0 now
	   fills the whole card. z-index: 1 keeps it above the card's own
	   (unpositioned) content; .post-card__chip's z-index: 2 still wins over
	   it, so the category chip stays independently clickable. */
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.post-card__cta {
	margin-top: var(--s2);
	align-self: flex-start;
	pointer-events: none;
}
.post-card:hover .post-card__cta,
.post-card:focus-within .post-card__cta {
	background: var(--navy);
	color: var(--white);
	border-color: var(--navy);
}

/* [data-reveal] stagger: reveal.js only toggles .is-revealed; the delay
   itself is a plain CSS custom property set inline per card (post-card.php,
   post-feature.php), same convention as related-cards.php. */
@media (scripting: enabled) {
	.post-grid [data-reveal] {
		transition-delay: var(--rd, 0ms);
	}
}

/* -----------------------------------------------------------------------------
   Single article.
   ----------------------------------------------------------------------------- */
.article__figure {
	margin: 0 0 var(--s8);
}
.article__img {
	width: 100%;
	border-radius: var(--r-card);
	aspect-ratio: 16 / 8;
	object-fit: cover;
}

/* Editorial breakout grid for the_content() output (Classic Editor HTML).
   Round 7 defect: the previous 68ch measure read as needlessly narrow given
   the space available ("content needs to be wider and use the space
   available"). Widened to 85ch (~900px at the body font size) — still well
   inside the ~75-character line where unbroken prose starts hurting reading
   comprehension, just no longer leaving a wide unused margin either side on
   real viewports. This remains the ONE constrained-measure exception to the
   sitewide full-width rule (claude.md section 1/DESIGN.md section 6), which
   targets marketing sections and their headings/leads, not long-form running
   prose. Photography, blockquotes and tables are let out of that column, up
   to 1100px (comfortably wider than the new 85ch text column, short of the
   full .wrap content width), so they read as full illustrations rather than
   being squeezed into the text width; short inline elements (a linked word,
   a caption) never need to escape the column at all. */
.entry-content {
	display: grid;
	grid-template-columns: minmax(0, 1fr) min(85ch, 100%) minmax(0, 1fr);
	/* No column-gap: the flanking tracks are always empty (nothing is ever
	   placed in column 1 or 3), so a gap here would only ever be added
	   ONCE either side of the populated middle track without ever being
	   subtracted from a percentage-based content column that legitimately
	   claims min(85ch, 100%) — on a narrow viewport that "100%" already
	   fills the container, and the gap then pushed the total past 100%,
	   clipping the last ~2 words of every line off the right edge at
	   mobile widths (caught in the 390px verification pass). Breakout
	   media already gets its own vertical rhythm from the sibling
	   margin-top rule below; no horizontal gap was ever needed. */
}
.entry-content > * {
	grid-column: 2;
}
.entry-content > figure,
.entry-content > blockquote,
.entry-content > .wp-caption,
.entry-content > table,
.entry-content > .alignwide {
	grid-column: 1 / -1;
	width: 100%;
	max-width: min(1100px, 100%);
	justify-self: center;
}
/* Classic Editor's most common image pattern is not a <figure> at all: a
   plain inserted image with no caption comes back from wpautop() as a <p>
   containing only that <img> (verified against the live imported posts,
   e.g. "Dry Rot Treatment Liverpool & Southport": <p><img .../></p> as the
   very first line of post_content). Without this rule every such photo would
   render squeezed into the 85ch text column instead of reading as the full
   illustration it is, which is exactly the cramped-media outcome the
   breakout grid exists to avoid. :has() support is broad enough now
   (Baseline widely-available) that no fallback is needed; unsupported
   browsers simply keep the image in the text column, still fully legible. */
.entry-content > p:has(> img:only-child) {
	grid-column: 1 / -1;
	width: 100%;
	max-width: min(1100px, 100%);
	justify-self: center;
}
.entry-content > .alignfull {
	grid-column: 1 / -1;
	max-width: none;
}
.entry-content table {
	border-collapse: collapse;
	width: 100%;
}
.entry-content th,
.entry-content td {
	padding: .6em .8em;
	border: 1px solid var(--line);
	text-align: left;
}
.entry-content blockquote {
	font-family: var(--ff-display);
	font-weight: 700;
	font-size: 1.25rem;
	line-height: 1.35;
}

/* -----------------------------------------------------------------------------
   Share links.
   ----------------------------------------------------------------------------- */
.share {
	/* Full width of .wrap, matching the hero/meta/figure above it (single.php's
	   own header comment states this row uses the full available width — it
	   was still centred to the old 68ch text measure, an artefact from before
	   the breakout grid existed; corrected here rather than left inconsistent
	   with the wider round-7 entry-content measure above). */
	margin-top: var(--s9);
	padding-top: var(--s7);
	border-top: 1px solid var(--line);
}
.share__title {
	margin-bottom: var(--s4);
	font-size: 1.0625rem;
}
.share__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s3);
}
.share__link {
	display: inline-flex;
	align-items: center;
	gap: .5em;
	padding: .55em .95em;
	border: 2px solid var(--navy);
	border-radius: var(--r-btn);
	color: var(--navy);
	font-weight: 700;
	font-size: .9rem;
	text-decoration: none;
	background: transparent;
	cursor: pointer;
	font-family: var(--ff-body);
	transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.share__link .samson-icon {
	width: 1.1em;
	height: 1.1em;
}
.share__link:hover {
	background: var(--navy);
	color: var(--white);
}
.share__link.is-copied {
	background: var(--blue);
	border-color: var(--blue);
	color: var(--white);
}

/* -----------------------------------------------------------------------------
   Related posts (reuses .post-grid/.post-card from the shared listing base).
   ----------------------------------------------------------------------------- */
.related-posts__title {
	margin-bottom: var(--s7);
}

/* -----------------------------------------------------------------------------
   Search results: refine row above the grid.
   ----------------------------------------------------------------------------- */
.search-refine {
	margin-bottom: var(--s7);
}
.search-refine .search-form {
	max-width: 32rem;
}
.search-results-count {
	margin-top: var(--s4);
	color: var(--slate);
}

/* -----------------------------------------------------------------------------
   CTA band (charslate) at the foot of single posts (template-parts/blocks/
   cta-band.php). Round 7 defect: this shared block is also used by single.php,
   but its layout rules lived only in components/pages.css, which is NOT
   enqueued on blog contexts — so the band rendered with just the bare
   .band--dark ground and no grid/copy/actions layout at all ("all that space
   and buttons squashed"). Restated here verbatim from pages.css (same
   established pattern as the .page-hero restatement above) so the single-post
   CTA band is pixel-identical to the one on the designed page templates.
   Foundation supplies .band--dark ground + light text remap (critical.css);
   .lead/.btn/.btn-primary/.btn-outline are also foundation classes already
   loaded everywhere, so only the .cta-band* layout rules need copying.
   ----------------------------------------------------------------------------- */
.cta-band {
	position: relative;
	overflow: hidden;
}

/* v2 restyle: cta-dark.webp is retired from cta-band.php (DESIGN.md section
   7); .cta-band__bg has no matching <img> left, so the rule (and this
   comment about it) is removed rather than left as dead CSS — plain
   .band--dark navy gradient ground, matching pages.css's identical fix. */

.cta-band__inner {
	position: relative;
	z-index: 1;
	display: grid;
	gap: var(--s7);
}

/* Heading size, ported from pages.css's shared inner-page H2 selector list
   (DESIGN.md section 3) — restated as its own rule here since blog.css does
   not also carry every other page-template heading class that list covers. */
.cta-band__title {
	font-family: var(--ff-display, "Plus Jakarta Sans", system-ui, sans-serif);
	font-weight: 800;
	font-size: clamp(1.875rem, 3.6vw, 3.25rem);
	line-height: 1.08;
	letter-spacing: -0.005em;
}

/* var(--on-dark) is safe here: a :root-level token, not one of the old alias
   names .band--dark remaps, so it always means "secondary text on dark". */
.cta-band__body {
	margin-top: var(--s4);
	color: var(--on-dark);
	max-width: 46ch;
}

.cta-band__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--s4);
	margin-top: var(--s6);
}

.cta-band__actions svg {
	width: 1.15em;
	height: 1.15em;
	flex: none;
}

/* Note: cta-band.php's outline buttons render .btn-outline (critical.css),
   not .btn--outline; the dark-ground on-white-outline treatment already lives
   in critical.css's ".band--dark .btn-outline" rule, so no duplicate is
   needed here (matches pages.css's identical cleanup). */

.cta-band__phone {
	color: var(--white);
	font-family: var(--ff-display, "Plus Jakarta Sans", system-ui, sans-serif);
	font-weight: 700;
	font-size: 1.35rem;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
}

.cta-band__phone:hover {
	color: var(--amber);
}

.cta-band__form .survey-card {
	max-width: 480px;
}

@media (min-width: 700px) {
	.cta-band--form .cta-band__inner {
		grid-template-columns: 1fr 1fr;
		align-items: center;
	}
}

@media (min-width: 1080px) {
	.cta-band--form .cta-band__inner {
		grid-template-columns: 6fr 5fr;
		gap: var(--s10);
	}
}

/* -----------------------------------------------------------------------------
   Reduced motion: settle every enhancement to its finished state.
   ----------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.post-card,
	.post-card__img,
	.post-feature__img,
	.post-chip,
	.share__link {
		transition: none;
	}
}
