/*
 * News & Community landing, category archives and single articles.
 * Shared card/chip/section styles come from components.css.
 */

.tg-news { padding-top: var(--tg-band-y); }
.tg-news__title { font-size: clamp(var(--tg-fs-2xl), 5vw, var(--tg-fs-3xl)); text-transform: uppercase; margin: 0 0 var(--tg-sp-4); }
.tg-news__desc { color: var(--tg-text-muted); margin-bottom: var(--tg-sp-4); }
.tg-news-tabs { border-block: var(--tg-bw) solid var(--tg-border); margin-bottom: var(--tg-sp-6); }

/* Landing layout: main + sidebar */
.tg-news__layout { display: grid; grid-template-columns: 1fr; gap: var(--tg-sp-7); padding-bottom: var(--tg-band-y-loose); }
@media (min-width: 1000px) { .tg-news__layout { grid-template-columns: minmax(0, 1fr) 320px; } }

/* Breaking hero */
.tg-news__hero { display: block; border-radius: var(--tg-radius-lg); overflow: hidden; border: var(--tg-bw) solid var(--tg-border); background: var(--tg-bg-muted); color: inherit; margin-bottom: var(--tg-sp-6); }
.tg-news__hero:hover { text-decoration: none; }
.tg-news__hero-media { display: block; aspect-ratio: 16/8; background: var(--tg-n-200); }
.tg-news__hero-media img { width: 100%; height: 100%; object-fit: cover; }
.tg-news__hero-body { display: block; padding: var(--tg-sp-5); }
.tg-news__hero-title { display: block; font-family: var(--tg-font-head); font-weight: var(--tg-fw-black); font-size: clamp(var(--tg-fs-lg), 3vw, var(--tg-fs-2xl)); line-height: 1.1; margin: var(--tg-sp-3) 0; }
.tg-news__hero-excerpt { display: block; color: var(--tg-text-muted); margin-bottom: var(--tg-sp-3); }
.tg-news__hero-meta { display: block; font-size: var(--tg-fs-sm); color: var(--tg-text-muted); margin-bottom: var(--tg-sp-4); }

/* Category cards row */
.tg-news__cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--tg-sp-3); margin-bottom: var(--tg-sp-7); }
@media (min-width: 700px) { .tg-news__cards { grid-template-columns: repeat(5, 1fr); } }
.tg-news__card { display: flex; flex-direction: column; gap: var(--tg-sp-2); padding: var(--tg-sp-4); border: var(--tg-bw) solid var(--tg-border); border-radius: var(--tg-radius); background: var(--tg-bg); color: inherit; }
.tg-news__card:hover { text-decoration: none; border-color: var(--tg-green); }
.tg-news__card-title { font-weight: var(--tg-fw-semi); font-size: var(--tg-fs-sm); line-height: 1.3; }
.tg-news__card-meta { font-size: var(--tg-fs-xs); color: var(--tg-text-muted); margin-top: auto; }

.tg-news__more-head { font-size: var(--tg-fs-xl); margin-bottom: var(--tg-sp-5); }
.tg-news__grid { display: grid; grid-template-columns: 1fr; gap: var(--tg-sp-5); }
@media (min-width: 560px) { .tg-news__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .tg-news__grid { grid-template-columns: repeat(3, 1fr); } }

/* Equal-height cards in the ONE-COLUMN layout.

   From two columns up, CSS grid stretches every card in a row to the tallest in
   that row, so they already match. Below 560px each card is its own row and its
   height follows its headline: measured across six categories at 430px the
   cards came out at 309px, 331px or 354px for a one, two or three line title.
   That is what made the first card, the one under the tab row, jump as you
   moved from tab to tab.

   The title is given a fixed allowance of two lines, which is what 97% of 60
   sampled headlines already use (45% one line, 52% two, 3% three), so the only
   visible change is that a one-line headline now reserves the second line and a
   three-line one is clipped at two. Clamping is kept to this breakpoint: in the
   two and three column layouts the columns are narrower and three-line titles
   are the norm, where a two-line clamp would truncate most of them. */
@media (max-width: 559px) {
	.tg-news__grid .tg-post-card__title {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
		/* line-height on this title is 1.25, so two lines is 2.5em. Reserved as
		   well as clamped: without the min-height a one-line headline still
		   makes a shorter card. */
		min-height: 2.5em;
	}
}

/* Sidebar */
.tg-news__side-panel { border: var(--tg-bw) solid var(--tg-border); border-radius: var(--tg-radius-lg); padding: var(--tg-sp-5); position: sticky; top: calc(var(--tg-header-h) + var(--tg-sp-4)); }
.tg-news__side-head { font-size: var(--tg-fs-lg); margin: 0 0 var(--tg-sp-4); }
.tg-news__list { list-style: none; margin: 0 0 var(--tg-sp-4); padding: 0; }
.tg-news__list li { padding: var(--tg-sp-3) 0; border-bottom: var(--tg-bw) solid var(--tg-border); }
.tg-news__list li:last-child { border-bottom: 0; }
.tg-news__list a { display: block; font-weight: var(--tg-fw-semi); font-size: var(--tg-fs-sm); color: var(--tg-text); }
.tg-news__list a:hover { color: var(--tg-link); }
.tg-news__list-meta { display: block; font-size: var(--tg-fs-xs); color: var(--tg-text-muted); margin-top: 2px; }

/* ===== Single article ===== */

/* `minmax(0, 1fr)`, not `1fr`. A bare `1fr` has an implicit minimum of AUTO, so
   the column refuses to shrink below its content's min-content width - and the
   migrated posts carry hard-coded `width="840"` on inline images (279 posts do).
   The column was blowing out to 840px inside a 390px phone, taking the title,
   byline and hero with it, and `img { max-width: 100% }` could not save it
   because 100% OF A COLUMN THE IMAGE ITSELF WIDENED is still 840px. The desktop
   rule below already had the 0 minimum, which is why this only broke on mobile. */
.tg-article__layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tg-sp-7); padding-block: var(--tg-band-y) var(--tg-band-y-loose); }
@media (min-width: 1000px) { .tg-article__layout { grid-template-columns: minmax(0, 1fr) 320px; } }
/* The article fills the column it is given. It used to be capped at the 720px
   reading measure, which squeezed the title, hero, body and shop block into 720
   of a ~1000px column and left 320px of dead space beside them.
   The body copy is NOT capped either, on the client's instruction: the text is
   to match the width of everything else on the page. That gives a longer line
   than a reading measure would, so if it ever reads as too wide the fix is one
   line - put `max-width: var(--tg-maxw-text)` back on .tg-prose. */
/* Belt and braces: a grid item's default `min-width: auto` is the actual
   mechanism above, so it is cancelled on the items themselves too. Anything
   dropped into the article later (a table, an embed) then cannot widen it. */
.tg-article, .tg-article__side { min-width: 0; }
.tg-article { max-width: none; }
.tg-article__title { font-size: clamp(var(--tg-fs-2xl), 5vw, var(--tg-fs-3xl)); line-height: 1.05; margin: 0 0 var(--tg-sp-4); }
.tg-article__standfirst { font-size: var(--tg-fs-md); color: var(--tg-text-muted); margin-bottom: var(--tg-sp-4); }
.tg-article__byline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--tg-sp-4); font-size: var(--tg-fs-sm); color: var(--tg-text-muted); padding-block: var(--tg-sp-4); border-block: var(--tg-bw) solid var(--tg-border); margin-bottom: var(--tg-sp-5); }
.tg-share { display: inline-flex; gap: var(--tg-sp-2); margin-left: auto; }
.tg-share a { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--tg-radius-pill); border: var(--tg-bw) solid var(--tg-border-strong); color: var(--tg-text); font-weight: var(--tg-fw-bold); font-size: var(--tg-fs-sm); }
.tg-share a:hover { background: var(--tg-green-fill); border-color: var(--tg-green-fill); color: #fff; text-decoration: none; }
/* The hero is centred and never upscaled. At `width: 100%` a 600x875 portrait
   was being stretched to the full column and rendering 1447px tall - taller
   than the viewport, and blurred by a 1.65x upscale from a 600px source. With
   `width: auto` plus `max-width: 100%` an image renders at its natural size
   unless it is wider than the column, so small portraits stay sharp and
   landscape photographs still fill the width. The height cap stops anything
   taller than the screen regardless. */
.tg-article__hero {
	position: relative;
	margin: 0 0 var(--tg-sp-5); border-radius: var(--tg-radius-lg); overflow: hidden;
	display: flex; justify-content: center; background: var(--tg-paper);
}
/* Fill the frame with a blurred copy of the photograph itself.

   A portrait image hits the height cap below, so its width shrinks and the
   frame's paper colour showed as two grey bars either side. Cropping to a fixed
   ratio would have taken the top off a tall shot, and re-cropping every picture
   by hand was the alternative the client was offered; blurring the same file
   costs nothing, needs no new artwork and works for every post already
   published. Scaled up slightly so the blur has no soft edge at the frame. */
.tg-article__hero::before {
	content: "";
	position: absolute; inset: 0;
	background-image: var(--tg-article-hero, none);
	background-size: cover;
	background-position: center;
	filter: blur(26px) saturate(1.15);
	transform: scale(1.12);
	opacity: .92;
}
/* No photograph set: no blurred layer, and the frame stays as it was. */
.tg-article__hero:not([style*="--tg-article-hero"])::before { display: none; }
.tg-article__hero img {
	position: relative; z-index: 1;
	width: auto; height: auto;
	max-width: 100%; max-height: 70vh;
}

.tg-article__summary { background: var(--tg-green-soft); border: var(--tg-bw) solid var(--tg-green-line); border-radius: var(--tg-radius-lg); padding: var(--tg-sp-5); margin: 0 0 var(--tg-sp-6); }
.tg-article__summary h2 { font-size: var(--tg-fs-lg); text-transform: uppercase; margin: 0 0 var(--tg-sp-3); color: var(--tg-green-strong); }
.tg-article__summary ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--tg-sp-2); }
.tg-article__summary li { display: flex; align-items: flex-start; gap: var(--tg-sp-2); }
.tg-article__summary li svg { color: var(--tg-green-strong); flex: 0 0 auto; margin-top: 3px; }


.tg-article__side { display: block; }
.tg-article__related { display: grid; gap: var(--tg-sp-4); }
@media (min-width: 1000px) {
	.tg-article__side { position: sticky; top: calc(var(--tg-header-h) + var(--tg-sp-4)); align-self: start; }
}

/* ===== Article sidebar modules (brief p9) ===== */
.tg-sidecard {
	border: var(--tg-bw) solid var(--tg-border); border-radius: var(--tg-radius-lg);
	padding: var(--tg-sp-5); margin-bottom: var(--tg-sp-5); background: var(--tg-bg);
}
.tg-sidecard__head {
	font-size: var(--tg-fs-sm); text-transform: uppercase; letter-spacing: .08em;
	font-weight: var(--tg-fw-bold); margin: 0 0 var(--tg-sp-4);
}
/* On this page */
.tg-onthispage ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--tg-sp-1); }
.tg-onthispage a {
	display: flex; align-items: center; justify-content: space-between; gap: var(--tg-sp-3);
	padding: var(--tg-sp-2) 0; color: var(--tg-text); font-size: var(--tg-fs-sm);
	border-bottom: var(--tg-bw) solid var(--tg-border);
}
.tg-onthispage li:last-child a { border-bottom: 0; }
.tg-onthispage a:hover { color: var(--tg-link); text-decoration: none; }
.tg-onthispage svg { color: var(--tg-green); flex: 0 0 auto; }
/* Shop promo */
.tg-promo {
	border: 0; color: #fff; background-color: var(--tg-black);
	background-image: linear-gradient(100deg, rgba(0,0,0,.95) 40%, rgba(0,0,0,.4) 100%), var(--tg-card-img, none);
	background-size: cover; background-position: center right;
}
.tg-promo__title { font-size: var(--tg-fs-xl); text-transform: uppercase; line-height: 1.05; margin: 0 0 var(--tg-sp-3); }
.tg-promo__accent { color: var(--tg-green); }
.tg-promo__text { color: var(--tg-n-300); font-size: var(--tg-fs-sm); margin: 0 0 var(--tg-sp-4); max-width: 30ch; }
/* Have your say */
.tg-poll__q { font-weight: var(--tg-fw-semi); margin: 0 0 var(--tg-sp-4); }
.tg-poll__form { display: grid; gap: var(--tg-sp-3); }
.tg-poll__opt {
	display: grid; grid-template-columns: 46px minmax(0, 1fr); gap: var(--tg-sp-3); align-items: center;
	text-align: left; padding: var(--tg-sp-2); border: var(--tg-bw) solid var(--tg-border);
	border-radius: var(--tg-radius); background: var(--tg-bg); color: var(--tg-text); font: inherit;
}
.tg-poll__opt:hover { border-color: var(--tg-green); }
.tg-poll__opt strong { display: block; }
.tg-poll__opt span span { display: block; font-size: var(--tg-fs-sm); color: var(--tg-text-muted); }
.tg-poll__icon {
	display: inline-flex; align-items: center; justify-content: center;
	width: 46px; height: 46px; border-radius: var(--tg-radius-sm); color: #fff;
}
.tg-poll__opt--yes .tg-poll__icon { background: var(--tg-green); }
.tg-poll__opt--no .tg-poll__icon { background: #cf3b2e; }
.tg-poll__results { list-style: none; margin: 0 0 var(--tg-sp-3); padding: 0; display: grid; gap: var(--tg-sp-3); }
.tg-poll__rowhead { display: flex; justify-content: space-between; font-size: var(--tg-fs-sm); margin-bottom: 4px; }
.tg-poll__bar { display: block; height: 10px; border-radius: var(--tg-radius-pill); background: var(--tg-n-200); overflow: hidden; }
.tg-poll__bar span { display: block; height: 100%; border-radius: inherit; }
.tg-poll__bar--yes span { background: var(--tg-green); }
.tg-poll__bar--no span { background: #cf3b2e; }
.tg-poll__total, .tg-poll__link { font-size: var(--tg-fs-sm); color: var(--tg-text-muted); margin: 0; }
.tg-poll__link a { font-weight: var(--tg-fw-semi); }

/* ===== Keep reading, related, product row ===== */
.tg-keepreading { margin: var(--tg-sp-7) 0 0; }
.tg-keepreading__grid { display: grid; gap: var(--tg-sp-3); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.tg-keepreading__chip {
	display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: var(--tg-sp-3); align-items: center;
	padding: var(--tg-sp-3); border-radius: var(--tg-radius); background: var(--tg-bg-muted); color: inherit;
}
.tg-keepreading__chip:hover { text-decoration: none; background: var(--tg-green-soft); }
.tg-keepreading__icon {
	display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
	border-radius: var(--tg-radius-pill); background: var(--tg-green-fill); color: #fff;
}
.tg-keepreading__title { display: block; font-weight: var(--tg-fw-semi); font-size: var(--tg-fs-sm); line-height: 1.3; }
.tg-keepreading__cta { display: block; font-size: var(--tg-fs-xs); color: var(--tg-green-text); font-weight: var(--tg-fw-semi); margin-top: 2px; }

.tg-article__related-wrap { margin-top: var(--tg-sp-7); }
.tg-article__related { display: grid; gap: var(--tg-sp-4); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.tg-artprods { margin-top: var(--tg-sp-7); padding: var(--tg-sp-5); border-radius: var(--tg-radius-lg); background: var(--tg-bg-muted); }
.tg-artprods__head p { margin: calc(var(--tg-sp-3) * -1) 0 var(--tg-sp-4); color: var(--tg-text-muted); font-size: var(--tg-fs-sm); }
.tg-artprods__grid { display: grid; gap: var(--tg-sp-3); grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.tg-artprod { display: block; padding: var(--tg-sp-3); border-radius: var(--tg-radius); background: var(--tg-white); color: var(--tg-ink); text-align: center; }
.tg-artprod:hover { text-decoration: none; box-shadow: var(--tg-shadow); }
.tg-artprod__media img { width: 100%; height: 120px; object-fit: contain; }
.tg-artprod__name { display: block; font-size: var(--tg-fs-sm); margin-top: var(--tg-sp-2); }
.tg-artprod__price { display: block; font-weight: var(--tg-fw-bold); margin-top: 2px; }

/* A section dropped inside the article column brings its own .tg-container with
   it, so the page gutter is applied twice and its contents sit 40px inside
   everything else on the page. The article column IS the container here, so the
   nested one gives up its gutter and its max-width. */
.tg-article .tg-container {
	max-width: none;
	padding-inline: 0;
}
