/**
 * TechBBQ Article — the single blog post page.
 *
 * Opens with the same gradient orb hero every other page uses (see startup-program-hero.css and
 * page-hero.css), with the same breadcrumb treatment, so an article reads as part of the site.
 * The orb is the PNG, not the generated gradient: the generated one measures 1.93:1 against the
 * PNG's 3.22:1, which is why the theme keeps the image.
 *
 * The 62 imported posts carry plain semantic HTML and no classes of their own, so the body is styled
 * by element. That is deliberate: an editor can paste ordinary markup and it lands on the design
 * system without needing to know any class names.
 *
 * Mobile first, min-width only, per the theme's CSS rules.
 */

.techbbq-article {
	--techbbq-article-header-offset: calc(
		var(--techbbq-banner-height) + var(--techbbq-space-1) + var(--techbbq-hero-header-bar, 72px)
	);
	--techbbq-article-breadcrumbs-top: calc(
		var(--techbbq-space-1) + var(--techbbq-hero-header-bar, 72px) + var(--techbbq-space-3)
	);

	background-color: var(--techbbq-bg-main);
	color: var(--techbbq-content-primary);
}

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

.techbbq-article__hero {
	position: relative;
	width: 100%;
	padding-block: calc(var(--techbbq-article-header-offset) + var(--techbbq-space-xl))
		var(--techbbq-space-2xl);
	overflow: hidden;
	background-color: var(--techbbq-bg-main);
}

.techbbq-article__orb {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-repeat: no-repeat;
	background-position: center top;
	background-size: cover;

	/* 2026-09-25 (Auri): use the site's standard hero artwork. Every page hero
	   (techbbq-page-hero__orb) renders hero-bg/hero-6.webp; articles and /blog/ were the only
	   templates still drawing the generated blob gradient, so they read as a different site. */
	background-image: url("../../images/hero-bg/hero-6.webp");
}

/* The generated blobs are what hero-6.webp replaces. Hidden rather than deleted so the markup
   single.php emits via TechBBQ_Gradient_Bg::render_orb() stays untouched and this is one
   revert away.

   The --blobs class also sets its own background-image gradient, and being a second class it
   beats the base .techbbq-article__orb rule on specificity. So the artwork has to be restated
   here, on the same selector, or the gradient keeps winning. */
.techbbq-article__orb--blobs .techbbq-hero__orb-gradients {
	display: none;
}

/* ---------------------------------------------------------------- orb
 *
 * Matched to assets/images/hero-orb-gradient.png, the artwork Auri pointed at: "two big circles
 * with blur around them and sort of melting a little bit and then there is just a slightly darker
 * color between them."
 *
 * Sampled from that PNG rather than guessed. It is orange edge to edge, running from #ba2d03 in
 * the bottom-left corner to #f56a00 on the right, with a darker seam where the two lobes meet.
 *
 * THE ARTWORK SOLVES ITS OWN CONTRAST. White on its brightest pixel is 2.66:1, which fails even
 * the large-text bar, but on the deep corner it is about 5.8:1. That is why the page heroes put
 * their copy bottom-left. This does the same, so no scrim is needed to rescue it: the text column
 * sits on the deep end by construction.
 *
 * The lobes are the blob elements from TechBBQ_Gradient_Bg, so they can drift. Heavily blurred and
 * only a few steps lighter than the ground, so they melt rather than read as separate circles.
 */
.techbbq-article__orb--blobs {
	--techbbq-orb-deep: #ba2d03;
	--techbbq-orb-mid: #d44200;
	--techbbq-orb-warm: #e85c01;
	--techbbq-orb-bright: #f56a00;
	--techbbq-orb-lobe: #f97a12;

	--techbbq-hero-blending: normal;
	--techbbq-hero-blob-blur: 3vw;
	--techbbq-hero-container-blur: 5vw;

	--techbbq-article-orb-size: 78vw;
	--techbbq-article-orb-size-mobile: 120vw;

	background-color: var(--techbbq-orb-mid);
	background-image: linear-gradient(
		102deg,
		var(--techbbq-orb-deep) 0%,
		var(--techbbq-orb-mid) 30%,
		var(--techbbq-orb-warm) 62%,
		var(--techbbq-orb-bright) 100%
	);
	overflow: hidden;
	isolation: isolate;
}

/* 2026-09-25 (Auri): the standard hero artwork replaces the generated gradient above.
   This must sit AFTER the block it overrides: same specificity (one class), so source order
   decides, and an earlier copy silently loses. */
.techbbq-article__orb--blobs {
	background-color: transparent;
	background-image: url("../../images/hero-bg/hero-6.webp");
}

/* A shade across the top strip only, for the breadcrumb row. Measured at 3.22:1 without it and 4.38:1 at 0.62 alpha,
   against the 4.5:1 small-text bar. The reference artwork is itself darker in its top-left corner
   (#cf5010 against #f56a00 on the right), so this follows the image rather than fighting it, and
   it stops well above the title. */
.techbbq-article__orb.techbbq-article__orb--blobs::before {
	content: "";
	position: absolute;
	z-index: 1;
	top: 0;
	right: 0;
	left: 0;
	height: 30%;
	background-image: linear-gradient(
		to bottom,
		rgba(13, 13, 13, 0.72) 0%,
		rgba(13, 13, 13, 0.42) 45%,
		rgba(13, 13, 13, 0) 100%
	);
}

/* Only the fade into the page below. The ground does the contrast work, so there is no scrim.
   Both classes: a modifier's ::after has the same specificity as the base's and would otherwise
   lose on source order. */
.techbbq-article__orb.techbbq-article__orb--blobs::after {
	content: "";
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	height: 34%;
	background-image: linear-gradient(to bottom, rgba(13, 13, 13, 0) 0%, var(--techbbq-bg-main) 100%);
}

.techbbq-article__orb--blobs .techbbq-hero__orb-gradients {
	position: absolute;
	inset: -10%;
	width: auto;
	height: auto;
	filter: blur(var(--techbbq-hero-container-blur));
}

/* Two lobes and a darker seam. The seam is a blob too, a few steps deeper than the ground, which
   is what makes the pair read as two circles melting rather than one wash. */
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--1,
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--2,
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--3 {
	width: var(--techbbq-article-orb-size-mobile);
	height: var(--techbbq-article-orb-size-mobile);
	left: auto;
}

/* Upper lobe, top right. */
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--1 {
	background: var(--techbbq-orb-lobe);
	top: -46%;
	right: -18%;
	opacity: 0.85;
	animation: techbbq-article-orb-drift-a 38s ease-in-out infinite;
}

/* Lower lobe, bottom right, brighter so the light pools there the way the PNG does. */
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--2 {
	display: block;
	background: var(--techbbq-orb-bright);
	top: 30%;
	right: -26%;
	opacity: 0.9;
	transform-origin: center center;
	animation: techbbq-article-orb-drift-b 46s ease-in-out infinite;
}

/* The seam between them. */
.techbbq-article__orb--blobs .techbbq-hero__orb-blob--3 {
	background: var(--techbbq-orb-mid);
	width: calc(var(--techbbq-article-orb-size-mobile) * 0.72);
	height: calc(var(--techbbq-article-orb-size-mobile) * 0.72);
	top: 4%;
	right: 6%;
	opacity: 0.55;
	transform-origin: center center;
	animation: techbbq-article-orb-drift-c 42s ease-in-out infinite;
}

@media (min-width: 768px) {
	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--1,
	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--2 {
		width: var(--techbbq-article-orb-size);
		height: var(--techbbq-article-orb-size);
	}

	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--3 {
		width: calc(var(--techbbq-article-orb-size) * 0.72);
		height: calc(var(--techbbq-article-orb-size) * 0.72);
	}
}

/* Very slight. A few percent each way, so it reads as breathing rather than sliding. */
@keyframes techbbq-article-orb-drift-a {
	0%,
	100% {
		transform: translate3d(0, 0, 0);
	}

	50% {
		transform: translate3d(-4%, 2%, 0);
	}
}

@keyframes techbbq-article-orb-drift-b {
	0%,
	100% {
		transform: translate3d(0, 0, 0);
	}

	50% {
		transform: translate3d(4%, -3%, 0);
	}
}

@keyframes techbbq-article-orb-drift-c {
	0%,
	100% {
		transform: translate3d(0, 0, 0);
	}

	50% {
		transform: translate3d(-5%, -2%, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--1,
	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--2,
	.techbbq-article__orb--blobs .techbbq-hero__orb-blob--3 {
		animation: none;
	}
}

/* Breadcrumbs, matching startup-program-hero.css exactly: absolute under the header bar,
   secondary colour, no underline, hover goes to primary. */
.techbbq-article__breadcrumbs-slot {
	position: absolute;
	top: var(--techbbq-article-breadcrumbs-top);
	right: 0;
	left: 0;
	z-index: 2;
}

.techbbq-article__breadcrumbs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--techbbq-space-1);
	align-items: center;
	margin: 0;
	font-family: var(--techbbq-font-family-body);
	font-size: var(--techbbq-text-paragraph-s-size);
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: 0.02em;
}

.techbbq-article__breadcrumb-link,
.techbbq-article__breadcrumb-sep {
	color: var(--techbbq-content-secondary);
}

.techbbq-article__breadcrumb-link {
	text-decoration: none;
}

.techbbq-article__breadcrumb-link:hover,
.techbbq-article__breadcrumb-link:focus-visible {
	color: var(--techbbq-content-primary);
	text-decoration: none;
}

.techbbq-article__breadcrumb-current {
	color: var(--techbbq-content-primary);
}

.techbbq-article__hero-inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: var(--techbbq-space-md);
	align-items: flex-start;
	max-width: 900px;
	margin-inline: auto;
}

/* The h2 token is a flat 88px with no mobile step, unlike H3 which the theme scales 30 / 42 / 48.
   Elementor headings never hit that, because Elementor sets its own per-breakpoint sizes; the two
   theme templates that carry `techbbq-text-h2` in markup do. At 375px an 88px "Groundbreakers" is
   654px wide, and the hero's `overflow: hidden` clips it off the screen rather than scrolling.

   The steps are the theme's own hero-title ladder in typography.css, 52 / 78 / 94, which is what
   every page hero already computes to at these widths. Only the top of it changes: the ladder ends
   at the H1 token and an article title ends at the H2 one, the cap single.php chose on 2026-09-11
   because an article title is a sentence and a page title is a name. So nothing here is a new
   number. The break-word is the backstop for any single word still too wide.

   The size rules carry the root class as well, because typography.css is enqueued after this file
   and `.techbbq-text-h2` is the same specificity: a bare `.techbbq-article__title` loses on source
   order and the title stays at 88px. Two classes beat one, so no !important is needed. */
.techbbq-article__title {
	margin: 0;
	text-wrap: balance;
}

/* 2026-09-25 (Auri): stepped down one level, H2 ladder -> H3 ladder.
   Was 52 / 78 / 88 (ending at --techbbq-text-h2-size). Now 30 / 42 / 48, which is the H3 ramp
   tokens.css already defines at these exact breakpoints, so this stays on the theme's scale
   instead of inventing a number. A flat 48px would have made mobile LARGER than it was. */
.techbbq-article .techbbq-article__title {
	font-size: 30px;
	overflow-wrap: break-word;
}

@media (min-width: 768px) {
	.techbbq-article .techbbq-article__title {
		font-size: 42px;
	}
}

@media (min-width: 1024px) {
	.techbbq-article .techbbq-article__title {
		font-size: var(--techbbq-text-h3-size);
	}
}

.techbbq-article__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--techbbq-space-2);
	align-items: center;
	margin: 0;
	color: var(--techbbq-content-primary);
}

/* A dot between items, never a dash. */
.techbbq-article__meta-sep {
	flex-shrink: 0;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background-color: var(--techbbq-content-accent-1);
}

.techbbq-article__byline a {
	color: inherit;
}

/* ------------------------------------------------------------------ featured image */

/* Sized to the text column, not the page. A portrait photo at full width filled the whole screen
   before the reader reached a word of the article. */
.techbbq-article__figure {
	max-width: 720px;
	margin: 0 auto;
}

.techbbq-article__figure img {
	display: block;
	width: 100%;
	height: auto;
	max-height: 420px;
	object-fit: cover;
	border-radius: var(--techbbq-radius-md);
}

/* ------------------------------------------------------------------ body */

.techbbq-article__main {
	padding-block: var(--techbbq-space-2xl) var(--techbbq-section-space-large);
}

/* 2026-09-25 (Auri): the text column sits on a raised surface instead of straight on the page
   ground, so long-form copy reads as a sheet rather than floating on black.
   #131313 is the theme's existing --techbbq-bg-surface, already used for card thumbs, the
   contact card and the current pagination chip, so this is the established "one step up"
   tone, not a new colour. #f2f2f2 on it still measures ~16.4:1.

   max-width 680px over 720px puts the measure at roughly 70 characters per line instead of 80.
   line-height 1.65 over 1.40 is the single biggest readability change here: this article runs
   79 paragraphs, and 1.4 is a UI value, not a long-form one. */
.techbbq-article__body {
	max-width: 680px;
	margin: var(--techbbq-space-2xl) auto 0;
	padding: var(--techbbq-space-2xl) var(--techbbq-space-xl);
	background-color: var(--techbbq-bg-surface);
	border: 1px solid var(--techbbq-color-grey-alpha-50-5);
	border-radius: var(--techbbq-radius-lg);
	/* Primary, not secondary. The 50% token is the site's tone for a one-line description under a
	   heading. An article is 12,000 words of it, and at that length it stops being readable. The
	   site's own long-form copy, the hero description, is full strength too. */
	color: var(--techbbq-content-primary);
}

/* 2026-09-25 (Auri): long-form leading, 1.65 instead of 1.4.
   single.php puts `techbbq-text-paragraph-m` on this same element, and typography.css is
   enqueued AFTER article.css, so a bare `.techbbq-article__body { line-height }` loses on
   source order at equal specificity. Two classes on one element beat one, which is the same
   trick the title size rules already use in this file. */
.techbbq-article__body.techbbq-text-paragraph-m,
.techbbq-article__body {
	line-height: 1.65;
}

.techbbq-article__body.techbbq-text-paragraph-m p,
.techbbq-article__body p {
	line-height: 1.65;
}

/* Mobile: a 32px inset on a 343px panel leaves only 279px of text. Tighten the gutter and drop
   the rounded card look at the narrowest width, where a full-bleed sheet reads better. */
@media (max-width: 599px) {
	.techbbq-article__body {
		padding: var(--techbbq-space-xl) var(--techbbq-space-md);
		border-radius: var(--techbbq-radius-md);
	}
}

.techbbq-article__body > *:first-child {
	margin-top: 0;
}

/* 2026-09-25 (Auri): 24px between paragraphs, was 16px. At line-height 1.65 a 16px gap is
   smaller than the leading inside the paragraph, so blocks ran together. The gap now reads as
   a deliberate break. */
.techbbq-article__body p {
	margin: 0 0 var(--techbbq-space-lg);
	color: inherit;
}

/* The opening paragraph acts as a lead-in, one step up from body copy. */
.techbbq-article__body > p:first-of-type {
	font-size: 20px;
	line-height: 1.6;
}

/* A heading that follows running copy gets real separation, so the article reads in sections
   rather than as one column of text. */
.techbbq-article__body p + h2,
.techbbq-article__body p + h3,
.techbbq-article__body figure + h2,
.techbbq-article__body figure + h3,
.techbbq-article__body blockquote + h2,
.techbbq-article__body blockquote + h3 {
	margin-top: var(--techbbq-space-2xl);
}

/* 2026-09-25 (Auri): a heading belongs to the text BELOW it, so the space above is now much
   larger than the space below (40 / 12 instead of 32 / 12). Proximity does the grouping. */
.techbbq-article__body h2,
.techbbq-article__body h3,
.techbbq-article__body h4,
.techbbq-article__body h5,
.techbbq-article__body h6 {
	margin: var(--techbbq-space-2xl) 0 var(--techbbq-space-sm);
	font-family: var(--techbbq-font-family-heading);
	color: var(--techbbq-content-primary);
	text-wrap: balance;
}

.techbbq-article__body h2 {
	font-size: 32px;
	line-height: 1.2;
	letter-spacing: -0.01em;
}

.techbbq-article__body h3 {
	font-size: 24px;
	line-height: 1.3;
}

.techbbq-article__body h4,
.techbbq-article__body h5,
.techbbq-article__body h6 {
	font-size: 20px;
	line-height: 1.35;
}

/* NO UNDERLINES ANYWHERE IN AN ARTICLE.
   link.css sets a global underline-on-hover, but it never actually shows on this site: of 289 links
   on /about-us/, the only ten that are not buttons, nav or cards are WordPress admin bar links. An
   article has 488 inline links, so that dormant rule would suddenly become the site's most visible
   link treatment. Switched off here. Links are told apart by colour, the way the contact card does
   it, which is the only real inline-link precedent in the theme. */
.techbbq-article__body h1 u,
.techbbq-article__body h2 u,
.techbbq-article__body h3 u,
.techbbq-article__body h4 u,
.techbbq-article__body h5 u,
.techbbq-article__body h6 u {
	text-decoration: none;
}

/* Accent 2, #fa7000, measures 6.83:1 on this background. Accent 1 red is only 3.45:1 and fails as
   text. Hover goes brighter to accent 3, #fd9d04 at 9.26:1, so the state change is visible without
   reaching for an underline. */
.techbbq-article__body a {
	color: var(--techbbq-content-accent-2);
}

/* A link inside a heading reads as a heading, so it keeps the heading's colour. The imported copy
   wraps 175 headings in an anchor, mostly speaker labels like "Al Gore, Former US Vice-President",
   and colouring those orange made them look like calls to action. */
.techbbq-article__body h1 a,
.techbbq-article__body h2 a,
.techbbq-article__body h3 a,
.techbbq-article__body h4 a,
.techbbq-article__body h5 a,
.techbbq-article__body h6 a,
.techbbq-article__body h1 a:hover,
.techbbq-article__body h2 a:hover,
.techbbq-article__body h3 a:hover,
.techbbq-article__body h4 a:hover,
.techbbq-article__body h5 a:hover,
.techbbq-article__body h6 a:hover {
	color: inherit;
	text-decoration: none;
}

/* 2026-09-25 (Auri, revised): matched to the Buy Tickets link treatment in ticket-info.css,
   which underlines at rest in accent 1 and shifts the RULE colour on hover, leaving the text
   itself alone. Softer than recolouring 488 inline links to red.

   Resting text stays accent 2 (#fa7000, 6.83:1) so links are findable without hovering; the
   1px rule sits in brand red; on hover the rule brightens to accent 3 and the text follows.
   Nothing here depends on red passing a text-contrast threshold, which it does not. */
.techbbq-article__body a {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-decoration-color: var(--techbbq-content-accent-1);
	text-underline-offset: 3px;
	transition: text-decoration-color 0.2s ease, color 0.2s ease;
}

.techbbq-article__body a:hover,
.techbbq-article__body a:focus-visible {
	color: var(--techbbq-content-accent-3);
	text-decoration-color: var(--techbbq-content-accent-3);
}

@media (prefers-reduced-motion: reduce) {
	.techbbq-article__body a {
		transition: none;
	}
}

/* A link wrapping only an image carries no text, so it takes the body colour and stays out of the
   way. Hello Elementor's reset.css sets a { color: #c36 }, a pink at 3.92:1, which reached every
   link this component did not name. */
.techbbq-article__body figure a {
	color: inherit;
}

.techbbq-article__body a:focus-visible {
	outline: 2px solid var(--techbbq-content-accent-1);
	outline-offset: 2px;
}

.techbbq-article__body strong,
.techbbq-article__body b {
	color: var(--techbbq-content-primary);
	font-weight: 600;
}

.techbbq-article__body ul,
.techbbq-article__body ol {
	margin: 0 0 var(--techbbq-space-md);
	padding-inline-start: var(--techbbq-space-lg);
	color: inherit;
}

.techbbq-article__body li {
	margin-bottom: var(--techbbq-space-2);
}

.techbbq-article__body img {
	max-width: 100%;
	height: auto;
	border-radius: var(--techbbq-radius-md);
}

.techbbq-article__body figure {
	margin: var(--techbbq-space-xl) 0;
}

.techbbq-article__body figcaption {
	margin-top: var(--techbbq-space-2);
	/* Secondary, not tertiary: tertiary measures 3.52:1 on this background and captions are
	   normal-size text, so they need 4.5:1. Secondary gives 4.89:1. */
	color: var(--techbbq-content-secondary);
}

/* Pull quote. 61 paragraphs across 17 of the 62 posts are pure quoted speech, promoted to
   <blockquote> by scripts/promote-blog-quotes.php. They are the only natural breaks in an
   interview, so they carry the visual rhythm: larger type, indented, an accent rule on the side.
   The text stays white. Orange here read as a warning rather than a quote. */
.techbbq-article__body blockquote {
	margin: var(--techbbq-space-2xl) 0;
	padding: 0 0 0 var(--techbbq-space-md);
	border-inline-start: 2px solid var(--techbbq-content-accent-1);
	font-family: var(--techbbq-font-family-heading);
	font-size: 22px;
	line-height: 1.45;
	letter-spacing: -0.01em;
	color: var(--techbbq-content-primary);
}

.techbbq-article__body blockquote p {
	margin: 0 0 var(--techbbq-space-2);
	color: inherit;
}

.techbbq-article__body blockquote p:last-child {
	margin-bottom: 0;
}

/* The attribution line a quote often ends on. */
.techbbq-article__body blockquote footer,
.techbbq-article__body blockquote cite {
	display: block;
	margin-top: var(--techbbq-space-2);
	font-family: var(--techbbq-font-family-body);
	font-size: var(--techbbq-text-paragraph-s-size);
	letter-spacing: 0.02em;
	color: var(--techbbq-content-secondary);
	font-style: normal;
}

.techbbq-article__body cite {
	display: block;
	margin-top: var(--techbbq-space-2);
	color: var(--techbbq-content-secondary);
	font-style: normal;
}

.techbbq-article__body hr {
	margin: var(--techbbq-space-xl) 0;
	border: 0;
	border-top: 1px solid var(--techbbq-border-secondary);
}

/* Imported copy leans on <br> for spacing. Keep lines readable without letting
   a run of them open a hole in the page. */
.techbbq-article__body br + br {
	line-height: 0.4;
}

/* ------------------------------------------------------------------ next read */

.techbbq-article__next {
	margin-top: var(--techbbq-section-space-medium);
	padding-top: var(--techbbq-space-xl);
	border-top: 1px solid var(--techbbq-border-secondary);
}

.techbbq-article__next-title {
	margin: 0 0 var(--techbbq-space-lg);
	font-family: var(--techbbq-font-family-heading);
	color: var(--techbbq-content-primary);
}

.techbbq-article__next-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--techbbq-space-md);
}

.techbbq-article-card {
	display: flex;
	flex-direction: column;
	gap: var(--techbbq-space-2);
	color: var(--techbbq-content-primary);
	text-decoration: none;
}

.techbbq-article-card:hover,
.techbbq-article-card:focus-visible {
	text-decoration: none;
}

.techbbq-article-card__thumb {
	position: relative;
	aspect-ratio: 16 / 9;
	max-width: 100%;
	overflow: hidden;
	border-radius: var(--techbbq-radius-lg);
	background-color: var(--techbbq-bg-surface);
}

.techbbq-article-card__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}

.techbbq-article-card:hover .techbbq-article-card__thumb img,
.techbbq-article-card:focus-visible .techbbq-article-card__thumb img {
	transform: scale(1.04);
}

/* 2026-09-25 (Auri): clamped to 3 lines.
   Titles on /blog/ run 35 to 163 characters, 1 to 5 lines, and the single 5-line title made its
   whole grid row 417px against 365px for every other row. A line clamp beats a character cut:
   it breaks at a real line rather than mid-word, adapts to the card's actual width at every
   breakpoint, and leaves the full title in the DOM for search engines and screen readers.
   11 of the 12 titles on page 1 are unaffected. */
.techbbq-article-card__title {
	margin: 0;
	font-family: var(--techbbq-font-family-heading);
	font-size: 20px;
	line-height: 1.3;
	color: var(--techbbq-content-primary);
	text-wrap: balance;

	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
}

/* 2026-09-25 (Auri, revised): the heavy red underline replaced with the Buy Tickets treatment.
   That page never recolours body text to red; it paints the brand gradient
   (--techbbq-gradient-accent-1) and animates a thin rule. Same language here.

   The title text stays #f2f2f2 at 16.6:1 rather than taking a gradient FILL, because the
   gradient's red end measures only 3.30:1 on the #131313 card and 20px/500 is not WCAG large
   text. So the brand colour lives in the rule, where contrast thresholds do not apply, and the
   text stays fully legible.

   The rule is a background-image on the block, grown from 0 to 100% width, so it animates
   (text-decoration cannot be transitioned). background-position keeps it growing left to right. */
.techbbq-article-card__title {
	background-image: var(--techbbq-gradient-accent-1);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0% 2px;
	padding-bottom: 2px;
	transition: background-size 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.techbbq-article-card:hover .techbbq-article-card__title,
.techbbq-article-card:focus-visible .techbbq-article-card__title {
	background-size: 100% 2px;
}

/* The thumb already scales 1.04 on hover; a 2px lift on the whole card makes the two read as one
   gesture rather than two unrelated effects. */
.techbbq-article-card {
	transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.techbbq-article-card:hover,
.techbbq-article-card:focus-visible {
	transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
	.techbbq-article-card,
	.techbbq-article-card__title,
	.techbbq-article-card__thumb img {
		transition: none;
	}

	.techbbq-article-card:hover,
	.techbbq-article-card:focus-visible {
		transform: none;
	}
}

.techbbq-article-card__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--techbbq-space-2);
	align-items: center;
	margin: 0;
	color: var(--techbbq-content-secondary);
}

@media (prefers-reduced-motion: reduce) {
	.techbbq-article-card__thumb img {
		transition: none;
	}

	.techbbq-article-card:hover .techbbq-article-card__thumb img,
	.techbbq-article-card:focus-visible .techbbq-article-card__thumb img {
		transform: none;
	}
}

/* ------------------------------------------------------------------ tablet up */

@media (min-width: 768px) {
	.techbbq-article__hero {
		padding-block: calc(var(--techbbq-article-header-offset) + var(--techbbq-space-2xl))
			var(--techbbq-space-3xl);
	}

	/* 2026-09-25 (Auri): 32px, was 40px. The page title dropped to 48px in this same session,
	   so a 40px section heading sat almost on top of it and the hierarchy flattened. 32px keeps
	   a clear step between title, section heading and 18px body. */
	.techbbq-article__body h2 {
		font-size: 32px;
	}

	.techbbq-article__body h3 {
		font-size: 24px;
	}

	.techbbq-article__next-grid {
		grid-template-columns: repeat(3, 1fr);
		gap: var(--techbbq-space-lg);
	}
}
