/**
 * css/components/template-blog.css — Website 2.0 Blog reskin (#67)
 *
 * Covers index.php/archive.php (cream band + card grid + category
 * filter), single.php (hero meta + title + sidebar), blocks/not_found.php,
 * and blocks/content.php's `.article-item` post card (`.cg-article-card`)
 * — the shared partial also reused, unchanged markup-wise, by
 * future_content/articles.php, universal/related_articles.php,
 * work_content/related_articles.php + latest_posts.php and
 * work_type_content/related_articles.php (docblock in blocks/content.php).
 * Restyling that card here is IN SCOPE and expected: css/components/
 * template-work.css's own docblock flagged it as "left legacy-styled —
 * shared with the not-yet-reskinned blog templates (#67)".
 *
 * `.article-item` / `.js-item` / `.js-load-more` / `.js-ajax-items-holder`
 * are NEVER touched by selector here — every new class is ADDITIVE
 * (docs/2.0-system-guide.md §5.2).
 *
 * Tokens only — no raw hex, no @layer, no !important.
 */

/* ------------------------------------------------------------------ *
 * Shared hero title (index.php / archive.php / single.php)
 *
 * Own dedicated class rather than the `cg_statement()` helper /
 * `.cg-statement` class: that helper only ever emits h2/h3 (docs/2.0-
 * system-guide.md §4 — section-statement contract), never h1. Values
 * mirror `.cg-statement` (css/components/type.css) for visual
 * consistency with the rest of the system's serif display type.
 * ------------------------------------------------------------------ */

/* #303: Tungsten Narrow Bold replaces Noe Text at 400. Smaller absolute
   letter-spacing than the marketing-hero titles since this sits at a
   smaller type size (proportionally the same easing toward 0 as the other
   four overrides). */
.cg-blog-title {
	margin: 0;
	font-family: var( --h1-font-family );
	font-weight: 700;
	font-size: clamp( 36px, 3.4vw, 62px );
	line-height: 1.08;
	letter-spacing: -0.3px;
	/* #403-era punch list, NEWS-1: the CD asked for the news headline in
	   #E3581D. Token, not the literal hex. This type role is shared by the
	   blog index, the archive and the search results head (index.php /
	   archive.php / search.php all emit `.cg-blog-title
	   .cg-blog-head__title`), so all three go rust together — they are one
	   heading role and splitting them would be the inconsistency. The
	   single-post title is a DIFFERENT class (`.cg-blog-post__title`,
	   below) and stays ink. */
	color: var( --accent );
	text-wrap: balance;
}

/* ------------------------------------------------------------------ *
 * Blog index / archive head (index.php, archive.php)
 * ------------------------------------------------------------------ */

.cg-blog-band {
	overflow: hidden;
}

.cg-blog-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 24px 40px;
	margin-bottom: 64px;
}

.cg-blog-head__intro {
	max-width: 640px;
}

/* Filter-action's own bottom alignment needs to sit on the title's own
   baseline, not the rule-mark's — override the flex item's default
   stretch so the select doesn't grow to the (taller) intro column. */
.cg-blog-head .filter-action {
	flex: none;
}

@media ( max-width: 680px ) {
	.cg-blog-head {
		align-items: flex-start;
		margin-bottom: 44px;
	}

	.cg-blog-head .filter-action {
		width: 100%;
	}
}

/* ------------------------------------------------------------------ *
 * Category filter (blocks/category_select.php) — the native <select> is
 * replaced client-side by jcf (js/jquery.main.js `initCustomForms` ->
 * `jcf.replaceAll()`) into `.jcf-select`/`.jcf-select-text`/`.jcf-select-
 * opener` — restyled here rather than in the PHP partial (the inline
 * onchange + page_for_posts logic, CLAUDE.md anti-hardcoding-safe, is
 * left completely untouched). Scoped to `.filter-action` (its only
 * caller, blocks/category_select.php) so Gravity Forms' many other
 * jcf-replaced <select>s sitewide are never touched.
 * ------------------------------------------------------------------ */

.filter-action .jcf-select {
	border-bottom: var( --hairline ) solid var( --rule );
	background: transparent;
	color: var( --text );
}

.filter-action .jcf-select .jcf-select-text {
	font-family: var( --font-sans );
	font-weight: 700;
	font-size: 11px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.filter-action .jcf-select.jcf-drop-active,
.filter-action .jcf-select:focus-within {
	border-bottom-color: var( --accent );
}

/* ------------------------------------------------------------------ *
 * Blog card grid — 3-up desktop, 2-up tablet, 1-up mobile. The legacy
 * flex/percentage-width mechanics (`.articles-cols`/`.list-w-33`/
 * `.list-w-sm-100`, style.css) are left in place (shared utility classes
 * used well beyond the blog, e.g. download_content/achievements/awards
 * groups) — only a NEW tablet step is added, scoped to the exact
 * `.articles-cols.list-w-33` combination that this card grid alone uses
 * (index.php/archive.php/search.php/single.php/future_content/
 * universal-related-articles), so nothing else with `.list-w-33` is
 * affected.
 *
 * The tablet override is 3 classes deep (`.articles-cols.list-w-33 >
 * .article-item`, specificity 0,3,0) so it reliably beats the legacy
 * `.list-w-33 > *` (0,1,0) regardless of source order — but that same
 * higher specificity would ALSO beat `.list-w-sm-100 > *{width:100%}`
 * (style.css, the ≤767px 1-up mobile stacking rule, itself only 0,1,0)
 * if the media ranges overlapped. The explicit `min-width: 768px` here
 * keeps this rule OUT of that range entirely, so mobile 1-up is
 * untouched (caught in manual mobile verification — a 50%-width card
 * inside the ≤767px `.articles-cols{flex-direction:column}` stack
 * rendered a ~90px-wide card, wrapping its title one character per line).
 * ------------------------------------------------------------------ */

@media ( min-width: 768px ) and ( max-width: 1024px ) {
	.articles-cols.list-w-33 > .article-item {
		width: calc( 50% * 1 );
	}
}

/* ------------------------------------------------------------------ *
 * `.article-item` post card -> `.cg-article-card` (blocks/content.php)
 *
 * Bordered cg card-box treatment (hairline border, hover fill, uniform
 * image crop) + arrow-link, matching the shared card-box/arrow-link
 * language (cardbox.css/button.css) without literally reusing their
 * `.cg-cardbox`/`.cg-card` DOM (that component's grid is a bare div
 * grid with no image slot; this card needs one, and its existing
 * `.articles-cols` parent grid mechanics are kept, see above) — same
 * "extrapolate the system, new component for a new shape" approach as
 * `.cg-work-tile` (template-work.css).
 *
 * Child-element overrides are qualified `.article-item.cg-article-card`
 * (3 classes total on the combinator) so they beat the legacy bare
 * `.article-item .box-img`/`.meta`/`.box-text > span` rules (style.css,
 * 2 classes/1 class+tag) by specificity alone, regardless of the fact
 * that style.css loads AFTER this file in the cascade (docs/2.0-system-
 * guide.md §2's companion-CSS technique, applied to descendant overrides
 * rather than a heading retag).
 * ------------------------------------------------------------------ */

/* `height: 100%` was here until the #403-era punch list (NEWS-2, "make
   every article block a consistent height"). It was the CAUSE of the
   uneven heights, not a fix for them: a flex item only stretches to its
   line when its cross size is `auto`, and a specified `height` — even
   `100%`, which resolves against the auto-height `.articles-cols` and so
   behaves as auto anyway — opts the item OUT of `align-self: stretch`.
   Removing it lets the row stretch normally.

   Measured at 1440 on /blog/, rows as they render:
     before  585/555/614 · 585/585/555 · 588/614/496
     after   640/640/640 · 611/611/611 · 640/640/640
   (The "after" figures include this file's `padding-top: var(--indent)`
   rule, which adds ~26px at this width — an earlier revision of this
   comment quoted the height-only intermediate state and was wrong by
   exactly that amount.)

   Heights are equal WITHIN each row at every breakpoint. They are NOT
   equal across the whole page — #406's NEWS-2 asks for that, and it is
   deliberately not delivered: page-wide equality needs the row grid
   converted to `grid-auto-rows: 1fr`, which changes card proportions
   across the blog, archive, search and related-articles listings. The
   owner scoped this issue to the padding fix instead. */
.cg-article-card {
	display: flex;
	flex-direction: column;
	border: var( --hairline ) solid var( --rule );
	text-decoration: none;
	transition:
		background-color var( --fade-out ) var( --fade-ease ),
		border-color var( --fade-out ) var( --fade-ease );
}

/* NEWS-3: one grey rule at rest on every card, rust on rollover. The
   `--featured` border-color override that used to sit below is gone —
   Featured cards are distinguished by their `.cg-article-card__badge`
   label, not by a second border colour. */
.cg-article-card:hover {
	background-color: var( --box-hover-cream );
	border-color: var( --accent );
}

.cg-article-card__img {
	overflow: hidden;
	aspect-ratio: 366 / 264;
	background: var( --cg-grey );
}

/* NEWS-2: the image ran flush to the card's top edge while the sides were
   inset, so the crop read as bleeding out of the frame. Match the top to
   the horizontal inset.

   `var( --indent )` — NOT a literal 26px — because that inset is not the
   card's own padding: `.articles-cols` (style.css) sets `--indent: 26px`
   with `margin-inline: calc(var(--indent) * -1)` and gives each
   `.article-item` `padding: 0 var(--indent) 20px`. It is the grid gutter,
   and the card's border happens to be drawn on the same element, so the
   gutter lands inside the frame. Reading the same custom property keeps
   top equal to left/right by construction if the gutter is ever retuned.

   Specificity is deliberate: `.articles-cols .article-item.cg-article-card`
   is 0,3,0, which beats the legacy `.articles-cols .article-item` (0,2,0)
   regardless of style.css loading after this file — the companion-CSS
   technique this file already uses for its child overrides. The
   `.articles-cols` ancestor also scopes this to the blog-family card grid
   (index/archive/search/single-related), leaving the horizontal
   `.cg-article-card--event` tile — which is not inside one — untouched. */
.articles-cols .article-item.cg-article-card {
	padding-top: var( --indent );
}

/* Beats the legacy `.article-item .box-img{max-width:400px}` (style.css)
   so every card's image fills its grid cell edge-to-edge, uniform across
   the row regardless of column width at each breakpoint (stakeholder
   image-consistency ask). */
.article-item.cg-article-card .box-img {
	max-width: none;
}

.article-item.cg-article-card .box-img img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier( 0.16, 1, 0.3, 1 );
}

.article-item.cg-article-card:hover .box-img img {
	transform: scale( 1.04 );
}

.cg-article-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: 28px var( --box-pad ) var( --box-pad );
}

.cg-article-card__badge {
	margin-bottom: 10px;
}

/* Beats the legacy `.article-item .meta{color:var(--violet3)}` (style.css)
   — `--violet3` is the system's soft BORDER token (#D9D5CC), near-invisible
   as text on the card's cream fill; the category label reads as an accent
   eyebrow tag instead, matching `.cg-card__label`/`.cg-eyebrow` elsewhere. */
.article-item.cg-article-card .cg-article-card__meta {
	display: block;
	margin: 0;
	font-family: var( --font-sans );
	font-weight: 700;
	font-size: 10px;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var( --accent );
}

.cg-article-card__title {
	margin: 14px 0 0;
	white-space: normal;
}

/* Beats the legacy `.article-item .box-text > span{font:700 16px …}`
   (style.css) so the "Read More" link matches the shared `.cg-link`
   arrow-link type role instead of the retired large serif treatment. */
.article-item.cg-article-card .cg-article-card__link {
	margin-top: auto;
	padding-top: 20px;
	font-family: var( --font-sans );
	font-weight: 700;
	font-size: 10px;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var( --accent );
}

/* ------------------------------------------------------------------ *
 * Blog single (single.php)
 * ------------------------------------------------------------------ */

.cg-blog-post__content > .cg-rule {
	margin-bottom: 22px;
}

.cg-blog-post__meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px 18px;
	margin-bottom: 18px;
}

.cg-blog-post__date {
	font-family: var( --font-sans );
	font-size: 13px;
	color: var( --cg-muted );
}

/* #303: Tungsten Narrow Bold replaces Noe Text at 400 -- same rationale as
   `.cg-blog-title` above. */
.cg-blog-post__title {
	margin: 0 0 28px;
	font-family: var( --h1-font-family );
	font-weight: 700;
	font-size: clamp( 40px, 4.4vw, 70px );
	line-height: 1.1;
	letter-spacing: -0.3px;
	color: var( --cg-ink );
	text-wrap: balance;
}

/* Sidebar category list — the shared `.nav-blog`/`.blog-sidebar` classes
   (style.css) are also used by single-event.php (out of this issue's
   scope, #69) — scoped to `body.single-post` (WP's default single-post
   body class) so only the blog single is affected. `--rule` replaces a
   hardcoded light-lavender `rgba(224,208,243,.5)` divider left over from
   the pre-2.0 palette (the only value on this element that wasn't
   already token-mapped). */
body.single-post .nav-blog a {
	border-color: var( --rule );
}

/* #299 — blog posts collapse to a ~255px text column at >=1600px wide.
 *
 * Two width systems nest here and multiply instead of one winning:
 *   1. `.cg-band` caps its inner content box at 1314px via
 *      `padding-inline: var(--pad-x)` (css/tokens.css).
 *   2. Inside it, `.container-wrap.container-md` (style.css) swaps its
 *      normal fixed `1140px` for a PERCENTAGE at `@media (min-width:1600px)`
 *      — `--max-container-width: 65%`.
 *
 * Below 1600px the fixed 1140px is simply smaller than the band's 1314px, so
 * nothing conflicts. At >=1600px the 65% resolves against its containing
 * block, which is no longer the viewport but the already-capped band:
 *
 *     1314px x 0.65 = 854.1px      (measured live at 1728px: 854.094px)
 *
 * That 854px minus the fixed 351px sidebar leaves ~335px, and the <h1> —
 * `clamp(40px, 4.4vw, 70px)`, so 70px here — gets 255px of it and wraps two
 * words per line into a 693px-tall stack. It gets WORSE on wider monitors,
 * not better: the band caps at 1314px however wide the screen is, so the
 * result is 854px at 1600, 1728, 1920 and 2560 alike.
 *
 * NOT a mobile fallback, despite looking like one — verified at 1728px the
 * sidebar is still `display:block` and still beside the text; the mobile
 * rules (sidebar `display:none`, stacked) do not apply. Chasing breakpoints
 * would find nothing.
 *
 * Scoped to the blog post row, which is the ONLY place this nesting occurs:
 * a sweep of /blog/, /contact-us/, /events/, /careers/, /about-us/,
 * /work/<case-study>/, /media-services/, /awards-testimonials/ and the home
 * page at 1728px found zero other `.container-wrap` inside a `.cg-band`.
 * A blanket fix to style.css's rule would be a sitewide change to solve a
 * one-template bug.
 *
 * `100%` (not a re-fixed 1140px) because inside a band the band IS the
 * frame — this hands the row the 2.0 1314px token width, which is what the
 * surrounding hero and related-posts bands already use.
 *
 * Specificity is (0,3,0) on purpose: style.css's
 * `.container-wrap.container-md` is (0,2,0) and the css/ layer loads BEFORE
 * style.css, so matching it would lose on source order. Winning on
 * specificity is order-independent (docs/2.0-system-guide.md §2).
 */
@media ( min-width: 1600px ) {
	.cg-blog-post .container-wrap.container-md {
		--max-container-width: var( --content-w );
	}
}
